Firmware SDK
twr_uart.c
1 #include <twr_uart.h>
2 #include <twr_scheduler.h>
3 #include <twr_irq.h>
4 #include <twr_system.h>
5 #include <stm32l0xx.h>
6 #include <twr_dma.h>
7 #include <twr_gpio.h>
8 
9 typedef struct
10 {
11  bool initialized;
12  void (*event_handler)(twr_uart_channel_t, twr_uart_event_t, void *);
13  void *event_param;
14  twr_fifo_t *write_fifo;
15  twr_fifo_t *read_fifo;
16  twr_scheduler_task_id_t async_write_task_id;
17  twr_scheduler_task_id_t async_read_task_id;
18  bool async_write_in_progress;
19  bool async_read_in_progress;
20  twr_tick_t async_timeout;
21  USART_TypeDef *usart;
22 
23 } twr_uart_t;
24 
25 static twr_uart_t _twr_uart[3] =
26 {
27  [TWR_UART_UART0] = { .initialized = false },
28  [TWR_UART_UART1] = { .initialized = false },
29  [TWR_UART_UART2] = { .initialized = false }
30 };
31 
32 static struct
33 {
34  twr_scheduler_task_id_t read_task_id;
35  size_t length;
36 
37 } _twr_uart_2_dma;
38 
39 static uint32_t _twr_uart_brr_t[] =
40 {
41  [TWR_UART_BAUDRATE_9600] = 0xd05,
42  [TWR_UART_BAUDRATE_19200] = 0x682,
43  [TWR_UART_BAUDRATE_38400] = 0x341,
44  [TWR_UART_BAUDRATE_57600] = 0x22b,
45  [TWR_UART_BAUDRATE_115200] = 0x116,
47 };
48 
49 static void _twr_uart_async_write_task(void *param);
50 static void _twr_uart_async_read_task(void *param);
51 static void _twr_uart_2_dma_read_task(void *param);
52 static void _twr_uart_irq_handler(twr_uart_channel_t channel);
53 
55 {
56  memset(&_twr_uart[channel], 0, sizeof(_twr_uart[channel]));
57 
58  switch(channel)
59  {
60  case TWR_UART_UART0:
61  {
62  twr_gpio_init(TWR_GPIO_P0); // TXD0
63  twr_gpio_init(TWR_GPIO_P1); // RXD0
64 
65  // Enable pull-up on RXD0 pin
67 
68  // Select AF6 alternate function for TXD0 and RXD0 pins
71 
72  // Enable clock for USART4
73  RCC->APB1ENR |= RCC_APB1ENR_USART4EN;
74 
75  // Errata workaround
76  RCC->APB1ENR;
77 
78  // Enable transmitter and receiver, peripheral enabled in stop mode
79  USART4->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM;
80 
81  // Clock enabled in stop mode, disable overrun detection, one bit sampling method
82  USART4->CR3 = USART_CR3_UCESM | USART_CR3_OVRDIS | USART_CR3_ONEBIT;
83 
84  // Configure baudrate
85  USART4->BRR = _twr_uart_brr_t[baudrate];
86 
87  NVIC_EnableIRQ(USART4_5_IRQn);
88 
89  _twr_uart[channel].usart = USART4;
90 
91  break;
92  }
93  case TWR_UART_UART1:
94  {
95 
96  twr_gpio_init(TWR_GPIO_P2); // TXD1
97  twr_gpio_init(TWR_GPIO_P3); // RXD1
98 
99  // Enable pull-up on RXD1 pin
101 
102  if (baudrate <= TWR_UART_BAUDRATE_9600)
103  {
104  // Select AF6 alternate function for TXD1 and RXD1 pins
107 
108  // Set LSE as LPUART1 clock source
109  RCC->CCIPR |= RCC_CCIPR_LPUART1SEL_1 | RCC_CCIPR_LPUART1SEL_0;
110 
111  // Enable clock for LPUART1
112  RCC->APB1ENR |= RCC_APB1ENR_LPUART1EN;
113 
114  // Errata workaround
115  RCC->APB1ENR;
116 
117  // Enable transmitter and receiver, peripheral enabled in stop mode
118  LPUART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM;
119 
120  // Clock enabled in stop mode, disable overrun detection, one bit sampling method
121  LPUART1->CR3 = USART_CR3_UCESM | USART_CR3_OVRDIS | USART_CR3_ONEBIT;
122 
123  // Configure baudrate
124  LPUART1->BRR = 0x369;
125 
126  NVIC_EnableIRQ(LPUART1_IRQn);
127 
128  _twr_uart[channel].usart = LPUART1;
129  }
130  else
131  {
132  // Select AF4 alternate function for TXD1 and RXD1 pins
135 
136  // Enable clock for USART2
137  RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
138 
139  // Errata workaround
140  RCC->APB1ENR;
141 
142  // Enable transmitter and receiver, peripheral enabled in stop mode
143  USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM;
144 
145  // Clock enabled in stop mode, disable overrun detection, one bit sampling method
146  USART2->CR3 = USART_CR3_UCESM | USART_CR3_OVRDIS | USART_CR3_ONEBIT;
147 
148  // Configure baudrate
149  USART2->BRR = _twr_uart_brr_t[baudrate];
150 
151  NVIC_EnableIRQ(USART2_IRQn);
152 
153  _twr_uart[channel].usart = USART2;
154  }
155 
156  break;
157  }
158  case TWR_UART_UART2:
159  {
160  twr_gpio_init(TWR_GPIO_P11); // TXD2
161  twr_gpio_init(TWR_GPIO_P10); // RXD2
162 
163  // Enable pull-up on RXD2 pin
165 
166  // Select AF6 alternate function for TXD0 and RXD0 pins
169 
170  // Enable clock for USART1
171  RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
172 
173  // Errata workaround
174  RCC->APB2ENR;
175 
176  // Enable transmitter and receiver, peripheral enabled in stop mode
177  USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM;
178 
179  // Clock enabled in stop mode, disable overrun detection, one bit sampling method
180  USART1->CR3 = USART_CR3_UCESM | USART_CR3_OVRDIS | USART_CR3_ONEBIT;
181 
182  // Configure baudrate
183  USART1->BRR = _twr_uart_brr_t[baudrate];
184 
185  NVIC_EnableIRQ(USART1_IRQn);
186 
187  _twr_uart[channel].usart = USART1;
188 
189  break;
190  }
191  default:
192  {
193  return;
194  }
195  }
196 
197  // Clear ISR bits
198  _twr_uart[channel].usart->ICR |= USART_ICR_CMCF | USART_ICR_IDLECF | USART_ICR_FECF;
199 
200  // Stop bits
201  _twr_uart[channel].usart->CR2 &= ~USART_CR2_STOP_Msk;
202  _twr_uart[channel].usart->CR2 |= ((uint32_t) setting & 0x03) << USART_CR2_STOP_Pos;
203 
204  // Parity
205  _twr_uart[channel].usart->CR1 &= ~(USART_CR1_PCE_Msk | USART_CR1_PS_Msk);
206  _twr_uart[channel].usart->CR1 |= (((uint32_t) setting >> 2) & 0x03) << USART_CR1_PS_Pos;
207 
208  // Word length
209  _twr_uart[channel].usart->CR1 &= ~(USART_CR1_M1_Msk | USART_CR1_M0_Msk);
210 
211  uint32_t word_length = setting >> 4;
212 
213  if ((setting & 0x0c) != 0)
214  {
215  word_length++;
216  }
217 
218  if (word_length == 0x07)
219  {
220  word_length = 0x10;
221 
222  _twr_uart[channel].usart->CR1 |= 1 << USART_CR1_M1_Pos;
223  }
224  else if (word_length == 0x09)
225  {
226  _twr_uart[channel].usart->CR1 |= 1 << USART_CR1_M0_Pos;
227  }
228 
229  // Enable UART
230  _twr_uart[channel].usart->CR1 |= USART_CR1_UE;
231 
232  _twr_uart[channel].initialized = true;
233 }
234 
235 
237 {
239 
240  // Disable UART
241  _twr_uart[channel].usart->CR1 &= ~USART_CR1_UE_Msk;
242 
243  if (_twr_uart[channel].async_write_task_id != 0) {
244  twr_scheduler_unregister(_twr_uart[channel].async_write_task_id);
245  }
246 
247  switch(channel)
248  {
249  case TWR_UART_UART0:
250  {
251  NVIC_DisableIRQ(USART4_5_IRQn);
252 
253  // Disable clock for USART4
254  RCC->APB1ENR &= ~RCC_APB1ENR_USART4EN;
255 
256  // Disable pull-up on RXD0 pin
258 
259  // Configure TXD0 and RXD0 pins as Analog
262  break;
263  }
264  case TWR_UART_UART1:
265  {
266  if (_twr_uart[channel].usart == LPUART1)
267  {
268  NVIC_DisableIRQ(LPUART1_IRQn);
269 
270  // Disable clock for LPUART1
271  RCC->APB1ENR &= ~RCC_APB1ENR_LPUART1EN;
272  }
273  else
274  {
275  NVIC_DisableIRQ(USART2_IRQn);
276 
277  // Disable clock for USART2
278  RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
279  }
280 
281  // Disable pull-up on RXD1 pin
283 
284  // Configure TXD1 and RXD1 pins as Analog
287  break;
288  }
289  case TWR_UART_UART2:
290  {
291  NVIC_DisableIRQ(USART1_IRQn);
292 
293  // Disable clock for USART1
294  RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN_Msk;
295 
296  // Disable pull-up on RXD2 pin
298 
299  // Configure TXD2 and RXD2 pins as Analog
302  break;
303  }
304  default:
305  {
306  return;
307  }
308  }
309 
310  _twr_uart[channel].initialized = false;
311 }
312 
313 size_t twr_uart_write(twr_uart_channel_t channel, const void *buffer, size_t length)
314 {
315  if (!_twr_uart[channel].initialized || _twr_uart[channel].async_write_in_progress)
316  {
317  return 0;
318  }
319 
320  USART_TypeDef *usart = _twr_uart[channel].usart;
321 
322  size_t bytes_written = 0;
323 
324  if (_twr_uart[channel].usart != LPUART1)
325  {
326  twr_system_pll_enable();
327  }
328 
329  while (bytes_written != length)
330  {
331  // Until transmit data register is not empty...
332  while ((usart->ISR & USART_ISR_TXE) == 0)
333  {
334  continue;
335  }
336 
337  // Load transmit data register
338  usart->TDR = *((uint8_t *) buffer + bytes_written++);
339  }
340 
341  // Until transmission is not complete...
342  while ((usart->ISR & USART_ISR_TC) == 0)
343  {
344  continue;
345  }
346 
347  if (_twr_uart[channel].usart != LPUART1)
348  {
349  twr_system_pll_disable();
350  }
351 
352  return bytes_written;
353 }
354 
355 size_t twr_uart_read(twr_uart_channel_t channel, void *buffer, size_t length, twr_tick_t timeout)
356 {
357  if (!_twr_uart[channel].initialized)
358  {
359  return 0;
360  }
361 
362  USART_TypeDef *usart = _twr_uart[channel].usart;
363 
364  size_t bytes_read = 0;
365 
366  if (_twr_uart[channel].usart != LPUART1)
367  {
368  twr_system_pll_enable();
369  }
370 
371  twr_tick_t tick_timeout = timeout == TWR_TICK_INFINITY ? TWR_TICK_INFINITY : twr_tick_get() + timeout;
372 
373  while (bytes_read != length)
374  {
375  // If timeout condition is met...
376  if (twr_tick_get() >= tick_timeout)
377  {
378  break;
379  }
380 
381  // If receive data register is empty...
382  if ((usart->ISR & USART_ISR_RXNE) == 0)
383  {
384  continue;
385  }
386 
387  // Read receive data register
388  *((uint8_t *) buffer + bytes_read++) = usart->RDR;
389  }
390 
391  if (_twr_uart[channel].usart != LPUART1)
392  {
393  twr_system_pll_disable();
394  }
395 
396  return bytes_read;
397 }
398 
399 void twr_uart_set_event_handler(twr_uart_channel_t channel, void (*event_handler)(twr_uart_channel_t, twr_uart_event_t, void *), void *event_param)
400 {
401  _twr_uart[channel].event_handler = event_handler;
402  _twr_uart[channel].event_param = event_param;
403 }
404 
405 void twr_uart_set_async_fifo(twr_uart_channel_t channel, twr_fifo_t *write_fifo, twr_fifo_t *read_fifo)
406 {
407  _twr_uart[channel].write_fifo = write_fifo;
408  _twr_uart[channel].read_fifo = read_fifo;
409 }
410 
411 size_t twr_uart_async_write(twr_uart_channel_t channel, const void *buffer, size_t length)
412 {
413  if (!_twr_uart[channel].initialized || _twr_uart[channel].write_fifo == NULL)
414  {
415  return 0;
416  }
417 
418  size_t bytes_written = 0;
419 
420  for (size_t i = 0; i < length; i += 16)
421  {
422  bytes_written += twr_fifo_write(_twr_uart[channel].write_fifo, (uint8_t *)buffer + i, length - i > 16 ? 16 : length - i);
423  }
424 
425  if (bytes_written != 0)
426  {
427  if (!_twr_uart[channel].async_write_in_progress)
428  {
429  _twr_uart[channel].async_write_task_id = twr_scheduler_register(_twr_uart_async_write_task, (void *) channel, TWR_TICK_INFINITY);
430 
431  if (_twr_uart[channel].usart == LPUART1)
432  {
433  twr_system_deep_sleep_disable();
434  }
435  else
436  {
437  twr_system_pll_enable();
438  }
439  }
440  else
441  {
442  twr_scheduler_plan_absolute(_twr_uart[channel].async_write_task_id, TWR_TICK_INFINITY);
443  }
444 
445  twr_irq_disable();
446 
447  // Enable transmit interrupt
448  _twr_uart[channel].usart->CR1 |= USART_CR1_TXEIE;
449 
450  twr_irq_enable();
451 
452  _twr_uart[channel].async_write_in_progress = true;
453  }
454 
455  return bytes_written;
456 }
457 
459 {
460  if (!_twr_uart[channel].initialized || _twr_uart[channel].read_fifo == NULL || _twr_uart[channel].async_read_in_progress)
461  {
462  return false;
463  }
464 
465  _twr_uart[channel].async_timeout = timeout;
466 
467  _twr_uart[channel].async_read_task_id = twr_scheduler_register(_twr_uart_async_read_task, (void *) channel, _twr_uart[channel].async_timeout);
468 
469  if (channel == TWR_UART_UART2)
470  {
471  twr_dma_channel_config_t config = {
473  .direction = TWR_DMA_DIRECTION_TO_RAM,
474  .data_size_memory = TWR_DMA_SIZE_1,
475  .data_size_peripheral = TWR_DMA_SIZE_1,
476  .length = _twr_uart[channel].read_fifo->size,
477  .mode = TWR_DMA_MODE_CIRCULAR,
478  .address_memory = _twr_uart[channel].read_fifo->buffer,
479  .address_peripheral = (void *) &_twr_uart[channel].usart->RDR,
480  .priority = TWR_DMA_PRIORITY_HIGH
481  };
482 
483  twr_dma_init();
484 
486 
487  _twr_uart_2_dma.read_task_id = twr_scheduler_register(_twr_uart_2_dma_read_task, (void *) channel, 0);
488 
489  twr_irq_disable();
490  // Enable receive DMA interrupt
491  _twr_uart[channel].usart->CR3 |= USART_CR3_DMAR;
492  twr_irq_enable();
493 
495  }
496  else
497  {
498  twr_irq_disable();
499  // Enable receive interrupt
500  _twr_uart[channel].usart->CR1 |= USART_CR1_RXNEIE;
501  twr_irq_enable();
502  }
503 
504  if (_twr_uart[channel].usart != LPUART1)
505  {
506  twr_system_pll_enable();
507  }
508 
509  _twr_uart[channel].async_read_in_progress = true;
510 
511  return true;
512 }
513 
515 {
516  if (!_twr_uart[channel].initialized || !_twr_uart[channel].async_read_in_progress)
517  {
518  return false;
519  }
520 
521  _twr_uart[channel].async_read_in_progress = false;
522 
523  if (channel == TWR_UART_UART2)
524  {
526 
527  twr_scheduler_unregister(_twr_uart_2_dma.read_task_id);
528 
529  twr_irq_disable();
530  // Disable receive DMA interrupt
531  _twr_uart[channel].usart->CR3 &= ~USART_CR3_DMAR_Msk;
532  twr_irq_enable();
533  }
534  else
535  {
536  twr_irq_disable();
537 
538  // Disable receive interrupt
539  _twr_uart[channel].usart->CR1 &= ~USART_CR1_RXNEIE_Msk;
540 
541  twr_irq_enable();
542  }
543 
544  if (_twr_uart[channel].usart != LPUART1)
545  {
546  twr_system_pll_disable();
547  }
548 
549  twr_scheduler_unregister(_twr_uart[channel].async_read_task_id);
550 
551  return false;
552 }
553 
554 size_t twr_uart_async_read(twr_uart_channel_t channel, void *buffer, size_t length)
555 {
556  if (!_twr_uart[channel].initialized || !_twr_uart[channel].async_read_in_progress)
557  {
558  return 0;
559  }
560 
561  size_t bytes_read = twr_fifo_read(_twr_uart[channel].read_fifo, buffer, length);
562 
563  return bytes_read;
564 }
565 
566 static void _twr_uart_async_write_task(void *param)
567 {
568  twr_uart_channel_t channel = (twr_uart_channel_t) param;
569  twr_uart_t *uart = &_twr_uart[channel];
570 
571  uart->async_write_in_progress = false;
572 
573  twr_scheduler_unregister(uart->async_write_task_id);
574 
575  if (uart->usart == LPUART1)
576  {
577  twr_system_deep_sleep_enable();
578  }
579  else
580  {
581  twr_system_pll_disable();
582  }
583 
584  if (uart->event_handler != NULL)
585  {
586  uart->event_handler(channel, TWR_UART_EVENT_ASYNC_WRITE_DONE, uart->event_param);
587  }
588 }
589 
590 static void _twr_uart_async_read_task(void *param)
591 {
592  twr_uart_channel_t channel = (twr_uart_channel_t) param;
593  twr_uart_t *uart = &_twr_uart[channel];
594 
595  twr_scheduler_plan_current_relative(uart->async_timeout);
596 
597  if (uart->event_handler != NULL)
598  {
599  if (twr_fifo_is_empty(uart->read_fifo))
600  {
601  uart->event_handler(channel, TWR_UART_EVENT_ASYNC_READ_TIMEOUT, uart->event_param);
602  }
603  else
604  {
605  uart->event_handler(channel, TWR_UART_EVENT_ASYNC_READ_DATA, uart->event_param);
606  }
607  }
608 }
609 
610 static void _twr_uart_2_dma_read_task(void *param)
611 {
612  (void) param;
613 
614  size_t length = twr_dma_channel_get_length(TWR_DMA_CHANNEL_3);
615 
616  twr_uart_t *uart = &_twr_uart[TWR_UART_UART2];
617 
618  if (_twr_uart_2_dma.length != length)
619  {
620  uart->read_fifo->head = uart->read_fifo->size - length;
621 
622  _twr_uart_2_dma.length = length;
623 
624  twr_scheduler_plan_now(uart->async_read_task_id);
625  }
626 
628 }
629 
630 static void _twr_uart_irq_handler(twr_uart_channel_t channel)
631 {
632  USART_TypeDef *usart = _twr_uart[channel].usart;
633 
634  if ((usart->CR1 & USART_CR1_RXNEIE) != 0 && (usart->ISR & USART_ISR_RXNE) != 0)
635  {
636  uint8_t character;
637 
638  // Read receive data register
639  character = usart->RDR;
640 
641  twr_fifo_irq_write(_twr_uart[channel].read_fifo, &character, 1);
642 
643  twr_scheduler_plan_now(_twr_uart[channel].async_read_task_id);
644  }
645 
646  // If it is transmit interrupt...
647  if ((usart->CR1 & USART_CR1_TXEIE) != 0 && (usart->ISR & USART_ISR_TXE) != 0)
648  {
649  uint8_t character;
650 
651  // If there are still data in FIFO...
652  if (twr_fifo_irq_read(_twr_uart[channel].write_fifo, &character, 1) != 0)
653  {
654  // Load transmit data register
655  usart->TDR = character;
656  }
657  else
658  {
659  // Disable transmit interrupt
660  usart->CR1 &= ~USART_CR1_TXEIE;
661 
662  // Enable transmission complete interrupt
663  usart->CR1 |= USART_CR1_TCIE;
664  }
665  }
666 
667  // If it is transmit interrupt...
668  if ((usart->CR1 & USART_CR1_TCIE) != 0 && (usart->ISR & USART_ISR_TC) != 0)
669  {
670  // Disable transmission complete interrupt
671  usart->CR1 &= ~USART_CR1_TCIE;
672 
673  twr_scheduler_plan_now(_twr_uart[channel].async_write_task_id);
674  }
675 }
676 
677 void AES_RNG_LPUART1_IRQHandler(void)
678 {
679  _twr_uart_irq_handler(TWR_UART_UART1);
680 }
681 
682 void USART1_IRQHandler(void)
683 {
684  _twr_uart_irq_handler(TWR_UART_UART2);
685 }
686 
687 void USART2_IRQHandler(void)
688 {
689  _twr_uart_irq_handler(TWR_UART_UART1);
690 }
691 
692 void USART4_5_IRQHandler(void)
693 {
694  _twr_uart_irq_handler(TWR_UART_UART0);
695 }
twr_dma_request_t request
DMA channel request.
Definition: twr_dma.h:168
void twr_gpio_set_mode(twr_gpio_channel_t channel, twr_gpio_mode_t mode)
Set mode of operation for GPIO channel.
Definition: twr_gpio.c:367
GPIO channel operates in alternate mode AF6.
Definition: twr_gpio.h:138
size_t twr_fifo_write(twr_fifo_t *fifo, const void *buffer, size_t length)
Write data to FIFO.
Definition: twr_fifo.c:18
Event is writting done.
Definition: twr_uart.h:130
GPIO channel P0, A0, TXD0.
Definition: twr_gpio.h:15
void twr_scheduler_plan_current_relative(twr_tick_t tick)
Schedule current task to tick relative from current spin.
DMA channel data size 1B.
Definition: twr_dma.h:108
size_t twr_fifo_irq_write(twr_fifo_t *fifo, const void *buffer, size_t length)
Write data to FIFO from interrupt.
Definition: twr_fifo.c:101
void twr_irq_enable(void)
Enable interrupt requests globally (call can be nested)
Definition: twr_irq.c:21
DMA channel 3.
Definition: twr_dma.h:21
bool twr_uart_async_read_start(twr_uart_channel_t channel, twr_tick_t timeout)
Start async reading.
Definition: twr_uart.c:458
GPIO channel P3, A3, RXD1.
Definition: twr_gpio.h:24
twr_scheduler_task_id_t twr_scheduler_register(void(*task)(void *), void *param, twr_tick_t tick)
Register task in scheduler.
Definition: twr_scheduler.c:53
UART baudrat 19200 bps.
Definition: twr_uart.h:34
UART baudrat 9600 bps.
Definition: twr_uart.h:31
bool twr_uart_async_read_cancel(twr_uart_channel_t channel)
Cancel async reading.
Definition: twr_uart.c:514
void twr_gpio_set_pull(twr_gpio_channel_t channel, twr_gpio_pull_t pull)
Set pull-up/pull-down configuration for GPIO channel.
Definition: twr_gpio.c:340
Event is reading done.
Definition: twr_uart.h:133
UART channel UART2.
Definition: twr_uart.h:22
GPIO channel operates in analog mode.
Definition: twr_gpio.h:114
void twr_dma_channel_config(twr_dma_channel_t channel, twr_dma_channel_config_t *config)
Configure DMA channel.
Definition: twr_dma.c:95
void twr_uart_init(twr_uart_channel_t channel, twr_uart_baudrate_t baudrate, twr_uart_setting_t setting)
Initialize UART channel.
Definition: twr_uart.c:54
UART channel UART0.
Definition: twr_uart.h:16
GPIO channel has no pull-up/pull-down.
Definition: twr_gpio.h:90
size_t size
Size of buffer where FIFO holds data.
Definition: twr_fifo.h:18
void * buffer
Pointer to buffer where FIFO holds data.
Definition: twr_fifo.h:15
DMA request 3.
Definition: twr_dma.h:51
bool twr_fifo_is_empty(twr_fifo_t *fifo)
Is empty.
Definition: twr_fifo.c:161
void twr_dma_channel_run(twr_dma_channel_t channel)
Start DMA channel.
Definition: twr_dma.c:179
GPIO channel has pull-up.
Definition: twr_gpio.h:93
DMA channel configuration.
Definition: twr_dma.h:165
UART baudrat 57600 bps.
Definition: twr_uart.h:40
size_t twr_uart_async_read(twr_uart_channel_t channel, void *buffer, size_t length)
Get data that has been received in async mode.
Definition: twr_uart.c:554
size_t head
Position of FIFO&#39;s head.
Definition: twr_fifo.h:21
void twr_gpio_init(twr_gpio_channel_t channel)
Initialize GPIO channel.
Definition: twr_gpio.c:325
DMA channel direction from peripheral to RAM.
Definition: twr_dma.h:99
UART baudrat 921600 bps.
Definition: twr_uart.h:46
GPIO channel operates in alternate mode AF4.
Definition: twr_gpio.h:132
void twr_scheduler_plan_current_now(void)
Schedule current task for immediate execution.
GPIO channel P10, RXD2.
Definition: twr_gpio.h:45
size_t twr_scheduler_task_id_t
Task ID assigned by scheduler.
Definition: twr_scheduler.h:22
uint64_t twr_tick_t
Timestamp data type.
Definition: twr_tick.h:16
GPIO channel P2, A2, TXD1.
Definition: twr_gpio.h:21
twr_uart_setting_t
UART setting.
Definition: twr_uart.h:67
size_t twr_uart_read(twr_uart_channel_t channel, void *buffer, size_t length, twr_tick_t timeout)
Read data from UART channel (blocking call)
Definition: twr_uart.c:355
twr_uart_baudrate_t
UART baudrate.
Definition: twr_uart.h:28
void twr_uart_set_event_handler(twr_uart_channel_t channel, void(*event_handler)(twr_uart_channel_t, twr_uart_event_t, void *), void *event_param)
Set callback function.
Definition: twr_uart.c:399
twr_tick_t twr_tick_get(void)
Get absolute timestamp since start of program.
Definition: twr_tick.c:7
size_t twr_fifo_irq_read(twr_fifo_t *fifo, void *buffer, size_t length)
Read data from FIFO from interrupt.
Definition: twr_fifo.c:133
GPIO channel P1, A1, RXD0.
Definition: twr_gpio.h:18
void twr_scheduler_unregister(twr_scheduler_task_id_t task_id)
Unregister specified task.
Definition: twr_scheduler.c:77
DMA channel priority is high.
Definition: twr_dma.h:156
UART baudrat 115200 bps.
Definition: twr_uart.h:43
twr_uart_event_t
Callback events.
Definition: twr_uart.h:127
void twr_dma_channel_stop(twr_dma_channel_t channel)
Stop DMA channel.
Definition: twr_dma.c:184
UART channel UART1.
Definition: twr_uart.h:19
size_t twr_fifo_read(twr_fifo_t *fifo, void *buffer, size_t length)
Read data from FIFO.
Definition: twr_fifo.c:63
DMA channel mode circular.
Definition: twr_dma.h:126
void twr_irq_disable(void)
Disable interrupt requests globally (call can be nested)
Definition: twr_irq.c:7
Structure of FIFO instance.
Definition: twr_fifo.h:12
void twr_uart_deinit(twr_uart_channel_t channel)
Deinitialize UART channel.
Definition: twr_uart.c:236
twr_uart_channel_t
UART channels.
Definition: twr_uart.h:13
size_t twr_uart_write(twr_uart_channel_t channel, const void *buffer, size_t length)
Write data to UART channel (blocking call)
Definition: twr_uart.c:313
void twr_dma_init(void)
Initialize DMA.
Definition: twr_dma.c:56
#define TWR_TICK_INFINITY
Maximum timestamp value.
Definition: twr_tick.h:12
void twr_uart_set_async_fifo(twr_uart_channel_t channel, twr_fifo_t *write_fifo, twr_fifo_t *read_fifo)
Set buffers for async transfers.
Definition: twr_uart.c:405
void twr_scheduler_plan_absolute(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to absolute tick.
void twr_scheduler_plan_now(twr_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
UART baudrat 38400 bps.
Definition: twr_uart.h:37
size_t twr_uart_async_write(twr_uart_channel_t channel, const void *buffer, size_t length)
Add data to be transmited in async mode.
Definition: twr_uart.c:411
GPIO channel P11, TXD2.
Definition: twr_gpio.h:48