SPI_MASTER: SPI_MASTER.c Source File

SPI_MASTER

SPI_MASTER.c
Go to the documentation of this file.
1 
105 /***********************************************************************************************************************
106  * HEADER FILES
107  **********************************************************************************************************************/
108 #include "spi_master.h"
109 
110 
111 /***********************************************************************************************************************
112  * MACROS
113  **********************************************************************************************************************/
114 #define SPI_MASTER_WORD_LENGTH_8_BIT (8U) /* This is used to check while incrementing the data index */
115 #define SPI_MASTER_2_BYTES_PER_WORD (2U) /* Word length is 16-bits */
116 #define SPI_MASTER_1_BYTE_PER_WORD (1U) /* Word length is 8-bits */
117 
118 #define SPI_MASTER_RECEIVE_INDICATION_FLAG ((uint32_t)XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION | \
119  (uint32_t)XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION)
120 
121 #define SPI_MASTER_FIFO_RECEIVE_INDICATION_FLAG ((uint32_t)XMC_USIC_CH_RXFIFO_EVENT_STANDARD | \
122  (uint32_t)XMC_USIC_CH_RXFIFO_EVENT_ALTERNATE)
123 
124 #define SPI_MASTER_RECEIVE_EVENT ((uint32_t)XMC_SPI_CH_EVENT_STANDARD_RECEIVE | \
125  (uint32_t)XMC_SPI_CH_EVENT_ALTERNATIVE_RECEIVE)
126 
127 #define SPI_MASTER_FIFO_RECEIVE_EVENT ((uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD | \
128  (uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE)
129 /***********************************************************************************************************************
130  * LOCAL DATA
131 ***********************************************************************************************************************/
132 
133 
134 /***********************************************************************************************************************
135  * LOCAL ROUTINES
136  **********************************************************************************************************************/
137 #if (SPI_MASTER_INTERRUPT_TRANSMIT_MODE == 1U)
138 /* Transmit interrupt handler for the APP */
139 void SPI_MASTER_lTransmitHandler(const SPI_MASTER_t * const handle);
140 #endif
141 
142 #if (SPI_MASTER_INTERRUPT_RECEIVE_MODE == 1U)
143 static SPI_MASTER_STATUS_t SPI_MASTER_lReceiveIRQ(const SPI_MASTER_t *const handle, uint32_t count);
144 /* This is used to reconfigure the FIFO settings dynamically */
145 static void SPI_MASTER_lReconfigureRxFIFO(const SPI_MASTER_t * const handle, uint32_t data_size);
146 /* Read data from FIFO */
147 static void SPI_MASTER_lFIFORead(const SPI_MASTER_t * const handle, const uint32_t bytes_per_word);
148 /* Receive interrupt handler for the APP */
149 void SPI_MASTER_lReceiveHandler(const SPI_MASTER_t * const handle);
150 #endif
151 
152 #if(SPI_MASTER_DMA_RECEIVE_MODE == 1U)
153 static SPI_MASTER_STATUS_t SPI_MASTER_lReceiveDMA(const SPI_MASTER_t *const handle, uint32_t count);
154 #endif
155 
156 #if(SPI_MASTER_DIRECT_TRANSMIT_MODE == 1U)
157 static SPI_MASTER_STATUS_t SPI_MASTER_lStartTransmitPolling(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count);
158 #endif
159 
160 #if(SPI_MASTER_DIRECT_RECEIVE_MODE == 1U)
161 static SPI_MASTER_STATUS_t SPI_MASTER_lStartReceivePolling(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count);
162 static SPI_MASTER_STATUS_t SPI_MASTER_lReceivePolling(const SPI_MASTER_t *const handle, uint32_t count);
163 #endif
164 
165 #ifdef SPI_MASTER_PARITY_ERROR
166 /* Protocol interrupt handler for the APP */
167 void SPI_MASTER_lProtocolHandler(const SPI_MASTER_t * const handle);
168 #endif
169 
170 /* Flush RBUF0, RBUF1 */
171 static void SPI_MASTER_lStdRBUFFlush(XMC_USIC_CH_t *const channel);
172 
173 /* This is used to reconfigure the registers while changing the SPI mode dynamically */
174 static void SPI_MASTER_lPortConfig(const SPI_MASTER_t* handle);
175 /* Set the mode of the port pin according to the configuration */
176 static void SPI_MASTER_lPortModeSet(const SPI_MASTER_t* handle);
177 /* Set the mode of the port pin as input */
178 static void SPI_MASTER_lPortModeReset(const SPI_MASTER_t* handle);
179 /* Returns whether mode change is valid or not */
180 static SPI_MASTER_STATUS_t SPI_MASTER_lValidateModeChange(const SPI_MASTER_t * handle, XMC_SPI_CH_MODE_t mode);
181 /***********************************************************************************************************************
182  * API IMPLEMENTATION
183  **********************************************************************************************************************/
184 /*
185  * API to retrieve the version of the SPI_MASTER
186  */
187 DAVE_APP_VERSION_t SPI_MASTER_GetAppVersion()
188 {
189  DAVE_APP_VERSION_t version;
190 
191  version.major = SPI_MASTER_MAJOR_VERSION;
192  version.minor = SPI_MASTER_MINOR_VERSION;
193  version.patch = SPI_MASTER_PATCH_VERSION;
194 
195  return version;
196 }
197 
198 /*
199  * This function initializes the SPI channel, based on UI configuration.
200  */
202 {
203  SPI_MASTER_STATUS_t status;
204 
205  XMC_ASSERT("SPI_MASTER_Init:handle NULL" , (handle != NULL));
206 
207  /* Configure the port registers and data input registers of SPI channel */
208  status = handle->config->fptr_spi_master_config();
209 
210  return status;
211 }
212 
213 /*
214  * Change the SPI mode of communication.
215  */
217  const XMC_SPI_CH_MODE_t mode)
218 {
219  SPI_MASTER_STATUS_t status;
220 
221  XMC_ASSERT("SPI_MASTER_Configure:handle NULL" , (handle != NULL));
222 
223  status = SPI_MASTER_STATUS_SUCCESS;
224 
225  if ((false == handle->runtime->tx_busy) && (false == handle->runtime->rx_busy))
226  {
227  if (handle->runtime->spi_master_mode != mode)
228  {
229  status = SPI_MASTER_lValidateModeChange(handle, mode);
230 
231  if (SPI_MASTER_STATUS_SUCCESS == status)
232  {
233  handle->runtime->spi_master_mode = mode;
234 
235  /* This changes the operating mode and related settings */
236  SPI_MASTER_lPortConfig(handle);
237  }
238  }
239  }
240  else
241  {
242  status = SPI_MASTER_STATUS_BUSY;
243  }
244  return status;
245 }
246 
247 /*
248  * Set the baud rate during runtime.
249  */
250 SPI_MASTER_STATUS_t SPI_MASTER_SetBaudRate(SPI_MASTER_t* const handle, const uint32_t baud_rate)
251 {
252  SPI_MASTER_STATUS_t status;
253 
254  if ((false == handle->runtime->tx_busy) && (false == handle->runtime->rx_busy))
255  {
256  /* Stops the SPI channel */
257  status = (SPI_MASTER_STATUS_t)XMC_SPI_CH_Stop(handle->channel);
258 
259  if (SPI_MASTER_STATUS_SUCCESS == status)
260  {
261  /* Set all the pins as input */
262  SPI_MASTER_lPortModeReset(handle);
263 
264  /* Update the new baud rate */
265  status = (SPI_MASTER_STATUS_t)XMC_SPI_CH_SetBaudrate(handle->channel, baud_rate);
266 
267  if (SPI_MASTER_STATUS_SUCCESS == status)
268  {
269  /* Configure Leading/Trailing delay */
270  XMC_SPI_CH_SetSlaveSelectDelay(handle->channel, (uint32_t)handle->config->leading_trailing_delay);
271  }
272 
273  /* Configure the clock polarity and clock delay */
274  XMC_SPI_CH_ConfigureShiftClockOutput(handle->channel,
276  XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK);
277  /* Start the SPI channel */
278  XMC_SPI_CH_Start(handle->channel);
279 
280  /* Set the mode of the according the generated configuration */
281  SPI_MASTER_lPortModeSet(handle);
282  }
283  }
284  else
285  {
286  status = SPI_MASTER_STATUS_BUSY;
287  }
288 
289  return status;
290 }
291 
292 SPI_MASTER_STATUS_t SPI_MASTER_Transmit(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count)
293 {
294  SPI_MASTER_STATUS_t status;
295 
296  status = SPI_MASTER_STATUS_FAILURE;
297 
298 #if (SPI_MASTER_INTERRUPT_TRANSMIT_MODE == 1U)
300  {
301  status = SPI_MASTER_StartTransmitIRQ(handle, dataptr, count);
302  }
303 #endif
304 
305 #if (SPI_MASTER_DMA_TRANSMIT_MODE == 1U)
307  {
308  status = SPI_MASTER_StartTransmitDMA(handle, dataptr, count);
309  }
310 #endif
311 
312 #if (SPI_MASTER_DIRECT_TRANSMIT_MODE == 1U)
314  {
315  status = SPI_MASTER_lStartTransmitPolling(handle, dataptr, count);
316  }
317 #endif
318 
319  return status;
320 }
321 
322 SPI_MASTER_STATUS_t SPI_MASTER_Receive(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count)
323 {
324  SPI_MASTER_STATUS_t status;
325 
326  status = SPI_MASTER_STATUS_FAILURE;
327 
328 #if (SPI_MASTER_INTERRUPT_RECEIVE_MODE == 1U)
330  {
331  status = SPI_MASTER_StartReceiveIRQ(handle, dataptr, count);
332  }
333 #endif
334 
335 #if (SPI_MASTER_DMA_RECEIVE_MODE == 1U)
337  {
338  status = SPI_MASTER_StartReceiveDMA(handle, dataptr, count);
339  }
340 #endif
341 
342 #if (SPI_MASTER_DIRECT_RECEIVE_MODE == 1U)
344  {
345  status = SPI_MASTER_lStartReceivePolling(handle, dataptr, count);
346  }
347 #endif
348 
349  return status;
350 }
351 
352 #if (SPI_MASTER_INTERRUPT_TRANSMIT_MODE == 1U)
353 /*
354  * Transmit the number of data words specified.
355  */
356 SPI_MASTER_STATUS_t SPI_MASTER_StartTransmitIRQ(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count)
357 {
358  SPI_MASTER_STATUS_t status;
359  uint32_t bytes_per_word = SPI_MASTER_1_BYTE_PER_WORD; /* This is to support the word length 8 and 16.
360  Specify the number of bytes for the configured word length */
361  SPI_MASTER_RUNTIME_t * runtime_handle;
362 
363  XMC_ASSERT("SPI_MASTER_StartTransmitIRQ:handle NULL" , (handle != NULL));
364 
366  runtime_handle = handle->runtime;
367 
369  {
370  /* Check whether SPI channel is free or not */
371  if ((dataptr != NULL) && (count > 0U))
372  {
373  status = SPI_MASTER_STATUS_BUSY;
374  /*Check data pointer is valid or not*/
375  if (false == runtime_handle->tx_busy)
376  {
377  if (handle->runtime->word_length > SPI_MASTER_WORD_LENGTH_8_BIT)
378  {
379  bytes_per_word = SPI_MASTER_2_BYTES_PER_WORD; /* Word length is 16-bits */
380  }
381 
382  /* Obtain the address of data, size of data */
383  runtime_handle->tx_data = dataptr;
384  runtime_handle->tx_data_count = (uint32_t)count << (bytes_per_word - 1U);
385  /* Initialize to first index and set the busy flag */
386  runtime_handle->tx_data_index = 0U;
387  runtime_handle->tx_busy = true;
388 
389  /* Enable the transmit buffer event */
390  if ((uint32_t)handle->config->tx_fifo_size > 0U)
391  {
392  /* Flush the Transmit FIFO */
393  XMC_USIC_CH_TXFIFO_Flush(handle->channel);
394  XMC_USIC_CH_TXFIFO_EnableEvent(handle->channel,(uint32_t)XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);
395  }
396  else
397  {
398  XMC_USIC_CH_EnableEvent(handle->channel,(uint32_t)XMC_USIC_CH_EVENT_TRANSMIT_BUFFER);
399  }
400  XMC_SPI_CH_SetTransmitMode(handle->channel, runtime_handle->spi_master_mode);
401  status = SPI_MASTER_STATUS_SUCCESS;
402 
403  /* Trigger the transmit buffer interrupt */
404  XMC_USIC_CH_TriggerServiceRequest(handle->channel, (uint32_t)handle->config->tx_sr);
405  }
406  }
407  else
408  {
410  }
411  }
412  return status;
413 }
414 #endif
415 
416 #if(SPI_MASTER_DMA_TRANSMIT_MODE == 1U)
417 SPI_MASTER_STATUS_t SPI_MASTER_StartTransmitDMA(const SPI_MASTER_t *const handle, uint8_t *data_ptr, uint32_t block_size)
418 {
419  SPI_MASTER_STATUS_t status;
420  SPI_MASTER_RUNTIME_t * runtime_handle;
421  uint32_t dma_ctll;
422  uint32_t mode;
423 
424  XMC_ASSERT("SPI_MASTER_StartTransmitDMA:handle NULL" , (handle != NULL));
425 
427  runtime_handle = handle->runtime;
428 
430  {
431  /* Check whether SPI channel is free or not */
432  if (false == runtime_handle->tx_busy)
433  {
434  /* Check data pointer is valid or not */
435  if ((data_ptr != NULL) && (block_size > 0U) && (block_size <= SPI_MASTER_DMA_MAXCOUNT))
436  {
437  /* Obtain the address of data, size of data */
438  runtime_handle->tx_data_count = block_size;
439  /* Initialize to first index and set the busy flag */
440  runtime_handle->tx_data_index = 0U;
441  runtime_handle->tx_busy = true;
442 
443  if (runtime_handle->tx_data_dummy == true)
444  {
445  dma_ctll = (uint32_t)handle->global_dma->dma->CH[handle->dma_ch_tx_number].CTLL;
446 
447  dma_ctll = (uint32_t)(dma_ctll & (uint32_t)(~(GPDMA0_CH_CTLL_SINC_Msk))) |
448  ((uint32_t)XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE << GPDMA0_CH_CTLL_SINC_Pos);
449 
450  handle->global_dma->dma->CH[handle->dma_ch_tx_number].CTLL = dma_ctll;
451  mode = (uint32_t)((uint32_t)handle->runtime->spi_master_mode & 0xfffbU);
452  }
453  else
454  {
455  runtime_handle->tx_data = data_ptr;
456  dma_ctll = handle->global_dma->dma->CH[handle->dma_ch_tx_number].CTLL;
457 
458  dma_ctll = (uint32_t)(dma_ctll & (~GPDMA0_CH_CTLL_SINC_Msk)) |
459  ((uint32_t)XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT << GPDMA0_CH_CTLL_SINC_Pos);
460 
461  handle->global_dma->dma->CH[handle->dma_ch_tx_number].CTLL = dma_ctll;
462  mode = (uint32_t)handle->runtime->spi_master_mode;
463  }
464 
465  /* Enable transmit event generation */
466  XMC_SPI_CH_EnableEvent(handle->channel, (uint32_t)XMC_SPI_CH_EVENT_RECEIVE_START);
467 
468  XMC_DMA_CH_SetBlockSize(handle->global_dma->dma, handle->dma_ch_tx_number, block_size);
469 
470  XMC_DMA_CH_SetSourceAddress(handle->global_dma->dma, handle->dma_ch_tx_number, (uint32_t)runtime_handle->tx_data);
471 
472  XMC_SPI_CH_SetTransmitMode(handle->channel, runtime_handle->spi_master_mode);
473 
474  XMC_DMA_CH_SetDestinationAddress(handle->global_dma->dma,
475  handle->dma_ch_tx_number,
476  (uint32_t)&(handle->channel->TBUF[mode]));
477 
478  status = SPI_MASTER_STATUS_SUCCESS;
479 
480  XMC_DMA_CH_Enable(handle->global_dma->dma, handle->dma_ch_tx_number);
481  }
482  else
483  {
485  }
486  }
487  else
488  {
489  status = SPI_MASTER_STATUS_BUSY;
490  }
491  }
492 
493  return status;
494 }
495 #endif
496 
497 #if (SPI_MASTER_DIRECT_TRANSMIT_MODE == 1U)
498 SPI_MASTER_STATUS_t SPI_MASTER_lStartTransmitPolling(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count)
499 {
500  SPI_MASTER_STATUS_t status;
501  uint16_t data;
502  uint32_t bytes_per_word = SPI_MASTER_1_BYTE_PER_WORD;; /* This is to support the word length 8 and 16.
503  Specify the number of bytes for the configured word length */
504  SPI_MASTER_RUNTIME_t * runtime_handle;
505 
506  status = SPI_MASTER_STATUS_BUSY;
507  runtime_handle = handle->runtime;
508  data = 0U;
509 
510  XMC_ASSERT("SPI_MASTER_lStartTransmitPolling:handle NULL" , (handle != NULL));
511 
512  /* Check whether SPI channel is free or not */
513  if ((dataptr != NULL) && (count > 0U))
514  {
515  /* Check data pointer is valid or not */
516  if (false == runtime_handle->tx_busy)
517  {
518  if (handle->runtime->word_length > SPI_MASTER_WORD_LENGTH_8_BIT)
519  {
520  bytes_per_word = SPI_MASTER_2_BYTES_PER_WORD; /* Word length is 16-bits */
521  }
522 
523  runtime_handle->tx_busy = true;
524  /* Obtain the address of data, size of data */
525  runtime_handle->tx_data = dataptr;
526  runtime_handle->tx_data_count = (uint32_t)count << (bytes_per_word - 1U);
527  /* Initialize to first index and set the busy flag */
528  runtime_handle->tx_data_index = 0U;
529 
530  XMC_SPI_CH_SetTransmitMode(handle->channel, runtime_handle->spi_master_mode);
531 
532  if ((uint32_t)handle->config->tx_fifo_size > 0U)
533  {
534  /* Flush the Transmit FIFO */
535  XMC_USIC_CH_TXFIFO_Flush(handle->channel);
536 
537  while (runtime_handle->tx_data_index < runtime_handle->tx_data_count)
538  {
539  while (XMC_USIC_CH_TXFIFO_IsFull(handle->channel) == true)
540  {
541  /* Wait until FIFO is having space for next entry */
542  }
543  if (runtime_handle->tx_data_dummy == true)
544  {
545  XMC_USIC_CH_TXFIFO_PutDataHPCMode(handle->channel, 0xFFFFU, (uint32_t)runtime_handle->spi_master_mode);
546  }
547  else
548  {
549  if(bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
550  {
551  data = *((uint16_t*)&runtime_handle->tx_data[runtime_handle->tx_data_index]);
552  }
553  else
554  {
555  data = runtime_handle->tx_data[runtime_handle->tx_data_index];
556  }
557  XMC_USIC_CH_TXFIFO_PutDataHPCMode(handle->channel, data, (uint32_t)runtime_handle->spi_master_mode);
558  }
559  (runtime_handle->tx_data_index)+= bytes_per_word;
560  }
561  }
562  else
563  {
564  do
565  {
566  while((uint32_t)XMC_USIC_CH_GetTransmitBufferStatus(handle->channel) == (uint32_t)XMC_USIC_CH_TBUF_STATUS_BUSY)
567  {
568  }
569 
570  if (runtime_handle->tx_data_dummy == true)
571  {
572  XMC_USIC_CH_WriteToTBUFTCI(handle->channel, 0xFFFFU, runtime_handle->spi_master_mode);
573  }
574  else
575  {
576  if(bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
577  {
578  data = *((uint16_t*)&runtime_handle->tx_data[runtime_handle->tx_data_index]);
579  }
580  else
581  {
582  data = runtime_handle->tx_data[runtime_handle->tx_data_index];
583  }
584  XMC_USIC_CH_WriteToTBUFTCI(handle->channel, data, runtime_handle->spi_master_mode);
585  }
586  (runtime_handle->tx_data_index)+=bytes_per_word;
587 
588  while ((XMC_SPI_CH_GetStatusFlag(handle->channel) & (uint32_t)XMC_SPI_CH_STATUS_FLAG_RECEIVER_START_INDICATION) == 0U)
589  {
590 
591  }
592  XMC_SPI_CH_ClearStatusFlag(handle->channel, (uint32_t)XMC_SPI_CH_STATUS_FLAG_RECEIVER_START_INDICATION);
593  } while(runtime_handle->tx_data_index < runtime_handle->tx_data_count);
594  }
595 
596  while((uint32_t)XMC_USIC_CH_GetTransmitBufferStatus(handle->channel) == (uint32_t)XMC_USIC_CH_TBUF_STATUS_BUSY)
597  {
598  }
599 
600  runtime_handle->tx_busy = false;
601  runtime_handle->tx_data_count = 0U;
602  runtime_handle->tx_data_index = 0U;
603  status = SPI_MASTER_STATUS_SUCCESS;
604  }
605  }
606  else
607  {
609  }
610  runtime_handle->rx_data_dummy = true;
611  return status;
612 }
613 #endif
614 
615 #if (SPI_MASTER_DIRECT_RECEIVE_MODE == 1U)
616 
617 SPI_MASTER_STATUS_t SPI_MASTER_lStartReceivePolling(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count)
618 {
619  SPI_MASTER_STATUS_t status;
620 
621  SPI_MASTER_RUNTIME_t * runtime_handle;
622  static uint8_t dummy_data[2] = {0xFFU, 0xFFU};
623 
624  XMC_ASSERT("SPI_MASTER_lStartReceivePolling:handle NULL" , (handle != NULL));
625 
626  status = SPI_MASTER_STATUS_BUSY;
627  runtime_handle = handle->runtime;
628 
629  if ((dataptr != NULL) && (count > 0U))
630  {
631  /*Check data pointer is valid or not*/
632  if ((false == runtime_handle->rx_busy) && (false == runtime_handle->tx_busy))
633  {
634  runtime_handle->rx_busy = true;
635  runtime_handle->rx_data = dataptr;
636  runtime_handle->tx_data = &dummy_data[0];
637  runtime_handle->tx_data_dummy = true;
638  runtime_handle->rx_data_dummy = false;
639 
640  status = SPI_MASTER_lReceivePolling(handle, count);
641 
642  runtime_handle->tx_data_dummy = false;
643  runtime_handle->rx_busy = false;
644  }
645  }
646  else
647  {
649  }
650  return status;
651 }
652 
653 
654 #endif
655 
656 #if (SPI_MASTER_INTERRUPT_RECEIVE_MODE == 1U)
657 /*
658  * Receive the specified the number of data words.
659  */
660 SPI_MASTER_STATUS_t SPI_MASTER_StartReceiveIRQ(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count)
661 {
662  SPI_MASTER_STATUS_t status;
663  SPI_MASTER_RUNTIME_t * runtime_handle;
664  static uint8_t dummy_data[2] = {0xFFU, 0xFFU};
665 
666  XMC_ASSERT("SPI_MASTER_StartReceiveIRQ:handle NULL" , (handle != NULL));
667 
669  runtime_handle = handle->runtime;
670 
672  {
673  status = SPI_MASTER_STATUS_BUSY;
674  /* Check whether SPI channel is free or not */
675  if ((dataptr != NULL) && (count > 0U))
676  {
677  /*Check data pointer is valid or not*/
678  if ((false == runtime_handle->rx_busy) && (false == runtime_handle->tx_busy))
679  {
680  runtime_handle->rx_busy = true;
681  runtime_handle->rx_data = dataptr;
682  runtime_handle->tx_data = &dummy_data[0];
683  runtime_handle->tx_data_count = count;
684  runtime_handle->tx_data_dummy = true;
685  runtime_handle->rx_data_dummy = false;
686 
687  status = SPI_MASTER_lReceiveIRQ(handle, count);
688 
689  }
690  }
691  else
692  {
694  }
695  }
696  return status;
697 }
698 #endif
699 
700 #if(SPI_MASTER_DMA_RECEIVE_MODE == 1U)
701 SPI_MASTER_STATUS_t SPI_MASTER_StartReceiveDMA(const SPI_MASTER_t *const handle, uint8_t *dataptr, uint32_t block_size)
702 {
703  SPI_MASTER_STATUS_t status;
704  SPI_MASTER_RUNTIME_t * runtime_handle;
705  static uint8_t dummy_data[2] = {0xFFU, 0xFFU};
706 
707  XMC_ASSERT("SPI_MASTER_StartReceiveDMA:handle NULL" , (handle != NULL));
708 
710  runtime_handle = handle->runtime;
711 
713  {
714  status = SPI_MASTER_STATUS_BUSY;
715  /* Check whether SPI channel is free or not */
716  if ((false == runtime_handle->rx_busy) && (false == runtime_handle->tx_busy))
717  {
718  /* Check data pointer is valid or not */
719  if ((dataptr != NULL) && (block_size > 0U) && (block_size <= SPI_MASTER_DMA_MAXCOUNT))
720  {
721  runtime_handle->rx_busy = true;
722  runtime_handle->rx_data = dataptr;
723  runtime_handle->tx_data = &dummy_data[0];
724  runtime_handle->tx_data_count = block_size;
725  runtime_handle->tx_data_dummy = true;
726  runtime_handle->rx_data_dummy = false;
727 
728  status = SPI_MASTER_lReceiveDMA(handle, block_size);
729  }
730  else
731  {
733  }
734  }
735  else
736  {
737  status = SPI_MASTER_STATUS_BUSY;
738  }
739  }
740  return status;
741 }
742 #endif
743 
744 /*
745  * Transmit and receive the data at the same time. This is supported for full duplex mode only.
746  */
748  uint8_t* tx_dataptr,
749  uint8_t* rx_dataptr,
750  uint32_t count)
751 {
752  SPI_MASTER_STATUS_t status;
753  SPI_MASTER_RUNTIME_t * runtime_handle;
754 
755  XMC_ASSERT("SPI_MASTER_Transfer:handle NULL" , (handle != NULL));
756 
757  status = SPI_MASTER_STATUS_BUSY;
758  runtime_handle = handle->runtime;
759 
760  if (XMC_SPI_CH_MODE_STANDARD == runtime_handle->spi_master_mode)
761  {
762  /* Check whether SPI channel is free or not */
763  if ((tx_dataptr != NULL) && (rx_dataptr != NULL) && (count > 0U))
764  {
765  /*Check data pointer is valid or not*/
766  if ((false == runtime_handle->rx_busy) && (false == runtime_handle->tx_busy))
767  {
768  runtime_handle->rx_busy = true;
769  runtime_handle->rx_data = rx_dataptr;
770  runtime_handle->tx_data = tx_dataptr;
771  runtime_handle->tx_data_count = count;
772  runtime_handle->tx_data_dummy = false;
773  runtime_handle->rx_data_dummy = false;
774 
775 #if (SPI_MASTER_INTERRUPT_RECEIVE_MODE == 1U)
777  {
778  status = SPI_MASTER_lReceiveIRQ(handle, count);
779  }
780 #endif
781 #if (SPI_MASTER_DMA_RECEIVE_MODE == 1U)
783  {
784  status = SPI_MASTER_lReceiveDMA(handle, count);
785  }
786 #endif
787 #if (SPI_MASTER_DIRECT_RECEIVE_MODE == 1U)
789  {
790  status = SPI_MASTER_lReceivePolling(handle, count);
791  runtime_handle->rx_busy = false;
792  }
793 #endif
794  }
795  }
796  else
797  {
799  }
800  }
801  else
802  {
803  status = SPI_MASTER_STATUS_FAILURE;
804  }
805 
806  return status;
807 }
808 
809 
810 /*
811  * Aborts the ongoing data reception.
812  */
814 {
815  SPI_MASTER_STATUS_t status;
816 
817  status = SPI_MASTER_STATUS_FAILURE;
818 
819  if ((handle->config->receive_mode != SPI_MASTER_TRANSFER_MODE_DIRECT) && (handle->runtime->rx_busy))
820  {
821  /* Abort if any ongoing transmission w.r.t reception. */
822  status = SPI_MASTER_AbortTransmit(handle);
823 
824  if (status == SPI_MASTER_STATUS_SUCCESS)
825  {
826  /* Reset the user buffer pointer to null */
827  handle->runtime->rx_busy = false;
828  handle->runtime->rx_data = NULL;
829  handle->runtime->tx_data_dummy = false;
830  /* Disable the receive interrupts */
831  if ((uint32_t)handle->config->rx_fifo_size > 0U)
832  {
833  XMC_USIC_CH_RXFIFO_DisableEvent(handle->channel,(uint32_t)SPI_MASTER_FIFO_RECEIVE_EVENT);
834  }
835  else
836  {
837 #if (SPI_MASTER_DMA_RECEIVE_MODE == 1U)
839  {
840  /* Disable the receive event */
841  if(XMC_DMA_CH_IsEnabled(handle->global_dma->dma, handle->dma_ch_rx_number))
842  {
843  XMC_DMA_CH_Disable(handle->global_dma->dma, handle->dma_ch_rx_number);
844  while(XMC_DMA_CH_IsEnabled(handle->global_dma->dma, handle->dma_ch_rx_number)==true)
845  {
846  }
847  XMC_SPI_CH_DisableEvent(handle->channel,
848  (uint32_t)((uint32_t)XMC_USIC_CH_EVENT_STANDARD_RECEIVE | (uint32_t)XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE));
849  }
850  }
851  else
852 #endif
853  {
854  XMC_SPI_CH_DisableEvent(handle->channel,
855  (uint32_t)((uint32_t)XMC_USIC_CH_EVENT_STANDARD_RECEIVE | (uint32_t)XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE));
856  }
857  }
858  status = SPI_MASTER_STATUS_SUCCESS;
859  }
860  else
861  {
862  status = SPI_MASTER_STATUS_FAILURE;
863  }
864  }
865  return status;
866 }
867 
868 /*
869  * Aborts the ongoing data transmission.
870  */
872 {
873  SPI_MASTER_STATUS_t status;
874 
875  status = SPI_MASTER_STATUS_FAILURE;
876 
877  if ((handle->config->transmit_mode != SPI_MASTER_TRANSFER_MODE_DIRECT) && (handle->runtime->tx_busy))
878  {
879  /*Reset the user buffer pointer to null*/
880  handle->runtime->tx_busy = false;
881  handle->runtime->tx_data = NULL;
882  handle->runtime->tx_data_dummy = false;
883  /*Disable the transmit interrupts*/
884  if ((uint32_t)handle->config->tx_fifo_size > 0U)
885  {
886  /*Disable the transmit FIFO event*/
887  XMC_USIC_CH_TXFIFO_DisableEvent(handle->channel,(uint32_t)XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);
888  XMC_USIC_CH_TXFIFO_Flush(handle->channel);
889  }
890  else
891  {
892 #if (SPI_MASTER_DMA_TRANSMIT_MODE == 1U)
894  {
895  /*Disable the standard transmit event*/
896  if(XMC_DMA_CH_IsEnabled(handle->global_dma->dma, handle->dma_ch_tx_number))
897  {
898  XMC_DMA_CH_Disable(handle->global_dma->dma, handle->dma_ch_tx_number);
899  while(XMC_DMA_CH_IsEnabled(handle->global_dma->dma, handle->dma_ch_tx_number)==true)
900  {
901  }
902  XMC_SPI_CH_DisableEvent(handle->channel, (uint32_t)XMC_USIC_CH_EVENT_TRANSMIT_BUFFER);
903  }
904  }
905  else
906 #endif
907  {
908  /*Disable the standard transmit event*/
909  XMC_SPI_CH_DisableEvent(handle->channel, (uint32_t)XMC_USIC_CH_EVENT_TRANSMIT_BUFFER);
910  }
911  }
912  status = SPI_MASTER_STATUS_SUCCESS;
913  }
914  return status;
915 }
916 /***********************************************************************************************************************
917 ** Private API definitions **
918 ***********************************************************************************************************************/
919 #if(SPI_MASTER_INTERRUPT_TRANSMIT_MODE == 1U)
920 /*
921  * Transmit interrupt handler for the APP.
922  * This is a common interrupt handling function called for different instances of the APP.
923  *
924  */
925 void SPI_MASTER_lTransmitHandler(const SPI_MASTER_t * const handle)
926 {
927  uint16_t data; /* Data to be loaded into the TBUF */
928  uint32_t bytes_per_word = SPI_MASTER_1_BYTE_PER_WORD; /* This is to support the word length 8 and 16.*/
929  SPI_MASTER_RUNTIME_t * runtime_handle = handle->runtime;
930 
931  if (handle->runtime->word_length > SPI_MASTER_WORD_LENGTH_8_BIT)
932  {
933  bytes_per_word = SPI_MASTER_2_BYTES_PER_WORD; /* Word length is 16-bits */
934  }
935 
936  if (runtime_handle->tx_data_index < runtime_handle->tx_data_count)
937  {
938  data = 0U;
939  /*When Transmit FIFO is enabled*/
940  if ((uint32_t)handle->config->tx_fifo_size > 0U)
941  {
942  /*Fill the transmit FIFO */
943  while (XMC_USIC_CH_TXFIFO_IsFull(handle->channel) == false)
944  {
945  if (runtime_handle->tx_data_index < runtime_handle->tx_data_count)
946  {
947  /*Load the FIFO byte by byte till either FIFO is full or all data is loaded*/
948  if (runtime_handle->tx_data_dummy == true)
949  {
950  XMC_USIC_CH_TXFIFO_PutDataHPCMode(handle->channel, 0xFFFFU, (uint32_t)runtime_handle->spi_master_mode);
951  }
952  else
953  {
954  if(bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
955  {
956  data = *((uint16_t*)&runtime_handle->tx_data[runtime_handle->tx_data_index]);
957  }
958  else
959  {
960  data = runtime_handle->tx_data[runtime_handle->tx_data_index];
961  }
962  XMC_USIC_CH_TXFIFO_PutDataHPCMode(handle->channel, data, (uint32_t)runtime_handle->spi_master_mode);
963  }
964  (runtime_handle->tx_data_index)+= bytes_per_word;
965  }
966  else
967  {
968  break;
969  }
970  }
971  }
972  else/*When Transmit FIFO is disabled*/
973  {
974  if (runtime_handle->tx_data_dummy == true)
975  {
976  XMC_USIC_CH_WriteToTBUFTCI(handle->channel, 0xFFFFU, (uint32_t)runtime_handle->spi_master_mode);
977  }
978  else
979  {
980  if(bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
981  {
982  data = *((uint16_t*)&runtime_handle->tx_data[runtime_handle->tx_data_index]);
983  }
984  else
985  {
986  data = runtime_handle->tx_data[runtime_handle->tx_data_index];
987  }
988  XMC_USIC_CH_WriteToTBUFTCI(handle->channel, data, (uint32_t)runtime_handle->spi_master_mode);
989  }
990  (runtime_handle->tx_data_index)+= bytes_per_word;
991  }
992  }
993  else
994  {
995  if (XMC_USIC_CH_TXFIFO_IsEmpty(handle->channel) == true)
996  {
997  /* Clear the flag */
998  if ((uint32_t)handle->config->tx_fifo_size > 0U)
999  {
1000  /* Clear the transmit FIFO event */
1001  XMC_USIC_CH_TXFIFO_DisableEvent(handle->channel,(uint32_t)XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);
1002  }
1003  else
1004  {
1005  /* Clear the standard transmit event */
1006  XMC_USIC_CH_DisableEvent(handle->channel, (uint32_t)XMC_USIC_CH_EVENT_TRANSMIT_BUFFER);
1007  }
1008 
1009  /* Wait for the transmit buffer to be free to ensure that all data is transmitted */
1010  while (XMC_USIC_CH_GetTransmitBufferStatus(handle->channel) == XMC_USIC_CH_TBUF_STATUS_BUSY)
1011  {
1012 
1013  }
1014 
1015  /* All data is transmitted */
1016  runtime_handle->tx_busy = false;
1017  runtime_handle->tx_data = NULL;
1018 
1019  if ((handle->config->tx_cbhandler != NULL) && (runtime_handle->rx_busy == false))
1020  {
1021  /* Execute the callback function provided in the SPI_MASTER APP UI */
1022  handle->config->tx_cbhandler();
1023  }
1024  }
1025  }
1026 }
1027 #endif
1028 
1029 #if (SPI_MASTER_INTERRUPT_RECEIVE_MODE == 1U)
1030 
1031 SPI_MASTER_STATUS_t SPI_MASTER_lReceiveIRQ(const SPI_MASTER_t *const handle, uint32_t count)
1032 {
1033 
1034  SPI_MASTER_STATUS_t status;
1035  SPI_MASTER_RUNTIME_t * runtime_handle;
1036  uint32_t bytes_per_word = SPI_MASTER_1_BYTE_PER_WORD;; /* This is to support the word length 8 and 16.
1037  Specify the number of bytes for the configured word length*/
1038 
1039  runtime_handle = handle->runtime;
1040  runtime_handle->rx_data_index = 0U;
1041 
1042  if (handle->runtime->word_length > SPI_MASTER_WORD_LENGTH_8_BIT)
1043  {
1044  bytes_per_word = SPI_MASTER_2_BYTES_PER_WORD; /* Word length is 16-bits */
1045  }
1046 
1047  /* If no active reception in progress, obtain the address of data buffer and number of data bytes to be received */
1048  runtime_handle->rx_data_count = (uint32_t)count << (bytes_per_word - 1U);
1049 
1050  /* Check if FIFO is enabled */
1051  if ((uint32_t)handle->config->rx_fifo_size > 0U)
1052  {
1053  /* Clear the receive FIFO */
1054  XMC_USIC_CH_RXFIFO_Flush(handle->channel);
1055  SPI_MASTER_lStdRBUFFlush(handle->channel);
1056 
1057  /* Configure the FIFO trigger limit based on the required data size */
1058  SPI_MASTER_lReconfigureRxFIFO(handle, runtime_handle->rx_data_count);
1059 
1060  /* Enable the receive FIFO events */
1061  XMC_USIC_CH_RXFIFO_EnableEvent(handle->channel,(uint32_t)SPI_MASTER_FIFO_RECEIVE_EVENT);
1062  }
1063  else
1064  {
1065  /* Flush the RBUF0 and RBUF1 */
1066  SPI_MASTER_lStdRBUFFlush(handle->channel);
1067 
1068  /* Enable the standard receive events */
1069  XMC_USIC_CH_EnableEvent(handle->channel, (uint32_t)SPI_MASTER_RECEIVE_EVENT);
1070  }
1071  /* Call the transmit, to receive the data synchronously */
1072  status = SPI_MASTER_Transmit(handle, runtime_handle->tx_data, runtime_handle->tx_data_count);
1073 
1074  return status;
1075 }
1076 
1077 /*
1078  * Receive interrupt handler for the APP.
1079  * This is a common interrupt handling function for different instances of the SPI_MASTER APP.
1080  */
1081 void SPI_MASTER_lReceiveHandler(const SPI_MASTER_t * const handle)
1082 {
1083  uint16_t data; /* Data to be loaded into the TBUF */
1084  uint32_t bytes_per_word = SPI_MASTER_1_BYTE_PER_WORD; /* This is to support the word length 8 and 16. */
1085  SPI_MASTER_RUNTIME_t * runtime_handle = handle->runtime;
1086 
1087  data = 0U;
1088 
1089  if (handle->runtime->word_length > SPI_MASTER_WORD_LENGTH_8_BIT)
1090  {
1091  bytes_per_word = SPI_MASTER_2_BYTES_PER_WORD; /* Word length is 16-bits */
1092  }
1093 
1094  if ((uint32_t)handle->config->rx_fifo_size > 0U)
1095  {
1096  /* read the FIFO */
1097  SPI_MASTER_lFIFORead(handle, bytes_per_word);
1098  /* Reconfigure the RXFIFO trigger limit based on pending receive bytes */
1099  SPI_MASTER_lReconfigureRxFIFO(handle, (uint32_t)(runtime_handle->rx_data_count - runtime_handle->rx_data_index));
1100  }
1101  else
1102  {
1103  /* When RxFIFO is disabled */
1104  if ((XMC_USIC_CH_GetReceiveBufferStatus(handle->channel) & (uint32_t)XMC_USIC_CH_RBUF_STATUS_DATA_VALID0) != 0U )
1105  {
1106  if (runtime_handle->rx_data_index < runtime_handle->rx_data_count)
1107  {
1108  data = XMC_SPI_CH_GetReceivedData(handle->channel);
1109 
1110  runtime_handle->rx_data[runtime_handle->rx_data_index] = (uint8_t)data;
1111 
1112  if (bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1113  {
1114  runtime_handle->rx_data[runtime_handle->rx_data_index + 1U] = (uint8_t)((uint16_t)data >> 8);
1115  }
1116 
1117  (runtime_handle->rx_data_index)+= bytes_per_word;
1118  }
1119  }
1120  if ((XMC_USIC_CH_GetReceiveBufferStatus(handle->channel) & (uint32_t)XMC_USIC_CH_RBUF_STATUS_DATA_VALID1) != 0U)
1121  {
1122  if (runtime_handle->rx_data_index < runtime_handle->rx_data_count)
1123  {
1124  data = XMC_SPI_CH_GetReceivedData(handle->channel);
1125 
1126  runtime_handle->rx_data[runtime_handle->rx_data_index] = (uint8_t)data;
1127 
1128  if (bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1129  {
1130  runtime_handle->rx_data[runtime_handle->rx_data_index + 1U] = (uint8_t)((uint16_t)data >> 8);
1131  }
1132 
1133  (runtime_handle->rx_data_index)+= bytes_per_word;
1134  }
1135  }
1136 
1137  if (runtime_handle->rx_data_index == runtime_handle->rx_data_count)
1138  {
1139  /* Disable both standard receive and alternative receive FIFO events */
1140  if ((uint32_t)handle->config->rx_fifo_size > 0U)
1141  {
1142  /* Enable the receive FIFO events */
1143  XMC_USIC_CH_RXFIFO_DisableEvent(handle->channel,(uint32_t)SPI_MASTER_FIFO_RECEIVE_EVENT);
1144  }
1145  else
1146  {
1147  XMC_SPI_CH_DisableEvent(handle->channel, (uint32_t)SPI_MASTER_RECEIVE_EVENT);
1148  }
1149  /* Reception complete */
1150  runtime_handle->rx_busy = false;
1151  runtime_handle->tx_data_dummy = false;
1152  runtime_handle->rx_data_dummy = true;
1153  runtime_handle->rx_data = NULL;
1154 
1155  if (handle->config->rx_cbhandler != NULL)
1156  {
1157  /* Execute the 'End of reception' callback function */
1158  handle->config->rx_cbhandler();
1159  }
1160  }
1161  }
1162 }
1163 
1164 /*
1165  * Read the data from FIFO until it becomes empty.
1166  */
1167 void SPI_MASTER_lFIFORead(const SPI_MASTER_t * const handle, const uint32_t bytes_per_word)
1168 {
1169  SPI_MASTER_RUNTIME_t * runtime_handle;
1170  uint16_t data;
1171 
1172  runtime_handle = handle->runtime;
1173  data = 0U;
1174 
1175  /* When Receive FIFO is enabled*/
1176  while (XMC_USIC_CH_RXFIFO_IsEmpty(handle->channel) == false)
1177  {
1178  if (runtime_handle->rx_data_index < runtime_handle->rx_data_count)
1179  {
1180  data = XMC_SPI_CH_GetReceivedData(handle->channel);
1181  runtime_handle->rx_data[runtime_handle->rx_data_index] = (uint8_t)data;
1182 
1183  if (bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1184  {
1185  runtime_handle->rx_data[runtime_handle->rx_data_index + 1U] = (uint8_t)((uint16_t)data >> 8);
1186  }
1187  (runtime_handle->rx_data_index)+= bytes_per_word;
1188  }
1189 
1190  if (runtime_handle->rx_data_index == runtime_handle->rx_data_count)
1191  {
1192  /*Reception complete*/
1193  runtime_handle->rx_busy = false;
1194  runtime_handle->tx_data_dummy = false;
1195  /*Disable both standard receive and alternative receive FIFO events*/
1196  XMC_USIC_CH_RXFIFO_DisableEvent(handle->channel,(uint32_t)SPI_MASTER_FIFO_RECEIVE_EVENT);
1197  if (handle->config->rx_cbhandler != NULL)
1198  {
1199  /* Execute the 'End of reception' callback function */
1200  handle->config->rx_cbhandler();
1201  }
1202  break;
1203  }
1204  }
1205 }
1206 
1207 /*
1208  * This function configures the FIFO settings
1209  */
1210 static void SPI_MASTER_lReconfigureRxFIFO(const SPI_MASTER_t * const handle, uint32_t data_size)
1211 {
1212  uint32_t fifo_size;
1213  uint32_t ret_limit_val;
1214 
1215  if (((uint32_t)handle->config->rx_fifo_size > 0U) && (data_size > 0U))
1216  {
1217  fifo_size = (uint32_t)0x01 << handle->config->rx_fifo_size;
1218 
1219  if (handle->runtime->word_length > SPI_MASTER_WORD_LENGTH_8_BIT)
1220  {
1221  /* Data size is divided by 2, to change the trigger limit according the word length */
1222  data_size = (uint32_t)data_size >> 1U;
1223  }
1224 
1225  /*If data size is more than FIFO size, configure the limit to the FIFO size*/
1226  if (data_size < (fifo_size >> 1))
1227  {
1228  ret_limit_val = data_size - 1U;
1229  }
1230  else
1231  {
1232  ret_limit_val = fifo_size >> 1;
1233  }
1234 
1235  /*Set the limit value*/
1236  XMC_USIC_CH_RXFIFO_SetSizeTriggerLimit(handle->channel, handle->config->rx_fifo_size, ret_limit_val);
1237  }
1238 }
1239 #endif
1240 
1241 #if (SPI_MASTER_DIRECT_RECEIVE_MODE == 1U)
1242 SPI_MASTER_STATUS_t SPI_MASTER_lReceivePolling(const SPI_MASTER_t *const handle, uint32_t count)
1243 {
1244  SPI_MASTER_RUNTIME_t * runtime_handle;
1245  uint32_t bytes_per_word = SPI_MASTER_1_BYTE_PER_WORD; /* This is to support the word length 8 and 16.
1246  Specify the number of bytes for the configured word length */
1247  uint16_t data;
1248 
1249  runtime_handle = handle->runtime;
1250  data = 0U;
1251  runtime_handle->rx_data_index = 0U;
1252  runtime_handle->tx_data_index = 0U;
1253 
1254  if (handle->runtime->word_length > SPI_MASTER_WORD_LENGTH_8_BIT)
1255  {
1256  bytes_per_word = SPI_MASTER_2_BYTES_PER_WORD; /* Word length is 16-bits */
1257  }
1258 
1259  runtime_handle->rx_data_count = (uint32_t)count << (bytes_per_word - 1U);
1260 
1261  XMC_SPI_CH_SetTransmitMode(handle->channel, runtime_handle->spi_master_mode);
1262 
1263  /* Check if FIFO is enabled */
1264  if ((uint32_t)handle->config->rx_fifo_size > 0U)
1265  {
1266  /* Clear the receive FIFO */
1267  XMC_USIC_CH_RXFIFO_Flush(handle->channel);
1268  SPI_MASTER_lStdRBUFFlush(handle->channel);
1269 
1270  if (runtime_handle->tx_data_dummy == true)
1271  {
1272  XMC_USIC_CH_TXFIFO_PutDataHPCMode(handle->channel, 0xFFFFU, (uint32_t)runtime_handle->spi_master_mode);
1273  }
1274  else
1275  {
1276  if(bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1277  {
1278  data = *((uint16_t*)&runtime_handle->tx_data[runtime_handle->tx_data_index]);
1279  }
1280  else
1281  {
1282  data = runtime_handle->tx_data[runtime_handle->tx_data_index];
1283  }
1284  XMC_USIC_CH_TXFIFO_PutDataHPCMode(handle->channel, data, (uint32_t)runtime_handle->spi_master_mode);
1285  }
1286 
1287  (runtime_handle->tx_data_index)+= bytes_per_word;
1288 
1289 
1290  while (runtime_handle->tx_data_index < runtime_handle->rx_data_count)
1291  {
1292  if (runtime_handle->tx_data_dummy == true)
1293  {
1294  XMC_USIC_CH_TXFIFO_PutDataHPCMode(handle->channel, 0xFFFFU, (uint32_t)runtime_handle->spi_master_mode);
1295  }
1296  else
1297  {
1298  if(bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1299  {
1300  data = *((uint16_t*)&runtime_handle->tx_data[runtime_handle->tx_data_index]);
1301  }
1302  else
1303  {
1304  data = runtime_handle->tx_data[runtime_handle->tx_data_index];
1305  }
1306  XMC_USIC_CH_TXFIFO_PutDataHPCMode(handle->channel, data, (uint32_t)runtime_handle->spi_master_mode);
1307  }
1308 
1309  while(XMC_USIC_CH_RXFIFO_IsEmpty(handle->channel) == true)
1310  {
1311 
1312  }
1313 
1314  data = XMC_SPI_CH_GetReceivedData(handle->channel);
1315 
1316  runtime_handle->rx_data[runtime_handle->rx_data_index] = (uint8_t)data;
1317 
1318  if (bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1319  {
1320  runtime_handle->rx_data[runtime_handle->rx_data_index + 1U] = (uint8_t)((uint16_t)data >> 8);
1321  }
1322 
1323  (runtime_handle->rx_data_index)+= bytes_per_word;
1324  (runtime_handle->tx_data_index)+= bytes_per_word;
1325  }
1326 
1327  while(XMC_USIC_CH_RXFIFO_IsEmpty(handle->channel) == true)
1328  {
1329 
1330  }
1331 
1332  data = XMC_SPI_CH_GetReceivedData(handle->channel);
1333 
1334  runtime_handle->rx_data[runtime_handle->rx_data_index] = (uint8_t)data;
1335 
1336  if (bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1337  {
1338  runtime_handle->rx_data[runtime_handle->rx_data_index + 1U] = (uint8_t)((uint16_t)data >> 8);
1339  }
1340 
1341  XMC_USIC_CH_RXFIFO_ClearEvent(handle->channel, SPI_MASTER_FIFO_RECEIVE_INDICATION_FLAG);
1342  }
1343  else
1344  {
1345  /* Flush the RBUF0 and RBUF1 */
1346  SPI_MASTER_lStdRBUFFlush(handle->channel);
1347 
1348  while((uint32_t)XMC_USIC_CH_GetTransmitBufferStatus(handle->channel) == (uint32_t)XMC_USIC_CH_TBUF_STATUS_BUSY)
1349  {
1350  }
1351 
1352  if (runtime_handle->tx_data_dummy == true)
1353  {
1354  XMC_USIC_CH_WriteToTBUFTCI(handle->channel, 0xFFFFU, (uint32_t)runtime_handle->spi_master_mode);
1355  }
1356  else
1357  {
1358  if(bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1359  {
1360  data = *((uint16_t*)&runtime_handle->tx_data[runtime_handle->tx_data_index]);
1361  }
1362  else
1363  {
1364  data = runtime_handle->tx_data[runtime_handle->tx_data_index];
1365  }
1366  XMC_USIC_CH_WriteToTBUFTCI(handle->channel, data, (uint32_t)runtime_handle->spi_master_mode);
1367  }
1368 
1369  (runtime_handle->tx_data_index)+= bytes_per_word;
1370 
1371  while (runtime_handle->tx_data_index < runtime_handle->rx_data_count)
1372  {
1373  while((uint32_t)XMC_USIC_CH_GetTransmitBufferStatus(handle->channel) == (uint32_t)XMC_USIC_CH_TBUF_STATUS_BUSY)
1374  {
1375 
1376  }
1377 
1378  if (runtime_handle->tx_data_dummy == true)
1379  {
1380  XMC_USIC_CH_WriteToTBUFTCI(handle->channel, 0xFFFFU, (uint32_t)runtime_handle->spi_master_mode);
1381  }
1382  else
1383  {
1384  if(bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1385  {
1386  data = *((uint16_t*)&runtime_handle->tx_data[runtime_handle->tx_data_index]);
1387  }
1388  else
1389  {
1390  data = runtime_handle->tx_data[runtime_handle->tx_data_index];
1391  }
1392  XMC_USIC_CH_WriteToTBUFTCI(handle->channel, data, (uint32_t)runtime_handle->spi_master_mode);
1393  }
1394 
1395  while (XMC_USIC_CH_GetReceiveBufferStatus(handle->channel) == 0U)
1396  {
1397 
1398  }
1399 
1400  data = XMC_SPI_CH_GetReceivedData(handle->channel);
1401 
1402  runtime_handle->rx_data[runtime_handle->rx_data_index] = (uint8_t)data;
1403 
1404  if (bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1405  {
1406  runtime_handle->rx_data[runtime_handle->rx_data_index + 1U] = (uint8_t)((uint16_t)data >> 8);
1407  }
1408 
1409  (runtime_handle->rx_data_index)+= bytes_per_word;
1410  (runtime_handle->tx_data_index)+= bytes_per_word;
1411 
1412  XMC_SPI_CH_ClearStatusFlag(handle->channel, SPI_MASTER_RECEIVE_INDICATION_FLAG);
1413  }
1414 
1415  while (XMC_USIC_CH_GetReceiveBufferStatus(handle->channel) == 0U)
1416  {
1417 
1418  }
1419 
1420  data = XMC_SPI_CH_GetReceivedData(handle->channel);
1421 
1422  runtime_handle->rx_data[runtime_handle->rx_data_index] = (uint8_t)data;
1423 
1424  if (bytes_per_word == SPI_MASTER_2_BYTES_PER_WORD)
1425  {
1426  runtime_handle->rx_data[runtime_handle->rx_data_index + 1U] = (uint8_t)((uint16_t)data >> 8);
1427  }
1428 
1429  XMC_SPI_CH_ClearStatusFlag(handle->channel, SPI_MASTER_RECEIVE_INDICATION_FLAG);
1430  }
1431  runtime_handle->rx_data_count = 0U;
1432  runtime_handle->rx_data_index = 0U;
1433  runtime_handle->tx_data_index = 0U;
1434 
1436 }
1437 #endif
1438 
1439 #if (SPI_MASTER_DMA_RECEIVE_MODE == 1U)
1440 SPI_MASTER_STATUS_t SPI_MASTER_lReceiveDMA(const SPI_MASTER_t *const handle, uint32_t block_size)
1441 {
1442  SPI_MASTER_STATUS_t status;
1443  SPI_MASTER_RUNTIME_t * runtime_handle;
1444 
1445  runtime_handle = handle->runtime;
1446  runtime_handle->rx_data_index = 0U;
1447  runtime_handle->rx_data_count = (uint32_t)block_size;
1448 
1449  SPI_MASTER_lStdRBUFFlush(handle->channel);
1450 
1451  XMC_SPI_CH_EnableEvent(handle->channel, (uint32_t)SPI_MASTER_RECEIVE_EVENT);
1452 
1453  XMC_DMA_CH_SetBlockSize(handle->global_dma->dma, handle->dma_ch_rx_number, runtime_handle->rx_data_count);
1454 
1455  XMC_DMA_CH_SetSourceAddress(handle->global_dma->dma,
1456  handle->dma_ch_rx_number,
1457  (uint32_t)&(handle->channel->RBUF));
1458 
1459  XMC_DMA_CH_SetDestinationAddress(handle->global_dma->dma, handle->dma_ch_rx_number, (uint32_t)runtime_handle->rx_data);
1460 
1461  status = SPI_MASTER_STATUS_SUCCESS;
1462 
1463  XMC_DMA_CH_Enable(handle->global_dma->dma, handle->dma_ch_rx_number);
1464 
1465  /* Call the transmit, to receive the data synchronously */
1466  status = SPI_MASTER_Transmit(handle, runtime_handle->tx_data, runtime_handle->tx_data_count);
1467 
1468  return status;
1469 }
1470 #endif
1471 
1472 /*
1473  * Clears the receive buffers
1474  */
1475 static void SPI_MASTER_lStdRBUFFlush(XMC_USIC_CH_t *const channel)
1476 {
1477  /* Clear RBF0 */
1478  (void)XMC_SPI_CH_GetReceivedData(channel);
1479  /* Clear RBF1 */
1480  (void)XMC_SPI_CH_GetReceivedData(channel);
1481 }
1482 
1483 #if (SPI_MASTER_PARITY_ERROR == 1U)
1484 /*
1485  * Protocol interrupt handling function.
1486  * The function is common for different instances of the SPI_MASTER APP.
1487  */
1488 void SPI_MASTER_lProtocolHandler(const SPI_MASTER_t * const handle)
1489 {
1490  uint32_t psr_status;
1491 
1492  psr_status = XMC_SPI_CH_GetStatusFlag(handle->channel);
1493 
1494  /*Check for Parity detection error */
1495  if ((handle->config->parity_cbhandler != NULL) && \
1496  (psr_status & (uint32_t)XMC_SPI_CH_STATUS_FLAG_PARITY_ERROR_EVENT_DETECTED))
1497  {
1498  handle->config->parity_cbhandler();
1499  }
1500 }
1501 #endif
1502 
1503 /*
1504  * This is used to reconfigure the registers while changing the SPI mode dynamically
1505  */
1506 static void SPI_MASTER_lPortConfig(const SPI_MASTER_t* handle)
1507 {
1508  switch (handle->runtime->spi_master_mode)
1509  {
1510  case XMC_SPI_CH_MODE_STANDARD:
1511  /* Configure the data input line selected */
1512  XMC_SPI_CH_SetInputSource(handle->channel, XMC_SPI_CH_INPUT_DIN0, (uint8_t)(handle->runtime->dx0_input));
1513  /* Configure the pin as input */
1514  XMC_GPIO_SetMode(handle->config->mosi_1_pin->port, handle->config->mosi_1_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1515  /* Disable the HW control of the PINs */
1516  XMC_GPIO_SetHardwareControl(handle->config->mosi_0_pin->port,
1517  handle->config->mosi_0_pin->pin,
1518  XMC_GPIO_HWCTRL_DISABLED);
1519  XMC_GPIO_SetHardwareControl(handle->config->mosi_1_pin->port,
1520  handle->config->mosi_1_pin->pin,
1521  XMC_GPIO_HWCTRL_DISABLED);
1522 
1523  break;
1524 
1525  case XMC_SPI_CH_MODE_STANDARD_HALFDUPLEX:
1526  /* Configure the data input line selected */
1527  XMC_SPI_CH_SetInputSource(handle->channel, XMC_SPI_CH_INPUT_DIN0, (uint8_t)(handle->runtime->dx0_input_half_duplex));
1528  /* Disable the HW control of the PINs */
1529  XMC_GPIO_SetHardwareControl(handle->config->mosi_0_pin->port,
1530  handle->config->mosi_0_pin->pin,
1531  XMC_GPIO_HWCTRL_DISABLED);
1532  break;
1533 
1534  case XMC_SPI_CH_MODE_DUAL:
1535  case XMC_SPI_CH_MODE_QUAD:
1536  /* Configure the data input line for loopback mode */
1537  XMC_SPI_CH_SetInputSource(handle->channel, XMC_SPI_CH_INPUT_DIN0, (uint8_t)SPI_MASTER_INPUT_G);
1538  /* Configure the pin as input */
1539  XMC_GPIO_SetMode(handle->config->mosi_1_pin->port,
1540  handle->config->mosi_1_pin->pin,
1541  handle->config->mosi_1_pin_config->port_config.mode);
1542 
1543  /* Configure the Hardware control mode selected for the pin */
1544  XMC_GPIO_SetHardwareControl(handle->config->mosi_0_pin->port,
1545  handle->config->mosi_0_pin->pin,
1546  handle->config->mosi_0_pin_config->hw_control);
1547  XMC_GPIO_SetHardwareControl(handle->config->mosi_1_pin->port,
1548  handle->config->mosi_1_pin->pin,
1549  handle->config->mosi_1_pin_config->hw_control);
1550  break;
1551 
1552  default:
1553  break;
1554  }
1555 }
1556 
1557 /*
1558  * This is used to reassign the mode for ports after updating the baud rate
1559  */
1560 static void SPI_MASTER_lPortModeSet(const SPI_MASTER_t* handle)
1561 {
1562  uint32_t ss_line;
1563 
1564  /* Configure the ports with actual mode */
1565  for (ss_line = 0U; ss_line < handle->config->slave_select_lines; ss_line++)
1566  {
1567  XMC_GPIO_SetMode(handle->config->slave_select_pin[ss_line]->port,
1568  handle->config->slave_select_pin[ss_line]->pin,
1569  handle->config->slave_select_pin_config[ss_line]->port_config.mode);
1570  }
1571 
1572  XMC_GPIO_SetMode(handle->config->sclk_out_pin->port,
1573  handle->config->sclk_out_pin->pin,
1574  handle->config->sclk_out_pin_config->port_config.mode);
1575 
1576  switch (handle->runtime->spi_master_mode)
1577  {
1578  case XMC_SPI_CH_MODE_STANDARD:
1579  case XMC_SPI_CH_MODE_STANDARD_HALFDUPLEX:
1580  XMC_GPIO_SetMode(handle->config->mosi_0_pin->port,
1581  handle->config->mosi_0_pin->pin,
1582  handle->config->mosi_0_pin_config->port_config.mode);
1583  break;
1584 
1585  case XMC_SPI_CH_MODE_DUAL:
1586  XMC_GPIO_SetMode(handle->config->mosi_0_pin->port,
1587  handle->config->mosi_0_pin->pin,
1588  handle->config->mosi_0_pin_config->port_config.mode);
1589  XMC_GPIO_SetMode(handle->config->mosi_1_pin->port,
1590  handle->config->mosi_1_pin->pin,
1591  handle->config->mosi_1_pin_config->port_config.mode);
1592  break;
1593 
1594  case XMC_SPI_CH_MODE_QUAD:
1595  XMC_GPIO_SetMode(handle->config->mosi_0_pin->port,
1596  handle->config->mosi_0_pin->pin,
1597  handle->config->mosi_0_pin_config->port_config.mode);
1598  XMC_GPIO_SetMode(handle->config->mosi_1_pin->port,
1599  handle->config->mosi_1_pin->pin,
1600  handle->config->mosi_1_pin_config->port_config.mode);
1601  XMC_GPIO_SetMode(handle->config->mosi_2_pin->port,
1602  handle->config->mosi_2_pin->pin,
1603  handle->config->mosi_2_pin_config->port_config.mode);
1604  XMC_GPIO_SetMode(handle->config->mosi_3_pin->port,
1605  handle->config->mosi_3_pin->pin,
1606  handle->config->mosi_3_pin_config->port_config.mode);
1607  break;
1608 
1609  default:
1610  break;
1611  }
1612 }
1613 
1614 /*
1615  * This is used to make the ports as input during update of the baud rate, to avoid the noise in output ports
1616  */
1617 static void SPI_MASTER_lPortModeReset(const SPI_MASTER_t* handle)
1618 {
1619  uint32_t ss_line;
1620 
1621  /* Configure the ports as input */
1622  for (ss_line = 0U; ss_line < handle->config->slave_select_lines; ss_line++)
1623  {
1624  XMC_GPIO_SetMode(handle->config->slave_select_pin[ss_line]->port,
1625  handle->config->slave_select_pin[ss_line]->pin,
1626  XMC_GPIO_MODE_INPUT_TRISTATE);
1627  }
1628 
1629  XMC_GPIO_SetMode(handle->config->sclk_out_pin->port, handle->config->sclk_out_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1630 
1631  switch (handle->runtime->spi_master_mode)
1632  {
1633  case XMC_SPI_CH_MODE_STANDARD:
1634  case XMC_SPI_CH_MODE_STANDARD_HALFDUPLEX:
1635  XMC_GPIO_SetMode(handle->config->mosi_0_pin->port, handle->config->mosi_0_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1636  break;
1637 
1638  case XMC_SPI_CH_MODE_DUAL:
1639  XMC_GPIO_SetMode(handle->config->mosi_0_pin->port, handle->config->mosi_0_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1640  XMC_GPIO_SetMode(handle->config->mosi_1_pin->port, handle->config->mosi_1_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1641  break;
1642 
1643  case XMC_SPI_CH_MODE_QUAD:
1644  XMC_GPIO_SetMode(handle->config->mosi_0_pin->port, handle->config->mosi_0_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1645  XMC_GPIO_SetMode(handle->config->mosi_1_pin->port, handle->config->mosi_1_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1646  XMC_GPIO_SetMode(handle->config->mosi_2_pin->port, handle->config->mosi_2_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1647  XMC_GPIO_SetMode(handle->config->mosi_3_pin->port, handle->config->mosi_3_pin->pin, XMC_GPIO_MODE_INPUT_TRISTATE);
1648  break;
1649 
1650  default:
1651  break;
1652  }
1653 }
1654 
1655 /*
1656  * This is used check whether the mode change is valid or not
1657  */
1658 static SPI_MASTER_STATUS_t SPI_MASTER_lValidateModeChange(const SPI_MASTER_t * handle, XMC_SPI_CH_MODE_t mode)
1659 {
1660  SPI_MASTER_STATUS_t status;
1661 
1662  status = SPI_MASTER_STATUS_SUCCESS;
1663 
1664  if ((handle->config->spi_master_config_mode == XMC_SPI_CH_MODE_STANDARD_HALFDUPLEX) ||
1665  (handle->config->spi_master_config_mode < mode))
1666  {
1667  status = SPI_MASTER_STATUS_FAILURE;
1668  }
1669  else if (handle->config->spi_master_config_mode == XMC_SPI_CH_MODE_STANDARD)
1670  {
1671  if (XMC_SPI_CH_MODE_DUAL <= mode)
1672  {
1673  status = SPI_MASTER_STATUS_FAILURE;
1674  }
1675  }
1676  else
1677  {
1678  if ((mode == XMC_SPI_CH_MODE_STANDARD) && (handle->runtime->dx0_input == SPI_MASTER_INPUT_INVALID))
1679  {
1680  status = SPI_MASTER_STATUS_FAILURE;
1681  }
1682 
1683  else if ((mode == XMC_SPI_CH_MODE_STANDARD_HALFDUPLEX) && (handle->runtime->dx0_input_half_duplex == SPI_MASTER_INPUT_INVALID))
1684  {
1685  status = SPI_MASTER_STATUS_FAILURE;
1686  }
1687  else
1688  {
1689  /* added to abide MISRA */
1690  }
1691  }
1692  return status;
1693 }