38 #if defined(PIOS_INCLUDE_USART)
43 static void PIOS_USART_ChangeBaud(uintptr_t usart_id, uint32_t baud);
44 static void PIOS_USART_RegisterRxCallback(uintptr_t usart_id,
pios_com_callback rx_in_cb, uintptr_t context);
45 static void PIOS_USART_RegisterTxCallback(uintptr_t usart_id,
pios_com_callback tx_out_cb, uintptr_t context);
46 static void PIOS_USART_TxStart(uintptr_t usart_id, uint16_t tx_bytes_avail);
47 static void PIOS_USART_RxStart(uintptr_t usart_id, uint16_t rx_bytes_avail);
51 .tx_start = PIOS_USART_TxStart,
52 .rx_start = PIOS_USART_RxStart,
53 .bind_tx_cb = PIOS_USART_RegisterTxCallback,
54 .bind_rx_cb = PIOS_USART_RegisterRxCallback,
57 enum pios_usart_dev_magic {
58 PIOS_USART_DEV_MAGIC = 0x4152834A,
61 struct pios_usart_dev {
62 enum pios_usart_dev_magic
magic;
66 uintptr_t rx_in_context;
68 uintptr_t tx_out_context;
71 static bool PIOS_USART_validate(
struct pios_usart_dev * usart_dev)
73 return (usart_dev->magic == PIOS_USART_DEV_MAGIC);
76 static struct pios_usart_dev * PIOS_USART_alloc(
void)
78 struct pios_usart_dev * usart_dev;
80 usart_dev = (
struct pios_usart_dev *)
PIOS_malloc(
sizeof(*usart_dev));
81 if (!usart_dev)
return(NULL);
83 memset(usart_dev, 0,
sizeof(*usart_dev));
84 usart_dev->magic = PIOS_USART_DEV_MAGIC;
94 static void PIOS_USART_generic_irq_handler(uintptr_t usart_id);
96 static uintptr_t PIOS_USART_1_id;
98 static
void PIOS_USART_1_irq_handler (
void)
101 PIOS_USART_generic_irq_handler (PIOS_USART_1_id);
105 static uintptr_t PIOS_USART_2_id;
107 static
void PIOS_USART_2_irq_handler (
void)
110 PIOS_USART_generic_irq_handler (PIOS_USART_2_id);
114 static uintptr_t PIOS_USART_3_id;
116 static
void PIOS_USART_3_irq_handler (
void)
119 PIOS_USART_generic_irq_handler (PIOS_USART_3_id);
123 static uintptr_t PIOS_USART_4_id;
125 static
void PIOS_USART_4_irq_handler (
void)
128 PIOS_USART_generic_irq_handler (PIOS_USART_4_id);
132 static uintptr_t PIOS_USART_5_id;
134 static
void PIOS_USART_5_irq_handler (
void)
137 PIOS_USART_generic_irq_handler (PIOS_USART_5_id);
141 static uintptr_t PIOS_USART_6_id;
143 static
void PIOS_USART_6_irq_handler (
void)
146 PIOS_USART_generic_irq_handler (PIOS_USART_6_id);
158 struct pios_usart_dev * usart_dev;
160 usart_dev = (
struct pios_usart_dev *) PIOS_USART_alloc();
161 if (!usart_dev)
goto out_fail;
164 usart_dev->cfg =
cfg;
168 if (usart_dev->cfg->remap) {
169 if (usart_dev->cfg->rx.gpio != 0)
170 GPIO_PinAFConfig(usart_dev->cfg->rx.gpio,
171 __builtin_ctz(usart_dev->cfg->rx.init.GPIO_Pin),
172 usart_dev->cfg->remap);
173 if (usart_dev->cfg->tx.gpio != 0)
174 GPIO_PinAFConfig(usart_dev->cfg->tx.gpio,
175 __builtin_ctz(usart_dev->cfg->tx.init.GPIO_Pin),
176 usart_dev->cfg->remap);
180 if (usart_dev->cfg->rx.gpio != 0)
181 GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init);
182 if (usart_dev->cfg->tx.gpio != 0)
183 GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init);
187 USART_HalfDuplexCmd(usart_dev->cfg->regs, ENABLE);
189 USART_HalfDuplexCmd(usart_dev->cfg->regs, DISABLE);
192 USART_Init(usart_dev->cfg->regs, (USART_InitTypeDef *)¶ms->
init);
194 *usart_id = (uintptr_t)usart_dev;
197 switch ((uint32_t)usart_dev->cfg->regs) {
198 case (uint32_t)USART1:
199 PIOS_USART_1_id = (uintptr_t)usart_dev;
201 case (uint32_t)USART2:
202 PIOS_USART_2_id = (uintptr_t)usart_dev;
204 case (uint32_t)USART3:
205 PIOS_USART_3_id = (uintptr_t)usart_dev;
207 case (uint32_t)UART4:
208 PIOS_USART_4_id = (uintptr_t)usart_dev;
210 case (uint32_t)UART5:
211 PIOS_USART_5_id = (uintptr_t)usart_dev;
213 case (uint32_t)USART6:
214 PIOS_USART_6_id = (uintptr_t)usart_dev;
217 NVIC_Init((NVIC_InitTypeDef *)&(usart_dev->cfg->irq.init));
218 USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
219 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
224 USART_Cmd(usart_dev->cfg->regs, ENABLE);
232 static void PIOS_USART_RxStart(uintptr_t usart_id, uint16_t rx_bytes_avail)
234 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
236 bool valid = PIOS_USART_validate(usart_dev);
239 USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
241 static void PIOS_USART_TxStart(uintptr_t usart_id, uint16_t tx_bytes_avail)
243 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
245 bool valid = PIOS_USART_validate(usart_dev);
248 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
256 static void PIOS_USART_ChangeBaud(uintptr_t usart_id, uint32_t baud)
258 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
260 bool valid = PIOS_USART_validate(usart_dev);
263 USART_InitTypeDef USART_InitStructure;
266 USART_InitStructure.USART_BaudRate = baud;
269 USART_InitStructure.USART_WordLength = usart_dev->cfg->regs->CR1 & (uint32_t)USART_CR1_M;
270 USART_InitStructure.USART_Parity = usart_dev->cfg->regs->CR1 & ((uint32_t)USART_CR1_PCE | (uint32_t)USART_CR1_PS);
271 USART_InitStructure.USART_StopBits = usart_dev->cfg->regs->CR2 & (uint32_t)USART_CR2_STOP;
272 USART_InitStructure.USART_HardwareFlowControl = usart_dev->cfg->regs->CR3 & ((uint32_t)USART_CR3_CTSE | (uint32_t)USART_CR3_RTSE);
273 USART_InitStructure.USART_Mode = usart_dev->cfg->regs->CR1 & ((uint32_t)USART_CR1_TE | (uint32_t)USART_CR1_RE) ;
276 USART_Init(usart_dev->cfg->regs, &USART_InitStructure);
279 static void PIOS_USART_RegisterRxCallback(uintptr_t usart_id,
pios_com_callback rx_in_cb, uintptr_t context)
281 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
283 bool valid = PIOS_USART_validate(usart_dev);
290 usart_dev->rx_in_context = context;
291 usart_dev->rx_in_cb = rx_in_cb;
294 static void PIOS_USART_RegisterTxCallback(uintptr_t usart_id,
pios_com_callback tx_out_cb, uintptr_t context)
296 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
298 bool valid = PIOS_USART_validate(usart_dev);
305 usart_dev->tx_out_context = context;
306 usart_dev->tx_out_cb = tx_out_cb;
309 static void PIOS_USART_generic_irq_handler(uintptr_t usart_id)
311 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
313 bool valid = PIOS_USART_validate(usart_dev);
317 volatile uint16_t sr = usart_dev->cfg->regs->SR;
318 volatile uint8_t dr = usart_dev->cfg->regs->DR;
321 bool rx_need_yield =
false;
322 if (sr & USART_SR_RXNE) {
324 if (usart_dev->rx_in_cb) {
325 (void) (usart_dev->rx_in_cb)(usart_dev->rx_in_context, &byte, 1, NULL, &rx_need_yield);
330 bool tx_need_yield =
false;
331 if (sr & USART_SR_TXE) {
332 if (usart_dev->tx_out_cb) {
334 uint16_t bytes_to_send;
336 bytes_to_send = (usart_dev->tx_out_cb)(usart_dev->tx_out_context, &b, 1, NULL, &tx_need_yield);
338 if (bytes_to_send > 0) {
340 usart_dev->cfg->regs->DR = b;
343 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
347 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
Main PiOS header to include all the compiled in PiOS options.
void USART1_IRQHandler(void)
#define PIOS_DEBUG_Assert(test)
#define PIOS_IRQ_Epilogue()
void * PIOS_malloc(size_t size)
#define USART6_IRQHandler
#define USART5_IRQHandler
USART private definitions.
static struct flyingpicmd_cfg_fa cfg
const struct pios_com_driver pios_usart_com_driver
#define USART2_IRQHandler
#define USART3_IRQHandler
int32_t PIOS_USART_Init(uintptr_t *usart_id, const struct pios_usart_cfg *cfg, struct pios_usart_params *params)
#define USART4_IRQHandler
#define PIOS_IRQ_Prologue()
#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)