29static constexpr bool pc104_uart_en =
30 DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay);
32static struct k_thread radio_rx_thread_data;
34static struct k_thread uhf_tx_thread_data;
36static struct k_thread sband_tx_thread_data;
39#if CONFIG_IO_CAN1_ENABLE
40static const struct device *can1_dev = DEVICE_DT_GET(DT_NODELABEL(fdcan1));
42static struct k_thread can1_tx_thread_data;
43static struct k_thread can1_rx_thread_data;
48static const struct isotp_msg_id can1_rx_filter = {
49 .std_id = CONFIG_CAN1_ISOTP_REMOTE_PEER_RX_ADDR,
54static const struct isotp_msg_id can1_tx_conf = {
55 .std_id = CONFIG_CAN1_ISOTP_TX_ADDR, .ext_addr = 0, .dl = 8, .flags = 0};
56static const struct isotp_msg_id can1_tx_remote_conf = {
57 .std_id = CONFIG_CAN1_ISOTP_REMOTE_PEER_TX_ADDR,
62static const struct isotp_msg_id can1_rx_conf = {
63 .std_id = CONFIG_CAN1_ISOTP_RX_ADDR, .ext_addr = 0, .dl = 8, .flags = 0};
68const struct isotp_fc_opts can1_fc_opts = {.bs = 8, .stmin = 0};
70static struct isotp_recv_ctx can1_recv_ctx;
71static struct isotp_send_ctx can1_send_ctx;
75#if CONFIG_IO_CAN2_ENABLE
76static const struct device *can2_dev = DEVICE_DT_GET(DT_NODELABEL(fdcan2));
78static struct k_thread can2_tx_thread_data;
79static struct k_thread can2_rx_thread_data;
83static const struct isotp_msg_id can2_rx_filter = {
84 .std_id = CONFIG_CAN2_ISOTP_REMOTE_PEER_RX_ADDR,
89static const struct isotp_msg_id can2_tx_conf = {
90 .std_id = CONFIG_CAN2_ISOTP_TX_ADDR, .ext_addr = 0, .dl = 8, .flags = 0};
91static const struct isotp_msg_id can2_tx_remote_conf = {
92 .std_id = CONFIG_CAN2_ISOTP_REMOTE_PEER_TX_ADDR,
97static const struct isotp_msg_id can2_rx_conf = {
98 .std_id = CONFIG_CAN2_ISOTP_RX_ADDR, .ext_addr = 0, .dl = 8, .flags = 0};
103const struct isotp_fc_opts can2_fc_opts = {.bs = 8, .stmin = 0};
105static struct isotp_recv_ctx can2_recv_ctx;
106static struct isotp_send_ctx can2_send_ctx;
113#if CONFIG_IO_CAN1_ENABLE
118#if CONFIG_IO_CAN2_ENABLE
128#if DT_NODE_HAS_STATUS(DT_ALIAS(pc104_usart3), okay)
130uart_handling_callback(
const struct device *dev,
struct uart_event *evt,
134#if DT_NODE_HAS_STATUS(DT_ALIAS(pc104_usart3), okay)
162#if CONFIG_IO_CAN1_ENABLE
166 ret = can_start(can1_dev);
169 ret = isotp_bind(&can1_recv_ctx, can1_dev, &can1_rx_filter, &can1_rx_conf,
170 &can1_fc_opts, K_FOREVER);
173 m_can1_tx_tid = k_thread_create(&can1_tx_thread_data, can1_tx_thread_stack,
174 K_THREAD_STACK_SIZEOF(can1_tx_thread_stack),
175 can1_tx_thread, NULL, NULL, NULL,
176 CONFIG_CAN1_TX_THREAD_PRIO, 0, K_NO_WAIT);
177 if (!m_can1_tx_tid) {
180 k_thread_name_set(m_can1_tx_tid,
"can1_tx");
182 m_can1_rx_tid = k_thread_create(&can1_rx_thread_data, can1_rx_thread_stack,
183 K_THREAD_STACK_SIZEOF(can1_rx_thread_stack),
184 can1_rx_thread, NULL, NULL, NULL,
185 CONFIG_CAN1_RX_THREAD_PRIO, 0, K_NO_WAIT);
186 if (!m_can1_rx_tid) {
189 k_thread_name_set(m_can1_rx_tid,
"can1_rx");
192#if CONFIG_IO_CAN2_ENABLE
196 ret = can_start(can2_dev);
199 ret = isotp_bind(&can2_recv_ctx, can2_dev, &can2_rx_filter, &can2_rx_conf,
200 &can2_fc_opts, K_FOREVER);
203 m_can2_tx_tid = k_thread_create(&can2_tx_thread_data, can2_tx_thread_stack,
204 K_THREAD_STACK_SIZEOF(can2_tx_thread_stack),
205 can2_tx_thread, NULL, NULL, NULL,
206 CONFIG_CAN2_TX_THREAD_PRIO, 0, K_NO_WAIT);
207 if (!m_can2_tx_tid) {
210 k_thread_name_set(m_can2_tx_tid,
"can2_tx");
212 m_can2_rx_tid = k_thread_create(&can2_rx_thread_data, can2_rx_thread_stack,
213 K_THREAD_STACK_SIZEOF(can2_rx_thread_stack),
214 can2_rx_thread, NULL, NULL, NULL,
215 CONFIG_CAN2_RX_THREAD_PRIO, 0, K_NO_WAIT);
216 if (!m_can2_rx_tid) {
219 k_thread_name_set(m_can2_rx_tid,
"can2_rx");
222 m_radio_rx_tid = k_thread_create(&radio_rx_thread_data, radio_rx_thread_stack,
223 K_THREAD_STACK_SIZEOF(radio_rx_thread_stack),
224 radio_rx_thread, NULL, NULL, NULL,
225 CONFIG_RADIO_RX_THREAD_PRIO, 0, K_NO_WAIT);
227 m_uhf_tx_tid = k_thread_create(&uhf_tx_thread_data, uhf_tx_thread_stack,
228 K_THREAD_STACK_SIZEOF(uhf_tx_thread_stack),
229 uhf_tx_thread, NULL, NULL, NULL,
230 CONFIG_UHF_TX_THREAD_PRIO, 0, K_NO_WAIT);
232 m_sband_tx_tid = k_thread_create(&sband_tx_thread_data, sband_tx_thread_stack,
233 K_THREAD_STACK_SIZEOF(sband_tx_thread_stack),
234 sband_tx_thread, NULL, NULL, NULL,
235 CONFIG_SBAND_TX_THREAD_PRIO, 0, K_NO_WAIT);
237 if (!m_radio_rx_tid) {
244 if (!m_sband_tx_tid) {
247 k_thread_name_set(m_radio_rx_tid,
"radio_rx");
248 k_thread_name_set(m_uhf_tx_tid,
"uhf_tx");
249 k_thread_name_set(m_sband_tx_tid,
"sband_tx");
251#if DT_NODE_HAS_STATUS(DT_ALIAS(pc104_usart3), okay)
252 const struct device *uart_dev = DEVICE_DT_GET(DT_ALIAS(pc104_usart3));
254 const struct uart_config uart_cfg = {.baudrate = CONFIG_PC104_UART_BAUDRATE,
255 .parity = UART_CFG_PARITY_NONE,
256 .stop_bits = UART_CFG_STOP_BITS_1,
257 .data_bits = UART_CFG_DATA_BITS_8,
258 .flow_ctrl = UART_CFG_FLOW_CTRL_NONE};
259 uart_rx_disable(uart_dev);
260 uart_configure(uart_dev, &uart_cfg);
261 uart_callback_set(uart_dev, uart_handling_callback, &usart3);
263 CONFIG_PC104_UART_RX_TIMEOUT_MS);
267#if CONFIG_IO_CAN1_ENABLE
269io::can1_tx_thread(
void *arg1,
void *arg2,
void *arg3)
272 int task_wdt_id = task_wdt_add(CONFIG_WATCHDOG_PERIOD_CAN1_TX,
278 task_wdt_feed(task_wdt_id);
281 isotp_send(&can1_send_ctx, can1_dev, can1_tx_msg.data, can1_tx_msg.len,
282 &can1_tx_conf, &can1_tx_remote_conf, NULL, NULL);
286 }
catch (
const std::exception &e) {
293io::can1_rx_thread(
void *arg1,
void *arg2,
void *arg3)
296 int task_wdt_id = task_wdt_add(CONFIG_WATCHDOG_PERIOD_CAN1_RX,
304 task_wdt_feed(task_wdt_id);
308 ret = isotp_recv_net(&can1_recv_ctx, &
buf, K_MSEC(100));
309 if (ret == ISOTP_RECV_TIMEOUT) {
314 err.assert_error<isotp_recv_exception>(__FILE__, __LINE__);
317 while (
buf !=
nullptr) {
322 std::memcpy(can1_rx_msg.data + can1_rx_msg.len,
buf->data, ncpy);
323 can1_rx_msg.len += ncpy;
324 buf = net_buf_frag_del(NULL,
buf);
327 if (can1_rx_msg.len > 0) {
328 arb.push(can1_rx_msg);
330 }
catch (
const scl::exception &e) {
332 }
catch (
const std::exception &e) {
340#if CONFIG_IO_CAN2_ENABLE
342io::can2_tx_thread(
void *arg1,
void *arg2,
void *arg3)
345 int task_wdt_id = task_wdt_add(CONFIG_WATCHDOG_PERIOD_CAN2_TX,
351 task_wdt_feed(task_wdt_id);
354 isotp_send(&can2_send_ctx, can2_dev, can2_tx_msg.data, can2_tx_msg.len,
355 &can2_tx_conf, &can2_tx_remote_conf, NULL, NULL);
357 }
catch (
const scl::exception &e) {
359 }
catch (
const std::exception &e) {
366io::can2_rx_thread(
void *arg1,
void *arg2,
void *arg3)
369 int task_wdt_id = task_wdt_add(CONFIG_WATCHDOG_PERIOD_CAN2_RX,
377 task_wdt_feed(task_wdt_id);
381 ret = isotp_recv_net(&can2_recv_ctx, &
buf, K_MSEC(100));
382 if (ret == ISOTP_RECV_TIMEOUT) {
387 err.assert_error<isotp_recv_exception>(__FILE__, __LINE__);
390 while (
buf !=
nullptr) {
395 std::memcpy(can2_rx_msg.data + can2_rx_msg.len,
buf->data, ncpy);
396 can2_rx_msg.len += ncpy;
397 buf = net_buf_frag_del(NULL,
buf);
400 if (can2_rx_msg.len > 0) {
401 arb.push(can2_rx_msg);
403 }
catch (
const scl::exception &e) {
405 }
catch (
const std::exception &e) {
413received_crc(
const uint8_t *b, uint32_t len)
415 return (b[len -
sizeof(uint32_t)] << 24) |
416 (b[len -
sizeof(uint32_t) + 1] << 16) |
417 (b[len -
sizeof(uint32_t) + 2] << 8) | (b[len -
sizeof(uint32_t) + 3]);
421io::radio_rx_thread(
void *arg1,
void *arg2,
void *arg3)
423 int task_wdt_id = task_wdt_add(CONFIG_WATCHDOG_PERIOD_RADIO_RX,
429 task_wdt_feed(task_wdt_id);
430 int ret =
radio.recv_msg(radio_rx_msg, 1000);
436 auto crc = etl::crc32_c(radio_rx_msg.
pdu, radio_rx_msg.
pdu +
441 received_crc(radio_rx_msg.
pdu, radio_rx_msg.
info.
len);
444 radio_rx_msg.
info.iface, crc == recv_crc, radio_rx_msg.
info.
rssi);
447 if (crc == recv_crc) {
448 radio_msg_to_arb.
iface =
452 std::copy_n(radio_rx_msg.
pdu, radio_rx_msg.
info.
len,
453 radio_msg_to_arb.
data);
456 arb.push(radio_msg_to_arb);
459 }
catch (
const scl::exception &e) {
462 }
catch (
const std::exception &e) {
470io::uhf_tx_thread(
void *arg1,
void *arg2,
void *arg3)
472 int task_wdt_id = task_wdt_add(CONFIG_WATCHDOG_PERIOD_RADIO_TX,
479 task_wdt_feed(task_wdt_id);
488 }
catch (
const scl::exception &e) {
491 }
catch (
const std::exception &e) {
499io::sband_tx_thread(
void *arg1,
void *arg2,
void *arg3)
501 int task_wdt_id = task_wdt_add(CONFIG_WATCHDOG_PERIOD_RADIO_TX,
508 task_wdt_feed(task_wdt_id);
516 }
catch (
const scl::exception &e) {
519 }
catch (
const std::exception &e) {
531 m_radio.m_uhf.rx_frame_dropped();
534 m_radio.m_sband.rx_frame_dropped();
544 m_radio.m_uhf.frame_received(valid, rssi);
547 m_radio.m_sband.frame_received(valid, rssi);
552#if DT_NODE_HAS_STATUS(DT_ALIAS(pc104_usart3), okay)
554uart_handling_callback(
const struct device *dev,
struct uart_event *evt,
562 case UART_TX_ABORTED:
567 std::min<size_t>(CONFIG_MAX_MTU - uart->msg_idx, evt->data.rx.len);
568 std::copy_n(&evt->data.rx.buf[evt->data.rx.offset], ncopy,
569 &uart->msg.data[uart->msg_idx]);
570 uart->msg_idx += ncopy;
573 uart->msg.len = uart->msg_idx;
577 case UART_RX_BUF_RELEASED:
579 case UART_RX_BUF_REQUEST:
580 uart->buf_idx = (uart->buf_idx + 1) % 2;
583 case UART_RX_DISABLED:
static void descrambler(uint8_t *data, size_t len)
static error_handler & get_instance()
Singleton access to the error_handler subsystem.
static constexpr size_t buf_len
static io & get_instance()
comms::lib::power & power()
Returns a reference to the power subsystem.
comms::lib::radio & radio()
Returns a reference to the radio subsystem.
static board & get_instance()
Gets a reference to the single instance of the Board interface class.
void enable(subsys sys, bool en=true)
Enable/disable the power of subsystems.
uint32_t len
The frame length.
The RX message accompanied by its metadata.
uint8_t pdu[AT86RF215_MAX_PDU]
Buffer to hold the received frame.
void register_rx_drop_callback(etl::delegate< void(interface)> callback)
Registers a callback for the RX drop message event.
interface
Radio interface identifier.
uint8_t data[mtu]
Buffer to hold the data.
size_t len
Data size in bytes.
subsys iface
The interface from which the msg was received.
Incoming/Outgoing Message Arbiter.
int pull(msg_arbiter::msg &m, subsys s, k_timeout_t wait=K_MSEC(CONFIG_MSG_ARBITER_TIMEOUT_MS))
Pulls a message for a specific IO interface.
static constexpr size_t mtu
static msg_arbiter & get_instance()
Singleton access to a unique and global msg_arbiter instance.
void task_wdt_callback(int channel_id, void *user_data)
K_THREAD_STACK_DEFINE(radio_rx_thread_stack, CONFIG_RADIO_RX_THREAD_STACK_SIZE)