diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4fdaf4ba..e6b9e30c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -131,6 +131,7 @@ jobs: - path: rp2040/pico-rndis-dashboard - path: rp2040/pico-w - path: rp2040/pico-w5500 + target: test name: ${{ matrix.example.path }} steps: - uses: actions/checkout@v3 diff --git a/examples/rp2040/pico-w5500/CMakeLists.txt b/examples/rp2040/pico-w5500/CMakeLists.txt index 1e246630..829dff0c 100644 --- a/examples/rp2040/pico-w5500/CMakeLists.txt +++ b/examples/rp2040/pico-w5500/CMakeLists.txt @@ -1,16 +1,23 @@ cmake_minimum_required(VERSION 3.13) include(pico-sdk/pico_sdk_init.cmake) -project(example) +project(firmware) pico_sdk_init() -add_executable(example main.c mongoose.c) -target_link_libraries(example pico_stdlib hardware_spi) -pico_add_extra_outputs(example) +add_executable(firmware + main.c + ../../../mongoose.c + ../../device-dashboard/net.c + ../../device-dashboard/packed_fs.c) +target_include_directories(firmware PUBLIC ../../..) +target_link_libraries(firmware pico_stdlib hardware_spi) +pico_add_extra_outputs(firmware) # Enable USB output. Comment out in order to use UART -pico_enable_stdio_usb(example 1) -pico_enable_stdio_uart(example 0) +pico_enable_stdio_usb(firmware 0) +pico_enable_stdio_uart(firmware 1) # Mongoose build flags add_definitions(-DMG_ENABLE_MIP=1) +add_definitions(-DMG_ENABLE_PACKED_FS=1) +add_definitions(-DMG_ENABLE_FILE=0) diff --git a/examples/rp2040/pico-w5500/Makefile b/examples/rp2040/pico-w5500/Makefile index 3c375c5e..cc341abc 100644 --- a/examples/rp2040/pico-w5500/Makefile +++ b/examples/rp2040/pico-w5500/Makefile @@ -1,7 +1,7 @@ SDK_VERSION ?= 1.4.0 SDK_REPO ?= https://github.com/raspberrypi/pico-sdk -all example build: pico-sdk +all example build build/firmware.uf2: pico-sdk main.c test -d build || mkdir build cd build && cmake .. && make @@ -9,5 +9,15 @@ pico-sdk: git clone --depth 1 -b $(SDK_VERSION) $(SDK_REPO) $@ cd $@ && git submodule update --init +# Requires env variable VCON_API_KEY set +DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/3 +test: update + curl --fail -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt + grep 'Ethernet: up' /tmp/output.txt + grep 'MQTT connected' /tmp/output.txt + +update: build/firmware.uf2 + curl --fail -su :$(VCON_API_KEY) $(DEVICE_URL)/ota?uf2=1 --data-binary @$< + clean: rm -rf pico-sdk build diff --git a/examples/rp2040/pico-w5500/main.c b/examples/rp2040/pico-w5500/main.c index f95ab6b9..34c82763 100644 --- a/examples/rp2040/pico-w5500/main.c +++ b/examples/rp2040/pico-w5500/main.c @@ -8,28 +8,21 @@ #include "mongoose.h" +enum { BLINK_PERIOD_MS = 1000 }; enum { LED = 25, SPI_CS = 17, SPI_CLK = 18, SPI_TX = 19, SPI_RX = 16 }; // Pins -enum { STATUS_TIMER_MS = 3000, BLINK_TIMER_MS = 250 }; // Timeouts - -static void spi_begin(void *spi) { - gpio_put(SPI_CS, 0); -} - -static void spi_end(void *spi) { - gpio_put(SPI_CS, 1); -} +static void spi_begin(void *spi) { gpio_put(SPI_CS, 0); } +static void spi_end(void *spi) { gpio_put(SPI_CS, 1); } static uint8_t spi_txn(void *spi, uint8_t byte) { uint8_t result = 0; spi_write_read_blocking(spi0, &byte, &result, 1); - // MG_INFO(("%x -> %x", byte, result)); return result; } -static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { - if (ev == MG_EV_HTTP_MSG) { - mg_http_reply(c, 200, "", "ok\n"); - } +static void timer_cb(void *arg) { + gpio_put(PICO_DEFAULT_LED_PIN, !gpio_get_out_level(PICO_DEFAULT_LED_PIN)); + bool up = ((struct mip_if *) arg)->state == MIP_STATE_READY; + MG_INFO(("Ethernet: %s", up ? "up" : "down")); // Show network status } int main(void) { @@ -41,8 +34,7 @@ int main(void) { gpio_set_dir(LED, GPIO_OUT); // Init SPI pins - uint r = spi_init(spi0, 500 * 1000); - MG_INFO(("r = %x\n", r)); + spi_init(spi0, 500 * 1000); gpio_set_function(SPI_RX, GPIO_FUNC_SPI); // MISO gpio_set_function(SPI_TX, GPIO_FUNC_SPI); // MOSI gpio_set_function(SPI_CLK, GPIO_FUNC_SPI); // CLK @@ -55,25 +47,23 @@ int main(void) { struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 5}, .driver = &mip_driver_w5500, .driver_data = &spi}; - struct mg_mgr mgr; // Declare event manager - mg_mgr_init(&mgr); // Init event manager - mg_log_set(MG_LL_DEBUG); // Set DEBUG log level - mip_init(&mgr, &mif); // Init TCP/IP stack - mg_http_listen(&mgr, "http://0.0.0.0", fn, NULL); // HTTP listener + struct mg_mgr mgr; // Declare event manager + mg_mgr_init(&mgr); // Init event manager + mg_log_set(MG_LL_DEBUG); // Set DEBUG log level + mip_init(&mgr, &mif); // Init TCP/IP stack + mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_cb, &mif); - bool led_on = false; // Initial LED state - uint64_t status_timer = 0, blink_timer = 0; // Initial timer expirations + MG_INFO(("Waiting until network is up...")); + while (mif.state != MIP_STATE_READY) { + mg_mgr_poll(&mgr, 0); + } - // Infinite event manager loop + MG_INFO(("Initialising application...")); + extern void device_dashboard_fn(struct mg_connection *, int, void *, void *); + mg_http_listen(&mgr, "http://0.0.0.0", device_dashboard_fn, &mgr); + + MG_INFO(("Starting event loop")); for (;;) { - if (mg_timer_expired(&blink_timer, BLINK_TIMER_MS, mg_millis())) { - led_on = !led_on; // Flip LED state - if (mip_driver_w5500.up(&mif)) led_on = true; // Always on if Eth up - gpio_put(LED, led_on); // Set LED - } - if (mg_timer_expired(&status_timer, STATUS_TIMER_MS, mg_millis())) { - MG_INFO(("Ethernet: %s", mip_driver_w5500.up(&mif) ? "up" : "down")); - } mg_mgr_poll(&mgr, 1); } diff --git a/examples/rp2040/pico-w5500/mongoose.c b/examples/rp2040/pico-w5500/mongoose.c deleted file mode 120000 index 5e522bbc..00000000 --- a/examples/rp2040/pico-w5500/mongoose.c +++ /dev/null @@ -1 +0,0 @@ -../../../mongoose.c \ No newline at end of file diff --git a/examples/rp2040/pico-w5500/mongoose.h b/examples/rp2040/pico-w5500/mongoose.h deleted file mode 120000 index ee4ac823..00000000 --- a/examples/rp2040/pico-w5500/mongoose.h +++ /dev/null @@ -1 +0,0 @@ -../../../mongoose.h \ No newline at end of file