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);
119 struct pios_usart_dev * usart_dev;
121 usart_dev = (
struct pios_usart_dev *) PIOS_USART_alloc();
122 if (!usart_dev)
goto out_fail;
125 usart_dev->cfg =
cfg;
128 if (usart_dev->cfg->remap) {
129 if (usart_dev->cfg->rx.gpio != 0)
130 GPIO_PinAFConfig(usart_dev->cfg->rx.gpio,
131 usart_dev->cfg->rx.pin_source,
132 usart_dev->cfg->remap);
133 if (usart_dev->cfg->tx.gpio != 0)
134 GPIO_PinAFConfig(usart_dev->cfg->tx.gpio,
135 usart_dev->cfg->tx.pin_source,
136 usart_dev->cfg->remap);
140 if (usart_dev->cfg->rx.gpio != 0)
141 GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init);
142 if (usart_dev->cfg->tx.gpio != 0)
143 GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init);
147 USART_InvPinCmd(usart_dev->cfg->regs, USART_InvPin_Rx, ENABLE);
149 USART_InvPinCmd(usart_dev->cfg->regs, USART_InvPin_Rx, DISABLE);
152 USART_InvPinCmd(usart_dev->cfg->regs, USART_InvPin_Tx, ENABLE);
154 USART_InvPinCmd(usart_dev->cfg->regs, USART_InvPin_Tx, DISABLE);
157 USART_SWAPPinCmd(usart_dev->cfg->regs, ENABLE);
159 USART_SWAPPinCmd(usart_dev->cfg->regs, DISABLE);
162 USART_HalfDuplexCmd(usart_dev->cfg->regs, ENABLE);
164 USART_HalfDuplexCmd(usart_dev->cfg->regs, DISABLE);
167 USART_Init(usart_dev->cfg->regs, (USART_InitTypeDef *)¶ms->
init);
169 *usart_id = (uintptr_t)usart_dev;
172 switch ((uint32_t)usart_dev->cfg->regs) {
173 case (uint32_t)USART1:
174 PIOS_USART_1_id = (uintptr_t)usart_dev;
177 NVIC_Init((NVIC_InitTypeDef *)&(usart_dev->cfg->irq.init));
178 USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
179 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
184 USART_Cmd(usart_dev->cfg->regs, ENABLE);
192 static void PIOS_USART_RxStart(uintptr_t usart_id, uint16_t rx_bytes_avail)
194 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
196 bool valid = PIOS_USART_validate(usart_dev);
199 USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
201 static void PIOS_USART_TxStart(uintptr_t usart_id, uint16_t tx_bytes_avail)
203 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
205 bool valid = PIOS_USART_validate(usart_dev);
208 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
216 static void PIOS_USART_ChangeBaud(uintptr_t usart_id, uint32_t baud)
218 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
220 bool valid = PIOS_USART_validate(usart_dev);
223 USART_InitTypeDef USART_InitStructure;
226 USART_InitStructure.USART_BaudRate = baud;
229 USART_InitStructure.USART_WordLength = usart_dev->cfg->regs->CR1 & (uint32_t)USART_CR1_M;
230 USART_InitStructure.USART_Parity = usart_dev->cfg->regs->CR1 & ((uint32_t)USART_CR1_PCE | (uint32_t)USART_CR1_PS);
231 USART_InitStructure.USART_StopBits = usart_dev->cfg->regs->CR2 & (uint32_t)USART_CR2_STOP;
232 USART_InitStructure.USART_HardwareFlowControl = usart_dev->cfg->regs->CR3 & ((uint32_t)USART_CR3_CTSE | (uint32_t)USART_CR3_RTSE);
233 USART_InitStructure.USART_Mode = usart_dev->cfg->regs->CR1 & ((uint32_t)USART_CR1_TE | (uint32_t)USART_CR1_RE) ;
236 USART_Init(usart_dev->cfg->regs, &USART_InitStructure);
241 USART_Cmd(usart_dev->cfg->regs, ENABLE);
244 static void PIOS_USART_RegisterRxCallback(uintptr_t usart_id,
pios_com_callback rx_in_cb, uintptr_t context)
246 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
248 bool valid = PIOS_USART_validate(usart_dev);
255 usart_dev->rx_in_context = context;
256 usart_dev->rx_in_cb = rx_in_cb;
259 static void PIOS_USART_RegisterTxCallback(uintptr_t usart_id,
pios_com_callback tx_out_cb, uintptr_t context)
261 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
263 bool valid = PIOS_USART_validate(usart_dev);
270 usart_dev->tx_out_context = context;
271 usart_dev->tx_out_cb = tx_out_cb;
274 static void PIOS_USART_generic_irq_handler(uintptr_t usart_id)
276 struct pios_usart_dev * usart_dev = (
struct pios_usart_dev *)usart_id;
278 bool rx_need_yield =
false;
279 bool tx_need_yield =
false;
281 bool valid = PIOS_USART_validate(usart_dev);
285 if (USART_GetITStatus(usart_dev->cfg->regs, USART_IT_RXNE)) {
286 uint8_t byte = (uint8_t)USART_ReceiveData(usart_dev->cfg->regs);
287 if (usart_dev->rx_in_cb) {
288 (void) (usart_dev->rx_in_cb)(usart_dev->rx_in_context, &byte, 1, NULL, &rx_need_yield);
292 if (USART_GetITStatus(usart_dev->cfg->regs, USART_IT_TXE)) {
293 if (usart_dev->tx_out_cb) {
295 uint16_t bytes_to_send;
297 bytes_to_send = (usart_dev->tx_out_cb)(usart_dev->tx_out_context, &b, 1, NULL, &tx_need_yield);
299 if (bytes_to_send > 0) {
301 USART_SendData(usart_dev->cfg->regs, b);
304 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
308 USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
316 if (USART_GetFlagStatus(usart_dev->cfg->regs, USART_FLAG_ORE)) {
317 USART_ClearITPendingBit(usart_dev->cfg->regs, USART_IT_ORE);
318 ++usart_dev->error_overruns;
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)
USART private definitions.
static struct flyingpicmd_cfg_fa cfg
const struct pios_com_driver pios_usart_com_driver
int32_t PIOS_USART_Init(uintptr_t *usart_id, const struct pios_usart_cfg *cfg, struct pios_usart_params *params)
#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)