diff --git a/Makefile b/Makefile index a4b4168..50f6bef 100644 --- a/Makefile +++ b/Makefile @@ -5,9 +5,10 @@ all: cd src/pico_build; make -j4 @echo "build pico_w" mkdir -p src/pico_w_build - cd src/pico_w_build; make -j4 + cd src/pico_w_build; make - +#see fsfe reuse tool (https://git.fsfe.org/reuse/tool) @echo "reuse (license) check" - reuse lint + pipx run reuse lint # rebuild rebuild: @@ -19,13 +20,3 @@ rebuild: rm -rf src/pico_w_build mkdir src/pico_w_build cd src/pico_w_build; cmake .. -DPICO_BOARD=pico_w; make -j4 - -#install fsfe reuse tool (https://git.fsfe.org/reuse/tool) -# pre-conditions: -# - Python 3.6+ -# - pip -# install pre-conditions in Debian like linux distros: -# - sudo apt install python3 -# - sudo apt install python3-pip -reuse: - pip3 install --user --upgrade reuse diff --git a/README.md b/README.md index 3b5d067..86694d4 100644 --- a/README.md +++ b/README.md @@ -49,12 +49,14 @@ To mitigate some of the function setting issues the pico-cs command station is o - Connect the Raspberry Pi Pico to your PC via an USB cable - [Build](#build) the pico-cs firmware - Install firmware (Pico: cs.uf2, Pico W: cs_w.uf2) via BOOTSEL mode (see [Raspberry Pi Pico documentation](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html)) -- On macOS Ventura copying via drag&drop in Finder was broken but seems to work again with version 13.1 - anyway, copying the file via command line is always an option: +- On macOS Ventura copying via drag&drop in Finder was broken but seems to work again with version 13.1 - anyway, copying the file via the command line is always an option: ``` cp -X cs.uf2 /Volumes/RPI-RP2/ cp -X cs_w.uf2 /Volumes/RPI-RP2/ ``` -- Use a terminal emulation tool supporting serial over USB communication like the Serial Monotor of the [Arduino IDE](https://www.arduino.cc/en/software) +- Use a terminal emulation tool supporting serial over USB communication like + - the Serial Monotor of the [Arduino IDE](https://www.arduino.cc/en/software) or + - the [Serial Monitor](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-serial-monitor) extension of [Visual Studio Code](https://code.visualstudio.com/) - Set the baud rate to 115200 and \ (Carriage Return) as command / message ending character - The firmware uses the following Raspberry Pi Pico GPIOs: - GP2: DCC signal output @@ -113,15 +115,15 @@ File /firmware/src/pico_build/cs.uf2: Program Information name: cs - version: v0.8.0 + version: web site: https://github.com/pico-cs description: pico-cs DCC command station features: Refresh buffer size 128 double reset -> BOOTSEL UART stdin / stdout USB stdin / stdout - binary start: 0x10000000 - binary end: 0x1000e534 + binary start: + binary end: Fixed Pin Information 0: UART0 TX @@ -133,21 +135,21 @@ Fixed Pin Information 25: On-board LED Build Information - sdk version: 1.4.0 + sdk version: pico_board: pico boot2_name: boot2_w25q080 - build date: Feb 6 2023 + build date: build attributes: Release ``` ``` ./picotool info -a /firmware/src/pico_w_build/cs_w.uf2 -File ../../pico-cs/firmware/src/pico_w_build/cs_w.uf2: +File /firmware/src/pico_w_build/cs_w.uf2: Program Information name: cs_w - version: v0.8.0 + version: web site: https://github.com/pico-cs description: pico-cs DCC command station features: WiFi SSID MyWiFiSSID password MyWiFiPassword @@ -156,8 +158,8 @@ Program Information double reset -> BOOTSEL UART stdin / stdout USB stdin / stdout - binary start: 0x10000000 - binary end: 0x10055c2c + binary start: + binary end: Fixed Pin Information 0: CYW43 LED, UART0 TX @@ -168,10 +170,10 @@ Fixed Pin Information 5: Main track: DCC signal power (inverted) Build Information - sdk version: 1.4.0 + sdk version: pico_board: pico_w boot2_name: boot2_w25q080 - build date: Feb 6 2023 + build date: build attributes: Release ``` diff --git a/src/board.c b/src/board.c index 8268b32..44d73c9 100644 --- a/src/board.c +++ b/src/board.c @@ -16,8 +16,6 @@ static board_type_t board_get_type() { } void board_init_common(board_t *board, writer_t *logger) { - mutex_init(&(board->mu)); - board->logger = logger; // unique board id diff --git a/src/board.h b/src/board.h index 289109b..87d04c8 100644 --- a/src/board.h +++ b/src/board.h @@ -1,7 +1,6 @@ #ifndef _BOARD_H #define _BOARD_H -#include "pico/mutex.h" #include "pico/unique_id.h" #include "common.h" @@ -15,7 +14,6 @@ typedef enum { #define MAC_SIZE_BYTES 6 typedef struct { - mutex_t mu; writer_t *logger; board_type_t type; char id[PICO_UNIQUE_BOARD_ID_SIZE_BYTES*3]; diff --git a/src/board_pico.c b/src/board_pico.c index bcfe734..2c7fb97 100644 --- a/src/board_pico.c +++ b/src/board_pico.c @@ -23,15 +23,6 @@ void board_deinit(board_t *board) { board_set_led(board, false); } -void board_set_led(board_t *board, bool v) { - mutex_enter_blocking(&board->mu); - gpio_put(PICO_DEFAULT_LED_PIN, v); - mutex_exit(&board->mu); -} +void board_set_led(board_t *board, bool v) {gpio_put(PICO_DEFAULT_LED_PIN, v);} -bool board_get_led(board_t *board) { - mutex_enter_blocking(&board->mu); - bool rv = gpio_get(PICO_DEFAULT_LED_PIN); - mutex_exit(&board->mu); - return rv; -} +bool board_get_led(board_t *board) {return gpio_get(PICO_DEFAULT_LED_PIN);} diff --git a/src/board_pico_w.c b/src/board_pico_w.c index b6b49a3..8b052f5 100644 --- a/src/board_pico_w.c +++ b/src/board_pico_w.c @@ -30,19 +30,7 @@ bool board_init(board_t *board, writer_t *logger) { uint8_t mac[MAC_SIZE_BYTES]; cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, mac); uint8_hex_to_string(mac, MAC_SIZE_BYTES, board->mac, ':'); - - bool connected = false; - while (!connected) { - - write_eventf(logger, "wifi: connecting MAC: %s ...", board->mac); - if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) { - write_event(logger, "wifi: failed to connect"); - } else { - write_event(logger, "wifi: connected"); - return true; - } - } return true; } @@ -51,15 +39,6 @@ void board_deinit(board_t *board) { cyw43_arch_deinit(); } -void board_set_led(board_t *board, bool v) { - mutex_enter_blocking(&board->mu); - cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, v); - mutex_exit(&board->mu); -} +void board_set_led(board_t *board, bool v) {cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, v);} -bool board_get_led(board_t *board) { - mutex_enter_blocking(&board->mu); - bool rv = cyw43_arch_gpio_get(CYW43_WL_GPIO_LED_PIN); - mutex_exit(&board->mu); - return rv; -} +bool board_get_led(board_t *board) {return cyw43_arch_gpio_get(CYW43_WL_GPIO_LED_PIN);} diff --git a/src/cmd.c b/src/cmd.c index 31ca1f7..45926ff 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -100,6 +100,10 @@ static cmd_rc_t cmd_mt_enabled(cmd_t *cmd, int num_prm, reader_t *reader, writer break; case 2: if (!parse_bool(reader_get_prm(reader, 1), &on)) return CMD_RC_INVPRM; + + // switch led if CV flag is set + if (cfg_get_cv(CFG_MT_CFG)&CFG_MT_CFG_LED) board_set_led(cmd->board, on); + cfg_set_mt_enabled(on); break; } diff --git a/src/core.c b/src/core.c index 4fc5712..cad86c3 100644 --- a/src/core.c +++ b/src/core.c @@ -2,7 +2,6 @@ // command static const int core_num_entry_queue = 1; -static const bool core_dummy_data = true; void core_init(core_t *core) { queue_init(&core->q0, sizeof(bool), core_num_entry_queue); diff --git a/src/cs.c b/src/cs.c index 1bd9e3b..d3df027 100644 --- a/src/cs.c +++ b/src/cs.c @@ -10,26 +10,26 @@ #include "mt.h" #include "loop.h" -#define PROGRAM_VERSION "v0.8.0" +#define PROGRAM_VERSION "v0.8.1" #define PROGRAM_DESCRIPTION "pico-cs DCC command station" #define PROGRAM_URL "https://github.com/pico-cs" /* shared variables between cores */ -core_t core; // core (inter core communication) -board_t board; // board (shared for led) -rbuf_t rbuf; // refresh buffer -cmdq_t cmdq; // command queue (multicore) -mt_t mt; // main track +core_t core; // core (inter core communication) +rbuf_t rbuf; // refresh buffer +cmdq_t cmdq; // command queue (multicore) void core1_main() { multicore_lockout_victim_init(); // prepare lockout (suspend) of core 1 + mt_t mt; // main track + dcc_tx_pio_t tx_pio; dcc_tx_pio_init(&tx_pio); - mt_init(&mt, &tx_pio, &board, &rbuf, &cmdq); + mt_init(&mt, &tx_pio, &rbuf, &cmdq); core_signal_start1(&core); // signal core0 that core1 is started @@ -39,10 +39,10 @@ void core1_main() { } } -static const uint32_t wait_ms = 200; - int main() { + board_t board; + bi_decl(bi_program_version_string(PROGRAM_VERSION)); bi_decl(bi_program_description(PROGRAM_DESCRIPTION)); bi_decl(bi_program_url(PROGRAM_URL)); @@ -84,8 +84,8 @@ int main() { loop(&cmd, &usb_reader, &usb_writer); // finally loop until reboot // reboot - core_wait_stop1(&core); // wait for core1 to be stopped + core_wait_stop1(&core); // wait for core1 to be stopped board_deinit(&board); - sleep_ms(wait_ms); // wait for write output - watchdog_enable(0, true); // reboot immediately + uart_default_tx_wait_blocking(); // wait for write output + watchdog_enable(0, true); // reboot immediately } diff --git a/src/loop_pico_w.c b/src/loop_pico_w.c index b7a3882..33d5c35 100644 --- a/src/loop_pico_w.c +++ b/src/loop_pico_w.c @@ -4,11 +4,40 @@ #include "loop.h" #include "io.h" -void loop(cmd_t *cmd, reader_t *usb_reader, writer_t *usb_writer) { +static bool is_wifi_connected(cmd_t *cmd, writer_t *logger, bool log_success) { + switch (cyw43_wifi_link_status(&cyw43_state,CYW43_ITF_STA)) { + case CYW43_LINK_DOWN: + write_event(logger, "wifi: down"); return false; + case CYW43_LINK_JOIN: + if (log_success) write_event(logger, "wifi: connected"); + return true; + case CYW43_LINK_FAIL: + write_event(logger, "wifi: connection failed"); return false; + case CYW43_LINK_NONET: + write_event(logger, "wifi: no matching SSID found"); return false; + case CYW43_LINK_BADAUTH: + write_event(logger, "wifi: authenticatation failure"); return false; + default: + write_event(logger, "wifi: unknown error"); return false; + } +} + +static const int num_connect_retry = 5; +static const int connect_timeout_ms = 30000; // 30 sec +static const int check_wifi_int_us = 10000000; // 10 sec +static bool wifi_connect(cmd_t *cmd, writer_t *logger) { + write_eventf(logger, "wifi: connecting MAC: %s ...", cmd->board->mac); + for (int i=0; i < num_connect_retry; i++) { + cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, connect_timeout_ms); + if (is_wifi_connected(cmd, logger, true)) return true; + } + return false; +} + +void loop(cmd_t *cmd, reader_t *usb_reader, writer_t *usb_writer) { tcp_server_t server; tcp_server_init(&server, usb_writer); - tcp_server_open(&server); writer_t tcp_writer; writer_init(&tcp_writer, &server, &tcp_server_write); @@ -17,11 +46,25 @@ void loop(cmd_t *cmd, reader_t *usb_reader, writer_t *usb_writer) { byte usb_buf[PROT_BUFFER_SIZE]; + if (wifi_connect(cmd, usb_writer)) tcp_server_open(&server); + + absolute_time_t time_from = get_absolute_time(); + while (true) { server.recv_len = 0; cyw43_arch_poll(); + + if (absolute_time_diff_us(time_from, get_absolute_time()) >= check_wifi_int_us) { + if (!is_wifi_connected(cmd, usb_writer, false)) { + if (wifi_connect(cmd, usb_writer)) { + if (server.open) tcp_server_close(&server); + tcp_server_open(&server); + }; + }; + time_from = get_absolute_time(); + } if (reader_read_frame(&tcp_reader, server.buffer_recv, server.recv_len)) { if (!cmd_dispatch(cmd, &tcp_reader, &tcp_writer)) break; diff --git a/src/mt.c b/src/mt.c index fd4927d..cc5b10f 100644 --- a/src/mt.c +++ b/src/mt.c @@ -71,29 +71,22 @@ static void mt_refresh_dcc(mt_t *mt, bool one_entry, cmdq_in_t *in) { static void mt_set_enabled(mt_t *mt, bool enabled) { mt->enabled = enabled; if (enabled) { - // switch led on if CV flag is set - if (cfg_get_cv(CFG_MT_CFG)&CFG_MT_CFG_LED) board_set_led(mt->board, true); - // when switching on set whether def or bidi depending on CV if (cfg_get_cv(CFG_MT_CFG)&CFG_MT_CFG_BIDI) { mt->tx_sm = &mt->tx_pio->tx_sm_bidi; } else { mt->tx_sm = &mt->tx_pio->tx_sm_def; } - } else { - // switch led off if CV flag is set - if (cfg_get_cv(CFG_MT_CFG)&CFG_MT_CFG_LED) board_set_led(mt->board, false); } dcc_tx_sm_set_enabled(mt->tx_sm, enabled); } -void mt_init(mt_t *mt, dcc_tx_pio_t *tx_pio, board_t *board, rbuf_t *rbuf, cmdq_t *cmdq) { +void mt_init(mt_t *mt, dcc_tx_pio_t *tx_pio, rbuf_t *rbuf, cmdq_t *cmdq) { mt->enabled = false; // start not enabled mt->tx_pio = tx_pio; mt->tx_sm = &tx_pio->tx_sm_def; - mt->board = board; mt->rbuf = rbuf; mt->cmdq = cmdq; diff --git a/src/mt.h b/src/mt.h index bda61cf..0aadfdb 100644 --- a/src/mt.h +++ b/src/mt.h @@ -10,13 +10,12 @@ typedef struct { bool enabled; dcc_tx_pio_t *tx_pio; dcc_tx_sm_t *tx_sm; - board_t *board; rbuf_t *rbuf; cmdq_t *cmdq; } mt_t; // main track // public interface -void mt_init(mt_t *mt, dcc_tx_pio_t *tx_pio, board_t *board, rbuf_t *rbuf, cmdq_t *cmdq); +void mt_init(mt_t *mt, dcc_tx_pio_t *tx_pio, rbuf_t *rbuf, cmdq_t *cmdq); void mt_dispatch(mt_t *mt); #endif diff --git a/src/tcp_server.c b/src/tcp_server.c index cdb2013..f517dbf 100644 --- a/src/tcp_server.c +++ b/src/tcp_server.c @@ -101,10 +101,10 @@ void tcp_server_init(tcp_server_t *server, writer_t *logger) { server->port = TCP_PORT; server->logger = logger; server->recv_len = 0; + server->open = false; } bool tcp_server_open(tcp_server_t *server) { - server->open = false; write_eventf(server->logger, "tcp: starting server host %s port %d", ip4addr_ntoa(netif_ip4_addr(netif_list)), server->port); @@ -167,6 +167,6 @@ err_t tcp_server_close(tcp_server_t *server) { tcp_close(server->server_pcb); server->server_pcb = NULL; } - + server->open = false; return err; }