The shell sample, and a two-board rig for testing on hardware
samples/shell is `rb9704` on the shell with callbacks that print what arrives, a CRC-32 and the start of each message from the network. Board overlays for native_sim (the modem a host serial port, a pty or a real 9704 on USB), NUCLEO-U575ZI-Q, XIAO ESP32S3 and ESP32-S3-DevKitC. tests/rig/bridge copies bytes between a board's USB serial port and a UART, so two boards wired together stand in for a USB-serial adapter: one runs the sample, the other bridges its modem UART to the host, where the fake modem answers. Overlays for a Nucleo and a XIAO, either way round.
This commit is contained in:
1 parent
c0e92a7f02
commit
dbed9bbc88
17 files changed
+350
No files matched your search
@@ -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)
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/* ESP32-S3-DevKitC: the modem on uart1, GPIO17 (TX) and GPIO18 (RX). */
|
||||||
|
&pinctrl {
|
||||||
|
uart1_rb9704: uart1_rb9704 {
|
||||||
|
group1 {
|
||||||
|
pinmux = <UART1_TX_GPIO17>;
|
||||||
|
output-high;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART1_RX_GPIO18>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart1 {
|
||||||
|
pinctrl-0 = <&uart1_rb9704>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
current-speed = <230400>;
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
rockblock {
|
||||||
|
compatible = "rock7,rockblock-9704";
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# One log backend on native_sim, the shell's, as on a board.
|
||||||
|
CONFIG_LOG_BACKEND_NATIVE_POSIX=n
|
||||||
@@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# One log backend on native_sim, the shell's, as on a board.
|
||||||
|
CONFIG_LOG_BACKEND_NATIVE_POSIX=n
|
||||||
@@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -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 = <UART1_TX_GPIO43>;
|
||||||
|
output-high;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART1_RX_GPIO44>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart1 {
|
||||||
|
pinctrl-0 = <&uart1_rb9704>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
current-speed = <230400>;
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
rockblock {
|
||||||
|
compatible = "rock7,rockblock-9704";
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -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
|
||||||
@@ -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 <zephyr/kernel.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <zephyr/sys/crc.h>
|
||||||
|
|
||||||
|
#include <rb9704/rb9704.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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 = <UART1_TX_GPIO7>;
|
||||||
|
output-high;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART1_RX_GPIO8>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart1 {
|
||||||
|
pinctrl-0 = <&uart1_bridge>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
current-speed = <230400>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
@@ -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
|
||||||
@@ -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 <zephyr/kernel.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/drivers/uart.h>
|
||||||
|
#include <zephyr/sys/ring_buffer.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -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 = <UART1_TX_GPIO7>;
|
||||||
|
output-high;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART1_RX_GPIO8>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart1 {
|
||||||
|
pinctrl-0 = <&uart1_rig>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
current-speed = <230400>;
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
rockblock {
|
||||||
|
compatible = "rock7,rockblock-9704";
|
||||||
|
};
|
||||||
|
};
|
||||||
Reference in new issue
Block a user