Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_uart.c
1 #include <bc_uart.h>
2 #include <bc_scheduler.h>
3 #include <bc_irq.h>
4 #include <bc_system.h>
5 #include <stm32l0xx.h>
6 #include <bc_dma.h>
7 
8 typedef struct
9 {
10  bool initialized;
11  void (*event_handler)(bc_uart_channel_t, bc_uart_event_t, void *);
12  void *event_param;
13  bc_fifo_t *write_fifo;
14  bc_fifo_t *read_fifo;
15  bc_scheduler_task_id_t async_write_task_id;
16  bc_scheduler_task_id_t async_read_task_id;
17  bool async_write_in_progress;
18  bool async_read_in_progress;
19  bc_tick_t async_timeout;
20  USART_TypeDef *usart;
21 
22 } bc_uart_t;
23 
24 static bc_uart_t _bc_uart[3] =
25 {
26  [BC_UART_UART0] = { .initialized = false },
27  [BC_UART_UART1] = { .initialized = false },
28  [BC_UART_UART2] = { .initialized = false }
29 };
30 
31 static struct
32 {
33  bc_scheduler_task_id_t read_task_id;
34  size_t length;
35 
36 } _bc_uart_2_dma;
37 
38 static uint32_t _bc_uart_brr_t[] =
39 {
40  [BC_UART_BAUDRATE_9600] = 0xd05,
41  [BC_UART_BAUDRATE_19200] = 0x682,
42  [BC_UART_BAUDRATE_38400] = 0x341,
43  [BC_UART_BAUDRATE_57600] = 0x22b,
44  [BC_UART_BAUDRATE_115200] = 0x116,
46 };
47 
48 static void _bc_uart_async_write_task(void *param);
49 static void _bc_uart_async_read_task(void *param);
50 static void _bc_uart_2_dma_read_task(void *param);
51 static void _bc_uart_irq_handler(bc_uart_channel_t channel);
52 
54 {
55  memset(&_bc_uart[channel], 0, sizeof(_bc_uart[channel]));
56 
57  switch(channel)
58  {
59  case BC_UART_UART0:
60  {
61  // Enable GPIOA clock
62  RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
63 
64  // Errata workaround
65  RCC->IOPENR;
66 
67  // Enable pull-up on RXD0 pin
68  GPIOA->PUPDR |= GPIO_PUPDR_PUPD1_0;
69 
70  // Select AF6 alternate function for TXD0 and RXD0 pins
71  GPIOA->AFR[0] |= 6 << GPIO_AFRL_AFRL1_Pos | 6 << GPIO_AFRL_AFRL0_Pos;
72 
73  // Configure TXD0 and RXD0 pins as alternate function
74  GPIOA->MODER &= ~(1 << GPIO_MODER_MODE1_Pos | 1 << GPIO_MODER_MODE0_Pos);
75 
76  // Enable clock for USART4
77  RCC->APB1ENR |= RCC_APB1ENR_USART4EN;
78 
79  // Errata workaround
80  RCC->APB1ENR;
81 
82  // Enable transmitter and receiver, peripheral enabled in stop mode
83  USART4->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM;
84 
85  // Clock enabled in stop mode, disable overrun detection, one bit sampling method
86  USART4->CR3 = USART_CR3_UCESM | USART_CR3_OVRDIS | USART_CR3_ONEBIT;
87 
88  // Configure baudrate
89  USART4->BRR = _bc_uart_brr_t[baudrate];
90 
91  NVIC_EnableIRQ(USART4_5_IRQn);
92 
93  _bc_uart[channel].usart = USART4;
94 
95  break;
96  }
97  case BC_UART_UART1:
98  {
99  // Enable GPIOA clock
100  RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
101 
102  // Errata workaround
103  RCC->IOPENR;
104 
105  // Enable pull-up on RXD1 pin
106  GPIOA->PUPDR |= GPIO_PUPDR_PUPD3_0;
107 
108  if (baudrate <= BC_UART_BAUDRATE_9600)
109  {
110  // Select AF6 alternate function for TXD1 and RXD1 pins
111  GPIOA->AFR[0] |= 6 << GPIO_AFRL_AFRL3_Pos | 6 << GPIO_AFRL_AFRL2_Pos;
112 
113  // Configure TXD1 and RXD1 pins as alternate function
114  GPIOA->MODER &= ~(1 << GPIO_MODER_MODE3_Pos | 1 << GPIO_MODER_MODE2_Pos);
115 
116  // Set LSE as LPUART1 clock source
117  RCC->CCIPR |= RCC_CCIPR_LPUART1SEL_1 | RCC_CCIPR_LPUART1SEL_0;
118 
119  // Enable clock for LPUART1
120  RCC->APB1ENR |= RCC_APB1ENR_LPUART1EN;
121 
122  // Errata workaround
123  RCC->APB1ENR;
124 
125  // Enable transmitter and receiver, peripheral enabled in stop mode
126  LPUART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM;
127 
128  // Clock enabled in stop mode, disable overrun detection, one bit sampling method
129  LPUART1->CR3 = USART_CR3_UCESM | USART_CR3_OVRDIS | USART_CR3_ONEBIT;
130 
131  // Configure baudrate
132  LPUART1->BRR = 0x369;
133 
134  NVIC_EnableIRQ(LPUART1_IRQn);
135 
136  _bc_uart[channel].usart = LPUART1;
137  }
138  else
139  {
140  // Select AF4 alternate function for TXD1 and RXD1 pins
141  GPIOA->AFR[0] |= 4 << GPIO_AFRL_AFRL3_Pos | 4 << GPIO_AFRL_AFRL2_Pos;
142 
143  // Configure TXD1 and RXD1 pins as alternate function
144  GPIOA->MODER &= ~(1 << GPIO_MODER_MODE3_Pos | 1 << GPIO_MODER_MODE2_Pos);
145 
146  // Enable clock for USART2
147  RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
148 
149  // Errata workaround
150  RCC->APB1ENR;
151 
152  // Enable transmitter and receiver, peripheral enabled in stop mode
153  USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM;
154 
155  // Clock enabled in stop mode, disable overrun detection, one bit sampling method
156  USART2->CR3 = USART_CR3_UCESM | USART_CR3_OVRDIS | USART_CR3_ONEBIT;
157 
158  // Configure baudrate
159  USART2->BRR = _bc_uart_brr_t[baudrate];
160 
161  NVIC_EnableIRQ(USART2_IRQn);
162 
163  _bc_uart[channel].usart = USART2;
164  }
165 
166  break;
167  }
168  case BC_UART_UART2:
169  {
170  // Enable GPIOA clock
171  RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
172 
173  // Errata workaround
174  RCC->IOPENR;
175 
176  // Enable pull-up on RXD2 pin
177  GPIOA->PUPDR |= GPIO_PUPDR_PUPD10_0;
178 
179  // Select AF4 alternate function for TXD2 and RXD2 pins
180  GPIOA->AFR[1] |= 4 << GPIO_AFRH_AFRH2_Pos | 4 << GPIO_AFRH_AFRH1_Pos;
181 
182  // Configure TXD2 and RXD2 pins as alternate function
183  GPIOA->MODER &= ~(1 << GPIO_MODER_MODE10_Pos | 1 << GPIO_MODER_MODE9_Pos);
184 
185  // Enable clock for USART1
186  RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
187 
188  // Errata workaround
189  RCC->APB2ENR;
190 
191  // Enable transmitter and receiver, peripheral enabled in stop mode
192  USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM;
193 
194  // Clock enabled in stop mode, disable overrun detection, one bit sampling method
195  USART1->CR3 = USART_CR3_UCESM | USART_CR3_OVRDIS | USART_CR3_ONEBIT;
196 
197  // Configure baudrate
198  USART1->BRR = _bc_uart_brr_t[baudrate];
199 
200  NVIC_EnableIRQ(USART1_IRQn);
201 
202  _bc_uart[channel].usart = USART1;
203 
204  break;
205  }
206  default:
207  {
208  return;
209  }
210  }
211 
212  // Stop bits
213  _bc_uart[channel].usart->CR2 &= ~USART_CR2_STOP_Msk;
214  _bc_uart[channel].usart->CR2 |= ((uint32_t) setting & 0x03) << USART_CR2_STOP_Pos;
215 
216  // Parity
217  _bc_uart[channel].usart->CR1 &= ~(USART_CR1_PCE_Msk | USART_CR1_PS_Msk);
218  _bc_uart[channel].usart->CR1 |= (((uint32_t) setting >> 2) & 0x03) << USART_CR1_PS_Pos;
219 
220  // Word length
221  _bc_uart[channel].usart->CR1 &= ~(USART_CR1_M1_Msk | USART_CR1_M0_Msk);
222 
223  uint32_t word_length = setting >> 4;
224 
225  if ((setting & 0x0c) != 0)
226  {
227  word_length++;
228  }
229 
230  if (word_length == 0x07)
231  {
232  word_length = 0x10;
233 
234  _bc_uart[channel].usart->CR1 |= 1 << USART_CR1_M1_Pos;
235  }
236  else if (word_length == 0x09)
237  {
238  _bc_uart[channel].usart->CR1 |= 1 << USART_CR1_M0_Pos;
239  }
240 
241  // Enable UART
242  _bc_uart[channel].usart->CR1 |= USART_CR1_UE;
243 
244  _bc_uart[channel].initialized = true;
245 }
246 
247 
249 {
250  bc_uart_async_read_cancel(channel);
251 
252  // Disable UART
253  _bc_uart[channel].usart->CR1 &= ~USART_CR1_UE_Msk;
254 
255  switch(channel)
256  {
257  case BC_UART_UART0:
258  {
259  NVIC_DisableIRQ(USART4_5_IRQn);
260 
261  // Disable clock for USART4
262  RCC->APB1ENR &= ~RCC_APB1ENR_USART4EN;
263 
264  // Configure TXD0 and RXD0 pins as Analog
265  GPIOA->MODER |= (GPIO_MODER_MODE1_Msk | GPIO_MODER_MODE0_Msk);
266 
267  // Clear alternate function for TXD0 and RXD0 pins
268  GPIOA->AFR[0] &= ~(GPIO_AFRL_AFRL1_Msk | GPIO_AFRL_AFRL0_Msk);
269 
270  // Disable pull-up on RXD0 pin
271  GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD1_Msk;
272 
273  break;
274  }
275  case BC_UART_UART1:
276  {
277  if (_bc_uart[channel].usart == LPUART1)
278  {
279  NVIC_DisableIRQ(LPUART1_IRQn);
280 
281  // Disable clock for LPUART1
282  RCC->APB1ENR &= ~RCC_APB1ENR_LPUART1EN;
283  }
284  else
285  {
286  NVIC_DisableIRQ(USART2_IRQn);
287 
288  // Disable clock for USART2
289  RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
290  }
291 
292  // Configure TXD1 and RXD1 pins as Analog
293  GPIOA->MODER |= (GPIO_MODER_MODE3_Msk | GPIO_MODER_MODE2_Msk);
294 
295  // Clear alternate function for TXD1 and RXD1 pins
296  GPIOA->AFR[0] &= ~(GPIO_AFRL_AFRL3_Msk | GPIO_AFRL_AFRL2_Msk);
297 
298  // Disable pull-up on RXD1 pin
299  GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD3_Msk;
300 
301  break;
302  }
303  case BC_UART_UART2:
304  {
305  NVIC_DisableIRQ(USART1_IRQn);
306 
307  // Disable clock for USART1
308  RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN_Msk;
309 
310  // Configure TXD2 and RXD2 pins as Analog
311  GPIOA->MODER |= (GPIO_MODER_MODE10_Msk | GPIO_MODER_MODE9_Msk);
312 
313  // Clear alternate function for TXD2 and RXD2 pins
314  GPIOA->AFR[1] &= ~(GPIO_AFRH_AFRH2_Msk | GPIO_AFRH_AFRH1_Msk);
315 
316  // Disable pull-up on RXD2 pin
317  GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD10_Msk;
318 
319  break;
320  }
321  default:
322  {
323  return;
324  }
325  }
326 
327  _bc_uart[channel].initialized = false;
328 }
329 
330 size_t bc_uart_write(bc_uart_channel_t channel, const void *buffer, size_t length)
331 {
332  if (!_bc_uart[channel].initialized || _bc_uart[channel].async_write_in_progress)
333  {
334  return 0;
335  }
336 
337  USART_TypeDef *usart = _bc_uart[channel].usart;
338 
339  size_t bytes_written = 0;
340 
341  if (_bc_uart[channel].usart != LPUART1)
342  {
343  bc_system_pll_enable();
344  }
345 
346  while (bytes_written != length)
347  {
348  // Until transmit data register is not empty...
349  while ((usart->ISR & USART_ISR_TXE) == 0)
350  {
351  continue;
352  }
353 
354  // Load transmit data register
355  usart->TDR = *((uint8_t *) buffer + bytes_written++);
356  }
357 
358  // Until transmission is not complete...
359  while ((usart->ISR & USART_ISR_TC) == 0)
360  {
361  continue;
362  }
363 
364  if (_bc_uart[channel].usart != LPUART1)
365  {
366  bc_system_pll_disable();
367  }
368 
369  return bytes_written;
370 }
371 
372 size_t bc_uart_read(bc_uart_channel_t channel, void *buffer, size_t length, bc_tick_t timeout)
373 {
374  if (!_bc_uart[channel].initialized)
375  {
376  return 0;
377  }
378 
379  USART_TypeDef *usart = _bc_uart[channel].usart;
380 
381  size_t bytes_read = 0;
382 
383  if (_bc_uart[channel].usart != LPUART1)
384  {
385  bc_system_pll_enable();
386  }
387 
388  bc_tick_t tick_timeout = timeout == BC_TICK_INFINITY ? BC_TICK_INFINITY : bc_tick_get() + timeout;
389 
390  while (bytes_read != length)
391  {
392  // If timeout condition is met...
393  if (bc_tick_get() >= tick_timeout)
394  {
395  break;
396  }
397 
398  // If receive data register is empty...
399  if ((usart->ISR & USART_ISR_RXNE) == 0)
400  {
401  continue;
402  }
403 
404  // Read receive data register
405  *((uint8_t *) buffer + bytes_read++) = usart->RDR;
406  }
407 
408  if (_bc_uart[channel].usart != LPUART1)
409  {
410  bc_system_pll_disable();
411  }
412 
413  return bytes_read;
414 }
415 
416 void bc_uart_set_event_handler(bc_uart_channel_t channel, void (*event_handler)(bc_uart_channel_t, bc_uart_event_t, void *), void *event_param)
417 {
418  _bc_uart[channel].event_handler = event_handler;
419  _bc_uart[channel].event_param = event_param;
420 }
421 
422 void bc_uart_set_async_fifo(bc_uart_channel_t channel, bc_fifo_t *write_fifo, bc_fifo_t *read_fifo)
423 {
424  _bc_uart[channel].write_fifo = write_fifo;
425  _bc_uart[channel].read_fifo = read_fifo;
426 }
427 
428 size_t bc_uart_async_write(bc_uart_channel_t channel, const void *buffer, size_t length)
429 {
430  if (!_bc_uart[channel].initialized || _bc_uart[channel].write_fifo == NULL)
431  {
432  return 0;
433  }
434 
435  size_t bytes_written = 0;
436 
437  for (size_t i = 0; i < length; i += 16)
438  {
439  bytes_written += bc_fifo_write(_bc_uart[channel].write_fifo, (uint8_t *)buffer + i, length - i > 16 ? 16 : length - i);
440  }
441 
442  if (bytes_written != 0)
443  {
444  if (!_bc_uart[channel].async_write_in_progress)
445  {
446  _bc_uart[channel].async_write_task_id = bc_scheduler_register(_bc_uart_async_write_task, (void *) channel, BC_TICK_INFINITY);
447 
448  if (_bc_uart[channel].usart == LPUART1)
449  {
450  bc_system_deep_sleep_disable();
451  }
452  else
453  {
454  bc_system_pll_enable();
455  }
456  }
457  else
458  {
459  bc_scheduler_plan_absolute(_bc_uart[channel].async_write_task_id, BC_TICK_INFINITY);
460  }
461 
462  bc_irq_disable();
463 
464  // Enable transmit interrupt
465  _bc_uart[channel].usart->CR1 |= USART_CR1_TXEIE;
466 
467  bc_irq_enable();
468 
469  _bc_uart[channel].async_write_in_progress = true;
470  }
471 
472  return bytes_written;
473 }
474 
476 {
477  if (!_bc_uart[channel].initialized || _bc_uart[channel].read_fifo == NULL || _bc_uart[channel].async_read_in_progress)
478  {
479  return false;
480  }
481 
482  _bc_uart[channel].async_timeout = timeout;
483 
484  _bc_uart[channel].async_read_task_id = bc_scheduler_register(_bc_uart_async_read_task, (void *) channel, _bc_uart[channel].async_timeout);
485 
486  if (channel == BC_UART_UART2)
487  {
488  bc_dma_channel_config_t config = {
490  .direction = BC_DMA_DIRECTION_TO_RAM,
491  .data_size_memory = BC_DMA_SIZE_1,
492  .data_size_peripheral = BC_DMA_SIZE_1,
493  .length = _bc_uart[channel].read_fifo->size,
494  .mode = BC_DMA_MODE_CIRCULAR,
495  .address_memory = _bc_uart[channel].read_fifo->buffer,
496  .address_peripheral = (void *) &_bc_uart[channel].usart->RDR,
497  .priority = BC_DMA_PRIORITY_HIGH
498  };
499 
500  bc_dma_init();
501 
503 
504  _bc_uart_2_dma.read_task_id = bc_scheduler_register(_bc_uart_2_dma_read_task, (void *) channel, 0);
505 
506  bc_irq_disable();
507  // Enable receive DMA interrupt
508  _bc_uart[channel].usart->CR3 |= USART_CR3_DMAR;
509  bc_irq_enable();
510 
512  }
513  else
514  {
515  bc_irq_disable();
516  // Enable receive interrupt
517  _bc_uart[channel].usart->CR1 |= USART_CR1_RXNEIE;
518  bc_irq_enable();
519  }
520 
521  if (_bc_uart[channel].usart != LPUART1)
522  {
523  bc_system_pll_enable();
524  }
525 
526  _bc_uart[channel].async_read_in_progress = true;
527 
528  return true;
529 }
530 
532 {
533  if (!_bc_uart[channel].initialized || !_bc_uart[channel].async_read_in_progress)
534  {
535  return false;
536  }
537 
538  _bc_uart[channel].async_read_in_progress = false;
539 
540  if (channel == BC_UART_UART2)
541  {
543 
544  bc_scheduler_unregister(_bc_uart_2_dma.read_task_id);
545 
546  bc_irq_disable();
547  // Disable receive DMA interrupt
548  _bc_uart[channel].usart->CR3 &= ~USART_CR3_DMAR_Msk;
549  bc_irq_enable();
550  }
551  else
552  {
553  bc_irq_disable();
554 
555  // Disable receive interrupt
556  _bc_uart[channel].usart->CR1 &= ~USART_CR1_RXNEIE_Msk;
557 
558  bc_irq_enable();
559  }
560 
561  if (_bc_uart[channel].usart != LPUART1)
562  {
563  bc_system_pll_disable();
564  }
565 
566  bc_scheduler_unregister(_bc_uart[channel].async_read_task_id);
567 
568  return false;
569 }
570 
571 size_t bc_uart_async_read(bc_uart_channel_t channel, void *buffer, size_t length)
572 {
573  if (!_bc_uart[channel].initialized || !_bc_uart[channel].async_read_in_progress)
574  {
575  return 0;
576  }
577 
578  size_t bytes_read = bc_fifo_read(_bc_uart[channel].read_fifo, buffer, length);
579 
580  return bytes_read;
581 }
582 
583 static void _bc_uart_async_write_task(void *param)
584 {
585  bc_uart_channel_t channel = (bc_uart_channel_t) param;
586  bc_uart_t *uart = &_bc_uart[channel];
587 
588  uart->async_write_in_progress = false;
589 
590  bc_scheduler_unregister(uart->async_write_task_id);
591 
592  if (uart->usart == LPUART1)
593  {
594  bc_system_deep_sleep_enable();
595  }
596  else
597  {
598  bc_system_pll_disable();
599  }
600 
601  if (uart->event_handler != NULL)
602  {
603  uart->event_handler(channel, BC_UART_EVENT_ASYNC_WRITE_DONE, uart->event_param);
604  }
605 }
606 
607 static void _bc_uart_async_read_task(void *param)
608 {
609  bc_uart_channel_t channel = (bc_uart_channel_t) param;
610  bc_uart_t *uart = &_bc_uart[channel];
611 
612  bc_scheduler_plan_current_relative(uart->async_timeout);
613 
614  if (uart->event_handler != NULL)
615  {
616  if (bc_fifo_is_empty(uart->read_fifo))
617  {
618  uart->event_handler(channel, BC_UART_EVENT_ASYNC_READ_TIMEOUT, uart->event_param);
619  }
620  else
621  {
622  uart->event_handler(channel, BC_UART_EVENT_ASYNC_READ_DATA, uart->event_param);
623  }
624  }
625 }
626 
627 static void _bc_uart_2_dma_read_task(void *param)
628 {
629  (void) param;
630 
631  size_t length = bc_dma_channel_get_length(BC_DMA_CHANNEL_3);
632 
633  bc_uart_t *uart = &_bc_uart[BC_UART_UART2];
634 
635  if (_bc_uart_2_dma.length != length)
636  {
637  uart->read_fifo->head = uart->read_fifo->size - length;
638 
639  _bc_uart_2_dma.length = length;
640 
641  bc_scheduler_plan_now(uart->async_read_task_id);
642  }
643 
645 }
646 
647 static void _bc_uart_irq_handler(bc_uart_channel_t channel)
648 {
649  USART_TypeDef *usart = _bc_uart[channel].usart;
650 
651  if ((usart->CR1 & USART_CR1_RXNEIE) != 0 && (usart->ISR & USART_ISR_RXNE) != 0)
652  {
653  uint8_t character;
654 
655  // Read receive data register
656  character = usart->RDR;
657 
658  bc_fifo_irq_write(_bc_uart[channel].read_fifo, &character, 1);
659 
660  bc_scheduler_plan_now(_bc_uart[channel].async_read_task_id);
661  }
662 
663  // If it is transmit interrupt...
664  if ((usart->CR1 & USART_CR1_TXEIE) != 0 && (usart->ISR & USART_ISR_TXE) != 0)
665  {
666  uint8_t character;
667 
668  // If there are still data in FIFO...
669  if (bc_fifo_irq_read(_bc_uart[channel].write_fifo, &character, 1) != 0)
670  {
671  // Load transmit data register
672  usart->TDR = character;
673  }
674  else
675  {
676  // Disable transmit interrupt
677  usart->CR1 &= ~USART_CR1_TXEIE;
678 
679  // Enable transmission complete interrupt
680  usart->CR1 |= USART_CR1_TCIE;
681  }
682  }
683 
684  // If it is transmit interrupt...
685  if ((usart->CR1 & USART_CR1_TCIE) != 0 && (usart->ISR & USART_ISR_TC) != 0)
686  {
687  // Disable transmission complete interrupt
688  usart->CR1 &= ~USART_CR1_TCIE;
689 
690  bc_scheduler_plan_now(_bc_uart[channel].async_write_task_id);
691  }
692 }
693 
694 void AES_RNG_LPUART1_IRQHandler(void)
695 {
696  _bc_uart_irq_handler(BC_UART_UART1);
697 }
698 
699 void USART1_IRQHandler(void)
700 {
701  _bc_uart_irq_handler(BC_UART_UART2);
702 }
703 
704 void USART2_IRQHandler(void)
705 {
706  _bc_uart_irq_handler(BC_UART_UART1);
707 }
708 
709 void USART4_5_IRQHandler(void)
710 {
711  _bc_uart_irq_handler(BC_UART_UART0);
712 }
UART channel UART2.
Definition: bc_uart.h:22
size_t bc_fifo_irq_read(bc_fifo_t *fifo, void *buffer, size_t length)
Read data from FIFO from interrupt.
Definition: bc_fifo.c:133
DMA channel configuration.
Definition: bc_dma.h:165
uint64_t bc_tick_t
Timestamp data type.
Definition: bc_tick.h:16
bc_uart_channel_t
UART channels.
Definition: bc_uart.h:13
Event is writting done.
Definition: bc_uart.h:130
UART baudrat 19200 bps.
Definition: bc_uart.h:34
void bc_irq_enable(void)
Enable interrupt requests globally (call can be nested)
Definition: bc_irq.c:21
Structure of FIFO instance.
Definition: bc_fifo.h:12
void bc_scheduler_plan_absolute(bc_scheduler_task_id_t task_id, bc_tick_t tick)
Schedule specified task to absolute tick.
Definition: bc_scheduler.c:124
bc_uart_setting_t
UART setting.
Definition: bc_uart.h:67
bool bc_uart_async_read_start(bc_uart_channel_t channel, bc_tick_t timeout)
Start async reading.
Definition: bc_uart.c:475
Event is reading done.
Definition: bc_uart.h:133
Event is timeout.
Definition: bc_uart.h:136
bc_scheduler_task_id_t bc_scheduler_register(void(*task)(void *), void *param, bc_tick_t tick)
Register task in scheduler.
Definition: bc_scheduler.c:56
UART channel UART0.
Definition: bc_uart.h:16
void bc_scheduler_plan_now(bc_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
Definition: bc_scheduler.c:119
DMA channel mode circular.
Definition: bc_dma.h:126
bc_dma_request_t request
DMA channel request.
Definition: bc_dma.h:168
void * buffer
Pointer to buffer where FIFO holds data.
Definition: bc_fifo.h:15
void bc_dma_init(void)
Initialize DMA.
Definition: bc_dma.c:56
DMA channel direction from peripheral to RAM.
Definition: bc_dma.h:99
DMA channel 3.
Definition: bc_dma.h:21
bc_tick_t bc_tick_get(void)
Get absolute timestamp since start of program.
Definition: bc_tick.c:7
void bc_uart_init(bc_uart_channel_t channel, bc_uart_baudrate_t baudrate, bc_uart_setting_t setting)
Initialize UART channel.
Definition: bc_uart.c:53
void bc_scheduler_plan_current_relative(bc_tick_t tick)
Schedule current task to tick relative from current spin.
Definition: bc_scheduler.c:149
void bc_dma_channel_run(bc_dma_channel_t channel)
Start DMA channel.
Definition: bc_dma.c:179
size_t bc_fifo_irq_write(bc_fifo_t *fifo, const void *buffer, size_t length)
Write data to FIFO from interrupt.
Definition: bc_fifo.c:101
bc_uart_event_t
Callback events.
Definition: bc_uart.h:127
size_t head
Position of FIFO's head.
Definition: bc_fifo.h:21
UART channel UART1.
Definition: bc_uart.h:19
size_t bc_uart_read(bc_uart_channel_t channel, void *buffer, size_t length, bc_tick_t timeout)
Read data from UART channel (blocking call)
Definition: bc_uart.c:372
size_t bc_scheduler_task_id_t
Task ID assigned by scheduler.
Definition: bc_scheduler.h:18
DMA channel priority is high.
Definition: bc_dma.h:156
void bc_uart_deinit(bc_uart_channel_t channel)
Deinitialize UART channel.
Definition: bc_uart.c:248
DMA channel data size 1B.
Definition: bc_dma.h:108
void bc_dma_channel_stop(bc_dma_channel_t channel)
Stop DMA channel.
Definition: bc_dma.c:184
void bc_dma_channel_config(bc_dma_channel_t channel, bc_dma_channel_config_t *config)
Configure DMA channel.
Definition: bc_dma.c:95
bool bc_uart_async_read_cancel(bc_uart_channel_t channel)
Cancel async reading.
Definition: bc_uart.c:531
size_t bc_uart_async_write(bc_uart_channel_t channel, const void *buffer, size_t length)
Add data to be transmited in async mode.
Definition: bc_uart.c:428
void bc_uart_set_async_fifo(bc_uart_channel_t channel, bc_fifo_t *write_fifo, bc_fifo_t *read_fifo)
Set buffers for async transfers.
Definition: bc_uart.c:422
void bc_uart_set_event_handler(bc_uart_channel_t channel, void(*event_handler)(bc_uart_channel_t, bc_uart_event_t, void *), void *event_param)
Set callback function.
Definition: bc_uart.c:416
#define BC_TICK_INFINITY
Maximum timestamp value.
Definition: bc_tick.h:12
size_t bc_fifo_write(bc_fifo_t *fifo, const void *buffer, size_t length)
Write data to FIFO.
Definition: bc_fifo.c:18
UART baudrat 9600 bps.
Definition: bc_uart.h:31
UART baudrat 38400 bps.
Definition: bc_uart.h:37
size_t bc_uart_write(bc_uart_channel_t channel, const void *buffer, size_t length)
Write data to UART channel (blocking call)
Definition: bc_uart.c:330
bc_uart_baudrate_t
UART baudrate.
Definition: bc_uart.h:28
size_t bc_fifo_read(bc_fifo_t *fifo, void *buffer, size_t length)
Read data from FIFO.
Definition: bc_fifo.c:63
size_t bc_uart_async_read(bc_uart_channel_t channel, void *buffer, size_t length)
Get data that has been received in async mode.
Definition: bc_uart.c:571
void bc_irq_disable(void)
Disable interrupt requests globally (call can be nested)
Definition: bc_irq.c:7
UART baudrat 57600 bps.
Definition: bc_uart.h:40
bool bc_fifo_is_empty(bc_fifo_t *fifo)
Is empty.
Definition: bc_fifo.c:161
size_t size
Size of buffer where FIFO holds data.
Definition: bc_fifo.h:18
UART baudrat 921600 bps.
Definition: bc_uart.h:46
UART baudrat 115200 bps.
Definition: bc_uart.h:43
void bc_scheduler_plan_current_now(void)
Schedule current task for immediate execution.
Definition: bc_scheduler.c:139
void bc_scheduler_unregister(bc_scheduler_task_id_t task_id)
Unregister specified task.
Definition: bc_scheduler.c:80
DMA request 3.
Definition: bc_dma.h:51