Add portal web simulator, SPI bridges, and Pico firmware updates.

Bring the five-panel hex portal online with a browser 3D/schematic preview, Pi SPI backends, and renamed multi-panel Pico UDP firmware.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-30 14:54:51 +12:00
parent d5cab2efdf
commit 5094c7bcee
78 changed files with 62251 additions and 832 deletions

121
firmware/pico/wizchip_spi.c Normal file
View File

@@ -0,0 +1,121 @@
/**
* W5500 SPI port for portal panel adapter (SPI1, GP913).
* Derived from WIZnet-PICO-C port/ioLibrary_Driver (BSD-3-Clause).
*/
#include <stdio.h>
#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]);
}