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