mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-06 15:51:25 +00:00
124 lines
3.9 KiB
C
124 lines
3.9 KiB
C
// Copyright (c) 2026 Cesanta Software Limited
|
|
// All rights reserved
|
|
|
|
#include "hal.h"
|
|
#include "mongoose.h"
|
|
|
|
#define LED_RADIO PIN(0, 12) // Green, active low
|
|
#define LED_LAN PIN(0, 0) // Blue, active low
|
|
#define LED_RED PIN(0, 1) // Red, active low
|
|
|
|
static uint64_t s_radio_led_until;
|
|
|
|
// Cumulative totals. Up: radio -> LAN; down: LAN -> radio queue.
|
|
static uint64_t s_frames_up, s_frames_down, s_bytes_up, s_bytes_down;
|
|
static uint64_t s_radio_sent, s_radio_received;
|
|
static size_t (*s_radio_tx)(struct mg_tcpip_if *, const void *, size_t);
|
|
|
|
static size_t radio_tx(struct mg_tcpip_if *ifp, const void *buf, size_t len) {
|
|
size_t sent = s_radio_tx(ifp, buf, len);
|
|
if (sent != 0) s_radio_sent++;
|
|
return sent;
|
|
}
|
|
|
|
static size_t eth_up(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
|
size_t sent = mg_tcpip_driver_rw612.tx(buf, len, ifp);
|
|
if (sent != 0) s_frames_up++, s_bytes_up += sent;
|
|
return sent;
|
|
}
|
|
|
|
static size_t eth_down(struct mg_mesh_node *node, const void *buf, size_t len) {
|
|
size_t queued = mg_mesh_default.tx(node, buf, len);
|
|
if (queued != 0) s_frames_down++, s_bytes_down += queued;
|
|
return queued;
|
|
}
|
|
|
|
static void radio_rx(struct mg_mesh_node *node, void *buf, size_t len) {
|
|
s_radio_received++;
|
|
s_radio_led_until = mg_millis() + 2;
|
|
mg_mesh_default.rx(node, buf, len);
|
|
}
|
|
|
|
static void log_fn(char ch, void *arg) {
|
|
hal_uart_write_buf(arg, &ch, 1);
|
|
}
|
|
|
|
uint64_t mg_millis(void) {
|
|
return hal_get_tick();
|
|
}
|
|
|
|
int main(void) {
|
|
static struct mg_tcpip_driver_rw612_data eth_data;
|
|
static struct mg_tcpip_if eth;
|
|
static struct mg_tcpip_driver eth_driver;
|
|
static char eth_queue[8192];
|
|
static struct mg_tcpip_driver_rw612w_data radio_data;
|
|
static struct mg_tcpip_if radio;
|
|
static struct mg_mesh mesh;
|
|
uint32_t lan_received = 0;
|
|
uint64_t lan_led_until = 0;
|
|
uint64_t link_timer = 0, stats_timer = 0;
|
|
|
|
hal_clock_init();
|
|
hal_rng_init();
|
|
hal_gpio_output(LED_RADIO);
|
|
hal_gpio_output(LED_LAN);
|
|
hal_gpio_output(LED_RED);
|
|
hal_gpio_write(LED_RADIO, true);
|
|
hal_gpio_write(LED_LAN, true);
|
|
hal_gpio_write(LED_RED, true);
|
|
hal_uart_init(USART3, 115200, PIN(0, 26), PIN(0, 24));
|
|
mg_log_set_fn(log_fn, USART3);
|
|
hal_ethernet_init();
|
|
|
|
mesh = mg_mesh_default;
|
|
mesh.tx = eth_down;
|
|
mesh.rx = radio_rx; // Observe radio reception without modifying the driver.
|
|
radio_data.strategy = &mesh;
|
|
radio.driver = &mg_tcpip_driver_rw612w;
|
|
radio.driver_data = &radio_data;
|
|
if (!radio.driver->init(&radio)) return 1;
|
|
s_radio_tx = radio_data.mesh->tx;
|
|
radio_data.mesh->tx = radio_tx;
|
|
|
|
eth_data.mdc_cr = MG_DRIVER_MDC_CR;
|
|
eth_data.mdc_holdtime = MG_DRIVER_MDC_HOLDTIME;
|
|
eth_data.phy_addr = MG_TCPIP_PHY_ADDR;
|
|
eth_driver = mg_tcpip_driver_rw612;
|
|
eth_driver.tx = eth_up;
|
|
eth.driver = ð_driver;
|
|
eth.driver_data = ð_data;
|
|
memcpy(eth.mac, radio.mac, 6);
|
|
mg_queue_init(ð.recv_queue, eth_queue, sizeof(eth_queue));
|
|
if (!eth.driver->init(ð)) return 1;
|
|
|
|
ENET->RCR |= ENET_RCR_PROM_MASK; // Receive frames addressed to radio nodes.
|
|
radio_data.mesh->lan = ð
|
|
radio_data.mesh->next_tick = 0;
|
|
|
|
MG_INFO(("Ethernet/radio bridge, channel %u", MG_802154_CHANNEL));
|
|
stats_timer = mg_millis() + 5000;
|
|
for (;;) {
|
|
uint64_t now = mg_millis();
|
|
if (mg_timer_expired(&link_timer, 100, mg_millis())) {
|
|
eth.state = eth.driver->poll(ð, true) ? MG_TCPIP_STATE_UP
|
|
: MG_TCPIP_STATE_DOWN;
|
|
}
|
|
radio.driver->poll(&radio, false);
|
|
if (mg_timer_expired(&stats_timer, 5000, now)) {
|
|
MG_INFO(
|
|
("ETH frames up/down %llu/%llu, bytes up/down "
|
|
"%llu/%llu, radio frames sent/rcvd %llu/%llu",
|
|
s_frames_up, s_frames_down, s_bytes_up, s_bytes_down, s_radio_sent,
|
|
s_radio_received));
|
|
}
|
|
if (eth.nrecv != lan_received) {
|
|
lan_received = eth.nrecv;
|
|
lan_led_until = now + 2;
|
|
}
|
|
hal_gpio_write(LED_RADIO, now >= s_radio_led_until);
|
|
hal_gpio_write(LED_LAN, now >= lan_led_until);
|
|
}
|
|
return 0;
|
|
}
|