UART: UART.c Source File

Modbus RTU XMC47

UART.c
Go to the documentation of this file.
1 
61 /***********************************************************************************************************************
62  * HEADER FILES
63  **********************************************************************************************************************/
64 #include "uart.h"
65 
66 /***********************************************************************************************************************
67  * MACROS
68  **********************************************************************************************************************/
69 
70 /***********************************************************************************************************************
71  * LOCAL DATA
72  **********************************************************************************************************************/
73 const XMC_UART_CH_STATUS_FLAG_t uart_event_status_flags[UART_EVENT_MAX] = {
74  XMC_UART_CH_STATUS_FLAG_SYNCHRONIZATION_BREAK_DETECTED,
75  XMC_UART_CH_STATUS_FLAG_RECEIVER_NOISE_DETECTED,
76  XMC_UART_CH_STATUS_FLAG_FORMAT_ERROR_IN_STOP_BIT_0,
77  XMC_UART_CH_STATUS_FLAG_FORMAT_ERROR_IN_STOP_BIT_1,
78  XMC_UART_CH_STATUS_FLAG_COLLISION_DETECTED
79 };
80 const XMC_UART_CH_EVENT_t uart_event_conf_flags[UART_EVENT_MAX] = {
81  XMC_UART_CH_EVENT_SYNCHRONIZATION_BREAK,
82  XMC_UART_CH_EVENT_RECEIVER_NOISE,
83  XMC_UART_CH_EVENT_FORMAT_ERROR,
84  XMC_UART_CH_EVENT_FORMAT_ERROR,
85  XMC_UART_CH_EVENT_COLLISION
86 };
87 /***********************************************************************************************************************
88  * LOCAL ROUTINES
89  **********************************************************************************************************************/
90 #ifdef UART_TX_INTERRUPT_USED
91 /*Function used for handling transmit interrupt.*/
92 void UART_lTransmitHandler(const UART_t * const handle);
93 #endif
94 #ifdef UART_RX_INTERRUPT_USED
95 /*Function used for handling data reception interrupts.*/
96 void UART_lReceiveHandler(const UART_t * const handle);
97 /*Function used for reconfiguring rx FIFO while receiving data.*/
98 static void UART_lReconfigureRxFIFO(const UART_t * const handle, uint32_t data_size);
99 #endif
100 #ifdef UART_TX_DIRECT_USED
101 /*Function for transmitting data using polling.*/
102 static UART_STATUS_t UART_lStartTransmitPolling (const UART_t *const handle, uint8_t* data_ptr, uint32_t count);
103 #endif
104 #ifdef UART_RX_DIRECT_USED
105 /*Function for receiving data using polling.*/
106 static UART_STATUS_t UART_lStartReceivePolling (const UART_t *const handle, uint8_t* data_ptr, uint32_t count);
107 #endif
108 /*Function used for handling protocol related interrupt.*/
109 void UART_lProtocolHandler(const UART_t * const handle);
110 
111 
112 /**********************************************************************************************************************
113  * API IMPLEMENTATION
114  **********************************************************************************************************************/
115 
116 /*
117  * @brief API to retrieve the version of the UART APP.
118  *
119  * @return DAVE_APP_VERSION_t Structure containing major version, minor version
120  * and patch version.
121  */
122 DAVE_APP_VERSION_t UART_GetAppVersion()
123 {
124  DAVE_APP_VERSION_t version;
125 
126  version.major = UART_MAJOR_VERSION;
127  version.minor = UART_MINOR_VERSION;
128  version.patch = UART_PATCH_VERSION;
129 
130  return version;
131 }
132 
133 /*
134  * @brief Function to initialize the USIC Channel with GUI configured values.
135  *
136  * @param[in] handle UART APP handle pointer of type UART_t*
137  *
138  * @return UART_STATUS_t
139  * UART_SUCCESS: for successful UART initialization.<BR>
140  * UART_STATUS_FAILURE : If UART initialization fails.<BR>
141  *
142  */
143 UART_STATUS_t UART_Init(const UART_t *const handle)
144 {
146  XMC_ASSERT("UART_Init : UART APP handle invalid", (((handle != NULL)&&
147  (handle->config != NULL)) &&((handle->config->fptr_uart_config != NULL)&&
148  (handle->runtime != NULL))))
149 
150  /*Initialize the multiplexers required for UART configuration*/
151  status = handle->config->fptr_uart_config();
152 
153  return status;
154 }
155 
156 /*
157  * @brief Common function to transmit data.
158  *
159  * @param[in] handle UART APP handle pointer of type UART_t*
160  * @param[in] data_ptr Pointer to data of type uint8_t
161  * @param[in] count Number of uint8_t type bytes to be transmitted
162  *
163  * @return UART_STATUS_t
164  * UART_SUCCESS: If the data is put to transmit.<BR>
165  * UART_STATUS_BUSY : If the channel is busy.<BR>
166  * UART_STATUS_BUFFER_INVALID: Either if buffer is NULL or count is 0.<BR>
167  * UART_STATUS_MODE_MISMATCH: If the configured mode is invalid.<BR>
168  *
169  */
170 UART_STATUS_t UART_Transmit(const UART_t *const handle, uint8_t* data_ptr, uint32_t count)
171 {
173 
174  switch(handle->config->transmit_mode)
175  {
176 #ifdef UART_TX_INTERRUPT_USED
178  ret_stat = UART_StartTransmitIRQ(handle, data_ptr, count);
179  break;
180 #endif
181 #ifdef UART_TX_DMA_USED
183  ret_stat = UART_StartTransmitDMA(handle, data_ptr, count);
184  break;
185 #endif
186 #ifdef UART_TX_DIRECT_USED
188  ret_stat = UART_lStartTransmitPolling(handle, data_ptr, count);
189  break;
190 #endif
191  default:
192  break;
193  }
194  return ret_stat;
195 }
196 
197 /*
198  * @brief Common function to receive data.
199  *
200  * @param[in] handle UART APP handle pointer of type UART_t*
201  * @param[in] data_ptr Pointer to data of type uint8_t
202  * @param[in] count Number of uint8_t type bytes to be received
203  *
204  * @return UART_STATUS_t
205  * UART_SUCCESS: If the data is put to transmit.<BR>
206  * UART_STATUS_BUSY : If the channel is busy.<BR>
207  * UART_STATUS_BUFFER_INVALID: Either if buffer is NULL or count is 0.<BR>
208  * UART_STATUS_MODE_MISMATCH: If the configured mode is invalid.<BR>
209  *
210  */
211 UART_STATUS_t UART_Receive(const UART_t *const handle, uint8_t* data_ptr, uint32_t count)
212 {
214 
215  switch(handle->config->receive_mode)
216  {
217 #ifdef UART_RX_INTERRUPT_USED
219  ret_stat = UART_StartReceiveIRQ(handle, data_ptr, count);
220  break;
221 #endif
222 #ifdef UART_RX_DMA_USED
224  ret_stat = UART_StartReceiveDMA(handle, data_ptr, count);
225  break;
226 #endif
227 #ifdef UART_RX_DIRECT_USED
229  ret_stat = UART_lStartReceivePolling(handle, data_ptr, count);
230  break;
231 #endif
232  default:
233  break;
234  }
235  return ret_stat;
236 }
237 
238 #if (defined UART_TX_INTERRUPT_USED || defined UART_TX_DMA_USED)
239 /*
240  * @brief Common function to abort ongoing transmission.
241  *
242  * @param[in] handle UART APP handle pointer of type UART_t*
243  *
244  * @return UART_STATUS_t
245  * UART_SUCCESS: If the transmission is aborted.<BR>
246  * UART_STATUS_FAILURE: If the channel is not transmitting.<BR>
247  * UART_STATUS_MODE_MISMATCH: If the configured mode is Direct.<BR>
248  *
249  */
250 UART_STATUS_t UART_AbortTransmit(const UART_t *const handle)
251 {
253 #ifdef UART_TX_DMA_USED
254  const UART_DMA_CONFIG_t * ptr_dma_config = handle->config->transmit_dma_config;
255  XMC_DMA_t * ptr_gpdma = handle->config->global_dma->dma;
256 #endif
257 
258  XMC_ASSERT("UART_AbortTransmit: UART APP handle invalid", ((handle != NULL)&&
259  (handle->runtime != NULL)))
260 
261  /*Reset the user buffer pointer to null*/
262  handle->runtime->tx_busy = false;
263  handle->runtime->tx_data = NULL;
264 
265  switch(handle->config->transmit_mode)
266  {
267 #ifdef UART_TX_INTERRUPT_USED
269  /*Disable the transmit interrupts*/
270  if (handle->config->tx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
271  {
272  /*Disable the transmit FIFO event*/
273  XMC_USIC_CH_TXFIFO_DisableEvent(handle->channel,(uint32_t)XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);
274  XMC_USIC_CH_TXFIFO_Flush(handle->channel);
275  }
276  else
277  {
278  /*Disable the standard transmit event*/
279  XMC_USIC_CH_DisableEvent(handle->channel, (uint32_t)XMC_USIC_CH_EVENT_TRANSMIT_BUFFER);
280  }
281  XMC_USIC_CH_SetTransmitBufferStatus(handle->channel, XMC_USIC_CH_TBUF_STATUS_SET_IDLE);
282  break;
283 #endif
284 #ifdef UART_TX_DMA_USED
286  /*Disable the standard transmit event*/
287  if (XMC_DMA_CH_IsEnabled(ptr_gpdma, ptr_dma_config->dma_channel))
288  {
289  XMC_DMA_CH_Disable(ptr_gpdma, ptr_dma_config->dma_channel);
290  while(XMC_DMA_CH_IsEnabled(ptr_gpdma, ptr_dma_config->dma_channel)==true)
291  {
292  }
293  XMC_USIC_CH_DisableEvent(handle->channel, (uint32_t)XMC_USIC_CH_EVENT_TRANSMIT_BUFFER);
294  }
295  XMC_USIC_CH_SetTransmitBufferStatus(handle->channel, XMC_USIC_CH_TBUF_STATUS_SET_IDLE);
296  break;
297 #endif
298  default:
299  ret_stat = UART_STATUS_MODE_MISMATCH;
300  break;
301  }
302  return ret_stat;
303 }
304 #endif
305 
306 #if (defined UART_RX_INTERRUPT_USED || defined UART_RX_DMA_USED)
307 /*
308  * @brief Common function to abort ongoing reception.
309  *
310  * @param[in] handle UART APP handle pointer of type UART_t*
311  *
312  * @return UART_STATUS_t
313  * UART_SUCCESS: If the reception is aborted.<BR>
314  * UART_STATUS_FAILURE : If the channel is not busy.<BR>
315  * UART_STATUS_MODE_MISMATCH: If the configured mode is Direct.<BR>
316  *
317  */
318 UART_STATUS_t UART_AbortReceive(const UART_t *const handle)
319 {
321 #ifdef UART_RX_DMA_USED
322  const UART_DMA_CONFIG_t * ptr_dma_config = handle->config->receive_dma_config;
323  XMC_DMA_t * ptr_gpdma = handle->config->global_dma->dma;
324 #endif
325  XMC_ASSERT("UART_AbortReceive: UART APP handle invalid", ((handle != NULL)&&
326  (handle->runtime != NULL)))
327 
328  /*Reset the user buffer pointer to null*/
329  handle->runtime->rx_busy = false;
330  handle->runtime->rx_data = NULL;
331  switch(handle->config->receive_mode)
332  {
333 #ifdef UART_RX_INTERRUPT_USED
335  /*Disable the receive interrupts*/
336  if (handle->config->rx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
337  {
338  XMC_USIC_CH_RXFIFO_DisableEvent(handle->channel,
339  ((uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD |
340  (uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE));
341  }
342  else
343  {
344  XMC_UART_CH_DisableEvent(handle->channel,
345  ((uint32_t)XMC_USIC_CH_EVENT_STANDARD_RECEIVE |
346  (uint32_t)XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE));
347  }
348  break;
349 #endif
350 #ifdef UART_RX_DMA_USED
352  /*Disable the receive interrupts*/
353  if (XMC_DMA_CH_IsEnabled(ptr_gpdma, ptr_dma_config->dma_channel))
354  {
355  XMC_DMA_CH_Disable(ptr_gpdma, ptr_dma_config->dma_channel);
356  while(XMC_DMA_CH_IsEnabled(ptr_gpdma, ptr_dma_config->dma_channel)==true)
357  {
358  }
359  XMC_UART_CH_DisableEvent(handle->channel,
360  ((uint32_t)XMC_USIC_CH_EVENT_STANDARD_RECEIVE |
361  (uint32_t)XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE));
362  }
363  break;
364 #endif
365  default:
366  ret_stat = UART_STATUS_MODE_MISMATCH;
367  break;
368  }
369  return ret_stat;
370 }
371 #endif
372 
373 /*
374  * @brief Changes the baudrate of UART channel.
375  *
376  * @param UART_t * Pointer to the UART APP handle.
377  * @param baud Value of new baudrate.
378  * @param oversampling Number of samples to be considered for each symbol. 16 is the standard value.
379  *
380  * @return UART_STATUS_t UART_STATUS_SUCCESS if baudrate changed successfully.
381  * UART_STATUS_BUSY if the UART channel is busy.
382  *
383  * \par<b>Description:</b><br>
384  * The function stops the channel, calculates the clock divider values to achieve the desired baudrate.
385  * Sets the divider values and reconfigures the channel as per the configuration in the UI. The channel is
386  * enabled at the end of configuration.
387  */
388 UART_STATUS_t UART_SetBaudrate(const UART_t * handle, uint32_t baud, uint32_t oversampling)
389 {
390  UART_STATUS_t ret_stat = UART_STATUS_BUSY;
391  const UART_TX_CONFIG_t * ptr_tx_conf = handle->config->tx_pin_config;
392 
393  XMC_ASSERT("UART_SetBaudrate: UART APP handle invalid", ((handle != NULL)&&
394  ((handle->config != NULL) && (handle->runtime != NULL))))
395 
396  if ((handle->runtime->tx_busy == false) && (handle->runtime->rx_busy == false))
397  {
398  /* Set UART TX pin as input pin to avoid spikes on the pin.*/
399  if (handle->config->mode != UART_MODE_LOOPBACK)
400  {
401  XMC_GPIO_SetMode(ptr_tx_conf->port, ptr_tx_conf->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
402  }
403  /* Stop the UART channel before changing the baudrate.*/
404  if (XMC_UART_CH_Stop(handle->channel) == XMC_UART_CH_STATUS_OK)
405  {
406  /*Change the baudrate*/
407  ret_stat = (UART_STATUS_t)XMC_UART_CH_SetBaudrate(handle->channel, baud, oversampling);
408  /*Set the sample point if the baudrate is modified*/
409  if (ret_stat == UART_STATUS_SUCCESS)
410  {
411  XMC_UART_CH_SetSamplePoint(handle->channel, (uint32_t)(oversampling >> 1U)+1U);
412  }
413  /*Enable UART*/
414  XMC_UART_CH_Start(handle->channel);
415  /* Initialize UART TX pin */
416  if (handle->config->mode != UART_MODE_LOOPBACK)
417  {
418  XMC_GPIO_Init(ptr_tx_conf->port, ptr_tx_conf->pin, ptr_tx_conf->config);
419  }
420  }
421  else
422  {
423  ret_stat = UART_STATUS_BUSY;
424  }
425  }
426  return ret_stat;
427 }
428 
429 #ifdef UART_TX_INTERRUPT_USED
430 /*
431  * @brief Registers a request for transmitting data over UART channel.
432  *
433  * @param[in] UART_t* UART APP handle pointer of type UART_t
434  * @param[in] uint8_t* Pointer to data
435  * @param[in] uint32_t Total no of words to be transmitted.
436  *
437  * @return UART_STATUS_t UART_STATUS_SUCCESS if the request is accepted.
438  * UART_STATUS_BUSY if a transmission is in progress.
439  * Details of function:
440  * The data transmission is accomplished using transmit interrupt. User can configure
441  * a callback function in the APP UI. When the data is fully transmitted, the callback
442  * function will be executed. If transmit FIFO is enabled, the trigger limit is set to 0.
443  * So the transmit interrupt will be generated when all the data in FIFO is moved from FIFO.
444  *
445  * <i>Imp Note:</i> Return value should be validated by user to ensure that the
446  * request is registered.
447  *
448  *
449  */
450 UART_STATUS_t UART_StartTransmitIRQ(const UART_t *const handle, uint8_t* data_ptr, uint32_t count)
451 {
453  UART_RUNTIME_t * ptr_runtime = handle->runtime;
454 
455  XMC_ASSERT("UART_StartTransmitIRQ: UART APP handle invalid", ((handle != NULL)&&
456  (handle->runtime != NULL)))
457 
458  if (handle->config->transmit_mode == UART_TRANSFER_MODE_INTERRUPT)
459  {
460  ret_stat = UART_STATUS_BUSY;
461  if (ptr_runtime->tx_busy == false)
462  {
463  /*If there is no transmission in progress*/
464  if ((data_ptr != NULL) && (count > 0U))
465  {
466  /*Obtain the address of data, size of data*/
467  ptr_runtime->tx_data = data_ptr;
468  ptr_runtime->tx_data_count = count;
469  /*Initialize to first index and set the busy flag*/
470  ptr_runtime->tx_data_index = 0U;
471  ptr_runtime->tx_busy = true;
472 
473  /*Enable the transmit buffer event*/
474  if (handle->config->tx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
475  {
476  /*Clear the transmit FIFO*/
477  XMC_USIC_CH_TXFIFO_Flush(handle->channel);
478  /*Enable transmit buffer interrupt*/
479  XMC_USIC_CH_TXFIFO_EnableEvent(handle->channel,(uint32_t)XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);
480  }
481  else
482  {
483  XMC_USIC_CH_EnableEvent(handle->channel, (uint32_t)XMC_USIC_CH_EVENT_TRANSMIT_BUFFER);
484  }
485  ret_stat = UART_STATUS_SUCCESS;
486  /*Trigger the transmit buffer interrupt*/
487  XMC_USIC_CH_TriggerServiceRequest(handle->channel, (uint32_t)handle->config->tx_sr);
488  }
489  else
490  {
491  ret_stat = UART_STATUS_BUFFER_INVALID;
492  }
493  }
494  }
495  return ret_stat;
496 }
497 #endif
498 
499 #ifdef UART_RX_INTERRUPT_USED
500 /*
501  * @brief Registers a request to receive data over UART channel.
502  *
503  * @param[in] UART_t* UART APP handle pointer of type UART_t
504  * @param[in] uint8_t* Pointer to data array
505  * @param[in] uint32_t Total no of bytes to be read.
506  *
507  * @return UART_STATUS_t UART_STATUS_SUCCESS if the request is accepted.
508  * UART_STATUS_BUSY if a reception is in progress.
509  * Details of function:
510  * This function registers the receive request by configuring the UART
511  * receive FIFO/Standard buffer (depending on the user configuration). The data
512  * is received asynchronously. When the requested number of data bytes are received,
513  * optionally, the user configured callback function will be executed. If a callback
514  * function is not configured on the APP UI, the user has to poll for the status of
515  * rx_busy variable of the APP handle structure.
516  *
517  * <i>Imp Note:</i> Return value should be validated by user to ensure that the
518  * request is registered.
519  *
520  *
521  */
522 UART_STATUS_t UART_StartReceiveIRQ(const UART_t *const handle, uint8_t* data_ptr, uint32_t count)
523 {
525  UART_RUNTIME_t * ptr_runtime = handle->runtime;
526 
527  XMC_ASSERT("UART_StartReceiveIRQ: UART APP handle invalid", ((handle != NULL)&&
528  (handle->runtime != NULL)))
529 
530  if (handle->config->receive_mode == UART_TRANSFER_MODE_INTERRUPT)
531  {
532  ret_stat = UART_STATUS_BUSY;
533  if (ptr_runtime->rx_busy == false)
534  {
535  /*If no active reception in progress*/
536  if ((data_ptr != NULL) && (count > 0U))
537  {
538  /*Obtain the address of data buffer and
539  * number of data bytes to be received*/
540  ptr_runtime->rx_data = data_ptr;
541  ptr_runtime->rx_data_count = count;
542  ptr_runtime->rx_busy = true;
543  ptr_runtime->rx_data_index = 0U;
544 
545  if (handle->config->rx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
546  {
547  /*Clear the receive FIFO, configure the trigger lime
548  * and enable the receive events*/
549  XMC_USIC_CH_RXFIFO_Flush(handle->channel);
550 
551  /*Configure the FIFO trigger limit based on the required data size*/
552  UART_lReconfigureRxFIFO(handle, count);
553 
554  XMC_USIC_CH_RXFIFO_EnableEvent(handle->channel,
555  (uint32_t)((uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD |
556  (uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE));
557  }
558  else
559  {
560  XMC_USIC_CH_EnableEvent(handle->channel,
561  (uint32_t)((uint32_t)XMC_USIC_CH_EVENT_STANDARD_RECEIVE | (uint32_t)XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE));
562  }
563  ret_stat = UART_STATUS_SUCCESS;
564  }
565  else
566  {
567  ret_stat = UART_STATUS_BUFFER_INVALID;
568  }
569  }
570  }
571  return ret_stat;
572 }
573 #endif
574 
575 #ifdef UART_TX_DMA_USED
576 /*
577  * @brief Registers a request for transmitting data over UART channel using DMA.
578  *
579  * @param[in] UART_t* UART APP handle pointer of type UART_t
580  * @param[in] uint8_t* Pointer to data
581  * @param[in] uint32_t Total no of words to be transmitted.
582  *
583  * @return UART_STATUS_t UART_STATUS_SUCCESS if the request is accepted.
584  * UART_STATUS_BUSY if a transmission is in progress.
585  * Details of function:
586  * The data transmission is accomplished using a DMA channel. User can configure
587  * a callback function in the APP UI. When the data is fully transmitted, the callback
588  * function will be executed.
589  * <i>Imp Note:</i> Return value should be validated by user to ensure that the
590  * request is registered.
591  *
592  *
593  */
594 UART_STATUS_t UART_StartTransmitDMA(const UART_t *const handle, uint8_t* data_ptr, uint32_t count)
595 {
597  UART_RUNTIME_t * ptr_runtime = handle->runtime;
598  const UART_DMA_CONFIG_t * ptr_dma_config = handle->config->transmit_dma_config;
599  XMC_DMA_t * ptr_gpdma = handle->config->global_dma->dma;
600 
601  XMC_ASSERT("UART_StartTransmitDMA: UART APP handle invalid", (((handle != NULL)&&
602  (handle->runtime != NULL))&&(handle->config != NULL)))
603 
604  if (handle->config->transmit_mode == UART_TRANSFER_MODE_DMA)
605  {
606  ret_stat = UART_STATUS_BUSY;
607  if (ptr_runtime->tx_busy == false)
608  {
609  /*If there is no transmission in progress*/
610  if ((data_ptr != NULL) && ((count > 0U) &&(count <= UART_DMA_MAXCOUNT)))
611  {
612  /*Obtain the address of data, size of data*/
613  ptr_runtime->tx_data = data_ptr;
614  ptr_runtime->tx_data_count = count;
615  /*Initialize to first index and set the busy flag*/
616  ptr_runtime->tx_data_index = 0U;
617  ptr_runtime->tx_busy = true;
618 
619  /*Enable transmit event generation*/
620  XMC_UART_CH_EnableEvent(handle->channel, (uint32_t)XMC_UART_CH_EVENT_TRANSMIT_BUFFER);
621  ret_stat = UART_STATUS_SUCCESS;
622 
623  /*Enable DMA channel*/
624  XMC_DMA_CH_SetBlockSize(ptr_gpdma, ptr_dma_config->dma_channel, count);
625  XMC_DMA_CH_SetSourceAddress(ptr_gpdma, ptr_dma_config->dma_channel, (uint32_t)data_ptr);
626  XMC_DMA_CH_SetDestinationAddress(ptr_gpdma, ptr_dma_config->dma_channel,
627  (uint32_t)&(handle->channel->TBUF[0]));
628  XMC_DMA_CH_Enable(ptr_gpdma, ptr_dma_config->dma_channel);
629  }
630  else
631  {
632  ret_stat = UART_STATUS_BUFFER_INVALID;
633  }
634  }
635  }
636  return ret_stat;
637 }
638 #endif
639 
640 #ifdef UART_RX_DMA_USED
641 /*
642  * @brief Registers a request to receive data over UART channel using DMA.
643  *
644  * @param[in] UART_t* UART APP handle pointer of type UART_t
645  * @param[in] uint8_t* Pointer to data array
646  * @param[in] uint32_t Total no of bytes to be read.
647  *
648  * @return UART_STATUS_t UART_STATUS_SUCCESS if the request is accepted.
649  * UART_STATUS_BUSY if a reception is in progress.
650  * Details of function:
651  * This function registers the receive request by configuring the UART
652  * receive Standard buffer and the DMA channel. The data
653  * is received asynchronously. When the requested number of data bytes are received,
654  * optionally, the user configured callback function will be executed.
655  *
656  * <i>Imp Note:</i> Return value should be validated by user to ensure that the
657  * request is registered.
658  *
659  *
660  */
661 UART_STATUS_t UART_StartReceiveDMA(const UART_t *const handle, uint8_t* data_ptr, uint32_t count)
662 {
664  UART_RUNTIME_t * ptr_runtime = handle->runtime;
665  const UART_DMA_CONFIG_t * ptr_dma_config = handle->config->receive_dma_config;
666  XMC_DMA_t * ptr_gpdma = handle->config->global_dma->dma;
667 
668  XMC_ASSERT("UART_StartReceiveDMA: UART APP handle invalid", (((handle != NULL)&&
669  (handle->runtime != NULL)) && (handle->config != NULL)))
670 
671  if (handle->config->receive_mode == UART_TRANSFER_MODE_DMA)
672  {
673  ret_stat = UART_STATUS_BUSY;
674  if (ptr_runtime->rx_busy == false)
675  {
676  /*If no active reception in progress*/
677  if ((data_ptr != NULL) && ((count > 0U) && (count <= UART_DMA_MAXCOUNT)))
678  {
679  /*Obtain the address of data buffer and
680  * number of data bytes to be received*/
681  ptr_runtime->rx_data = data_ptr;
682  ptr_runtime->rx_data_count = count;
683  ptr_runtime->rx_busy = true;
684  ptr_runtime->rx_data_index = 0U;
685 
686  XMC_USIC_CH_EnableEvent(handle->channel,
687  (uint32_t)((uint32_t)XMC_USIC_CH_EVENT_STANDARD_RECEIVE | (uint32_t)XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE));
688  ret_stat = UART_STATUS_SUCCESS;
689 
690  /*Enable DMA channel*/
691  XMC_DMA_CH_SetBlockSize(ptr_gpdma, ptr_dma_config->dma_channel, count);
692  XMC_DMA_CH_SetSourceAddress(ptr_gpdma, ptr_dma_config->dma_channel, (uint32_t)&(handle->channel->RBUF));
693  XMC_DMA_CH_SetDestinationAddress(ptr_gpdma, ptr_dma_config->dma_channel, (uint32_t)data_ptr);
694  XMC_DMA_CH_Enable(ptr_gpdma, ptr_dma_config->dma_channel);
695  }
696  else
697  {
698  ret_stat = UART_STATUS_BUFFER_INVALID;
699  }
700  }
701  }
702  return ret_stat;
703 }
704 #endif
705 
706 #ifdef UART_TX_DIRECT_USED
707 /*
708  * Polling method to transmit data.
709  * @param[in] UART_t* handle UART APP handle pointer
710  * @param[in] uint8_t* Pointer to data array
711  * @param[in] uint32_t number of bytes to be transmitted.
712  *
713  * @return UART_STATUS_t Status of transmit request handling.
714  *
715  * Description:
716  * Transmits data by blocking the CPU until all data is sent. Transmission
717  * cannot be aborted since it is blocking implementation. Based on FIFO selection,
718  * either TBUF or IN register is updated with the data.
719  *
720  */
721 static UART_STATUS_t UART_lStartTransmitPolling(const UART_t *const handle, uint8_t* data_ptr, uint32_t count)
722 {
724  uint32_t loc_index;
725 
726  XMC_ASSERT("UART_Transmit: UART APP handle invalid", (((handle != NULL)&&
727  (handle->runtime != NULL))&&(handle->config != NULL)))
728 
729  if ((data_ptr != NULL) && (count > 0U))
730  {
731  ret_stat = UART_STATUS_BUSY;
732  if (handle->runtime->tx_busy == false)
733  {
734  handle->runtime->tx_busy = true;
735  if (handle->config->tx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
736  {
737  /*Clear the transmit FIFO*/
738  XMC_USIC_CH_TXFIFO_Flush(handle->channel);
739  }
740  /*Loop through each byte*/
741  for (loc_index = 0U; loc_index < count; loc_index++)
742  {
743  /*If FIFO is enabled, FIFO filling status should be checked
744  * to avoid overflow error*/
745  if (handle->config->tx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
746  {
747  /*Wait if transmit FIFO is full*/
748  while (XMC_USIC_CH_TXFIFO_IsFull(handle->channel) == true)
749  {
750  }
751  }
752  XMC_UART_CH_Transmit(handle->channel, (uint16_t)data_ptr[loc_index]);
753  }
754 
755  if (handle->config->tx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
756  {
757  /*Wait till FIFO is empty*/
758  while (XMC_USIC_CH_TXFIFO_IsEmpty(handle->channel) == false)
759  {
760  }
761  }
762  ret_stat = UART_STATUS_SUCCESS;
763  handle->runtime->tx_busy = false;
764  }
765  }
766  return ret_stat;
767 }
768 #endif
769 
770 #ifdef UART_RX_DIRECT_USED
771 /*
772  * Polling method to receive data.
773  * @param[in] UART_t* handle UART APP handle pointer
774  * @param[in] uint8_t* Pointer to data array
775  * @param[in] uint32_t number of bytes to be received.
776  *
777  * @return UART_STATUS_t Status of receive request handling.
778  *
779  * Description:
780  * Receives data by blocking the CPU until all data is received. Reception
781  * cannot be aborted since it is blocking implementation. Based on FIFO selection,
782  * either RBUF or OUT register will be read.
783  *
784  */
785 static UART_STATUS_t UART_lStartReceivePolling(const UART_t *const handle, uint8_t* data_ptr, uint32_t count)
786 {
788  uint32_t loc_index;
789  uint32_t loc_status;
790 
791  XMC_ASSERT("UART_Receive: UART APP handle invalid", ((handle != NULL)&&
792  (handle->runtime != NULL)))
793 
794  if ((data_ptr != NULL) && (count > 0U))
795  {
796  ret_stat = UART_STATUS_BUSY;
797  if (handle->runtime->rx_busy == false)
798  {
799  handle->runtime->rx_busy = true;
800  if (handle->config->rx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
801  {
802  /*Clear the receive FIFO, configure the trigger lime
803  * and enable the receive events*/
804  XMC_USIC_CH_RXFIFO_Flush(handle->channel);
805  }
806  for (loc_index = 0U; loc_index < count; loc_index++)
807  {
808  /*If receive FIFO is configured, wait for FIFO to get data.*/
809  if (handle->config->rx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
810  {
811  /*Wait if FIFO empty*/
812  while(XMC_USIC_CH_RXFIFO_IsEmpty(handle->channel) == true)
813  {
814  }
815  }
816  else
817  {
818  /*Wait for RIF or AIF flag update*/
819  loc_status = XMC_UART_CH_GetStatusFlag(handle->channel);
820  while (!(loc_status & ((uint32_t)XMC_UART_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION |
821  (uint32_t)XMC_UART_CH_STATUS_FLAG_RECEIVE_INDICATION)))
822  {
823  loc_status = XMC_UART_CH_GetStatusFlag(handle->channel);
824  }
825  /*Clear the detected event.
826  * Both events should not be cleared at once, otherwise if 2 bytes are received, only
827  * one byte will be read.*/
828  XMC_UART_CH_ClearStatusFlag(handle->channel,
829  ((uint32_t)XMC_UART_CH_STATUS_FLAG_RECEIVE_INDICATION | (uint32_t)XMC_UART_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION));
830  }
831  data_ptr[loc_index] = (uint8_t)XMC_UART_CH_GetReceivedData(handle->channel);
832  }
833  ret_stat = UART_STATUS_SUCCESS;
834  handle->runtime->rx_busy = false;
835  }
836  }
837  return ret_stat;
838 }
839 #endif
840 
841 #ifdef UART_TX_INTERRUPT_USED
842 /*
843  * Transmit interrupt handler for the APP.
844  * This is a common interrupt handling function called for different instances of the APP.
845  *
846  * * param[in] handle UART APP handle pointer of type UART_t*
847  *
848  * * return void
849  */
850 void UART_lTransmitHandler(const UART_t * const handle)
851 {
852  UART_RUNTIME_t * ptr_runtime = handle->runtime;
853 
854  if (ptr_runtime->tx_data_index < ptr_runtime->tx_data_count)
855  {
856  if (handle->config->tx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
857  {
858  /*When Transmit FIFO is enabled*/
859  /*Fill the transmit FIFO */
860  while (XMC_USIC_CH_TXFIFO_IsFull(handle->channel) == false)
861  {
862  if (ptr_runtime->tx_data_index < ptr_runtime->tx_data_count)
863  {
864  /*Load the FIFO byte by byte till either FIFO is full or all data is loaded*/
865  XMC_UART_CH_Transmit(handle->channel,(uint16_t)ptr_runtime->tx_data[ptr_runtime->tx_data_index]);
866  (ptr_runtime->tx_data_index)++;
867  }
868  else
869  {
870  break;
871  }
872  }
873  }
874  else
875  {
876  /*When Transmit FIFO is disabled*/
877  XMC_UART_CH_Transmit(handle->channel,(uint16_t)ptr_runtime->tx_data[ptr_runtime->tx_data_index]);
878  (ptr_runtime->tx_data_index)++;
879  }
880  }
881  else
882  {
883  if (XMC_USIC_CH_TXFIFO_IsEmpty(handle->channel) == true)
884  {
885  if (handle->config->tx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
886  {
887  /*Disable the transmit FIFO event*/
888  XMC_USIC_CH_TXFIFO_DisableEvent(handle->channel,(uint32_t)XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);
889  }
890  else
891  {
892  /*Disable the standard transmit event*/
893  XMC_USIC_CH_DisableEvent(handle->channel, (uint32_t)XMC_USIC_CH_EVENT_TRANSMIT_BUFFER);
894  }
895 
896  /*Wait for the transmit buffer to be free to ensure that all data is transmitted*/
897  while (XMC_USIC_CH_GetTransmitBufferStatus(handle->channel) == XMC_USIC_CH_TBUF_STATUS_BUSY)
898  {
899 
900  }
901  /*All data is transmitted*/
902  ptr_runtime->tx_busy = false;
903  ptr_runtime->tx_data = NULL;
904 
905  if (handle->config->tx_cbhandler != NULL)
906  {
907  /*Execute the callback function provided in the UART APP UI*/
908  handle->config->tx_cbhandler();
909  }
910  }
911  }
912 }
913 #endif
914 
915 #ifdef UART_RX_INTERRUPT_USED
916 /*
917  * Receive interrupt handler for the APP.
918  * This is a common interrupt handling function for different instances of the UART APP.
919  *
920  * param[in] handle UART APP handle pointer of type UART_t*
921  *
922  * return void
923  */
924 void UART_lReceiveHandler(const UART_t * const handle)
925 {
926  UART_RUNTIME_t * ptr_runtime = handle->runtime;
927 
928  if (handle->config->rx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
929  {
930  /*When Receive FIFO is enabled*/
931  while (XMC_USIC_CH_RXFIFO_IsEmpty(handle->channel) == false)
932  {
933  if (ptr_runtime->rx_data_index < ptr_runtime->rx_data_count)
934  {
935  /*Read all the content of Receive FIFO */
936  ptr_runtime->rx_data[ptr_runtime->rx_data_index] = (uint8_t)XMC_UART_CH_GetReceivedData(handle->channel);
937  (ptr_runtime->rx_data_index)++;
938  }
939 
940  if (ptr_runtime->rx_data_index == ptr_runtime->rx_data_count)
941  {
942  /*Reception complete*/
943  ptr_runtime->rx_busy = false;
944  /*Disable both standard receive and alternative receive FIFO events*/
945  XMC_USIC_CH_RXFIFO_DisableEvent(handle->channel,
946  (uint32_t)((uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD |
947  (uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE));
948  if (handle->config->rx_cbhandler != NULL)
949  {
950  /*Execute the 'End of reception' callback function*/
951  handle->config->rx_cbhandler();
952  }
953  break;
954  }
955  }
956  /*Set the trigger limit if data still to be received*/
957  if (ptr_runtime->rx_data_index < ptr_runtime->rx_data_count)
958  {
959  UART_lReconfigureRxFIFO(handle,
960  (uint32_t)(ptr_runtime->rx_data_count - ptr_runtime->rx_data_index));
961  }
962  }
963  else
964  {
965  /*When RxFIFO is disabled*/
966  if (ptr_runtime->rx_data_index < ptr_runtime->rx_data_count)
967  {
968  ptr_runtime->rx_data[ptr_runtime->rx_data_index] = (uint8_t)XMC_UART_CH_GetReceivedData(handle->channel);
969  (ptr_runtime->rx_data_index)++;
970  }
971 
972  if (ptr_runtime->rx_data_index == ptr_runtime->rx_data_count)
973  {
974  /*Reception complete*/
975  ptr_runtime->rx_busy = false;
976  /*Disable both standard receive and alternative receive FIFO events*/
977  XMC_USIC_CH_DisableEvent(handle->channel,
978  (uint32_t)((uint32_t)XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE | (uint32_t)XMC_USIC_CH_EVENT_STANDARD_RECEIVE));
979 
980  if (handle->config->rx_cbhandler != NULL)
981  {
982  /*Execute the 'End of reception' callback function*/
983  handle->config->rx_cbhandler();
984  }
985  }
986  }
987 }
988 
989 /*
990  * A local function to reconfigure Receive FIFO with the given size and trigger limit.
991  * Size is needed because the FIFO should be disabled before changing the trigger limit by
992  * clearing the FIFO size.
993  *
994  * param[in] UART_t * pointer to the UART APP handle
995  * param[in] uint8_t number of bytes to be received.
996  *
997  * return void.
998  */
999 static void UART_lReconfigureRxFIFO(const UART_t * const handle, uint32_t data_size)
1000 {
1001  uint32_t fifo_size;
1002  uint32_t ret_limit_val = 0U;
1003 
1004  /*Get FIFO size in bytes*/
1005  fifo_size = (uint32_t)(0x01UL << (uint8_t)(handle->config->rx_fifo_size));
1006  /*If data size is more than FIFO size, configure the limit to the FIFO size*/
1007  if (data_size < fifo_size)
1008  {
1009  ret_limit_val = (uint32_t)(data_size - 1U);
1010  }
1011  else
1012  {
1013  ret_limit_val = (uint32_t)(fifo_size - 1U);
1014  }
1015  /*Set the limit value*/
1016  XMC_USIC_CH_RXFIFO_SetSizeTriggerLimit(handle->channel,
1017  handle->config->rx_fifo_size, ret_limit_val);
1018 }
1019 #endif
1020 
1021 #ifdef UART_PROTOCOL_EVENT_USED
1022 /*
1023  * Protocol interrupt handling function.
1024  * The function is common for different instances of the UART APP.
1025  *
1026  * param[in] handle UART APP handle pointer of type UART_t*
1027  *
1028  * return void
1029  */
1030 void UART_lProtocolHandler(const UART_t * const handle)
1031 {
1032  /*Protocol status value to check which event occured*/
1033  uint32_t psr_status = XMC_UART_CH_GetStatusFlag(handle->channel);
1034  /*Protocol event configuration to check which event is
1035  * configured for interrupt generation and hence callback*/
1036  uint32_t pcr_conf = handle->channel->PCR_ASCMode;
1037  /*Array of callback functions in the order of events*/
1038  const UART_cbhandler callback_arr[UART_EVENT_MAX] = {
1039  handle->config->sync_error_cbhandler,
1044  };
1045  UART_EVENT_t loc_index;
1046 
1047  for (loc_index = UART_EVENT_SYNC_BRK; loc_index < UART_EVENT_MAX; loc_index++)
1048  {
1049  /*Check if event is configured for interrupt generation and event has occured*/
1050  if ((pcr_conf & (uint32_t)uart_event_conf_flags[loc_index]) &&
1051  (psr_status & (uint32_t)uart_event_status_flags[loc_index]))
1052  {
1053  XMC_UART_CH_ClearStatusFlag(handle->channel, (uint32_t)uart_event_status_flags[(uint32_t)loc_index]);
1054  /*Call the callback function if it is valid*/
1055  if ((callback_arr[(uint32_t)loc_index] != NULL))
1056  {
1057  callback_arr[(uint32_t)loc_index]();
1058  }
1059  /*Process only one event*/
1060  break;
1061  }
1062  }
1063 }
1064 #endif