diff --git a/samples/shell/CMakeLists.txt b/samples/shell/CMakeLists.txt new file mode 100644 index 0000000..082ff5e --- /dev/null +++ b/samples/shell/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: MIT +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(rb9704_shell) +target_sources(app PRIVATE src/main.c) diff --git a/samples/shell/boards/esp32s3_devkitc_procpu.overlay b/samples/shell/boards/esp32s3_devkitc_procpu.overlay new file mode 100644 index 0000000..7078478 --- /dev/null +++ b/samples/shell/boards/esp32s3_devkitc_procpu.overlay @@ -0,0 +1,24 @@ +/* ESP32-S3-DevKitC: the modem on uart1, GPIO17 (TX) and GPIO18 (RX). */ +&pinctrl { + uart1_rb9704: uart1_rb9704 { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; + +&uart1 { + pinctrl-0 = <&uart1_rb9704>; + pinctrl-names = "default"; + current-speed = <230400>; + status = "okay"; + + rockblock { + compatible = "rock7,rockblock-9704"; + }; +}; diff --git a/samples/shell/boards/native_sim.conf b/samples/shell/boards/native_sim.conf new file mode 100644 index 0000000..17150dc --- /dev/null +++ b/samples/shell/boards/native_sim.conf @@ -0,0 +1,2 @@ +# One log backend on native_sim, the shell's, as on a board. +CONFIG_LOG_BACKEND_NATIVE_POSIX=n diff --git a/samples/shell/boards/native_sim.overlay b/samples/shell/boards/native_sim.overlay new file mode 100644 index 0000000..026b9d5 --- /dev/null +++ b/samples/shell/boards/native_sim.overlay @@ -0,0 +1,14 @@ +/* native_sim: the modem is a host serial device, the fake modem's pty + * (python/rb9704tools/fakemodem.py) or a real RockBLOCK on USB. Name it at + * run time: ./zephyr.exe --modem_uart_port=/dev/pts/N (the node name below). */ +/ { + modem_uart: modem_uart { + compatible = "zephyr,native-tty-uart"; + current-speed = <230400>; + status = "okay"; + + rockblock { + compatible = "rock7,rockblock-9704"; + }; + }; +}; diff --git a/samples/shell/boards/native_sim_native_64.conf b/samples/shell/boards/native_sim_native_64.conf new file mode 100644 index 0000000..17150dc --- /dev/null +++ b/samples/shell/boards/native_sim_native_64.conf @@ -0,0 +1,2 @@ +# One log backend on native_sim, the shell's, as on a board. +CONFIG_LOG_BACKEND_NATIVE_POSIX=n diff --git a/samples/shell/boards/native_sim_native_64.overlay b/samples/shell/boards/native_sim_native_64.overlay new file mode 100644 index 0000000..026b9d5 --- /dev/null +++ b/samples/shell/boards/native_sim_native_64.overlay @@ -0,0 +1,14 @@ +/* native_sim: the modem is a host serial device, the fake modem's pty + * (python/rb9704tools/fakemodem.py) or a real RockBLOCK on USB. Name it at + * run time: ./zephyr.exe --modem_uart_port=/dev/pts/N (the node name below). */ +/ { + modem_uart: modem_uart { + compatible = "zephyr,native-tty-uart"; + current-speed = <230400>; + status = "okay"; + + rockblock { + compatible = "rock7,rockblock-9704"; + }; + }; +}; diff --git a/samples/shell/boards/nucleo_u575zi_q.overlay b/samples/shell/boards/nucleo_u575zi_q.overlay new file mode 100644 index 0000000..49adff5 --- /dev/null +++ b/samples/shell/boards/nucleo_u575zi_q.overlay @@ -0,0 +1,16 @@ +/* NUCLEO-U575ZI-Q: the modem on USART3, PD8 (TX) and PD9 (RX). + * + * On this board those pins share solder bridges with the ST-LINK's virtual + * COM port; check UM2861 before wiring. To test without a modem, the fake + * modem (python/rb9704tools/fakemodem.py) on a 3.3 V USB-serial adapter + * wired to the same pins stands in for it. */ +&usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; + pinctrl-names = "default"; + current-speed = <230400>; + status = "okay"; + + rockblock { + compatible = "rock7,rockblock-9704"; + }; +}; diff --git a/samples/shell/boards/xiao_esp32s3_procpu.overlay b/samples/shell/boards/xiao_esp32s3_procpu.overlay new file mode 100644 index 0000000..89689b2 --- /dev/null +++ b/samples/shell/boards/xiao_esp32s3_procpu.overlay @@ -0,0 +1,29 @@ +/* Seeed XIAO ESP32S3: the modem on uart1, D6 (GPIO43, TX) and D7 (GPIO44, + * RX). The console stays on the native USB. */ +&pinctrl { + uart1_rb9704: uart1_rb9704 { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; + +&uart0 { + status = "disabled"; +}; + +&uart1 { + pinctrl-0 = <&uart1_rb9704>; + pinctrl-names = "default"; + current-speed = <230400>; + status = "okay"; + + rockblock { + compatible = "rock7,rockblock-9704"; + }; +}; diff --git a/samples/shell/prj.conf b/samples/shell/prj.conf new file mode 100644 index 0000000..973786e --- /dev/null +++ b/samples/shell/prj.conf @@ -0,0 +1,12 @@ +CONFIG_SERIAL=y +CONFIG_SHELL=y +CONFIG_LOG=y +# One log backend, the shell's: with the UART one as well every line +# printed twice. +CONFIG_LOG_BACKEND_UART=n +CONFIG_RB9704=y +CONFIG_RB9704_SHELL=y +# Long `rb9704 send` lines, typed or pasted. +CONFIG_SHELL_CMD_BUFF_SIZE=512 +CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE=256 +CONFIG_CRC=y diff --git a/samples/shell/src/main.c b/samples/shell/src/main.c new file mode 100644 index 0000000..06e3d3f --- /dev/null +++ b/samples/shell/src/main.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: MIT + * + * The rb9704 shell sample: `rb9704` on the console, and every message from + * the network, every finished send and every signal change printed as it + * happens. The same image is what the tests in tests/ drive, on native_sim + * against a fake modem and on a board against a fake or a real one. + */ +#include +#include + +#include + +#include + +#include + +LOG_MODULE_REGISTER(sample, LOG_LEVEL_INF); + +static void on_mo_done(uint16_t topic, uint16_t id, int result, void *user) +{ + ARG_UNUSED(user); + LOG_INF("mo done topic %u id %u result %d", topic, id, result); +} + +static void on_mt(const struct rb9704_mt *mt, void *user) +{ + /* The whole message's CRC and its start: a long one in a single log + * line would not survive every board's log buffer. */ + char text[65]; + size_t n = MIN(mt->len, sizeof(text) - 1); + + ARG_UNUSED(user); + for (size_t i = 0; i < n; i++) { + text[i] = isprint(mt->data[i]) ? mt->data[i] : '.'; + } + text[n] = '\0'; + LOG_INF("mt topic %u id %u len %u crc %08x: %s", mt->topic, mt->id, (unsigned int)mt->len, + crc32_ieee(mt->data, mt->len), text); +} + +static void on_signal(uint8_t bars, bool visible, void *user) +{ + ARG_UNUSED(user); + LOG_INF("signal %u bars%s", bars, visible ? "" : ", not visible"); +} + +static void on_provisioning(const struct rb9704_topic *topics, uint8_t n, void *user) +{ + ARG_UNUSED(user); + LOG_INF("provisioned, %u topic(s), the first %u", n, n > 0 ? topics[0].id : 0); +} + +static const struct rb9704_callbacks cb = { + .mo_done = on_mo_done, + .mt = on_mt, + .signal = on_signal, + .provisioning = on_provisioning, +}; + +int main(void) +{ + rb9704_set_callbacks(&cb); + LOG_INF("rb9704 shell sample: `rb9704 begin`, then `rb9704 info`"); + return 0; +} diff --git a/tests/rig/bridge/CMakeLists.txt b/tests/rig/bridge/CMakeLists.txt new file mode 100644 index 0000000..4fa8709 --- /dev/null +++ b/tests/rig/bridge/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: MIT +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(rb9704_bridge) +target_sources(app PRIVATE src/main.c) diff --git a/tests/rig/bridge/boards/nucleo_u575zi_q.overlay b/tests/rig/bridge/boards/nucleo_u575zi_q.overlay new file mode 100644 index 0000000..b1a4303 --- /dev/null +++ b/tests/rig/bridge/boards/nucleo_u575zi_q.overlay @@ -0,0 +1,18 @@ +/* host: USART1, the ST-LINK's virtual COM port. target: USART2 on PD5/PD6, + * the CN9 UART block, wired to the other board's modem UART. Both at the + * modem's 230400. */ +/ { + aliases { + bridge-host = &usart1; + bridge-target = &usart2; + }; +}; + +&usart1 { + current-speed = <230400>; +}; + +&usart2 { + current-speed = <230400>; + fifo-enable; +}; diff --git a/tests/rig/bridge/boards/xiao_esp32s3_procpu.overlay b/tests/rig/bridge/boards/xiao_esp32s3_procpu.overlay new file mode 100644 index 0000000..aefc1d5 --- /dev/null +++ b/tests/rig/bridge/boards/xiao_esp32s3_procpu.overlay @@ -0,0 +1,33 @@ +/* host: the native USB serial port. target: uart1 on D8 (GPIO7, TX) and D9 + * (GPIO8, RX), wired to the other board's modem UART. 230400, the modem's + * rate; the USB side has none. */ +/ { + aliases { + bridge-host = &usb_serial; + bridge-target = &uart1; + }; +}; + +&spi2 { + status = "disabled"; /* the board puts it on GPIO7 to 9 */ +}; + +&pinctrl { + uart1_bridge: uart1_bridge { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; + +&uart1 { + pinctrl-0 = <&uart1_bridge>; + pinctrl-names = "default"; + current-speed = <230400>; + status = "okay"; +}; diff --git a/tests/rig/bridge/prj.conf b/tests/rig/bridge/prj.conf new file mode 100644 index 0000000..4c73e70 --- /dev/null +++ b/tests/rig/bridge/prj.conf @@ -0,0 +1,9 @@ +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_RING_BUFFER=y +# Both UARTs carry the bridged bytes; nothing else may print on them. +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_PRINTK=n +CONFIG_LOG=n +CONFIG_BOOT_BANNER=n diff --git a/tests/rig/bridge/src/main.c b/tests/rig/bridge/src/main.c new file mode 100644 index 0000000..c4c6ad8 --- /dev/null +++ b/tests/rig/bridge/src/main.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: MIT + * + * A two-way UART bridge, for the test rig: every byte in on `host` goes out + * on `target`, and the other way round. With `host` a board's USB serial + * port and `target` a UART wired to another board's modem pins, the fake + * modem on the host answers that board as a modem would. The aliases are + * the board overlay's. */ +#include +#include +#include +#include + +static const struct device *const host = DEVICE_DT_GET(DT_ALIAS(bridge_host)); +static const struct device *const target = DEVICE_DT_GET(DT_ALIAS(bridge_target)); + +RING_BUF_DECLARE(to_target, 4096); +RING_BUF_DECLARE(to_host, 4096); + +static void isr(const struct device *dev, void *user) +{ + struct ring_buf *out = user; /* bytes read here go into this ring */ + const struct device *other = dev == host ? target : host; + struct ring_buf *back = out == &to_target ? &to_host : &to_target; + uint8_t b[64]; + + while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { + if (uart_irq_rx_ready(dev)) { + int n = uart_fifo_read(dev, b, sizeof(b)); + + if (n > 0) { + ring_buf_put(out, b, n); + uart_irq_tx_enable(other); + } + } + if (uart_irq_tx_ready(dev)) { + uint8_t *p; + uint32_t n = ring_buf_get_claim(back, &p, 64); + + if (n == 0) { + uart_irq_tx_disable(dev); + } else { + int w = uart_fifo_fill(dev, p, n); + + ring_buf_get_finish(back, w > 0 ? w : 0); + } + } + } +} + +int main(void) +{ + uart_irq_callback_user_data_set(host, isr, &to_target); + uart_irq_callback_user_data_set(target, isr, &to_host); + uart_irq_rx_enable(host); + uart_irq_rx_enable(target); + return 0; +} diff --git a/tests/rig/nucleo_u575zi_q_rig.overlay b/tests/rig/nucleo_u575zi_q_rig.overlay new file mode 100644 index 0000000..a9c3b9e --- /dev/null +++ b/tests/rig/nucleo_u575zi_q_rig.overlay @@ -0,0 +1,13 @@ +/* The shell sample on a NUCLEO-U575ZI-Q in the test rig: the modem UART on + * USART2, PD5 (TX) and PD6 (RX) on the CN9 UART block, wired to the bridge + * board's target UART (bridge/). The shell stays on the ST-LINK's port. + * west build -b nucleo_u575zi_q samples/shell -- \ + * -DDTC_OVERLAY_FILE=$PWD/tests/rig/nucleo_u575zi_q_rig.overlay */ +&usart2 { + current-speed = <230400>; + fifo-enable; + + rockblock { + compatible = "rock7,rockblock-9704"; + }; +}; diff --git a/tests/rig/xiao_esp32s3_rig.overlay b/tests/rig/xiao_esp32s3_rig.overlay new file mode 100644 index 0000000..16eb054 --- /dev/null +++ b/tests/rig/xiao_esp32s3_rig.overlay @@ -0,0 +1,32 @@ +/* The shell sample on a XIAO ESP32S3 in the test rig: the modem UART on + * D8 (GPIO7, TX) and D9 (GPIO8, RX), wired to the bridge board's target + * UART (bridge/). Use it in place of the sample's own XIAO overlay: + * west build -b xiao_esp32s3/esp32s3/procpu samples/shell -- \ + * -DDTC_OVERLAY_FILE=$PWD/tests/rig/xiao_esp32s3_rig.overlay */ +&spi2 { + status = "disabled"; /* the board puts it on GPIO7 to 9 */ +}; + +&pinctrl { + uart1_rig: uart1_rig { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; + +&uart1 { + pinctrl-0 = <&uart1_rig>; + pinctrl-names = "default"; + current-speed = <230400>; + status = "okay"; + + rockblock { + compatible = "rock7,rockblock-9704"; + }; +};