EFM32 Pearl Gecko Software Documentation  efm32pg1-doc-4.2.1
uartdrv.c
Go to the documentation of this file.
1 /***************************************************************************/
16 #include <string.h>
17 
18 #include "em_device.h"
19 #include "em_emu.h"
20 #include "em_gpio.h"
21 #include "em_int.h"
22 #include "em_usart.h"
23 #include "uartdrv.h"
24 #if defined(EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
25 #include "gpiointerrupt.h"
26 #endif
27 
29 
30 #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
31 static bool uartdrvHandleIsInitialized = false;
32 static UARTDRV_Handle_t uartdrvHandle[EMDRV_UARTDRV_MAX_DRIVER_INSTANCES];
33 #endif
34 
35 static bool ReceiveDmaComplete( unsigned int channel,
36  unsigned int sequenceNo,
37  void *userParam );
38 static bool TransmitDmaComplete( unsigned int channel,
39  unsigned int sequenceNo,
40  void *userParam );
41 
42 /***************************************************************************/
45 #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
46 static UARTDRV_Handle_t HwFcCtsIrqGetDrvHandle(uint32_t gpioPinNo)
47 {
48  uint32_t i;
49 
50  for(i = 0; i < EMDRV_UARTDRV_MAX_DRIVER_INSTANCES; i++)
51  {
52  if (uartdrvHandle[i]->initData.ctsPin == gpioPinNo)
53  {
54  return uartdrvHandle[i];
55  }
56  }
57  return NULL;
58 }
59 
60 
61 /***************************************************************************/
64 static UARTDRV_FlowControlState_t HwFcGetClearToSendPin(UARTDRV_Handle_t handle)
65 {
66  return (UARTDRV_FlowControlState_t)GPIO_PinInGet(handle->initData.ctsPort, handle->initData.ctsPin);
67 }
68 
69 
70 /***************************************************************************/
73 static void HwFcManageClearToSend(uint8_t gpioPinNo)
74 {
75  UARTDRV_Handle_t handle = HwFcCtsIrqGetDrvHandle(gpioPinNo);
76 
77  if (handle->initData.fcType == uartdrvFlowControlHw)
78  {
79  // If not auto mode, just assign the CTS pin state to the self state
80  // If auto mode, also control UART TX enable
81  handle->fcSelfState = HwFcGetClearToSendPin(handle);
82  if (handle->fcSelfCfg == uartdrvFlowControlAuto)
83  {
84  if ((HwFcGetClearToSendPin(handle) == uartdrvFlowControlOn) || handle->IgnoreRestrain)
85  {
86  handle->IgnoreRestrain = false;
87  handle->initData.port->CMD = USART_CMD_TXEN;
88  }
89  else
90  {
91  handle->initData.port->CMD = USART_CMD_TXDIS;
92  }
93  }
94  }
95 }
96 
97 
98 static Ecode_t FcApplyState(UARTDRV_Handle_t handle)
99 {
100  uint8_t FcSwCode;
101 
102  if (handle->initData.fcType == uartdrvFlowControlHw)
103  {
104  if (handle->fcSelfCfg == uartdrvFlowControlOn)
105  {
106  // Assert nRTS (application control)
107  GPIO_PinOutClear(handle->initData.rtsPort, handle->initData.rtsPin);
108  }
109  else if (handle->fcSelfCfg == uartdrvFlowControlOff)
110  {
111  // Deassert nRTS (application control)
112  GPIO_PinOutSet(handle->initData.rtsPort, handle->initData.rtsPin);
113  }
114  else // Auto mode
115  {
116  if (handle->fcSelfState == uartdrvFlowControlOn)
117  {
118  // Assert nRTS
119  GPIO_PinOutClear(handle->initData.rtsPort, handle->initData.rtsPin);
120  }
121  else // Off
122  {
123  // Deassert nRTS
124  GPIO_PinOutSet(handle->initData.rtsPort, handle->initData.rtsPin);
125  }
126  }
127  }
128  else if (handle->initData.fcType == uartdrvFlowControlSw)
129  {
130  if (handle->fcSelfState == uartdrvFlowControlOn)
131  {
132  FcSwCode = UARTDRV_FC_SW_XON;
133  UARTDRV_ForceTransmit(handle, &FcSwCode, 1);
134  }
135  else
136  {
137  FcSwCode = UARTDRV_FC_SW_XOFF;
138  UARTDRV_ForceTransmit(handle, &FcSwCode, 1);
139  }
140  }
141  return ECODE_EMDRV_UARTDRV_OK;
142 }
143 #endif /* EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE */
144 
145 
146 /***************************************************************************/
149 static Ecode_t EnqueueBuffer(UARTDRV_Buffer_FifoQueue_t *queue,
150  UARTDRV_Buffer_t *inputBuffer,
151  UARTDRV_Buffer_t **queueBuffer)
152 {
153  INT_Disable();
154  if (queue->used >= queue->size)
155  {
156  *queueBuffer = NULL;
157  INT_Enable();
159  }
160  memcpy((void *)&queue->fifo[queue->head], (const void *)inputBuffer, sizeof(UARTDRV_Buffer_t));
161  *queueBuffer = &queue->fifo[queue->head];
162  queue->head = (queue->head + 1) % queue->size;
163  queue->used++;
164  INT_Enable();
165 
166  return ECODE_EMDRV_UARTDRV_OK;
167 }
168 
169 
170 /***************************************************************************/
173 static Ecode_t DequeueBuffer(UARTDRV_Buffer_FifoQueue_t *queue,
174  UARTDRV_Buffer_t **buffer)
175 {
176  INT_Disable();
177  if (queue->used == 0)
178  {
179  *buffer = NULL;
180  INT_Enable();
182  }
183  *buffer = &queue->fifo[queue->tail];
184  queue->tail = (queue->tail + 1) % queue->size;
185  queue->used--;
186  INT_Enable();
187 
188  return ECODE_EMDRV_UARTDRV_OK;
189 }
190 
191 
192 /***************************************************************************/
195 static Ecode_t GetTailBuffer(UARTDRV_Buffer_FifoQueue_t *queue,
196  UARTDRV_Buffer_t **buffer)
197 {
198  INT_Disable();
199  if (queue->used == 0)
200  {
201  *buffer = NULL;
202  INT_Enable();
204  }
205  *buffer = &queue->fifo[queue->tail];
206 
207  INT_Enable();
208  return ECODE_EMDRV_UARTDRV_OK;
209 }
210 
211 
212 /***************************************************************************/
215 static void EnableTransmitter(UARTDRV_Handle_t handle)
216 {
217  handle->initData.port->CMD = USART_CMD_TXEN;
218  while (!(handle->initData.port->STATUS & USART_STATUS_TXENS));
219  #if defined( USART_ROUTEPEN_TXPEN )
220  handle->initData.port->ROUTEPEN |= USART_ROUTEPEN_TXPEN;
221  #else
222  handle->initData.port->ROUTE |= USART_ROUTE_TXPEN;
223  #endif
224 }
225 
226 
227 /***************************************************************************/
230 static void DisableTransmitter(UARTDRV_Handle_t handle)
231 {
232  #if defined( USART_ROUTEPEN_TXPEN )
233  handle->initData.port->ROUTEPEN &= ~USART_ROUTEPEN_TXPEN;
234  #else
235  handle->initData.port->ROUTE &= ~USART_ROUTE_TXPEN;
236  #endif
237  handle->initData.port->CMD = USART_CMD_TXDIS;
238 }
239 
240 
241 /***************************************************************************/
244 static void EnableReceiver(UARTDRV_Handle_t handle)
245 {
246  handle->initData.port->CMD = USART_CMD_RXEN;
247  while (!(handle->initData.port->STATUS & USART_STATUS_RXENS));
248  #if defined( USART_ROUTEPEN_RXPEN )
249  handle->initData.port->ROUTEPEN |= USART_ROUTEPEN_RXPEN;
250  #else
251  handle->initData.port->ROUTE |= USART_ROUTE_RXPEN;
252  #endif
253 }
254 
255 
256 /***************************************************************************/
259 static void DisableReceiver(UARTDRV_Handle_t handle)
260 {
261  #if defined( USART_ROUTEPEN_RXPEN )
262  handle->initData.port->ROUTEPEN &= ~USART_ROUTEPEN_RXPEN;
263  #else
264  handle->initData.port->ROUTE &= ~USART_ROUTE_RXPEN;
265  #endif
266  handle->initData.port->CMD = USART_CMD_RXDIS;
267 }
268 
269 
270 /***************************************************************************/
273 static void StartReceiveDma(UARTDRV_Handle_t handle,
274  UARTDRV_Buffer_t *buffer)
275 {
276  void *rxPort;
277 
278  handle->rxDmaActive = true;
279  rxPort = (void *)&(handle->initData.port->RXDATA);
280 
281  DMADRV_PeripheralMemory( handle->rxDmaCh,
282  handle->rxDmaSignal,
283  buffer->data,
284  rxPort,
285  true,
286  buffer->transferCount,
288  ReceiveDmaComplete,
289  handle );
290 }
291 
292 
293 /***************************************************************************/
296 static void StartTransmitDma(UARTDRV_Handle_t handle,
297  UARTDRV_Buffer_t *buffer)
298 {
299  void *txPort;
300 
301  handle->txDmaActive = true;
302  txPort = (void *)&(handle->initData.port->TXDATA);
303 
304  DMADRV_MemoryPeripheral( handle->txDmaCh,
305  handle->txDmaSignal,
306  txPort,
307  buffer->data,
308  true,
309  buffer->transferCount,
311  TransmitDmaComplete,
312  handle );
313 }
314 
315 
316 /***************************************************************************/
319 static bool ReceiveDmaComplete( unsigned int channel,
320  unsigned int sequenceNo,
321  void *userParam )
322 {
323  UARTDRV_Handle_t handle;
324  UARTDRV_Buffer_t *buffer;
325  (void)channel;
326  (void)sequenceNo;
327 
328  handle = (UARTDRV_Handle_t)userParam;
329  GetTailBuffer(handle->rxQueue, &buffer);
330 
331  if (handle->initData.port->IF & USART_IF_FERR)
332  {
334  buffer->itemsRemaining = buffer->transferCount; // nothing received
335  handle->initData.port->IFC = USART_IFC_FERR;
336  }
337  else if (handle->initData.port->IF & USART_IF_PERR)
338  {
340  buffer->itemsRemaining = buffer->transferCount; // nothing received
341  handle->initData.port->IFC = USART_IFC_PERR;
342  }
343  else
344  {
346  buffer->itemsRemaining = 0;
347  }
348 
349  INT_Disable();
350 
351  if (buffer->callback != NULL)
352  {
353  buffer->callback(handle, buffer->transferStatus, buffer->data, buffer->transferCount - buffer->itemsRemaining);
354  }
355  // Dequeue the current tail RX operation, check if more in queue
356  DequeueBuffer(handle->rxQueue, &buffer);
357 
358  if (handle->rxQueue->used > 0)
359  {
360  GetTailBuffer(handle->rxQueue, &buffer);
361  StartReceiveDma(handle, buffer);
362  }
363  else
364  {
365  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
366  handle->fcSelfState = uartdrvFlowControlOff;
367  FcApplyState(handle);
368  #endif
369  handle->rxDmaActive = false;
370  DisableReceiver(handle);
371  }
372  INT_Enable();
373  return true;
374 }
375 
376 
377 /***************************************************************************/
380 static bool TransmitDmaComplete( unsigned int channel,
381  unsigned int sequenceNo,
382  void *userParam )
383 {
384  UARTDRV_Handle_t handle;
385  UARTDRV_Buffer_t *buffer;
386  (void)channel;
387  (void)sequenceNo;
388 
389  handle = (UARTDRV_Handle_t)userParam;
390  GetTailBuffer(handle->txQueue, &buffer);
391 
393  buffer->itemsRemaining = 0;
394 
395  INT_Disable();
396 
397  if (buffer->callback != NULL)
398  {
399  buffer->callback(handle, ECODE_EMDRV_UARTDRV_OK, buffer->data, buffer->transferCount);
400  }
401  // Dequeue the current tail TX operation, check if more in queue
402  DequeueBuffer(handle->txQueue, &buffer);
403 
404  if (handle->txQueue->used > 0)
405  {
406  GetTailBuffer(handle->txQueue, &buffer);
407  StartTransmitDma(handle, buffer);
408  }
409  else
410  {
411  handle->txDmaActive = false;
412  }
413  INT_Enable();
414  return true;
415 }
416 
417 
418 /***************************************************************************/
421 static Ecode_t CheckParams(UARTDRV_Handle_t handle, void *data, uint32_t count)
422 {
423  if (handle == NULL)
424  {
426  }
427  if ((data == NULL) || (count == 0) || (count > DMADRV_MAX_XFER_COUNT )) {
429  }
430  return ECODE_EMDRV_UARTDRV_OK;
431 }
432 
433 
434 /***************************************************************************/
437 static Ecode_t ConfigGPIO(UARTDRV_Handle_t handle, bool enable)
438 {
439 #if defined( _USART_ROUTELOC0_MASK )
440  UARTDRV_Init_t *initData;
441 #else
442  uint32_t location;
443 #endif
444 
445 #if defined( _USART_ROUTELOC0_MASK )
446  initData = &handle->initData;
447 
448  if ( 0 ) {
449  #if defined(USARTRF0)
450  } else if (handle->initData.port == USARTRF0) {
451  handle->txPort = (GPIO_Port_TypeDef)AF_USARTRF0_TX_PORT( initData->portLocationTx );
452  handle->rxPort = (GPIO_Port_TypeDef)AF_USARTRF0_RX_PORT( initData->portLocationRx );
453  handle->txPin = AF_USARTRF0_TX_PIN( initData->portLocationTx );
454  handle->rxPin = AF_USARTRF0_RX_PIN( initData->portLocationRx );
455  #endif
456  #if defined(USARTRF1)
457  } else if (handle->initData.port == USARTRF1) {
458  handle->txPort = (GPIO_Port_TypeDef)AF_USARTRF1_TX_PORT( initData->portLocationTx );
459  handle->rxPort = (GPIO_Port_TypeDef)AF_USARTRF1_RX_PORT( initData->portLocationRx );
460  handle->txPin = AF_USARTRF1_TX_PIN( initData->portLocationTx );
461  handle->rxPin = AF_USARTRF1_RX_PIN( initData->portLocationRx );
462  #endif
463  #if defined(USART0)
464  } else if (handle->initData.port == USART0) {
465  handle->txPort = (GPIO_Port_TypeDef)AF_USART0_TX_PORT( initData->portLocationTx );
466  handle->rxPort = (GPIO_Port_TypeDef)AF_USART0_RX_PORT( initData->portLocationRx );
467  handle->txPin = AF_USART0_TX_PIN( initData->portLocationTx );
468  handle->rxPin = AF_USART0_RX_PIN( initData->portLocationRx );
469  #endif
470  #if defined(USART1)
471  } else if (handle->initData.port == USART1) {
472  handle->txPort = (GPIO_Port_TypeDef)AF_USART1_TX_PORT( initData->portLocationTx );
473  handle->rxPort = (GPIO_Port_TypeDef)AF_USART1_RX_PORT( initData->portLocationRx );
474  handle->txPin = AF_USART1_TX_PIN( initData->portLocationTx );
475  handle->rxPin = AF_USART1_RX_PIN( initData->portLocationRx );
476  #endif
477  #if defined(USART2)
478  } else if (handle->initData.port == USART2) {
479  handle->txPort = (GPIO_Port_TypeDef)AF_USART2_TX_PORT( initData->portLocationTx );
480  handle->rxPort = (GPIO_Port_TypeDef)AF_USART2_RX_PORT( initData->portLocationRx );
481  handle->txPin = AF_USART2_TX_PIN( initData->portLocationTx );
482  handle->rxPin = AF_USART2_RX_PIN( initData->portLocationRx );
483  #endif
484  #if defined(UART0)
485  } else if (handle->initData.port == UART0) {
486  handle->txPort = (GPIO_Port_TypeDef)AF_UART0_TX_PORT( initData->portLocationTx );
487  handle->rxPort = (GPIO_Port_TypeDef)AF_UART0_RX_PORT( initData->portLocationRx );
488  handle->txPin = AF_UART0_TX_PIN( initData->portLocationTx );
489  handle->rxPin = AF_UART0_RX_PIN( initData->portLocationRx );
490  #endif
491  #if defined(UART1)
492  } else if (handle->initData.port == UART1) {
493  handle->txPort = (GPIO_Port_TypeDef)AF_UART1_TX_PORT( initData->portLocationTx );
494  handle->rxPort = (GPIO_Port_TypeDef)AF_UART1_RX_PORT( initData->portLocationRx );
495  handle->txPin = AF_UART1_TX_PIN( initData->portLocationTx );
496  handle->rxPin = AF_UART1_RX_PIN( initData->portLocationRx );
497  #endif
498  } else {
500  }
501 #else
502  location = handle->initData.portLocation;
503 
504  if ( 0 ) {
505  #if defined(USART0)
506  } else if (handle->initData.port == USART0) {
507  handle->txPort = (GPIO_Port_TypeDef)AF_USART0_TX_PORT(location);
508  handle->rxPort = (GPIO_Port_TypeDef)AF_USART0_RX_PORT(location);
509  handle->txPin = AF_USART0_TX_PIN(location);
510  handle->rxPin = AF_USART0_RX_PIN(location);
511  #endif
512  #if defined(USART1)
513  } else if (handle->initData.port == USART1) {
514  handle->txPort = (GPIO_Port_TypeDef)AF_USART1_TX_PORT(location);
515  handle->rxPort = (GPIO_Port_TypeDef)AF_USART1_RX_PORT(location);
516  handle->txPin = AF_USART1_TX_PIN(location);
517  handle->rxPin = AF_USART1_RX_PIN(location);
518  #endif
519  #if defined(USART2)
520  } else if (handle->initData.port == USART2) {
521  handle->txPort = (GPIO_Port_TypeDef)AF_USART2_TX_PORT(location);
522  handle->rxPort = (GPIO_Port_TypeDef)AF_USART2_RX_PORT(location);
523  handle->txPin = AF_USART2_TX_PIN(location);
524  handle->rxPin = AF_USART2_RX_PIN(location);
525  #endif
526  #if defined(UART0)
527  } else if (handle->initData.port == UART0) {
528  handle->txPort = (GPIO_Port_TypeDef)AF_UART0_TX_PORT(location);
529  handle->rxPort = (GPIO_Port_TypeDef)AF_UART0_RX_PORT(location);
530  handle->txPin = AF_UART0_TX_PIN(location);
531  handle->rxPin = AF_UART0_RX_PIN(location);
532  #endif
533  #if defined(UART1)
534  } else if (handle->initData.port == UART1) {
535  handle->txPort = (GPIO_Port_TypeDef)AF_UART1_TX_PORT(location);
536  handle->rxPort = (GPIO_Port_TypeDef)AF_UART1_RX_PORT(location);
537  handle->txPin = AF_UART1_TX_PIN(location);
538  handle->rxPin = AF_UART1_RX_PIN(location);
539  #endif
540  } else {
542  }
543 #endif
544 
545  if (enable)
546  {
547  GPIO_PinModeSet(handle->txPort, handle->txPin, gpioModePushPull, 1);
548  GPIO_PinModeSet(handle->rxPort, handle->rxPin, gpioModeInput, 0);
549  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
550  if (handle->initData.fcType == uartdrvFlowControlHw)
551  {
552  GPIO_PinModeSet(handle->initData.ctsPort, handle->initData.ctsPin, gpioModeInput, 0);
553  GPIO_PinModeSet(handle->initData.rtsPort, handle->initData.rtsPin, gpioModePushPull, 0);
554  GPIO_IntConfig(handle->initData.ctsPort, handle->initData.ctsPin, true, true, true);
555  }
556  #endif
557  }
558  else
559  {
560  GPIO_PinModeSet(handle->txPort, handle->txPin, gpioModeDisabled, 0);
561  GPIO_PinModeSet(handle->rxPort, handle->rxPin, gpioModeDisabled, 0);
562  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
563  if (handle->initData.fcType == uartdrvFlowControlHw)
564  {
565  GPIO_PinModeSet(handle->initData.ctsPort, handle->initData.ctsPin, gpioModeDisabled, 0);
566  GPIO_PinModeSet(handle->initData.rtsPort, handle->initData.rtsPin, gpioModeDisabled, 0);
567  GPIO_IntConfig(handle->initData.ctsPort, handle->initData.ctsPin, true, true, false);
568  }
569  #endif
570  }
571  return ECODE_EMDRV_UARTDRV_OK;
572 }
573 
575 
576 
577 /***************************************************************************/
592 {
593  Ecode_t retVal;
594  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
595  uint32_t handleIdx;
596  bool handleIsSet;
597  #endif
599 
600 
601  if (handle == NULL)
602  {
604  }
605  if (initData == NULL)
606  {
608  }
609  memset(handle, 0, sizeof(UARTDRV_HandleData_t));
610 
611 
612  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
613  // Set handler pointer in handler array
614  if (!uartdrvHandleIsInitialized)
615  {
616  for (handleIdx = 0; handleIdx < EMDRV_UARTDRV_MAX_DRIVER_INSTANCES; handleIdx++)
617  {
618  uartdrvHandle[handleIdx] = NULL;
619  }
620  uartdrvHandleIsInitialized = true;
621  }
622 
623  handleIsSet = false;
624  for (handleIdx = 0; handleIdx < EMDRV_UARTDRV_MAX_DRIVER_INSTANCES; handleIdx++)
625  {
626  if ((uartdrvHandle[handleIdx] == NULL) || (uartdrvHandle[handleIdx] == handle))
627  {
628  uartdrvHandle[handleIdx] = handle;
629  handleIsSet = true;
630  break;
631  }
632  }
633 
634  if (!handleIsSet)
635  {
637  }
638  #else
639  // Force init data to uartdrvFlowControlNone if flow control is excluded by EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE
640  handle->initData.fcType = uartdrvFlowControlNone;
641  #endif
642 
643 
644  // Set clocks and DMA requests according to available peripherals
645  if (false)
646  {
647  #if defined(USART0)
648  } else if (initData->port == USART0)
649  {
650  handle->uartClock = cmuClock_USART0;
651  handle->txDmaSignal = dmadrvPeripheralSignal_USART0_TXBL;
652  handle->rxDmaSignal = dmadrvPeripheralSignal_USART0_RXDATAV;
653  #endif
654  #if defined(USART1)
655  }
656  else if (initData->port == USART1)
657  {
658  handle->uartClock = cmuClock_USART1;
659  handle->txDmaSignal = dmadrvPeripheralSignal_USART1_TXBL;
660  handle->rxDmaSignal = dmadrvPeripheralSignal_USART1_RXDATAV;
661  #endif
662  #if defined(USART2)
663  }
664  else if (initData->port == USART2)
665  {
666  handle->uartClock = cmuClock_USART2;
667  handle->txDmaSignal = dmadrvPeripheralSignal_USART2_TXBL;
668  handle->rxDmaSignal = dmadrvPeripheralSignal_USART2_RXDATAV;
669  #endif
670  #if defined(UART0)
671  }
672  else if (initData->port == UART0)
673  {
674  handle->uartClock = cmuClock_UART0;
675  handle->txDmaSignal = dmadrvPeripheralSignal_UART0_TXBL;
676  handle->rxDmaSignal = dmadrvPeripheralSignal_UART0_RXDATAV;
677  #endif
678  #if defined(UART1)
679  }
680  else if (initData->port == UART1)
681  {
682  handle->uartClock = cmuClock_UART1;
683  handle->txDmaSignal = dmadrvPeripheralSignal_UART1_TXBL;
684  handle->rxDmaSignal = dmadrvPeripheralSignal_UART1_RXDATAV;
685  #endif
686  #if defined(UART2)
687  }
688  else if (initData->port == UART2)
689  {
690  handle->uartClock = cmuClock_UART2;
691  handle->txDmaSignal = dmadrvPeripheralSignal_UART2_TXBL;
692  handle->rxDmaSignal = dmadrvPeripheralSignal_UART2_RXDATAV;
693  #endif
694  }
695  else
696  {
698  }
699 
700  memcpy((void *)&handle->initData, (const void *)initData, sizeof(UARTDRV_Init_t));
701  handle->rxQueue = initData->rxQueue;
702  handle->rxQueue->head = 0;
703  handle->rxQueue->tail = 0;
704  handle->rxQueue->used = 0;
705  handle->rxDmaActive = false;
706 
707  handle->txQueue = initData->txQueue;
708  handle->txQueue->head = 0;
709  handle->txQueue->tail = 0;
710  handle->txQueue->used = 0;
711  handle->txDmaActive = false;
712 
713  handle->IgnoreRestrain = false;
714 
715  usartInit.baudrate = initData->baudRate;
716  usartInit.stopbits = initData->stopBits;
717  usartInit.parity = initData->parity;
718  usartInit.oversampling = initData->oversampling;
719 #if defined(USART_CTRL_MVDIS)
720  usartInit.mvdis = initData->mvdis;
721 #endif
722 
723  // UARTDRV is fixed at 8 bit frames.
725 
726  // Enable clocks
729  CMU_ClockEnable(handle->uartClock, true);
730 
731  // Init U(S)ART to default async config.
732  // RX/TX enable is done on demand
733  usartInit.enable = usartDisable;
734  USART_InitAsync(initData->port, &usartInit);
735 
736  #if defined( USART_ROUTEPEN_TXPEN )
737  initData->port->ROUTEPEN = USART_ROUTEPEN_TXPEN
739  initData->port->ROUTELOC0 = ( initData->port->ROUTELOC0 &
743  | ( initData->portLocationRx << _USART_ROUTELOC0_RXLOC_SHIFT );
744  #else
745  initData->port->ROUTE = USART_ROUTE_TXPEN
746  | USART_ROUTE_RXPEN
747  | (initData->portLocation
748  << _USART_ROUTE_LOCATION_SHIFT);
749  #endif
750 
751  if ((retVal = ConfigGPIO(handle, true)) != ECODE_EMDRV_UARTDRV_OK)
752  {
753  return retVal;
754  }
755 
756  INT_Disable();
757 
758  // Configure hardware flow control pins and interrupt vectors
759  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
760  GPIOINT_Init();
761  GPIOINT_CallbackRegister(initData->ctsPin, HwFcManageClearToSend);
762  handle->fcPeerState = uartdrvFlowControlOn;
763  handle->fcSelfState = uartdrvFlowControlOn;
764  handle->fcSelfCfg = uartdrvFlowControlAuto;
765  FcApplyState(handle);
766  #endif
767 
768  // Clear any false IRQ/DMA request
769  USART_IntClear(initData->port, ~0x0);
770 
771  // Enable TX permanently as the TX circuit consumes very little energy.
772  // RX is enabled on demand as the RX circuit consumes some energy due to
773  // continuous (over)sampling.
774  USART_Enable(initData->port, usartEnableTx);
775 
776  // Discard false frames and/or IRQs
778 
779  // Initialize DMA.
780  DMADRV_Init();
781 
782  if ( DMADRV_AllocateChannel(&handle->txDmaCh,NULL) != ECODE_EMDRV_DMADRV_OK )
783  {
784  INT_Enable();
786  }
787 
788  if ( DMADRV_AllocateChannel(&handle->rxDmaCh,NULL) != ECODE_EMDRV_DMADRV_OK )
789  {
790  INT_Enable();
792  }
793 
794  INT_Enable();
795  return ECODE_EMDRV_UARTDRV_OK;
796 }
797 
798 
799 /***************************************************************************/
810 {
811  if (handle == NULL)
812  {
814  }
815  // Stop DMA's.
816  DMADRV_StopTransfer( handle->rxDmaCh );
817  DMADRV_StopTransfer( handle->txDmaCh );
818 
819  // Do not leave any peer restrained on DeInit
821 
822  ConfigGPIO(handle, false);
823 
824  USART_Reset(handle->initData.port);
825  handle->initData.port->CMD = USART_CMD_RXDIS;
826  handle->initData.port->CMD = USART_CMD_TXDIS;
827 
828  CMU_ClockEnable(handle->uartClock, false);
829 
830  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
831  GPIOINT_CallbackRegister(handle->initData.ctsPin, NULL);
832  #endif
833 
834  DMADRV_FreeChannel( handle->txDmaCh );
835  DMADRV_FreeChannel( handle->rxDmaCh );
836  DMADRV_DeInit();
837 
838  handle->rxQueue->head = 0;
839  handle->rxQueue->tail = 0;
840  handle->rxQueue->used = 0;
841 
842  handle->txQueue->head = 0;
843  handle->txQueue->tail = 0;
844  handle->txQueue->used = 0;
845 
846  return ECODE_EMDRV_UARTDRV_OK;
847 }
848 
849 
850 /***************************************************************************/
863 {
864  UARTDRV_Buffer_t *rxBuffer, *txBuffer;
865 
866  if (handle == NULL) {
868  }
869 
870  INT_Disable();
871  if ((type == uartdrvAbortTransmit) && (handle->txQueue->used == 0))
872  {
873  INT_Enable();
875  }
876  else if ((type == uartdrvAbortReceive) && (handle->rxQueue->used == 0))
877  {
878  INT_Enable();
880  }
881  else if ((type == uartdrvAbortAll) && (handle->txQueue->used == 0)
882  && (handle->rxQueue->used == 0))
883  {
884  INT_Enable();
886  }
887 
888  // Stop DMA's.
889  if ((type == uartdrvAbortTransmit) || (type == uartdrvAbortAll))
890  {
891  GetTailBuffer(handle->txQueue, &txBuffer);
892  DMADRV_StopTransfer( handle->txDmaCh );
893  DMADRV_TransferRemainingCount( handle->txDmaCh,
894  (int*)&txBuffer->itemsRemaining );
896  if (txBuffer->callback != NULL)
897  {
898  txBuffer->callback(handle,
900  NULL,
901  txBuffer->itemsRemaining);
902  }
903  }
904  if ((type == uartdrvAbortReceive) || (type == uartdrvAbortAll))
905  {
906  GetTailBuffer(handle->rxQueue, &rxBuffer);
907  DMADRV_StopTransfer( handle->rxDmaCh );
908  DMADRV_TransferRemainingCount( handle->rxDmaCh,
909  (int*)&rxBuffer->itemsRemaining );
911  if (rxBuffer->callback != NULL)
912  {
913  rxBuffer->callback(handle,
915  NULL,
916  rxBuffer->itemsRemaining);
917  }
918  }
919  INT_Enable();
920 
921  return ECODE_EMDRV_UARTDRV_OK;
922 }
923 
924 
925 /***************************************************************************/
935 {
936  return (uint8_t)handle->rxQueue->used;
937 }
938 
939 
940 /***************************************************************************/
957  uint8_t **buffer,
958  UARTDRV_Count_t *itemsReceived,
959  UARTDRV_Count_t *itemsRemaining)
960 {
962  uint32_t remaining;
963 
964  if (handle->rxQueue->used > 0)
965  {
966  GetTailBuffer(handle->rxQueue, &rxBuffer);
967  DMADRV_TransferRemainingCount( handle->rxDmaCh,
968  (int*)&remaining );
969 
970  *itemsReceived = rxBuffer->transferCount - remaining;
971  *itemsRemaining = remaining;
972  *buffer = rxBuffer->data;
973  }
974  else
975  {
976  *itemsRemaining = 0;
977  *itemsReceived = 0;
978  *buffer = NULL;
979  }
980  return handle->initData.port->STATUS;
981 }
982 
983 
984 /***************************************************************************/
994 {
995  return (uint8_t)handle->txQueue->used;
996 }
997 
998 
999 /***************************************************************************/
1016  uint8_t **buffer,
1017  UARTDRV_Count_t *itemsSent,
1018  UARTDRV_Count_t *itemsRemaining)
1019 {
1020  UARTDRV_Buffer_t *txBuffer;
1021  uint32_t remaining;
1022 
1023  if (handle->txQueue->used > 0)
1024  {
1025  GetTailBuffer(handle->txQueue, &txBuffer);
1026  DMADRV_TransferRemainingCount( handle->txDmaCh,
1027  (int*)&remaining );
1028 
1029  *itemsSent = txBuffer->transferCount - remaining;
1030  *itemsRemaining = remaining;
1031  *buffer = txBuffer->data;
1032  }
1033  else
1034  {
1035  *itemsRemaining = 0;
1036  *itemsSent = 0;
1037  *buffer = NULL;
1038  }
1039  return handle->initData.port->STATUS;
1040 }
1041 
1042 
1043 /***************************************************************************/
1056 {
1057  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
1058  handle->fcSelfCfg = state;
1059  if (state != uartdrvFlowControlAuto)
1060  {
1061  handle->fcSelfState = state;
1062  }
1063  return FcApplyState(handle);
1064  #else
1065  return ECODE_EMDRV_UARTDRV_OK;
1066  #endif
1067 }
1068 
1069 
1070 /***************************************************************************/
1080 {
1081  return handle->fcPeerState;
1082 }
1083 
1084 
1085 /***************************************************************************/
1095 {
1096  return handle->fcSelfState;
1097 }
1098 
1099 
1100 /***************************************************************************/
1110 {
1111  handle->IgnoreRestrain = true;
1112 
1113  return ECODE_EMDRV_UARTDRV_OK;
1114 }
1115 
1116 
1117 /***************************************************************************/
1131  uint8_t *data,
1132  UARTDRV_Count_t maxCount)
1133 {
1134  Ecode_t retVal;
1135  uint32_t rxState;
1136  UARTDRV_Count_t i = 0;
1137 
1138  retVal = CheckParams(handle, data, maxCount);
1139  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1140  {
1141  return 0;
1142  }
1143 
1144  // Wait for DMA receive to complete and clear
1145  while(handle->rxQueue->used > 0);
1146 
1147  rxState = (handle->initData.port->STATUS & USART_STATUS_RXENS);
1148  if (!rxState)
1149  {
1150  EnableReceiver(handle);
1151  }
1152 
1153  while ((handle->initData.port->STATUS & USART_STATUS_RXDATAV))
1154  {
1155  *data = (uint8_t)handle->initData.port->RXDATA;
1156  data++;
1157  i++;
1158  if (i >= maxCount)
1159  {
1160  break;
1161  }
1162  }
1163  data -= i;
1164 
1165  if (!rxState)
1166  {
1167  DisableReceiver(handle);
1168  }
1169  return i;
1170 }
1171 
1172 
1173 /***************************************************************************/
1188  uint8_t *data,
1189  UARTDRV_Count_t count)
1190 {
1191  Ecode_t retVal;
1192  uint32_t txState;
1193 
1194  retVal = CheckParams(handle, data, count);
1195  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1196  {
1197  return retVal;
1198  }
1199 
1200  // Wait for DMA transmit to complete and clear
1201  while(handle->txQueue->used > 0);
1202 
1203  txState = (handle->initData.port->STATUS & USART_STATUS_TXENS);
1204  if (!txState)
1205  {
1206  EnableTransmitter(handle);
1207  }
1208 
1209  while (count--)
1210  {
1211  while (!(handle->initData.port->STATUS & USART_STATUS_TXBL));
1212  handle->initData.port->TXDATA = *data;
1213  data++;
1214  }
1215  while (!(handle->initData.port->STATUS & USART_STATUS_TXC));
1216 
1217  if (!txState)
1218  {
1219  DisableTransmitter(handle);
1220  }
1221 
1222  return ECODE_EMDRV_UARTDRV_OK;
1223 }
1224 
1225 
1226 /***************************************************************************/
1242  uint8_t *data,
1243  UARTDRV_Count_t count,
1244  UARTDRV_Callback_t callback)
1245 {
1246  Ecode_t retVal;
1247  UARTDRV_Buffer_t outputBuffer;
1248  UARTDRV_Buffer_t *queueBuffer;
1249 
1250  retVal = CheckParams(handle, data, count);
1251  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1252  {
1253  return retVal;
1254  }
1255  outputBuffer.data = data;
1256  outputBuffer.transferCount = count;
1257  outputBuffer.itemsRemaining = count;
1258  outputBuffer.callback = callback;
1260 
1261  retVal = EnqueueBuffer(handle->rxQueue, &outputBuffer, &queueBuffer);
1262  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1263  {
1264  return retVal;
1265  }
1266  if (!(handle->rxDmaActive))
1267  {
1268  EnableReceiver(handle);
1269  StartReceiveDma(handle, queueBuffer);
1270  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
1271  handle->fcSelfState = uartdrvFlowControlOn;
1272  FcApplyState(handle);
1273  #endif
1274  } // else: started by ReceiveDmaComplete
1275 
1276  return ECODE_EMDRV_UARTDRV_OK;
1277 }
1278 
1279 
1280 /***************************************************************************/
1294  uint8_t *data,
1295  UARTDRV_Count_t count)
1296 {
1297  Ecode_t retVal;
1298  UARTDRV_Buffer_t inputBuffer;
1299  UARTDRV_Buffer_t *queueBuffer;
1300 
1301  retVal = CheckParams(handle, data, count);
1302  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1303  {
1304  return retVal;
1305  }
1306  inputBuffer.data = data;
1307  inputBuffer.transferCount = count;
1308  inputBuffer.itemsRemaining = count;
1309  inputBuffer.callback = NULL;
1311 
1312  retVal = EnqueueBuffer(handle->rxQueue, &inputBuffer, &queueBuffer);
1313  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1314  {
1315  return retVal;
1316  }
1317  while(handle->rxQueue->used > 1)
1318  {
1319  EMU_EnterEM1();
1320  }
1321  EnableReceiver(handle);
1322  #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
1323  handle->fcSelfState = uartdrvFlowControlOn;
1324  FcApplyState(handle);
1325  #endif
1326  StartReceiveDma(handle, queueBuffer);
1327  while(handle->rxDmaActive)
1328  {
1329  EMU_EnterEM1();
1330  }
1331  return queueBuffer->transferStatus;
1332 }
1333 
1334 
1335 /***************************************************************************/
1351  uint8_t *data,
1352  UARTDRV_Count_t count,
1353  UARTDRV_Callback_t callback)
1354 {
1355  Ecode_t retVal;
1356  UARTDRV_Buffer_t inputBuffer;
1357  UARTDRV_Buffer_t *queueBuffer;
1358 
1359  retVal = CheckParams(handle, data, count);
1360  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1361  {
1362  return retVal;
1363  }
1364  inputBuffer.data = data;
1365  inputBuffer.transferCount = count;
1366  inputBuffer.itemsRemaining = count;
1367  inputBuffer.callback = callback;
1369 
1370  retVal = EnqueueBuffer(handle->txQueue, &inputBuffer, &queueBuffer);
1371  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1372  {
1373  return retVal;
1374  }
1375  if (!(handle->txDmaActive))
1376  {
1377  StartTransmitDma(handle, queueBuffer);
1378  } // else: started by TransmitDmaComplete
1379 
1380  return ECODE_EMDRV_UARTDRV_OK;
1381 }
1382 
1383 
1384 /***************************************************************************/
1398  uint8_t *data,
1399  UARTDRV_Count_t count)
1400 {
1401  Ecode_t retVal;
1402  UARTDRV_Buffer_t outputBuffer;
1403  UARTDRV_Buffer_t *queueBuffer;
1404 
1405  retVal = CheckParams(handle, data, count);
1406  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1407  {
1408  return retVal;
1409  }
1410  outputBuffer.data = data;
1411  outputBuffer.transferCount = count;
1412  outputBuffer.itemsRemaining = count;
1413  outputBuffer.callback = NULL;
1415 
1416  retVal = EnqueueBuffer(handle->txQueue, &outputBuffer, &queueBuffer);
1417  if (retVal != ECODE_EMDRV_UARTDRV_OK)
1418  {
1419  return retVal;
1420  }
1421  while(handle->txQueue->used > 1)
1422  {
1423  EMU_EnterEM1();
1424  }
1425  StartTransmitDma(handle, queueBuffer);
1426  while(handle->txDmaActive)
1427  {
1428  EMU_EnterEM1();
1429  }
1430  return queueBuffer->transferStatus;
1431 }
1432 
1433 
1434 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/
Byte.
Definition: dmadrv.h:449
#define USART_CMD_TXDIS
Software XON/XOFF.
Definition: uartdrv.h:74
USART_Stopbits_TypeDef stopbits
Definition: em_usart.h:275
Trig on USART1_RXDATAV.
Definition: dmadrv.h:430
XOFF or nRTS/nCTS high.
Definition: uartdrv.h:82
UARTDRV_Buffer_FifoQueue_t * txQueue
Transmit operation queue.
Definition: uartdrv.h:184
uint8_t portLocationTx
Location number for UART Tx pin.
Definition: uartdrv.h:167
Ecode_t UARTDRV_Transmit(UARTDRV_Handle_t handle, uint8_t *data, UARTDRV_Count_t count, UARTDRV_Callback_t callback)
Start a non-blocking transmit.
Definition: uartdrv.c:1350
#define USART_CMD_RXDIS
#define ECODE_EMDRV_UARTDRV_PARAM_ERROR
Illegal input parameter.
Definition: uartdrv.h:46
uint8_t UARTDRV_GetTransmitDepth(UARTDRV_Handle_t handle)
Returns the number of queued transmit operations.
Definition: uartdrv.c:993
UARTDRV_Buffer_FifoQueue_t * rxQueue
Receive operation queue.
Definition: uartdrv.h:183
GPIO_Port_TypeDef
Definition: em_gpio.h:232
enum UARTDRV_AbortType UARTDRV_AbortType_t
Transfer abort type.
__IO uint32_t ROUTELOC0
#define USART_ROUTEPEN_RXPEN
Abort all current and queued operations.
Definition: uartdrv.h:91
Ecode_t transferStatus
Completion status of transfer operation.
Definition: uartdrv.h:125
#define USART_IF_FERR
#define USART0
Ecode_t DMADRV_PeripheralMemory(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst, void *src, bool dstInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a peripheral to memory DMA transfer.
Definition: dmadrv.c:535
#define ECODE_EMDRV_UARTDRV_QUEUE_EMPTY
UART operation queue is empty.
Definition: uartdrv.h:52
USART_OVS_TypeDef oversampling
Definition: em_usart.h:265
UARTDRV_Buffer_t fifo[]
FIFO of queue data.
Definition: uartdrv.h:135
Trig on USART0_RXDATAV.
Definition: dmadrv.h:421
UARTDRV_FlowControlState_t UARTDRV_FlowControlGetSelfStatus(UARTDRV_Handle_t handle)
Checks the self's flow control status.
Definition: uartdrv.c:1094
__STATIC_INLINE void USART_IntClear(USART_TypeDef *usart, uint32_t flags)
Clear one or more pending USART interrupts.
Definition: em_usart.h:605
USART_Databits_TypeDef databits
Definition: em_usart.h:269
#define ECODE_EMDRV_UARTDRV_FRAME_ERROR
UART frame error. Data is ignored.
Definition: uartdrv.h:54
USART_OVS_TypeDef oversampling
Oversampling mode.
Definition: uartdrv.h:174
__STATIC_INLINE uint32_t INT_Enable(void)
Enable interrupts.
Definition: em_int.h:94
USART_TypeDef * port
The peripheral used for UART.
Definition: uartdrv.h:164
Ecode_t DMADRV_StopTransfer(unsigned int channelId)
Stop an ongoing DMA transfer.
Definition: dmadrv.c:641
#define _USART_ROUTELOC0_RXLOC_MASK
#define USART_STATUS_RXENS
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
#define USART_STATUS_TXBL
#define USART_FRAME_DATABITS_EIGHT
USART_Parity_TypeDef parity
Definition: em_usart.h:272
#define ECODE_EMDRV_UARTDRV_OK
Success return value.
Definition: uartdrv.h:43
Universal synchronous/asynchronous receiver/transmitter (USART/UART) peripheral API.
void GPIOINT_CallbackRegister(uint8_t pin, GPIOINT_IrqCallbackPtr_t callbackPtr)
Registers user callback for given pin number.
Definition: gpiointerrupt.c:91
USART_Enable_TypeDef enable
Definition: em_usart.h:253
#define USART_ROUTEPEN_TXPEN
#define USART_CMD_CLEARRX
Ecode_t UARTDRV_Init(UARTDRV_Handle_t handle, UARTDRV_Init_t *initData)
Initialize a UART driver instance.
Definition: uartdrv.c:591
Ecode_t UARTDRV_FlowControlSet(UARTDRV_Handle_t handle, UARTDRV_FlowControlState_t state)
Set UART flow control state. Set nRTS pin if hardware flow control is enabled.
Definition: uartdrv.c:1055
#define USART_IF_PERR
const uint16_t size
Size of FIFO.
Definition: uartdrv.h:134
uint8_t portLocationRx
Location number for UART Rx pin.
Definition: uartdrv.h:168
This driver controls the state.
Definition: uartdrv.h:83
UARTDRV_Count_t transferCount
Transfer item count.
Definition: uartdrv.h:122
USART_Stopbits_TypeDef stopBits
Number of stop bits.
Definition: uartdrv.h:172
bool mvdis
Majority Vote Disable for 16x, 8x and 6x oversampling modes.
Definition: uartdrv.h:176
enum UARTDRV_FlowControlState UARTDRV_FlowControlState_t
Flow Control state.
Transfer operation FIFO queue typedef.
Definition: uartdrv.h:129
UARTDRV_HandleData_t * UARTDRV_Handle_t
Handle pointer.
Definition: uartdrv.h:216
Ecode_t DMADRV_TransferRemainingCount(unsigned int channelId, int *remaining)
Get number of items remaining in a transfer.
Definition: dmadrv.c:852
nRTS/nCTS hardware handshake
Definition: uartdrv.h:75
Ecode_t UARTDRV_ForceTransmit(UARTDRV_Handle_t handle, uint8_t *data, UARTDRV_Count_t count)
Direct transmit without interrupts or callback. Blocking function that ignores flow control if enable...
Definition: uartdrv.c:1187
#define ECODE_EMDRV_UARTDRV_DMA_ALLOC_ERROR
Unable to allocated DMA channels.
Definition: uartdrv.h:55
Interrupt enable/disable unit API.
#define _USART_ROUTELOC0_TXLOC_MASK
XON or nRTS/nCTS low.
Definition: uartdrv.h:81
#define ECODE_EMDRV_UARTDRV_QUEUE_FULL
UART operation queue is full.
Definition: uartdrv.h:51
USART_Parity_TypeDef parity
Parity configuration.
Definition: uartdrv.h:173
UARTDRV_Count_t itemsRemaining
Transfer items remaining.
Definition: uartdrv.h:123
void GPIO_PinModeSet(GPIO_Port_TypeDef port, unsigned int pin, GPIO_Mode_TypeDef mode, unsigned int out)
Set the mode for a GPIO pin.
Definition: em_gpio.c:226
#define ECODE_EMDRV_UARTDRV_PARITY_ERROR
UART parity error frame. Data is ignored.
Definition: uartdrv.h:53
Ecode_t UARTDRV_ReceiveB(UARTDRV_Handle_t handle, uint8_t *data, UARTDRV_Count_t count)
Start a blocking receive.
Definition: uartdrv.c:1293
Trig on USART1_TXBL.
Definition: dmadrv.h:436
__STATIC_INLINE void EMU_EnterEM1(void)
Enter energy mode 1 (EM1).
Definition: em_emu.h:448
General Purpose IO (GPIO) peripheral API.
#define USART_IFC_FERR
UARTDRV API definition.
Trig on USART0_TXBL.
Definition: dmadrv.h:424
USART_Databits_TypeDef
Definition: em_usart.h:63
UARTDRV_Callback_t callback
Completion callback.
Definition: uartdrv.h:124
#define USART_STATUS_TXENS
#define DMADRV_MAX_XFER_COUNT
Maximum length of one DMA transfer.
Definition: dmadrv.h:312
__STATIC_INLINE void GPIO_PinOutSet(GPIO_Port_TypeDef port, unsigned int pin)
Set a single pin in GPIO data out register to 1.
Definition: em_gpio.h:745
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Definition: em_cmu.c:1369
Ecode_t DMADRV_Init(void)
Initialize DMADRV.
Definition: dmadrv.c:258
uint32_t baudRate
UART baud rate.
Definition: uartdrv.h:165
uint8_t ctsPin
CTS pin number.
Definition: uartdrv.h:180
UART transfer buffer.
Definition: uartdrv.h:119
void(* UARTDRV_Callback_t)(struct UARTDRV_HandleData *handle, Ecode_t transferStatus, uint8_t *data, UARTDRV_Count_t transferCount)
UARTDRV transfer completion callback function.
Definition: uartdrv.h:113
#define USART_CMD_CLEARTX
__IO uint32_t CMD
Ecode_t UARTDRV_Receive(UARTDRV_Handle_t handle, uint8_t *data, UARTDRV_Count_t count, UARTDRV_Callback_t callback)
Start a non-blocking receive.
Definition: uartdrv.c:1241
#define USART1
Ecode_t UARTDRV_DeInit(UARTDRV_Handle_t handle)
Deinitialize a UART driver instance.
Definition: uartdrv.c:809
Abort current and queued receive operations.
Definition: uartdrv.h:90
#define ECODE_EMDRV_DMADRV_OK
Success return value.
Definition: dmadrv.h:51
UARTDRV_Count_t UARTDRV_ForceReceive(UARTDRV_Handle_t handle, uint8_t *data, UARTDRV_Count_t maxCount)
Direct receive without interrupts or callback. Blocking function.
Definition: uartdrv.c:1130
void USART_Reset(USART_TypeDef *usart)
Reset USART/UART to same state as after a HW reset.
Definition: em_usart.c:876
Ecode_t DMADRV_DeInit(void)
Deinitialize DMADRV.
Definition: dmadrv.c:176
Energy management unit (EMU) peripheral API.
uint32_t UARTDRV_Count_t
UART transfer count.
Definition: uartdrv.h:67
#define ECODE_EMDRV_UARTDRV_WAITING
Operation is waiting in queue.
Definition: uartdrv.h:44
UARTDRV_Status_t UARTDRV_GetReceiveStatus(UARTDRV_Handle_t handle, uint8_t **buffer, UARTDRV_Count_t *itemsReceived, UARTDRV_Count_t *itemsRemaining)
Check the status of the UART and gather information about any ongoing receive operations.
Definition: uartdrv.c:956
#define USART_CMD_RXEN
Ecode_t DMADRV_AllocateChannel(unsigned int *channelId, void *capabilities)
Allocate (reserve) a DMA channel.
Definition: dmadrv.c:131
uint8_t UARTDRV_GetReceiveDepth(UARTDRV_Handle_t handle)
Returns the number of queued receive operations.
Definition: uartdrv.c:934
static volatile uint8_t rxBuffer[RXBUFSIZE]
void GPIOINT_Init(void)
Initialization of GPIOINT module.
Definition: gpiointerrupt.c:67
Ecode_t DMADRV_MemoryPeripheral(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst, void *src, bool srcInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a memory to peripheral DMA transfer.
Definition: dmadrv.c:402
uint8_t * data
Transfer data buffer.
Definition: uartdrv.h:121
#define USART_IFC_PERR
GPIOINT API definition.
#define _USART_ROUTELOC0_TXLOC_SHIFT
#define USART_INITASYNC_DEFAULT
Definition: em_usart.h:314
#define ECODE_EMDRV_UARTDRV_ABORTED
UART transfer has been aborted.
Definition: uartdrv.h:50
uint32_t Ecode_t
Typedef for API function errorcode return values.
Definition: ecode.h:31
Ecode_t UARTDRV_Abort(UARTDRV_Handle_t handle, UARTDRV_AbortType_t type)
Abort an ongoing UART transfer.
Definition: uartdrv.c:862
UARTDRV_Status_t UARTDRV_GetTransmitStatus(UARTDRV_Handle_t handle, uint8_t **buffer, UARTDRV_Count_t *itemsSent, UARTDRV_Count_t *itemsRemaining)
Check the status of the UART and gather information about any ongoing transmit operations.
Definition: uartdrv.c:1015
UARTDRV_FlowControlState_t UARTDRV_FlowControlGetPeerStatus(UARTDRV_Handle_t handle)
Checks the peer's flow control status.
Definition: uartdrv.c:1079
#define USART_STATUS_RXDATAV
#define USART_STATUS_TXC
__STATIC_INLINE uint32_t INT_Disable(void)
Disable interrupts.
Definition: em_int.h:71
Ecode_t UARTDRV_TransmitB(UARTDRV_Handle_t handle, uint8_t *data, UARTDRV_Count_t count)
Start a blocking transmit.
Definition: uartdrv.c:1397
__STATIC_INLINE void GPIO_PinOutClear(GPIO_Port_TypeDef port, unsigned int pin)
Set a single pin in GPIO data out port register to 0.
Definition: em_gpio.h:698
void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable)
Enable/disable USART/UART receiver and/or transmitter.
Definition: em_usart.c:541
void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init)
Init USART/UART for normal asynchronous mode.
Definition: em_usart.c:583
uint16_t used
Number of bytes queued.
Definition: uartdrv.h:133
Ecode_t UARTDRV_FlowControlIgnoreRestrain(UARTDRV_Handle_t handle)
Enables transmission when restrained by flow control.
Definition: uartdrv.c:1109
#define _USART_ROUTELOC0_RXLOC_SHIFT
__STATIC_INLINE unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin)
Read the pad value for a single pin in a GPIO port.
Definition: em_gpio.h:675
#define ECODE_EMDRV_UARTDRV_ILLEGAL_HANDLE
Illegal UART handle.
Definition: uartdrv.h:45
uint16_t head
Index of next byte to send.
Definition: uartdrv.h:131
Abort current and queued transmit operations.
Definition: uartdrv.h:89
void GPIO_IntConfig(GPIO_Port_TypeDef port, unsigned int pin, bool risingEdge, bool fallingEdge, bool enable)
Configure GPIO interrupt.
Definition: em_gpio.c:168
#define USART_CMD_TXEN
#define ECODE_EMDRV_UARTDRV_IDLE
No UART transfer in progress.
Definition: uartdrv.h:49
uint32_t UARTDRV_Status_t
UART status return type.
Definition: uartdrv.h:68
Ecode_t DMADRV_FreeChannel(unsigned int channelId)
Free an allocate (reserved) DMA channel.
Definition: dmadrv.c:223
uint16_t tail
Index of where to enqueue next message.
Definition: uartdrv.h:132
__IO uint32_t ROUTEPEN