EFM32 Happy Gecko Software Documentation  efm32hg-doc-5.1.2
spidrv.c
Go to the documentation of this file.
1 /***************************************************************************/
16 #include <string.h>
17 
18 #include "em_device.h"
19 #include "em_gpio.h"
20 #include "em_core.h"
21 #include "em_usart.h"
22 
23 #include "dmadrv.h"
24 #include "spidrv.h"
25 
27 
28 #if defined( DMA_PRESENT ) && ( DMA_COUNT == 1 )
29 #define SPI_DMA_IRQ DMA_IRQn
30 
31 #elif defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 )
32 #define SPI_DMA_IRQ LDMA_IRQn
33 
34 #else
35 #error "No valid SPIDRV DMA engine defined."
36 #endif
37 
38 static bool spidrvIsInitialized = false;
39 
40 static void BlockingComplete( SPIDRV_Handle_t handle,
41  Ecode_t transferStatus,
42  int itemsTransferred );
43 
44 static Ecode_t ConfigGPIO( SPIDRV_Handle_t handle, bool enable );
45 
46 static bool RxDMAComplete( unsigned int channel,
47  unsigned int sequenceNo,
48  void *userParam );
49 
50 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
51 static void SlaveTimeout( RTCDRV_TimerID_t id,
52  void *user );
53 #endif
54 
55 static void StartReceiveDMA( SPIDRV_Handle_t handle,
56  void *buffer,
57  int count,
58  SPIDRV_Callback_t callback );
59 
60 static void StartTransferDMA( SPIDRV_Handle_t handle,
61  const void *txBuffer,
62  void *rxBuffer,
63  int count,
64  SPIDRV_Callback_t callback );
65 
66 static void StartTransmitDMA( SPIDRV_Handle_t handle,
67  const void *buffer,
68  int count,
69  SPIDRV_Callback_t callback );
70 
71 static Ecode_t TransferApiPrologue( SPIDRV_Handle_t handle,
72  void *buffer,
73  int count );
74 
75 static Ecode_t TransferApiBlockingPrologue( SPIDRV_Handle_t handle,
76  void *buffer,
77  int count );
78 
79 static void WaitForTransferCompletion( SPIDRV_Handle_t handle );
80 
81 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
82 static Ecode_t WaitForIdleLine( SPIDRV_Handle_t handle );
83 #endif
84 
86 
87 /***************************************************************************/
102 {
103  Ecode_t retVal;
106 
107  if ( handle == NULL )
108  {
110  }
111 
112  if ( initData == NULL )
113  {
115  }
116 
117  memset( handle, 0, sizeof( SPIDRV_HandleData_t ) );
118 
119  if ( 0 )
120  {
121 #if defined( USART0 )
122  }
123  else if ( initData->port == USART0 )
124  {
125  handle->usartClock = cmuClock_USART0;
126  handle->txDMASignal = dmadrvPeripheralSignal_USART0_TXBL;
127  handle->rxDMASignal = dmadrvPeripheralSignal_USART0_RXDATAV;
128 #endif
129 #if defined( USART1 )
130  }
131  else if ( initData->port == USART1 )
132  {
133  handle->usartClock = cmuClock_USART1;
134  handle->txDMASignal = dmadrvPeripheralSignal_USART1_TXBL;
135  handle->rxDMASignal = dmadrvPeripheralSignal_USART1_RXDATAV;
136 #endif
137 #if defined( USART2 )
138  }
139  else if ( initData->port == USART2 )
140  {
141  handle->usartClock = cmuClock_USART2;
142  handle->txDMASignal = dmadrvPeripheralSignal_USART2_TXBL;
143  handle->rxDMASignal = dmadrvPeripheralSignal_USART2_RXDATAV;
144 #endif
145 #if defined( USART3 )
146  }
147  else if ( initData->port == USART3 )
148  {
149  handle->usartClock = cmuClock_USART3;
150  handle->txDMASignal = dmadrvPeripheralSignal_USART3_TXBL;
151  handle->rxDMASignal = dmadrvPeripheralSignal_USART3_RXDATAV;
152 #endif
153 #if defined( USART4 )
154  }
155  else if ( initData->port == USART4 )
156  {
157  handle->usartClock = cmuClock_USART4;
158  handle->txDMASignal = dmadrvPeripheralSignal_USART4_TXBL;
159  handle->rxDMASignal = dmadrvPeripheralSignal_USART4_RXDATAV;
160 #endif
161 #if defined( USART5 )
162  }
163  else if ( initData->port == USART5 )
164  {
165  handle->usartClock = cmuClock_USART5;
166  handle->txDMASignal = dmadrvPeripheralSignal_USART5_TXBL;
167  handle->rxDMASignal = dmadrvPeripheralSignal_USART5_RXDATAV;
168 #endif
169 #if defined( USARTRF0 )
170  }
171  else if ( initData->port == USARTRF0 )
172  {
173  handle->usartClock = cmuClock_USARTRF0;
174  handle->txDMASignal = dmadrvPeripheralSignal_USARTRF0_TXBL;
175  handle->rxDMASignal = dmadrvPeripheralSignal_USARTRF0_RXDATAV;
176 #endif
177 #if defined( USARTRF1 )
178  }
179  else if ( initData->port == USARTRF1 )
180  {
181  handle->usartClock = cmuClock_USARTRF1;
182  handle->txDMASignal = dmadrvPeripheralSignal_USARTRF1_TXBL;
183  handle->rxDMASignal = dmadrvPeripheralSignal_USARTRF1_RXDATAV;
184 #endif
185  }
186  else
187  {
189  }
190 
191  handle->initData = *initData;
192 
193  if ( initData->bitOrder == spidrvBitOrderMsbFirst )
194  {
195  usartInit.msbf = true;
196  }
197 
198  if ( initData->clockMode == spidrvClockMode0 )
199  {
200  usartInit.clockMode = usartClockMode0;
201  }
202  else if ( initData->clockMode == spidrvClockMode1 )
203  {
204  usartInit.clockMode = usartClockMode1;
205  }
206  else if ( initData->clockMode == spidrvClockMode2 )
207  {
208  usartInit.clockMode = usartClockMode2;
209  }
210  else if ( initData->clockMode == spidrvClockMode3 )
211  {
212  usartInit.clockMode = usartClockMode3;
213  }
214  else
215  {
217  }
218 
219  if ( initData->type == spidrvSlave )
220  {
221  usartInit.master = false;
222  usartInit.baudrate = 1000; // Dummy value needed by USART_InitSync()
223  }
224  else
225  {
226  usartInit.baudrate = initData->bitRate;
227  }
228 
231  CMU_ClockEnable( handle->usartClock, true );
232  USART_InitSync( initData->port, &usartInit );
233 
234  if ( ( initData->type == spidrvMaster )
235  && ( initData->csControl == spidrvCsControlAuto ) )
236  {
237  initData->port->CTRL |= USART_CTRL_AUTOCS;
238  }
239 
240  if ( initData->csControl == spidrvCsControlAuto )
241  {
242  // SPI 4 wire mode
243 #if defined( USART_ROUTEPEN_TXPEN )
244  initData->port->ROUTEPEN = USART_ROUTEPEN_TXPEN
245  | USART_ROUTEPEN_RXPEN
246  | USART_ROUTEPEN_CLKPEN
247  | USART_ROUTEPEN_CSPEN;
248 
249  initData->port->ROUTELOC0 = ( initData->port->ROUTELOC0 &
250  ~( _USART_ROUTELOC0_TXLOC_MASK
251  | _USART_ROUTELOC0_RXLOC_MASK
252  | _USART_ROUTELOC0_CLKLOC_MASK
253  | _USART_ROUTELOC0_CSLOC_MASK ) )
254  | ( initData->portLocationTx << _USART_ROUTELOC0_TXLOC_SHIFT )
255  | ( initData->portLocationRx << _USART_ROUTELOC0_RXLOC_SHIFT )
256  | ( initData->portLocationClk << _USART_ROUTELOC0_CLKLOC_SHIFT )
257  | ( initData->portLocationCs << _USART_ROUTELOC0_CSLOC_SHIFT );
258 #else
259  initData->port->ROUTE = USART_ROUTE_TXPEN
263  | (initData->portLocation
265 #endif
266  }
267  else
268  {
269  // SPI 3 wire mode
270 #if defined( USART_ROUTEPEN_TXPEN )
271  initData->port->ROUTEPEN = USART_ROUTEPEN_TXPEN
272  | USART_ROUTEPEN_RXPEN
273  | USART_ROUTEPEN_CLKPEN;
274 
275  initData->port->ROUTELOC0 = ( initData->port->ROUTELOC0 &
276  ~( _USART_ROUTELOC0_TXLOC_MASK
277  | _USART_ROUTELOC0_RXLOC_MASK
278  | _USART_ROUTELOC0_CLKLOC_MASK ) )
279  | ( initData->portLocationTx << _USART_ROUTELOC0_TXLOC_SHIFT )
280  | ( initData->portLocationRx << _USART_ROUTELOC0_RXLOC_SHIFT )
281  | ( initData->portLocationClk << _USART_ROUTELOC0_CLKLOC_SHIFT );
282 #else
283  initData->port->ROUTE = USART_ROUTE_TXPEN
286  | (initData->portLocation
288 #endif
289  }
290 
291  if ( ( retVal = ConfigGPIO( handle, true ) ) != ECODE_EMDRV_SPIDRV_OK )
292  {
293  return retVal;
294  }
295 
297  if ( ! spidrvIsInitialized )
298  {
299  spidrvIsInitialized = true;
301 
302 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
303  RTCDRV_Init();
304 #endif
305  }
306  else
307  {
309  }
310 
311 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
312  if ( initData->type == spidrvSlave )
313  {
314  if ( RTCDRV_AllocateTimer( &handle->timer ) != ECODE_EMDRV_RTCDRV_OK )
315  {
317  }
318  }
319 #endif
320 
321  // Initialize DMA.
322  DMADRV_Init();
323 
324  if ( DMADRV_AllocateChannel(&handle->txDMACh,NULL) != ECODE_EMDRV_DMADRV_OK )
325  {
327  }
328 
329  if ( DMADRV_AllocateChannel(&handle->rxDMACh,NULL) != ECODE_EMDRV_DMADRV_OK )
330  {
332  }
333 
334  return ECODE_EMDRV_SPIDRV_OK;
335 }
336 
337 /***************************************************************************/
348 {
349  if ( handle == NULL )
350  {
352  }
353 
354  // Stop DMA's.
355  DMADRV_StopTransfer( handle->rxDMACh );
356  DMADRV_StopTransfer( handle->txDMACh );
357 
358  ConfigGPIO( handle, false );
359 
360 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
361  if ( handle->initData.type == spidrvSlave )
362  {
363  RTCDRV_StopTimer( handle->timer );
364  RTCDRV_FreeTimer( handle->timer );
365  }
366 #endif
367 
368  USART_Reset( handle->initData.port );
369  CMU_ClockEnable( handle->usartClock, false );
370 
371  DMADRV_FreeChannel( handle->txDMACh );
372  DMADRV_FreeChannel( handle->rxDMACh );
373  DMADRV_DeInit();
374 
375  return ECODE_EMDRV_SPIDRV_OK;
376 }
377 
378 /***************************************************************************/
389 {
391 
392  if ( handle == NULL )
393  {
395  }
396 
398  if ( handle->state == spidrvStateIdle )
399  {
402  }
403 
404 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
405  if ( handle->initData.type == spidrvSlave )
406  {
407  RTCDRV_StopTimer( handle->timer );
408  }
409 #endif
410 
411  // Stop DMA's.
412  DMADRV_StopTransfer( handle->rxDMACh );
413  DMADRV_StopTransfer( handle->txDMACh );
414  DMADRV_TransferRemainingCount( handle->rxDMACh, &handle->remaining );
415  handle->transferStatus = ECODE_EMDRV_SPIDRV_ABORTED;
416  handle->state = spidrvStateIdle;
417  handle->transferStatus = ECODE_EMDRV_SPIDRV_ABORTED;
418  handle->blockingCompleted = true;
419 
420  if ( handle->userCallback != NULL )
421  {
422  handle->userCallback( handle,
424  handle->transferCount - handle->remaining );
425  }
427 
428  return ECODE_EMDRV_SPIDRV_OK;
429 }
430 
431 /***************************************************************************/
443 Ecode_t SPIDRV_GetBitrate( SPIDRV_Handle_t handle, uint32_t *bitRate )
444 {
445  if ( handle == NULL )
446  {
448  }
449 
450  if ( bitRate == NULL )
451  {
453  }
454 
455  *bitRate = USART_BaudrateGet( handle->initData.port );
456 
457  return ECODE_EMDRV_SPIDRV_OK;
458 }
459 
460 /***************************************************************************/
472 Ecode_t SPIDRV_GetFramelength( SPIDRV_Handle_t handle, uint32_t *frameLength )
473 {
474  if ( handle == NULL )
475  {
477  }
478 
479  if ( frameLength == NULL )
480  {
482  }
483 
484  *frameLength = handle->initData.frameLength;
485 
486  return ECODE_EMDRV_SPIDRV_OK;
487 }
488 
489 /***************************************************************************/
508  int *itemsTransferred,
509  int *itemsRemaining )
510 {
511  int remaining;
512 
513  if ( handle == NULL )
514  {
516  }
517 
518  if ( ( itemsTransferred == NULL ) || ( itemsRemaining == NULL ) )
519  {
521  }
522 
524  if ( handle->state == spidrvStateIdle )
525  {
526  remaining = handle->remaining;
527  }
528  else
529  {
530  DMADRV_TransferRemainingCount( handle->rxDMACh, &remaining );
531  }
532  )
533 
534  *itemsTransferred = handle->transferCount - remaining;
535  *itemsRemaining = remaining;
536 
537  return ECODE_EMDRV_SPIDRV_OK;
538 }
539 
540 /***************************************************************************/
560  void *buffer,
561  int count,
562  SPIDRV_Callback_t callback )
563 {
564  Ecode_t retVal;
565 
566  if ( handle->initData.type == spidrvSlave )
567  {
569  }
570 
571  if ( ( retVal = TransferApiPrologue( handle, buffer, count ) )
573  {
574  return retVal;
575  }
576 
577  StartReceiveDMA( handle, buffer, count, callback );
578 
579  return ECODE_EMDRV_SPIDRV_OK;
580 }
581 
582 /***************************************************************************/
603  void *buffer,
604  int count )
605 {
606  Ecode_t retVal;
607 
608  if ( handle->initData.type == spidrvSlave )
609  {
611  }
612 
613  if ( ( retVal = TransferApiBlockingPrologue( handle, buffer, count ) )
615  {
616  return retVal;
617  }
618 
619  StartReceiveDMA( handle, buffer, count, BlockingComplete );
620 
621  WaitForTransferCompletion( handle );
622 
623  return handle->transferStatus;
624 }
625 
626 /***************************************************************************/
645  const void *txBuffer,
646  void *rxBuffer,
647  int count,
648  SPIDRV_Callback_t callback )
649 {
650  Ecode_t retVal;
651 
652  if ( handle->initData.type == spidrvSlave )
653  {
655  }
656 
657  if ( ( retVal = TransferApiPrologue( handle, (void*)txBuffer, count ) )
659  {
660  return retVal;
661  }
662 
663  if ( rxBuffer == NULL )
664  {
666  }
667 
668  StartTransferDMA( handle, txBuffer, rxBuffer, count, callback );
669 
670  return ECODE_EMDRV_SPIDRV_OK;
671 }
672 
673 /***************************************************************************/
695  const void *txBuffer,
696  void *rxBuffer,
697  int count )
698 {
699  Ecode_t retVal;
700 
701  if ( handle->initData.type == spidrvSlave )
702  {
704  }
705 
706  if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)txBuffer, count ))
708  {
709  return retVal;
710  }
711 
712  if ( rxBuffer == NULL )
713  {
715  }
716 
717  StartTransferDMA( handle, txBuffer, rxBuffer, count, BlockingComplete );
718 
719  WaitForTransferCompletion( handle );
720 
721  return handle->transferStatus;
722 }
723 
724 /***************************************************************************/
744  uint32_t txValue,
745  void *rxValue )
746 {
747  void *pRx;
749  uint32_t rxBuffer;
750 
751  if ( handle == NULL )
752  {
754  }
755 
756  if ( handle->initData.type == spidrvSlave )
757  {
759  }
760 
762  if ( handle->state != spidrvStateIdle )
763  {
766  }
767  handle->state = spidrvStateTransferring;
769 
770  if ( ( pRx = rxValue ) == NULL )
771  {
772  pRx = &rxBuffer;
773  }
774 
775  StartTransferDMA( handle, &txValue, pRx, 1, BlockingComplete );
776 
777  WaitForTransferCompletion( handle );
778 
779  return handle->transferStatus;
780 }
781 
782 /***************************************************************************/
802  const void *buffer,
803  int count,
804  SPIDRV_Callback_t callback )
805 {
806  Ecode_t retVal;
807 
808  if ( handle->initData.type == spidrvSlave )
809  {
811  }
812 
813  if ( ( retVal = TransferApiPrologue( handle, (void*)buffer, count ) )
815  {
816  return retVal;
817  }
818 
819  StartTransmitDMA( handle, buffer, count, callback );
820 
821  return ECODE_EMDRV_SPIDRV_OK;
822 }
823 
824 /***************************************************************************/
844  const void *buffer,
845  int count )
846 {
847  Ecode_t retVal;
848 
849  if ( handle->initData.type == spidrvSlave )
850  {
852  }
853 
854  if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)buffer, count ) )
856  {
857  return retVal;
858  }
859 
860  StartTransmitDMA( handle, buffer, count, BlockingComplete );
861 
862  WaitForTransferCompletion( handle );
863 
864  return handle->transferStatus;
865 }
866 
867 /***************************************************************************/
879 Ecode_t SPIDRV_SetBitrate( SPIDRV_Handle_t handle, uint32_t bitRate )
880 {
882 
883  if ( handle == NULL )
884  {
886  }
887 
889  if ( handle->state != spidrvStateIdle )
890  {
893  }
894 
895  handle->initData.bitRate = bitRate;
896  USART_BaudrateSyncSet( handle->initData.port, 0, bitRate );
898 
899  return ECODE_EMDRV_SPIDRV_OK;
900 }
901 
902 /***************************************************************************/
914 Ecode_t SPIDRV_SetFramelength( SPIDRV_Handle_t handle, uint32_t frameLength )
915 {
917 
918  if ( handle == NULL )
919  {
921  }
922 
923  frameLength -= 3;
924  if ( ( frameLength < _USART_FRAME_DATABITS_FOUR )
925  || ( frameLength > _USART_FRAME_DATABITS_SIXTEEN ) )
926  {
928  }
929 
931  if ( handle->state != spidrvStateIdle )
932  {
935  }
936 
937  handle->initData.frameLength = frameLength + 3;
938  handle->initData.port->FRAME = ( handle->initData.port->FRAME
940  | ( frameLength
943 
944  return ECODE_EMDRV_SPIDRV_OK;
945 }
946 
947 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
948 /***************************************************************************/
970  void *buffer,
971  int count,
972  SPIDRV_Callback_t callback,
973  int timeoutMs )
974 {
975  Ecode_t retVal;
976 
977  if ( handle->initData.type == spidrvMaster )
978  {
980  }
981 
982  if ( ( retVal = TransferApiPrologue( handle, buffer, count ) )
984  {
985  return retVal;
986  }
987 
988  if ( timeoutMs )
989  {
990  RTCDRV_StartTimer( handle->timer,
992  timeoutMs,
993  SlaveTimeout,
994  handle );
995  }
996 
997  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
998  {
999  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1000  {
1001  return retVal;
1002  }
1003  }
1004 
1005  StartReceiveDMA( handle, buffer, count, callback );
1006 
1007  return ECODE_EMDRV_SPIDRV_OK;
1008 }
1009 
1010 /***************************************************************************/
1034  void *buffer,
1035  int count,
1036  int timeoutMs )
1037 {
1038  Ecode_t retVal;
1039 
1040  if ( handle->initData.type == spidrvMaster )
1041  {
1043  }
1044 
1045  if ( ( retVal = TransferApiBlockingPrologue( handle, buffer, count ) )
1047  {
1048  return retVal;
1049  }
1050 
1051  if ( timeoutMs )
1052  {
1053  RTCDRV_StartTimer( handle->timer,
1055  timeoutMs,
1056  SlaveTimeout,
1057  handle );
1058  }
1059 
1060  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1061  {
1062  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1063  {
1064  return retVal;
1065  }
1066  }
1067 
1068  StartReceiveDMA( handle, buffer, count, BlockingComplete );
1069 
1070  WaitForTransferCompletion( handle );
1071 
1072  return handle->transferStatus;
1073 }
1074 
1075 /***************************************************************************/
1096  const void *txBuffer,
1097  void *rxBuffer,
1098  int count,
1099  SPIDRV_Callback_t callback,
1100  int timeoutMs )
1101 {
1102  Ecode_t retVal;
1103 
1104  if ( handle->initData.type == spidrvMaster )
1105  {
1107  }
1108 
1109  if ( ( retVal = TransferApiPrologue( handle, (void*)txBuffer, count ) )
1111  {
1112  return retVal;
1113  }
1114 
1115  if ( rxBuffer == NULL )
1116  {
1118  }
1119 
1120  if ( timeoutMs )
1121  {
1122  RTCDRV_StartTimer( handle->timer,
1124  timeoutMs,
1125  SlaveTimeout,
1126  handle );
1127  }
1128 
1129  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1130  {
1131  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1132  {
1133  return retVal;
1134  }
1135  }
1136 
1137  StartTransferDMA( handle, txBuffer, rxBuffer, count, callback );
1138 
1139  return ECODE_EMDRV_SPIDRV_OK;
1140 }
1141 
1142 /***************************************************************************/
1167  const void *txBuffer,
1168  void *rxBuffer,
1169  int count,
1170  int timeoutMs )
1171 {
1172  Ecode_t retVal;
1173 
1174  if ( handle->initData.type == spidrvMaster )
1175  {
1177  }
1178 
1179  if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)txBuffer, count ))
1181  {
1182  return retVal;
1183  }
1184 
1185  if ( rxBuffer == NULL )
1186  {
1188  }
1189 
1190  if ( timeoutMs )
1191  {
1192  RTCDRV_StartTimer( handle->timer,
1194  timeoutMs,
1195  SlaveTimeout,
1196  handle );
1197  }
1198 
1199  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1200  {
1201  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1202  {
1203  return retVal;
1204  }
1205  }
1206 
1207  StartTransferDMA( handle, txBuffer, rxBuffer, count, BlockingComplete );
1208 
1209  WaitForTransferCompletion( handle );
1210 
1211  return handle->transferStatus;
1212 }
1213 
1214 /***************************************************************************/
1236  const void *buffer,
1237  int count,
1238  SPIDRV_Callback_t callback,
1239  int timeoutMs )
1240 {
1241  Ecode_t retVal;
1242 
1243  if ( handle->initData.type == spidrvMaster )
1244  {
1246  }
1247 
1248  if ( ( retVal = TransferApiPrologue( handle, (void*)buffer, count ) )
1250  {
1251  return retVal;
1252  }
1253 
1254  if ( timeoutMs )
1255  {
1256  RTCDRV_StartTimer( handle->timer,
1258  timeoutMs,
1259  SlaveTimeout,
1260  handle );
1261  }
1262 
1263  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1264  {
1265  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1266  {
1267  return retVal;
1268  }
1269  }
1270 
1271  StartTransmitDMA( handle, buffer, count, callback );
1272 
1273  return ECODE_EMDRV_SPIDRV_OK;
1274 }
1275 
1276 /***************************************************************************/
1300  const void *buffer,
1301  int count,
1302  int timeoutMs )
1303 {
1304  Ecode_t retVal;
1305 
1306  if ( handle->initData.type == spidrvMaster )
1307  {
1309  }
1310 
1311  if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)buffer, count ) )
1313  {
1314  return retVal;
1315  }
1316 
1317  if ( timeoutMs )
1318  {
1319  RTCDRV_StartTimer( handle->timer,
1321  timeoutMs,
1322  SlaveTimeout,
1323  handle );
1324  }
1325 
1326  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1327  {
1328  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1329  {
1330  return retVal;
1331  }
1332  }
1333 
1334  StartTransmitDMA( handle, buffer, count, BlockingComplete );
1335 
1336  WaitForTransferCompletion( handle );
1337 
1338  return handle->transferStatus;
1339 }
1340 #endif
1341 
1343 
1344 /***************************************************************************/
1350 static void BlockingComplete( SPIDRV_Handle_t handle,
1351  Ecode_t transferStatus,
1352  int itemsTransferred )
1353 {
1354  (void)itemsTransferred;
1355 
1356  handle->transferStatus = transferStatus;
1357  handle->blockingCompleted = true;
1358 }
1359 
1360 /***************************************************************************/
1363 static Ecode_t ConfigGPIO( SPIDRV_Handle_t handle, bool enable )
1364 {
1365 #if defined( _USART_ROUTELOC0_MASK )
1366  SPIDRV_Init_t *initData;
1367 #else
1368  uint32_t location;
1369 #endif
1370  int mosiPin, misoPin, clkPin;
1371  int mosiPort, misoPort, clkPort;
1372 
1373 #if defined( _USART_ROUTELOC0_MASK )
1374  initData = &handle->initData;
1375 
1376  if ( 0 )
1377  {
1378 #if defined( USART0 )
1379  }
1380  else if ( handle->initData.port == USART0 )
1381  {
1382  mosiPort = AF_USART0_TX_PORT( initData->portLocationTx );
1383  misoPort = AF_USART0_RX_PORT( initData->portLocationRx );
1384  clkPort = AF_USART0_CLK_PORT( initData->portLocationClk );
1385  handle->csPort = AF_USART0_CS_PORT( initData->portLocationCs );
1386  mosiPin = AF_USART0_TX_PIN( initData->portLocationTx );
1387  misoPin = AF_USART0_RX_PIN( initData->portLocationRx );
1388  clkPin = AF_USART0_CLK_PIN( initData->portLocationClk );
1389  handle->csPin = AF_USART0_CS_PIN( initData->portLocationCs );
1390 #endif
1391 #if defined( USART1 )
1392  }
1393  else if ( handle->initData.port == USART1 )
1394  {
1395  mosiPort = AF_USART1_TX_PORT( initData->portLocationTx );
1396  misoPort = AF_USART1_RX_PORT( initData->portLocationRx );
1397  clkPort = AF_USART1_CLK_PORT( initData->portLocationClk );
1398  handle->csPort = AF_USART1_CS_PORT( initData->portLocationCs );
1399  mosiPin = AF_USART1_TX_PIN( initData->portLocationTx );
1400  misoPin = AF_USART1_RX_PIN( initData->portLocationRx );
1401  clkPin = AF_USART1_CLK_PIN( initData->portLocationClk );
1402  handle->csPin = AF_USART1_CS_PIN( initData->portLocationCs );
1403 #endif
1404 #if defined( USART2 )
1405  }
1406  else if ( handle->initData.port == USART2 )
1407  {
1408  mosiPort = AF_USART2_TX_PORT( initData->portLocationTx );
1409  misoPort = AF_USART2_RX_PORT( initData->portLocationRx );
1410  clkPort = AF_USART2_CLK_PORT( initData->portLocationClk );
1411  handle->csPort = AF_USART2_CS_PORT( initData->portLocationCs );
1412  mosiPin = AF_USART2_TX_PIN( initData->portLocationTx );
1413  misoPin = AF_USART2_RX_PIN( initData->portLocationRx );
1414  clkPin = AF_USART2_CLK_PIN( initData->portLocationClk );
1415  handle->csPin = AF_USART2_CS_PIN( initData->portLocationCs );
1416 #endif
1417 #if defined( USART3 )
1418  }
1419  else if ( handle->initData.port == USART3 )
1420  {
1421  mosiPort = AF_USART3_TX_PORT( initData->portLocationTx );
1422  misoPort = AF_USART3_RX_PORT( initData->portLocationRx );
1423  clkPort = AF_USART3_CLK_PORT( initData->portLocationClk );
1424  handle->csPort = AF_USART3_CS_PORT( initData->portLocationCs );
1425  mosiPin = AF_USART3_TX_PIN( initData->portLocationTx );
1426  misoPin = AF_USART3_RX_PIN( initData->portLocationRx );
1427  clkPin = AF_USART3_CLK_PIN( initData->portLocationClk );
1428  handle->csPin = AF_USART3_CS_PIN( initData->portLocationCs );
1429 #endif
1430 #if defined( USART4 )
1431  }
1432  else if ( handle->initData.port == USART4 )
1433  {
1434  mosiPort = AF_USART4_TX_PORT( initData->portLocationTx );
1435  misoPort = AF_USART4_RX_PORT( initData->portLocationRx );
1436  clkPort = AF_USART4_CLK_PORT( initData->portLocationClk );
1437  handle->csPort = AF_USART4_CS_PORT( initData->portLocationCs );
1438  mosiPin = AF_USART4_TX_PIN( initData->portLocationTx );
1439  misoPin = AF_USART4_RX_PIN( initData->portLocationRx );
1440  clkPin = AF_USART4_CLK_PIN( initData->portLocationClk );
1441  handle->csPin = AF_USART4_CS_PIN( initData->portLocationCs );
1442 #endif
1443 #if defined( USART5 )
1444  }
1445  else if ( handle->initData.port == USART5 )
1446  {
1447  mosiPort = AF_USART5_TX_PORT( initData->portLocationTx );
1448  misoPort = AF_USART5_RX_PORT( initData->portLocationRx );
1449  clkPort = AF_USART5_CLK_PORT( initData->portLocationClk );
1450  handle->csPort = AF_USART5_CS_PORT( initData->portLocationCs );
1451  mosiPin = AF_USART5_TX_PIN( initData->portLocationTx );
1452  misoPin = AF_USART5_RX_PIN( initData->portLocationRx );
1453  clkPin = AF_USART5_CLK_PIN( initData->portLocationClk );
1454  handle->csPin = AF_USART5_CS_PIN( initData->portLocationCs );
1455 #endif
1456 #if defined( USARTRF0 )
1457  }
1458  else if ( handle->initData.port == USARTRF0 )
1459  {
1460  mosiPort = AF_USARTRF0_TX_PORT( initData->portLocationTx );
1461  misoPort = AF_USARTRF0_RX_PORT( initData->portLocationRx );
1462  clkPort = AF_USARTRF0_CLK_PORT( initData->portLocationClk );
1463  handle->csPort = AF_USARTRF0_CS_PORT( initData->portLocationCs );
1464  mosiPin = AF_USARTRF0_TX_PIN( initData->portLocationTx );
1465  misoPin = AF_USARTRF0_RX_PIN( initData->portLocationRx );
1466  clkPin = AF_USARTRF0_CLK_PIN( initData->portLocationClk );
1467  handle->csPin = AF_USARTRF0_CS_PIN( initData->portLocationCs );
1468 #endif
1469 #if defined( USARTRF1 )
1470  }
1471  else if ( handle->initData.port == USARTRF1 )
1472  {
1473  mosiPort = AF_USARTRF1_TX_PORT( initData->portLocationTx );
1474  misoPort = AF_USARTRF1_RX_PORT( initData->portLocationRx );
1475  clkPort = AF_USARTRF1_CLK_PORT( initData->portLocationClk );
1476  handle->csPort = AF_USARTRF1_CS_PORT( initData->portLocationCs );
1477  mosiPin = AF_USARTRF1_TX_PIN( initData->portLocationTx );
1478  misoPin = AF_USARTRF1_RX_PIN( initData->portLocationRx );
1479  clkPin = AF_USARTRF1_CLK_PIN( initData->portLocationClk );
1480  handle->csPin = AF_USARTRF1_CS_PIN( initData->portLocationCs );
1481 #endif
1482  }
1483  else
1484  {
1486  }
1487 
1488 #else
1489  location = handle->initData.portLocation;
1490 
1491  if ( 0 )
1492  {
1493 #if defined( USART0 )
1494  }
1495  else if ( handle->initData.port == USART0 )
1496  {
1497  mosiPort = AF_USART0_TX_PORT( location );
1498  misoPort = AF_USART0_RX_PORT( location );
1499  clkPort = AF_USART0_CLK_PORT( location );
1500  handle->csPort = AF_USART0_CS_PORT( location );
1501  mosiPin = AF_USART0_TX_PIN( location );
1502  misoPin = AF_USART0_RX_PIN( location );
1503  clkPin = AF_USART0_CLK_PIN( location );
1504  handle->csPin = AF_USART0_CS_PIN( location );
1505 #endif
1506 #if defined( USART1 )
1507  }
1508  else if ( handle->initData.port == USART1 )
1509  {
1510  mosiPort = AF_USART1_TX_PORT( location );
1511  misoPort = AF_USART1_RX_PORT( location );
1512  clkPort = AF_USART1_CLK_PORT( location );
1513  handle->csPort = AF_USART1_CS_PORT( location );
1514  mosiPin = AF_USART1_TX_PIN( location );
1515  misoPin = AF_USART1_RX_PIN( location );
1516  clkPin = AF_USART1_CLK_PIN( location );
1517  handle->csPin = AF_USART1_CS_PIN( location );
1518 #endif
1519 #if defined( USART2 )
1520  }
1521  else if ( handle->initData.port == USART2 )
1522  {
1523  mosiPort = AF_USART2_TX_PORT( location );
1524  misoPort = AF_USART2_RX_PORT( location );
1525  clkPort = AF_USART2_CLK_PORT( location );
1526  handle->csPort = AF_USART2_CS_PORT( location );
1527  mosiPin = AF_USART2_TX_PIN( location );
1528  misoPin = AF_USART2_RX_PIN( location );
1529  clkPin = AF_USART2_CLK_PIN( location );
1530  handle->csPin = AF_USART2_CS_PIN( location );
1531 #endif
1532 #if defined( USARTRF0 )
1533  }
1534  else if ( handle->initData.port == USARTRF0 )
1535  {
1536  mosiPort = AF_USARTRF0_TX_PORT( location );
1537  misoPort = AF_USARTRF0_RX_PORT( location );
1538  clkPort = AF_USARTRF0_CLK_PORT( location );
1539  handle->csPort = AF_USARTRF0_CS_PORT( location );
1540  mosiPin = AF_USARTRF0_TX_PIN( location );
1541  misoPin = AF_USARTRF0_RX_PIN( location );
1542  clkPin = AF_USARTRF0_CLK_PIN( location );
1543  handle->csPin = AF_USARTRF0_CS_PIN( location );
1544 #endif
1545 #if defined( USARTRF1 )
1546  }
1547  else if ( handle->initData.port == USARTRF1 )
1548  {
1549  mosiPort = AF_USARTRF1_TX_PORT( location );
1550  misoPort = AF_USARTRF1_RX_PORT( location );
1551  clkPort = AF_USARTRF1_CLK_PORT( location );
1552  handle->csPort = AF_USARTRF1_CS_PORT( location );
1553  mosiPin = AF_USARTRF1_TX_PIN( location );
1554  misoPin = AF_USARTRF1_RX_PIN( location );
1555  clkPin = AF_USARTRF1_CLK_PIN( location );
1556  handle->csPin = AF_USARTRF1_CS_PIN( location );
1557 #endif
1558  }
1559  else
1560  {
1562  }
1563 #endif
1564 
1565  if ( enable )
1566  {
1567  if ( handle->initData.type == spidrvMaster )
1568  {
1569  GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin,
1570  gpioModePushPull, 0 );
1571  GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin,
1572  gpioModeInputPull, 0 );
1573 
1574  if ( ( handle->initData.clockMode == spidrvClockMode0 )
1575  || ( handle->initData.clockMode == spidrvClockMode1 ) )
1576  {
1577  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
1578  gpioModePushPull, 0 );
1579  }
1580  else
1581  {
1582  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
1583  gpioModePushPull, 1 );
1584  }
1585 
1586  if ( handle->initData.csControl == spidrvCsControlAuto )
1587  {
1588  GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
1589  gpioModePushPull, 1 );
1590  }
1591  }
1592  else
1593  {
1594  GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin,
1595  gpioModeInputPull, 0 );
1596  GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin,
1597  gpioModePushPull, 0 );
1598 
1599  if ( ( handle->initData.clockMode == spidrvClockMode0 )
1600  || ( handle->initData.clockMode == spidrvClockMode1 ) )
1601  {
1602  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
1603  gpioModeInputPull, 0 );
1604  }
1605  else
1606  {
1607  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
1608  gpioModeInputPull, 1 );
1609  }
1610 
1611  if ( handle->initData.csControl == spidrvCsControlAuto )
1612  {
1613  GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
1614  gpioModeInputPull, 1 );
1615  }
1616  }
1617  }
1618  else
1619  {
1620  GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin, gpioModeInputPull,0);
1621  GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin, gpioModeInputPull,0);
1622 
1623  if ( ( handle->initData.clockMode == spidrvClockMode0 )
1624  || ( handle->initData.clockMode == spidrvClockMode1 ) )
1625  {
1626  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin, gpioModeInputPull,0);
1627  }
1628  else
1629  {
1630  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin, gpioModeInputPull,1);
1631  }
1632 
1633  if ( handle->initData.csControl == spidrvCsControlAuto )
1634  {
1635  GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
1636  gpioModeDisabled, 0);
1637  }
1638  }
1639 
1640  return ECODE_EMDRV_SPIDRV_OK;
1641 }
1642 
1643 /***************************************************************************/
1646 static bool RxDMAComplete( unsigned int channel,
1647  unsigned int sequenceNo,
1648  void *userParam )
1649 {
1651  SPIDRV_Handle_t handle;
1652  (void)channel;
1653  (void)sequenceNo;
1654 
1656 
1657  handle = (SPIDRV_Handle_t)userParam;
1658 
1659  handle->transferStatus = ECODE_EMDRV_SPIDRV_OK;
1660  handle->state = spidrvStateIdle;
1661  handle->remaining = 0;
1662 
1663 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
1664  if ( handle->initData.type == spidrvSlave )
1665  {
1666  RTCDRV_StopTimer( handle->timer );
1667  }
1668 #endif
1669 
1670  if ( handle->userCallback != NULL )
1671  {
1672  handle->userCallback( handle, ECODE_EMDRV_SPIDRV_OK, handle->transferCount);
1673  }
1674 
1675  CORE_EXIT_ATOMIC();
1676  return true;
1677 }
1678 
1679 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
1680 /***************************************************************************/
1683 static void SlaveTimeout( RTCDRV_TimerID_t id, void *user )
1684 {
1685  bool active, pending;
1686  SPIDRV_Handle_t handle;
1687  (void)id;
1688 
1689  handle = (SPIDRV_Handle_t)user;
1690 
1691  if ( handle->state == spidrvStateTransferring )
1692  {
1693  DMADRV_TransferActive( handle->rxDMACh, &active );
1694  if ( active )
1695  {
1696  // Stop running DMA's
1697  DMADRV_StopTransfer( handle->rxDMACh );
1698  DMADRV_StopTransfer( handle->txDMACh );
1699  DMADRV_TransferRemainingCount( handle->rxDMACh, &handle->remaining );
1700  }
1701  else
1702  {
1703  // DMA is either completed or not yet started
1704  DMADRV_TransferCompletePending( handle->txDMACh, &pending );
1705  if ( pending )
1706  {
1707  // We have a pending DMA interrupt, let the DMA handler do the rest
1708  return;
1709  }
1710  handle->remaining = handle->transferCount;
1711  }
1712  handle->transferStatus = ECODE_EMDRV_SPIDRV_TIMEOUT;
1713  handle->state = spidrvStateIdle;
1714 
1715  if ( handle->userCallback != NULL )
1716  {
1717  handle->userCallback( handle,
1719  handle->transferCount - handle->remaining );
1720  }
1721  }
1722 }
1723 #endif
1724 
1725 /***************************************************************************/
1728 static void StartReceiveDMA( SPIDRV_Handle_t handle,
1729  void *buffer,
1730  int count,
1731  SPIDRV_Callback_t callback )
1732 {
1733  void *rxPort, *txPort;
1734  DMADRV_DataSize_t size;
1735 
1736  handle->blockingCompleted = false;
1737  handle->transferCount = count;
1738  handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
1739  handle->userCallback = callback;
1740 
1741  if ( handle->initData.frameLength > 8 )
1742  {
1743  size = dmadrvDataSize2;
1744  }
1745  else
1746  {
1747  size = dmadrvDataSize1;
1748  }
1749 
1750  if ( handle->initData.frameLength > 8 )
1751  {
1752  rxPort = (void *)&(handle->initData.port->RXDOUBLE);
1753  txPort = (void *)&(handle->initData.port->TXDOUBLE);
1754  }
1755  else
1756  {
1757  rxPort = (void *)&(handle->initData.port->RXDATA);
1758  txPort = (void *)&(handle->initData.port->TXDATA);
1759  }
1760 
1761  // Start receive dma.
1762  DMADRV_PeripheralMemory( handle->rxDMACh,
1763  handle->rxDMASignal,
1764  (void*)buffer,
1765  rxPort,
1766  true,
1767  count,
1768  size,
1769  RxDMAComplete,
1770  handle );
1771 
1772  // Start transmit dma.
1773  DMADRV_MemoryPeripheral( handle->txDMACh,
1774  handle->txDMASignal,
1775  txPort,
1776  (void *)&(handle->initData.dummyTxValue),
1777  false,
1778  count,
1779  size,
1780  NULL,
1781  NULL );
1782 }
1783 
1784 /***************************************************************************/
1787 static void StartTransferDMA( SPIDRV_Handle_t handle,
1788  const void *txBuffer,
1789  void *rxBuffer,
1790  int count,
1791  SPIDRV_Callback_t callback )
1792 {
1793  void *rxPort, *txPort;
1794  DMADRV_DataSize_t size;
1795 
1796  handle->blockingCompleted = false;
1797  handle->transferCount = count;
1798  handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
1799  handle->userCallback = callback;
1800 
1801  if ( handle->initData.frameLength > 8 )
1802  {
1803  size = dmadrvDataSize2;
1804  }
1805  else
1806  {
1807  size = dmadrvDataSize1;
1808  }
1809 
1810  if ( handle->initData.frameLength > 8 )
1811  {
1812  rxPort = (void *)&(handle->initData.port->RXDOUBLE);
1813  txPort = (void *)&(handle->initData.port->TXDOUBLE);
1814  }
1815  else
1816  {
1817  rxPort = (void *)&(handle->initData.port->RXDATA);
1818  txPort = (void *)&(handle->initData.port->TXDATA);
1819  }
1820 
1821  // Start receive dma.
1822  DMADRV_PeripheralMemory( handle->rxDMACh,
1823  handle->rxDMASignal,
1824  rxBuffer,
1825  rxPort,
1826  true,
1827  count,
1828  size,
1829  RxDMAComplete,
1830  handle );
1831 
1832  // Start transmit dma.
1833  DMADRV_MemoryPeripheral( handle->txDMACh,
1834  handle->txDMASignal,
1835  txPort,
1836  (void*)txBuffer,
1837  true,
1838  count,
1839  size,
1840  NULL,
1841  NULL );
1842 }
1843 
1844 /***************************************************************************/
1847 static void StartTransmitDMA( SPIDRV_Handle_t handle,
1848  const void *buffer,
1849  int count,
1850  SPIDRV_Callback_t callback )
1851 {
1852  void *rxPort, *txPort;
1853  DMADRV_DataSize_t size;
1854 
1855  handle->blockingCompleted = false;
1856  handle->transferCount = count;
1857  handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
1858  handle->userCallback = callback;
1859 
1860  if ( handle->initData.frameLength > 8 )
1861  {
1862  size = dmadrvDataSize2;
1863  }
1864  else
1865  {
1866  size = dmadrvDataSize1;
1867  }
1868 
1869  if ( handle->initData.frameLength > 8 )
1870  {
1871  rxPort = (void *)&(handle->initData.port->RXDOUBLE);
1872  txPort = (void *)&(handle->initData.port->TXDOUBLE);
1873  }
1874  else
1875  {
1876  rxPort = (void *)&(handle->initData.port->RXDATA);
1877  txPort = (void *)&(handle->initData.port->TXDATA);
1878  }
1879 
1880  // Receive DMA runs only to get precise numbers for SPIDRV_GetTransferStatus()
1881  // Start receive dma.
1882  DMADRV_PeripheralMemory( handle->rxDMACh,
1883  handle->rxDMASignal,
1884  &(handle->dummyRx),
1885  rxPort,
1886  false,
1887  count,
1888  size,
1889  RxDMAComplete,
1890  handle );
1891 
1892  // Start transmit dma.
1893  DMADRV_MemoryPeripheral( handle->txDMACh,
1894  handle->txDMASignal,
1895  txPort,
1896  (void*)buffer,
1897  true,
1898  count,
1899  size,
1900  NULL,
1901  NULL );
1902 }
1903 
1904 /***************************************************************************/
1907 static Ecode_t TransferApiBlockingPrologue( SPIDRV_Handle_t handle,
1908  void *buffer,
1909  int count )
1910 {
1912 
1913  if ( handle == NULL )
1914  {
1916  }
1917 
1918  if (( buffer == NULL ) || ( count == 0 )|| ( count > DMADRV_MAX_XFER_COUNT ))
1919  {
1921  }
1922 
1924  if ( handle->state != spidrvStateIdle )
1925  {
1926  CORE_EXIT_ATOMIC();
1927  return ECODE_EMDRV_SPIDRV_BUSY;
1928  }
1929  handle->state = spidrvStateTransferring;
1930  CORE_EXIT_ATOMIC();
1931 
1932  return ECODE_EMDRV_SPIDRV_OK;
1933 }
1934 
1935 /***************************************************************************/
1938 static Ecode_t TransferApiPrologue( SPIDRV_Handle_t handle,
1939  void *buffer,
1940  int count )
1941 {
1943 
1944  if ( handle == NULL )
1945  {
1947  }
1948 
1949  if (( buffer == NULL ) || ( count == 0 ) || ( count > DMADRV_MAX_XFER_COUNT ))
1950  {
1952  }
1953 
1955  if ( handle->state != spidrvStateIdle )
1956  {
1957  CORE_EXIT_ATOMIC();
1958  return ECODE_EMDRV_SPIDRV_BUSY;
1959  }
1960  handle->state = spidrvStateTransferring;
1961  CORE_EXIT_ATOMIC();
1962 
1963  return ECODE_EMDRV_SPIDRV_OK;
1964 }
1965 
1966 /***************************************************************************/
1969 static void WaitForTransferCompletion( SPIDRV_Handle_t handle )
1970 {
1971  if (CORE_IrqIsBlocked(SPI_DMA_IRQ))
1972  {
1973  // Poll for completion by calling IRQ handler.
1974  while ( handle->blockingCompleted == false )
1975  {
1976 #if defined( DMA_PRESENT ) && ( DMA_COUNT == 1 )
1977  DMA_IRQHandler();
1978 #elif defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 )
1979  LDMA_IRQHandler();
1980 #else
1981 #error "No valid SPIDRV DMA engine defined."
1982 #endif
1983  }
1984  }
1985  else
1986  {
1987  while ( handle->blockingCompleted == false );
1988  }
1989 }
1990 
1991 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
1992 /***************************************************************************/
1995 static Ecode_t WaitForIdleLine( SPIDRV_Handle_t handle )
1996 {
1997  while ( !GPIO_PinInGet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin )
1998  && ( handle->state != spidrvStateIdle ) );
1999 
2000  if ( handle->state == spidrvStateIdle )
2001  {
2002  return handle->transferStatus;
2003  }
2004 
2005  return ECODE_EMDRV_SPIDRV_OK;
2006 }
2007 #endif
2008 
2010 
2011 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/
#define ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE
Illegal SPI handle.
Definition: spidrv.h:44
#define USART_CMD_CLEARRX
Ecode_t SPIDRV_GetTransferStatus(SPIDRV_Handle_t handle, int *itemsTransferred, int *itemsRemaining)
Get the status of a SPI transfer.
Definition: spidrv.c:507
SPIDRV_Type_t type
SPI type, master or slave.
Definition: spidrv.h:137
DMADRV API definition.
Ecode_t SPIDRV_DeInit(SPIDRV_Handle_t handle)
Deinitialize a SPI driver instance.
Definition: spidrv.c:347
Ecode_t SPIDRV_AbortTransfer(SPIDRV_Handle_t handle)
Abort an ongoing SPI transfer.
Definition: spidrv.c:388
Trig on USART0_RXDATAV.
Definition: dmadrv.h:232
#define CORE_DECLARE_IRQ_STATE
Definition: em_core.h:85
Trig on USART0_TXBL.
Definition: dmadrv.h:235
GPIO_Port_TypeDef
Definition: em_gpio.h:345
uint32_t RTCDRV_TimerID_t
Timer ID.
Definition: rtcdriver.h:47
Act as SPI slave.
Definition: spidrv.h:58
#define ECODE_EMDRV_RTCDRV_OK
Success return value.
Definition: rtcdriver.h:39
Trig on USART1_RXDATAV.
Definition: dmadrv.h:259
#define USART1
#define USART_ROUTE_TXPEN
Ecode_t SPIDRV_STransferB(SPIDRV_Handle_t handle, const void *txBuffer, void *rxBuffer, int count, int timeoutMs)
Start a SPI slave blocking transfer.
Definition: spidrv.c:1166
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:539
SPIDRV API definition.
Ecode_t SPIDRV_GetBitrate(SPIDRV_Handle_t handle, uint32_t *bitRate)
Get current SPI bus bitrate.
Definition: spidrv.c:443
void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init)
Init USART for synchronous mode.
Definition: em_usart.c:640
#define ECODE_EMDRV_SPIDRV_ABORTED
SPI transfer has been aborted.
Definition: spidrv.h:50
Ecode_t SPIDRV_MTransmitB(SPIDRV_Handle_t handle, const void *buffer, int count)
Start a SPI master blocking transmit transfer.
Definition: spidrv.c:843
Ecode_t DMADRV_TransferActive(unsigned int channelId, bool *active)
Check if a transfer is running.
Definition: dmadrv.c:759
Oneshot timer.
Definition: rtcdriver.h:67
#define ECODE_EMDRV_SPIDRV_TIMER_ALLOC_ERROR
Unable to allocated timeout timer.
Definition: spidrv.h:47
#define ECODE_EMDRV_SPIDRV_MODE_ERROR
SPI master used slave API or vica versa.
Definition: spidrv.h:51
void USART_BaudrateSyncSet(USART_TypeDef *usart, uint32_t refFreq, uint32_t baudrate)
Configure USART operating in synchronous mode to use a given baudrate (or as close as possible to spe...
Definition: em_usart.c:480
MSB bit is transmitted first.
Definition: spidrv.h:65
Ecode_t SPIDRV_MTransfer(SPIDRV_Handle_t handle, const void *txBuffer, void *rxBuffer, int count, SPIDRV_Callback_t callback)
Start a SPI master transfer.
Definition: spidrv.c:644
void DMA_IRQHandler(void)
Interrupt handler for DMA cycle completion handling.
Definition: em_dma.c:284
Ecode_t SPIDRV_MReceive(SPIDRV_Handle_t handle, void *buffer, int count, SPIDRV_Callback_t callback)
Start a SPI master receive transfer.
Definition: spidrv.c:559
SPIDRV_BitOrder_t bitOrder
Bit order on SPI bus, MSB or LSB first.
Definition: spidrv.h:138
USART_TypeDef * port
The USART used for SPI.
Definition: spidrv.h:125
Ecode_t SPIDRV_MTransferSingleItemB(SPIDRV_Handle_t handle, uint32_t txValue, void *rxValue)
Start a SPI master blocking single item (frame) transfer.
Definition: spidrv.c:743
Ecode_t DMADRV_StopTransfer(unsigned int channelId)
Stop an ongoing DMA transfer.
Definition: dmadrv.c:719
Ecode_t RTCDRV_AllocateTimer(RTCDRV_TimerID_t *id)
Allocate timer.
Definition: rtcdriver.c:231
Halfword.
Definition: dmadrv.h:298
#define _USART_FRAME_DATABITS_MASK
#define ECODE_EMDRV_SPIDRV_IDLE
No SPI transfer in progress.
Definition: spidrv.h:49
Ecode_t SPIDRV_MTransferB(SPIDRV_Handle_t handle, const void *txBuffer, void *rxBuffer, int count)
Start a SPI master blocking transfer.
Definition: spidrv.c:694
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
Universal synchronous/asynchronous receiver/transmitter (USART/UART) peripheral API.
__IOM uint32_t CTRL
Definition: efm32hg_usart.h:43
#define USART_CMD_CLEARTX
#define ECODE_EMDRV_SPIDRV_DMA_ALLOC_ERROR
Unable to allocated DMA channels.
Definition: spidrv.h:52
SPI mode 2: CLKPOL=1, CLKPHA=0.
Definition: spidrv.h:73
#define ECODE_EMDRV_SPIDRV_PARAM_ERROR
Illegal input parameter.
Definition: spidrv.h:45
uint8_t portLocation
Location number for SPI pins.
Definition: spidrv.h:132
Byte.
Definition: dmadrv.h:297
uint32_t bitRate
SPI bitrate.
Definition: spidrv.h:134
#define ECODE_EMDRV_SPIDRV_BUSY
The SPI port is busy.
Definition: spidrv.h:46
#define ECODE_EMDRV_SPIDRV_OK
Success return value.
Definition: spidrv.h:43
#define USART0
Ecode_t SPIDRV_SetFramelength(SPIDRV_Handle_t handle, uint32_t frameLength)
Set SPI framelength.
Definition: spidrv.c:914
Ecode_t DMADRV_TransferRemainingCount(unsigned int channelId, int *remaining)
Get number of items remaining in a transfer.
Definition: dmadrv.c:930
Trig on USART1_TXBL.
Definition: dmadrv.h:265
SPI mode 1: CLKPOL=0, CLKPHA=1.
Definition: spidrv.h:72
Ecode_t RTCDRV_StopTimer(RTCDRV_TimerID_t id)
Stop a given timer.
Definition: rtcdriver.c:674
Ecode_t RTCDRV_Init(void)
Initialize RTCDRV driver.
Definition: rtcdriver.c:324
#define _USART_FRAME_DATABITS_SHIFT
__IOM uint32_t ROUTE
Definition: efm32hg_usart.h:64
#define CORE_ENTER_ATOMIC()
Definition: em_core.h:138
#define CORE_ATOMIC_SECTION(yourcode)
Definition: em_core.h:126
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:269
#define USART_ROUTE_CSPEN
Transfer is started when bus is idle (CS deasserted).
Definition: spidrv.h:88
General Purpose IO (GPIO) peripheral API.
#define _USART_FRAME_DATABITS_SIXTEEN
Ecode_t RTCDRV_FreeTimer(RTCDRV_TimerID_t id)
Free timer.
Definition: rtcdriver.c:298
uint32_t Ecode_t
Typedef for API function error code return values.
Definition: ecode.h:51
#define _USART_ROUTE_LOCATION_SHIFT
#define DMADRV_MAX_XFER_COUNT
Maximum length of one DMA transfer.
Definition: dmadrv.h:87
Core interrupt handling API.
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Definition: em_cmu.c:1453
Ecode_t DMADRV_Init(void)
Initialize DMADRV.
Definition: dmadrv.c:262
Ecode_t SPIDRV_SetBitrate(SPIDRV_Handle_t handle, uint32_t bitRate)
Set SPI bus bitrate.
Definition: spidrv.c:879
USART_ClockMode_TypeDef clockMode
Definition: em_usart.h:442
Ecode_t SPIDRV_MTransmit(SPIDRV_Handle_t handle, const void *buffer, int count, SPIDRV_Callback_t callback)
Start a SPI master transmit transfer.
Definition: spidrv.c:801
#define _USART_FRAME_DATABITS_FOUR
#define CORE_EXIT_ATOMIC()
Definition: em_core.h:142
#define ECODE_EMDRV_DMADRV_OK
Success return value.
Definition: dmadrv.h:50
void USART_Reset(USART_TypeDef *usart)
Reset USART/UART to same state as after a HW reset.
Definition: em_usart.c:856
bool CORE_IrqIsBlocked(IRQn_Type irqN)
Check if a specific interrupt is disabled or blocked.
Definition: em_core.c:662
Ecode_t DMADRV_DeInit(void)
Deinitialize DMADRV.
Definition: dmadrv.c:177
Ecode_t DMADRV_AllocateChannel(unsigned int *channelId, void *capabilities)
Allocate (reserve) a DMA channel.
Definition: dmadrv.c:131
Ecode_t RTCDRV_StartTimer(RTCDRV_TimerID_t id, RTCDRV_TimerType_t type, uint32_t timeout, RTCDRV_Callback_t callback, void *user)
Start a timer.
Definition: rtcdriver.c:515
static volatile uint8_t rxBuffer[RXBUFSIZE]
Ecode_t SPIDRV_STransfer(SPIDRV_Handle_t handle, const void *txBuffer, void *rxBuffer, int count, SPIDRV_Callback_t callback, int timeoutMs)
Start a SPI slave transfer.
Definition: spidrv.c:1095
Ecode_t SPIDRV_STransmitB(SPIDRV_Handle_t handle, const void *buffer, int count, int timeoutMs)
Start a SPI slave blocking transmit transfer.
Definition: spidrv.c:1299
#define USART_CTRL_AUTOCS
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:406
SPI mode 0: CLKPOL=0, CLKPHA=0.
Definition: spidrv.h:71
Ecode_t SPIDRV_GetFramelength(SPIDRV_Handle_t handle, uint32_t *frameLength)
Get current SPI framelength.
Definition: spidrv.c:472
Ecode_t SPIDRV_Init(SPIDRV_Handle_t handle, SPIDRV_Init_t *initData)
Initialize a SPI driver instance.
Definition: spidrv.c:101
Ecode_t SPIDRV_STransmit(SPIDRV_Handle_t handle, const void *buffer, int count, SPIDRV_Callback_t callback, int timeoutMs)
Start a SPI slave transmit transfer.
Definition: spidrv.c:1235
#define ECODE_EMDRV_SPIDRV_TIMEOUT
SPI transfer timeout.
Definition: spidrv.h:48
Ecode_t DMADRV_TransferCompletePending(unsigned int channelId, bool *pending)
Check if a transfer complete is pending.
Definition: dmadrv.c:811
CS controlled by SPI driver.
Definition: spidrv.h:80
Act as SPI master.
Definition: spidrv.h:57
Ecode_t SPIDRV_SReceive(SPIDRV_Handle_t handle, void *buffer, int count, SPIDRV_Callback_t callback, int timeoutMs)
Start a SPI slave receive transfer.
Definition: spidrv.c:969
#define USART_INITSYNC_DEFAULT
Definition: em_usart.h:484
uint32_t USART_BaudrateGet(USART_TypeDef *usart)
Get current baudrate for USART/UART.
Definition: em_usart.c:431
__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:781
#define USART_ROUTE_CLKPEN
void(* SPIDRV_Callback_t)(struct SPIDRV_HandleData *handle, Ecode_t transferStatus, int itemsTransferred)
SPIDRV transfer completion callback function.
Definition: spidrv.h:114
SPI mode 3: CLKPOL=1, CLKPHA=1.
Definition: spidrv.h:74
Ecode_t SPIDRV_SReceiveB(SPIDRV_Handle_t handle, void *buffer, int count, int timeoutMs)
Start a SPI slave blocking receive transfer.
Definition: spidrv.c:1033
SPIDRV_HandleData_t * SPIDRV_Handle_t
SPI driver instance handle.
Definition: spidrv.h:174
SPIDRV_CsControl_t csControl
Select master mode chip select (CS) control scheme.
Definition: spidrv.h:140
#define USART_ROUTE_RXPEN
SPIDRV_ClockMode_t clockMode
SPI mode, CLKPOL/CLKPHASE setting.
Definition: spidrv.h:139
Ecode_t SPIDRV_MReceiveB(SPIDRV_Handle_t handle, void *buffer, int count)
Start a SPI master blocking receive transfer.
Definition: spidrv.c:602
Ecode_t DMADRV_FreeChannel(unsigned int channelId)
Free an allocate (reserved) DMA channel.
Definition: dmadrv.c:225