39 #if defined(PIOS_INCLUDE_USART)
44 static void PIOS_USART_ChangeBaud(uintptr_t usart_id, uint32_t baud);
45 static void PIOS_USART_RegisterRxCallback(uintptr_t usart_id,
pios_com_callback rx_in_cb, uintptr_t context);
46 static void PIOS_USART_RegisterTxCallback(uintptr_t usart_id,
pios_com_callback tx_out_cb, uintptr_t context);
47 static void PIOS_USART_TxStart(uintptr_t usart_id, uint16_t tx_bytes_avail);
48 static void PIOS_USART_RxStart(uintptr_t usart_id, uint16_t rx_bytes_avail);
52 .tx_start = PIOS_USART_TxStart,
53 .rx_start = PIOS_USART_RxStart,
54 .bind_tx_cb = PIOS_USART_RegisterTxCallback,
55 .bind_rx_cb = PIOS_USART_RegisterRxCallback,
58 enum pios_usart_dev_magic {
59 PIOS_USART_DEV_MAGIC = 0x4152834A,
62 struct pios_usart_dev {
63 enum pios_usart_dev_magic
magic;
67 uintptr_t rx_in_context;
69 uintptr_t tx_out_context;
71 uint32_t error_overruns;
74 static bool PIOS_USART_validate(
struct pios_usart_dev * usart_dev)
76 return (usart_dev->magic == PIOS_USART_DEV_MAGIC);
79 static struct pios_usart_dev * PIOS_USART_alloc(
void)
81 struct pios_usart_dev * usart_dev;
83 usart_dev = (
struct pios_usart_dev *)
PIOS_malloc(
sizeof(*usart_dev));
84 if (!usart_dev)
return(NULL);
86 memset(usart_dev, 0,
sizeof(*usart_dev));
87 usart_dev->magic = PIOS_USART_DEV_MAGIC;
89 usart_dev->error_overruns = 0;
100 static void PIOS_USART_generic_irq_handler(uintptr_t usart_id);
102 static uintptr_t PIOS_USART_1_id;
104 static
void PIOS_USART_1_irq_handler (
void)
107 PIOS_USART_generic_irq_handler (PIOS_USART_1_id);
111 static uintptr_t PIOS_USART_2_id;
113 static
void PIOS_USART_2_irq_handler (
void)
116 PIOS_USART_generic_irq_handler (PIOS_USART_2_id);
120 static uintptr_t PIOS_USART_3_id;
122 static
void PIOS_USART_3_irq_handler (
void)
125 PIOS_USART_generic_irq_handler (PIOS_USART_3_id);
129 static uintptr_t PIOS_UART_4_id;
131 static
void PIOS_UART_4_irq_handler (
void)
134 PIOS_USART_generic_irq_handler (PIOS_UART_4_id);
138 static uintptr_t PIOS_UART_5_id;
140 static
void PIOS_UART_5_irq_handler (
void)
143 PIOS_USART_generic_irq_handler (PIOS_UART_5_id);
155 struct pios_usart_dev * usart_dev;
157 usart_dev = (
struct pios_usart_dev *) PIOS_USART_alloc();
158 if (!usart_dev)
goto out_fail;
161 usart_dev->cfg =
cfg;
164 if (usart_dev->cfg->remap) {
165 if (usart_dev->cfg->rx.gpio != 0)
166 GPIO_PinAFConfig(usart_dev->cfg->rx.gpio,
167 usart_dev->cfg->rx.pin_source,
168 usart_dev->cfg->remap);
169 if (usart_dev->cfg->tx.gpio != 0)
170 GPIO_PinAFConfig(usart_dev->cfg->tx.gpio,
171 usart_dev->cfg->tx.pin_source,
172 usart_dev->cfg->remap);
176 if (usart_dev->cfg->rx.gpio != 0)
177 GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init);
178 if (usart_dev->cfg->tx.gpio != 0)
179 GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init);
183 USART_InvPinCmd(usart_dev->cfg->regs, USART_InvPin_Rx, ENABLE);
185 USART_InvPinCmd(usart_dev->cfg->regs, USART_InvPin_Rx, DISABLE);
188 USART_InvPinCmd(usart_dev->cfg->regs, USART_InvPin_Tx, ENABLE);
190 USART_InvPinCmd(usart_dev->cfg->regs, USART_InvPin_Tx, DISABLE);
193 USART_SWAPPinCmd(usart_dev->cfg->regs, ENABLE);
195 USART_SWAPPinCmd(usart_dev->cfg->regs, DISABLE);
198 USART_HalfDuplexCmd(usart_dev->cfg->regs, ENABLE);
200 USART_HalfDuplexCmd(usart_dev->cfg->regs, DISABLE);
203 USART_Init(usart_dev->cfg->regs, (USART_InitTypeDef *)¶ms->
init);
205 *usart_id = (uintptr_t)usart_dev;
208 switch ((uint32_t)usart_dev->cfg->regs) {
209 case (uint32_t)USART1:
210 PIOS_USART_1_id = (uintptr_t)usart_dev;
212 case (uint32_t)USART2:
213 PIOS_USART_2_id = (uintptr_t)usart_dev;
215 case (uint32_t)USART3:
216 PIOS_USART_3_id = (uintptr_t)usart_dev;
218 case (uint32_t)UART4:
219 PIOS_UART_4_id = (uintptr_t)usart_dev;
221 case (uint32_t)UART5:
222 PIOS_UART_5_id = (uintptr_t)usart_dev;
225 NVIC_Init((NVIC_InitTypeDef *)&(usart_dev->cfg->irq.init));
226 USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
227 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
232 USART_Cmd(usart_dev->cfg->regs, ENABLE);
240 static void PIOS_USART_RxStart(uintptr_t usart_id, uint16_t rx_bytes_avail)
242 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
244 bool valid = PIOS_USART_validate(usart_dev);
247 USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
249 static void PIOS_USART_TxStart(uintptr_t usart_id, uint16_t tx_bytes_avail)
251 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
253 bool valid = PIOS_USART_validate(usart_dev);
256 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
264 static void PIOS_USART_ChangeBaud(uintptr_t usart_id, uint32_t baud)
266 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
268 bool valid = PIOS_USART_validate(usart_dev);
271 USART_InitTypeDef USART_InitStructure;
274 USART_InitStructure.USART_BaudRate = baud;
277 USART_InitStructure.USART_WordLength = usart_dev->cfg->regs->CR1 & (uint32_t)USART_CR1_M;
278 USART_InitStructure.USART_Parity = usart_dev->cfg->regs->CR1 & ((uint32_t)USART_CR1_PCE | (uint32_t)USART_CR1_PS);
279 USART_InitStructure.USART_StopBits = usart_dev->cfg->regs->CR2 & (uint32_t)USART_CR2_STOP;
280 USART_InitStructure.USART_HardwareFlowControl = usart_dev->cfg->regs->CR3 & ((uint32_t)USART_CR3_CTSE | (uint32_t)USART_CR3_RTSE);
281 USART_InitStructure.USART_Mode = usart_dev->cfg->regs->CR1 & ((uint32_t)USART_CR1_TE | (uint32_t)USART_CR1_RE) ;
284 USART_Init(usart_dev->cfg->regs, &USART_InitStructure);
289 USART_Cmd(usart_dev->cfg->regs, ENABLE);
292 static void PIOS_USART_RegisterRxCallback(uintptr_t usart_id,
pios_com_callback rx_in_cb, uintptr_t context)
294 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
296 bool valid = PIOS_USART_validate(usart_dev);
303 usart_dev->rx_in_context = context;
304 usart_dev->rx_in_cb = rx_in_cb;
307 static void PIOS_USART_RegisterTxCallback(uintptr_t usart_id,
pios_com_callback tx_out_cb, uintptr_t context)
309 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
311 bool valid = PIOS_USART_validate(usart_dev);
318 usart_dev->tx_out_context = context;
319 usart_dev->tx_out_cb = tx_out_cb;
322 static void PIOS_USART_generic_irq_handler(uintptr_t usart_id)
324 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
326 bool rx_need_yield =
false;
327 bool tx_need_yield =
false;
329 bool valid = PIOS_USART_validate(usart_dev);
333 if (USART_GetITStatus(usart_dev->cfg->regs, USART_IT_RXNE)) {
334 uint8_t byte = (uint8_t)USART_ReceiveData(usart_dev->cfg->regs);
335 if (usart_dev->rx_in_cb) {
336 (void) (usart_dev->rx_in_cb)(usart_dev->rx_in_context, &byte, 1, NULL, &rx_need_yield);
340 if (USART_GetITStatus(usart_dev->cfg->regs, USART_IT_TXE)) {
341 if (usart_dev->tx_out_cb) {
343 uint16_t bytes_to_send;
345 bytes_to_send = (usart_dev->tx_out_cb)(usart_dev->tx_out_context, &b, 1, NULL, &tx_need_yield);
347 if (bytes_to_send > 0) {
349 USART_SendData(usart_dev->cfg->regs, b);
352 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
356 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
364 if (USART_GetFlagStatus(usart_dev->cfg->regs, USART_FLAG_ORE)) {
365 USART_ClearITPendingBit(usart_dev->cfg->regs, USART_IT_ORE);
366 ++usart_dev->error_overruns;
Main PiOS header to include all the compiled in PiOS options.
#define PIOS_DEBUG_Assert(test)
#define PIOS_IRQ_Epilogue()
void * PIOS_malloc(size_t size)
#define USART2_EXTI26_IRQHandler
USART private definitions.
static struct flyingpicmd_cfg_fa cfg
const struct pios_com_driver pios_usart_com_driver
#define UART5_EXTI35_IRQHandler
#define USART1_EXTI25_IRQHandler
int32_t PIOS_USART_Init(uintptr_t *usart_id, const struct pios_usart_cfg *cfg, struct pios_usart_params *params)
#define USART3_EXTI28_IRQHandler
#define PIOS_IRQ_Prologue()
#define UART4_EXTI34_IRQHandler
#define PIOS_Assert(test)
uint16_t(* pios_com_callback)(uintptr_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken)
void(* set_baud)(uintptr_t id, uint32_t baud)