/** * W5500 SPI port for portal panel adapter (SPI1, GP9–13). * Derived from WIZnet-PICO-C port/ioLibrary_Driver (BSD-3-Clause). */ #include #include "board_config.h" #include "wizchip_conf.h" #include "wizchip_spi.h" #include "hardware/gpio.h" #include "hardware/spi.h" #include "pico/binary_info.h" #include "pico/critical_section.h" #include "pico/stdlib.h" static critical_section_t g_wizchip_cri_sec; static inline void wizchip_select(void) { gpio_put(PIN_CS, 0); } static inline void wizchip_deselect(void) { gpio_put(PIN_CS, 1); } static uint8_t wizchip_read(void) { uint8_t rx = 0; uint8_t tx = 0xff; spi_read_blocking(SPI_PORT, tx, &rx, 1); return rx; } static void wizchip_write(uint8_t tx) { spi_write_blocking(SPI_PORT, &tx, 1); } static void wizchip_critical_section_lock(void) { critical_section_enter_blocking(&g_wizchip_cri_sec); } static void wizchip_critical_section_unlock(void) { critical_section_exit(&g_wizchip_cri_sec); } void wizchip_reset(void) { gpio_init(PIN_RST); gpio_set_dir(PIN_RST, GPIO_OUT); gpio_put(PIN_RST, 0); sleep_ms(100); gpio_put(PIN_RST, 1); sleep_ms(100); bi_decl(bi_1pin_with_name(PIN_RST, "W5500 RESET")); } void wizchip_spi_initialize(void) { spi_init(SPI_PORT, SPI_CLK_MHZ * 1000 * 1000); gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI); gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); bi_decl(bi_3pins_with_func(PIN_MISO, PIN_MOSI, PIN_SCK, GPIO_FUNC_SPI)); gpio_init(PIN_CS); gpio_set_dir(PIN_CS, GPIO_OUT); gpio_put(PIN_CS, 1); bi_decl(bi_1pin_with_name(PIN_CS, "W5500 CS")); } void wizchip_cris_initialize(void) { critical_section_init(&g_wizchip_cri_sec); reg_wizchip_cris_cbfunc(wizchip_critical_section_lock, wizchip_critical_section_unlock); } void wizchip_initialize(void) { wizchip_deselect(); reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); reg_wizchip_spi_cbfunc(wizchip_read, wizchip_write); uint8_t memsize[2][8] = { {2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}, }; if (ctlwizchip(CW_INIT_WIZCHIP, (void *)memsize) == -1) { printf("W5500 init failed\n"); return; } uint8_t link = PHY_LINK_OFF; do { if (ctlwizchip(CW_GET_PHYLINK, (void *)&link) == -1) { printf("PHY link unknown\n"); return; } } while (link == PHY_LINK_OFF); } void wizchip_check(void) { if (getVERSIONR() != 0x04) { printf("W5500 version mismatch: 0x%02x\n", getVERSIONR()); while (1) { tight_loop_contents(); } } } void network_initialize(wiz_NetInfo net_info) { ctlnetwork(CN_SET_NETINFO, (void *)&net_info); } void print_network_information(wiz_NetInfo net_info) { ctlnetwork(CN_GET_NETINFO, (void *)&net_info); printf("MAC %02X:%02X:%02X:%02X:%02X:%02X\n", net_info.mac[0], net_info.mac[1], net_info.mac[2], net_info.mac[3], net_info.mac[4], net_info.mac[5]); printf("IP %d.%d.%d.%d\n", net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3]); }