37 class CommBridge<std::tuple<TxPackets...>, std::tuple<RxPackets...>>
43 static std::unique_ptr<CommBridge>
create(
const device* uart_dev)
45 return std::unique_ptr<CommBridge>(
new CommBridge(uart_dev));
63 LOG_MODULE_DECLARE(
CommBridge, CONFIG_COMM_BRIDGE_LOG_LEVEL);
67 LOG_WRN(
"Receive already enabled");
71 uart_irq_callback_user_data_set(m_UartDev, uart_rx_callback,
this);
72 uart_irq_rx_enable(m_UartDev);
75 LOG_INF(
"UART RX interrupt enabled");
88 uart_irq_rx_disable(m_UartDev);
90 LOG_MODULE_DECLARE(
CommBridge, CONFIG_COMM_BRIDGE_LOG_LEVEL);
91 LOG_INF(
"UART RX interrupt disabled");
97 template <
typename... Packets>
98 requires(
sizeof...(Packets) == 0 || (RPL::Serializable<Packets, TxPackets...> && ...))
99 void
send(const Packets&... packets)
101 LOG_MODULE_DECLARE(
CommBridge, CONFIG_COMM_BRIDGE_LOG_LEVEL);
104 if constexpr (
sizeof...(Packets) == 0)
109 k_sem_take(&m_TxDoneSem, K_FOREVER);
111 auto res = m_Serializer.serialize(m_TxBuffer, TxBufferSize, packets...);
114 LOG_ERR(
"Serialize failed");
115 k_sem_give(&m_TxDoneSem);
119 m_TxSize = res.value();
122 k_timer_start(&m_TxWatchdog, K_MSEC(50), K_MSEC(50));
124 for (
size_t i = 0; i < m_TxSize; ++i)
126 uart_poll_out(m_UartDev, m_TxBuffer[i]);
130 k_timer_stop(&m_TxWatchdog);
133 k_sem_give(&m_TxDoneSem);
139 template <
typename T>
140 requires(
sizeof...(RxPackets) == 0 ? false : RPL::Deserializable<T, RxPackets...>)
143 return m_Deserializer.template
get<T>();
150 m_Parser(m_Deserializer)
152 LOG_MODULE_DECLARE(
CommBridge, CONFIG_COMM_BRIDGE_LOG_LEVEL);
153 LOG_INF(
"Creating CommBridge");
154 if (!device_is_ready(m_UartDev))
156 LOG_ERR(
"UART not ready");
160 k_sem_init(&m_TxDoneSem, 1, 1);
162 k_timer_init(&m_TxWatchdog, tx_watchdog_expiry,
nullptr);
163 k_timer_user_data_set(&m_TxWatchdog,
this);
165 LOG_INF(
"CommBridge initialized, UART device: %s", m_UartDev->name);
169 static constexpr size_t calculateTxBufferSize()
171 if constexpr (
sizeof...(TxPackets) == 0)
177 return (RPL::Serializer<TxPackets...>::template frame_size<TxPackets>() + ...);
181 static constexpr size_t TxBufferSize = calculateTxBufferSize();
182 static constexpr size_t RxBufferSize = CONFIG_COMM_BRIDGE_MAX_RX_SIZE;
184 const device* m_UartDev;
186 RPL::Serializer<TxPackets...> m_Serializer{};
187 uint8_t m_TxBuffer[TxBufferSize > 0 ? TxBufferSize : 1]{};
191 RPL::Deserializer<RxPackets...> m_Deserializer{};
192 RPL::Parser<RxPackets...> m_Parser;
193 uint8_t m_RxBuffer[RxBufferSize]{};
195 bool m_RxEnabled{
false};
197 k_timer m_TxWatchdog{};
198 uint32_t m_BusyCount{0};
200 static void tx_watchdog_expiry(k_timer* timer)
202 auto* bridge =
static_cast<CommBridge*
>(k_timer_user_data_get(timer));
203 bridge->m_BusyCount++;
205 if (bridge->m_BusyCount >= 5)
215 static void uart_rx_callback(
const device* dev,
void* user_data)
217 LOG_MODULE_DECLARE(CommBridge, CONFIG_COMM_BRIDGE_LOG_LEVEL);
218 auto* bridge =
static_cast<CommBridge*
>(user_data);
220 if (!uart_irq_update(dev))
225 if (uart_irq_rx_ready(dev))
228 int len = uart_fifo_read(dev, buffer,
sizeof(buffer));
231 bridge->m_Parser.push_data(buffer, len);