EFM32 Giant Gecko Software Documentation  efm32gg-doc-4.2.1
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_int.h"
21 #include "em_usart.h"
22 
23 #include "dmadrv.h"
24 #include "spidrv.h"
25 
27 
28 static bool spidrvIsInitialized = false;
29 
30 static void BlockingComplete( SPIDRV_Handle_t handle,
31  Ecode_t transferStatus,
32  int itemsTransferred );
33 
34 static Ecode_t ConfigGPIO( SPIDRV_Handle_t handle, bool enable );
35 
36 static bool RxDMAComplete( unsigned int channel,
37  unsigned int sequenceNo,
38  void *userParam );
39 
40 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
41 static void SlaveTimeout( RTCDRV_TimerID_t id,
42  void *user );
43 #endif
44 
45 static void StartReceiveDMA( SPIDRV_Handle_t handle,
46  void *buffer,
47  int count,
48  SPIDRV_Callback_t callback );
49 
50 static void StartTransferDMA( SPIDRV_Handle_t handle,
51  const void *txBuffer,
52  void *rxBuffer,
53  int count,
54  SPIDRV_Callback_t callback );
55 
56 static void StartTransmitDMA( SPIDRV_Handle_t handle,
57  const void *buffer,
58  int count,
59  SPIDRV_Callback_t callback );
60 
61 static Ecode_t TransferApiPrologue( SPIDRV_Handle_t handle,
62  void *buffer,
63  int count );
64 
65 static Ecode_t TransferApiBlockingPrologue( SPIDRV_Handle_t handle,
66  void *buffer,
67  int count );
68 
69 static void WaitForTransferCompletion( SPIDRV_Handle_t handle );
70 
71 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
72 static Ecode_t WaitForIdleLine( SPIDRV_Handle_t handle );
73 #endif
74 
76 
77 /***************************************************************************/
92 {
93  Ecode_t retVal;
95 
96  if ( handle == NULL )
97  {
99  }
100 
101  if ( initData == NULL )
102  {
104  }
105 
106  memset( handle, 0, sizeof( SPIDRV_HandleData_t ) );
107 
108  if ( 0 )
109  {
110 #if defined( USART0 )
111  }
112  else if ( initData->port == USART0 )
113  {
114  handle->usartClock = cmuClock_USART0;
115  handle->txDMASignal = dmadrvPeripheralSignal_USART0_TXBL;
116  handle->rxDMASignal = dmadrvPeripheralSignal_USART0_RXDATAV;
117 #endif
118 #if defined( USART1 )
119  }
120  else if ( initData->port == USART1 )
121  {
122  handle->usartClock = cmuClock_USART1;
123  handle->txDMASignal = dmadrvPeripheralSignal_USART1_TXBL;
124  handle->rxDMASignal = dmadrvPeripheralSignal_USART1_RXDATAV;
125 #endif
126 #if defined( USART2 )
127  }
128  else if ( initData->port == USART2 )
129  {
130  handle->usartClock = cmuClock_USART2;
131  handle->txDMASignal = dmadrvPeripheralSignal_USART2_TXBL;
132  handle->rxDMASignal = dmadrvPeripheralSignal_USART2_RXDATAV;
133 #endif
134 #if defined( USARTRF0 )
135  }
136  else if ( initData->port == USARTRF0 )
137  {
138  handle->usartClock = cmuClock_USARTRF0;
139  handle->txDMASignal = dmadrvPeripheralSignal_USARTRF0_TXBL;
140  handle->rxDMASignal = dmadrvPeripheralSignal_USARTRF0_RXDATAV;
141 #endif
142 #if defined( USARTRF1 )
143  }
144  else if ( initData->port == USARTRF1 )
145  {
146  handle->usartClock = cmuClock_USARTRF1;
147  handle->txDMASignal = dmadrvPeripheralSignal_USARTRF1_TXBL;
148  handle->rxDMASignal = dmadrvPeripheralSignal_USARTRF1_RXDATAV;
149 #endif
150  }
151  else
152  {
154  }
155 
156  handle->initData = *initData;
157 
158  if ( initData->bitOrder == spidrvBitOrderMsbFirst )
159  {
160  usartInit.msbf = true;
161  }
162 
163  if ( initData->clockMode == spidrvClockMode0 )
164  {
165  usartInit.clockMode = usartClockMode0;
166  }
167  else if ( initData->clockMode == spidrvClockMode1 )
168  {
169  usartInit.clockMode = usartClockMode1;
170  }
171  else if ( initData->clockMode == spidrvClockMode2 )
172  {
173  usartInit.clockMode = usartClockMode2;
174  }
175  else if ( initData->clockMode == spidrvClockMode3 )
176  {
177  usartInit.clockMode = usartClockMode3;
178  }
179  else
180  {
182  }
183 
184  if ( initData->type == spidrvSlave )
185  {
186  usartInit.master = false;
187  usartInit.baudrate = 1000; // Dummy value needed by USART_InitSync()
188  }
189  else
190  {
191  usartInit.baudrate = initData->bitRate;
192  }
193 
196  CMU_ClockEnable( handle->usartClock, true );
197  USART_InitSync( initData->port, &usartInit );
198 
199  if ( ( initData->type == spidrvMaster )
200  && ( initData->csControl == spidrvCsControlAuto ) )
201  {
202  initData->port->CTRL |= USART_CTRL_AUTOCS;
203  }
204 
205  if ( initData->csControl == spidrvCsControlAuto )
206  {
207  // SPI 4 wire mode
208 #if defined( USART_ROUTEPEN_TXPEN )
209  initData->port->ROUTEPEN = USART_ROUTEPEN_TXPEN
210  | USART_ROUTEPEN_RXPEN
211  | USART_ROUTEPEN_CLKPEN
212  | USART_ROUTEPEN_CSPEN;
213 
214  initData->port->ROUTELOC0 = ( initData->port->ROUTELOC0 &
215  ~( _USART_ROUTELOC0_TXLOC_MASK
216  | _USART_ROUTELOC0_RXLOC_MASK
217  | _USART_ROUTELOC0_CLKLOC_MASK
218  | _USART_ROUTELOC0_CSLOC_MASK ) )
219  | ( initData->portLocationTx << _USART_ROUTELOC0_TXLOC_SHIFT )
220  | ( initData->portLocationRx << _USART_ROUTELOC0_RXLOC_SHIFT )
221  | ( initData->portLocationClk << _USART_ROUTELOC0_CLKLOC_SHIFT )
222  | ( initData->portLocationCs << _USART_ROUTELOC0_CSLOC_SHIFT );
223 #else
224  initData->port->ROUTE = USART_ROUTE_TXPEN
228  | (initData->portLocation
230 #endif
231  }
232  else
233  {
234  // SPI 3 wire mode
235 #if defined( USART_ROUTEPEN_TXPEN )
236  initData->port->ROUTEPEN = USART_ROUTEPEN_TXPEN
237  | USART_ROUTEPEN_RXPEN
238  | USART_ROUTEPEN_CLKPEN;
239 
240  initData->port->ROUTELOC0 = ( initData->port->ROUTELOC0 &
241  ~( _USART_ROUTELOC0_TXLOC_MASK
242  | _USART_ROUTELOC0_RXLOC_MASK
243  | _USART_ROUTELOC0_CLKLOC_MASK ) )
244  | ( initData->portLocationTx << _USART_ROUTELOC0_TXLOC_SHIFT )
245  | ( initData->portLocationRx << _USART_ROUTELOC0_RXLOC_SHIFT )
246  | ( initData->portLocationClk << _USART_ROUTELOC0_CLKLOC_SHIFT );
247 #else
248  initData->port->ROUTE = USART_ROUTE_TXPEN
251  | (initData->portLocation
253 #endif
254  }
255 
256  if ( ( retVal = ConfigGPIO( handle, true ) ) != ECODE_EMDRV_SPIDRV_OK )
257  {
258  return retVal;
259  }
260 
261  INT_Disable();
262  if ( ! spidrvIsInitialized )
263  {
264  spidrvIsInitialized = true;
265  INT_Enable();
266 
267 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
268  RTCDRV_Init();
269 #endif
270  }
271  else
272  {
273  INT_Enable();
274  }
275 
276 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
277  if ( initData->type == spidrvSlave )
278  {
279  if ( RTCDRV_AllocateTimer( &handle->timer ) != ECODE_EMDRV_RTCDRV_OK )
280  {
282  }
283  }
284 #endif
285 
286  // Initialize DMA.
287  DMADRV_Init();
288 
289  if ( DMADRV_AllocateChannel(&handle->txDMACh,NULL) != ECODE_EMDRV_DMADRV_OK )
290  {
292  }
293 
294  if ( DMADRV_AllocateChannel(&handle->rxDMACh,NULL) != ECODE_EMDRV_DMADRV_OK )
295  {
297  }
298 
299  return ECODE_EMDRV_SPIDRV_OK;
300 }
301 
302 /***************************************************************************/
313 {
314  if ( handle == NULL )
315  {
317  }
318 
319  // Stop DMA's.
320  DMADRV_StopTransfer( handle->rxDMACh );
321  DMADRV_StopTransfer( handle->txDMACh );
322 
323  ConfigGPIO( handle, false );
324 
325 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
326  if ( handle->initData.type == spidrvSlave )
327  {
328  RTCDRV_StopTimer( handle->timer );
329  RTCDRV_FreeTimer( handle->timer );
330  }
331 #endif
332 
333  USART_Reset( handle->initData.port );
334  CMU_ClockEnable( handle->usartClock, false );
335 
336  DMADRV_FreeChannel( handle->txDMACh );
337  DMADRV_FreeChannel( handle->rxDMACh );
338  DMADRV_DeInit();
339 
340  return ECODE_EMDRV_SPIDRV_OK;
341 }
342 
343 /***************************************************************************/
354 {
355  if ( handle == NULL )
356  {
358  }
359 
360  INT_Disable();
361  if ( handle->state == spidrvStateIdle )
362  {
363  INT_Enable();
365  }
366 
367 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
368  if ( handle->initData.type == spidrvSlave )
369  {
370  RTCDRV_StopTimer( handle->timer );
371  }
372 #endif
373 
374  // Stop DMA's.
375  DMADRV_StopTransfer( handle->rxDMACh );
376  DMADRV_StopTransfer( handle->txDMACh );
377  DMADRV_TransferRemainingCount( handle->rxDMACh, &handle->remaining );
378  handle->transferStatus = ECODE_EMDRV_SPIDRV_ABORTED;
379  handle->state = spidrvStateIdle;
380  handle->transferStatus = ECODE_EMDRV_SPIDRV_ABORTED;
381  handle->blockingCompleted = true;
382 
383  if ( handle->userCallback != NULL )
384  {
385  handle->userCallback( handle,
387  handle->transferCount - handle->remaining );
388  }
389  INT_Enable();
390 
391  return ECODE_EMDRV_SPIDRV_OK;
392 }
393 
394 /***************************************************************************/
406 Ecode_t SPIDRV_GetBitrate( SPIDRV_Handle_t handle, uint32_t *bitRate )
407 {
408  if ( handle == NULL )
409  {
411  }
412 
413  if ( bitRate == NULL )
414  {
416  }
417 
418  *bitRate = USART_BaudrateGet( handle->initData.port );
419 
420  return ECODE_EMDRV_SPIDRV_OK;
421 }
422 
423 /***************************************************************************/
435 Ecode_t SPIDRV_GetFramelength( SPIDRV_Handle_t handle, uint32_t *frameLength )
436 {
437  if ( handle == NULL )
438  {
440  }
441 
442  if ( frameLength == NULL )
443  {
445  }
446 
447  *frameLength = handle->initData.frameLength;
448 
449  return ECODE_EMDRV_SPIDRV_OK;
450 }
451 
452 /***************************************************************************/
471  int *itemsTransferred,
472  int *itemsRemaining )
473 {
474  int remaining;
475 
476  if ( handle == NULL )
477  {
479  }
480 
481  if ( ( itemsTransferred == NULL ) || ( itemsRemaining == NULL ) )
482  {
484  }
485 
486  INT_Disable();
487  if ( handle->state == spidrvStateIdle )
488  {
489  remaining = handle->remaining;
490  }
491  else
492  {
493  DMADRV_TransferRemainingCount( handle->rxDMACh, &remaining );
494  }
495  INT_Enable();
496 
497  *itemsTransferred = handle->transferCount - remaining;
498  *itemsRemaining = remaining;
499 
500  return ECODE_EMDRV_SPIDRV_OK;
501 }
502 
503 /***************************************************************************/
523  void *buffer,
524  int count,
525  SPIDRV_Callback_t callback )
526 {
527  Ecode_t retVal;
528 
529  if ( handle->initData.type == spidrvSlave )
530  {
532  }
533 
534  if ( ( retVal = TransferApiPrologue( handle, buffer, count ) )
536  {
537  return retVal;
538  }
539 
540  StartReceiveDMA( handle, buffer, count, callback );
541 
542  return ECODE_EMDRV_SPIDRV_OK;
543 }
544 
545 /***************************************************************************/
566  void *buffer,
567  int count )
568 {
569  Ecode_t retVal;
570 
571  if ( handle->initData.type == spidrvSlave )
572  {
574  }
575 
576  if ( ( retVal = TransferApiBlockingPrologue( handle, buffer, count ) )
578  {
579  return retVal;
580  }
581 
582  StartReceiveDMA( handle, buffer, count, BlockingComplete );
583 
584  WaitForTransferCompletion( handle );
585 
586  return handle->transferStatus;
587 }
588 
589 /***************************************************************************/
608  const void *txBuffer,
609  void *rxBuffer,
610  int count,
611  SPIDRV_Callback_t callback )
612 {
613  Ecode_t retVal;
614 
615  if ( handle->initData.type == spidrvSlave )
616  {
618  }
619 
620  if ( ( retVal = TransferApiPrologue( handle, (void*)txBuffer, count ) )
622  {
623  return retVal;
624  }
625 
626  if ( rxBuffer == NULL )
627  {
629  }
630 
631  StartTransferDMA( handle, txBuffer, rxBuffer, count, callback );
632 
633  return ECODE_EMDRV_SPIDRV_OK;
634 }
635 
636 /***************************************************************************/
658  const void *txBuffer,
659  void *rxBuffer,
660  int count )
661 {
662  Ecode_t retVal;
663 
664  if ( handle->initData.type == spidrvSlave )
665  {
667  }
668 
669  if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)txBuffer, count ))
671  {
672  return retVal;
673  }
674 
675  if ( rxBuffer == NULL )
676  {
678  }
679 
680  StartTransferDMA( handle, txBuffer, rxBuffer, count, BlockingComplete );
681 
682  WaitForTransferCompletion( handle );
683 
684  return handle->transferStatus;
685 }
686 
687 /***************************************************************************/
707  uint32_t txValue,
708  void *rxValue )
709 {
710  void *pRx;
711  uint32_t rxBuffer;
712 
713  if ( handle->initData.type == spidrvSlave )
714  {
716  }
717 
718  if ( handle == NULL )
719  {
721  }
722 
723  INT_Disable();
724  if ( handle->state != spidrvStateIdle )
725  {
726  INT_Enable();
728  }
729  handle->state = spidrvStateTransferring;
730  INT_Enable();
731 
732  if ( ( pRx = rxValue ) == NULL )
733  {
734  pRx = &rxBuffer;
735  }
736 
737  StartTransferDMA( handle, &txValue, pRx, 1, BlockingComplete );
738 
739  WaitForTransferCompletion( handle );
740 
741  return handle->transferStatus;
742 }
743 
744 /***************************************************************************/
764  const void *buffer,
765  int count,
766  SPIDRV_Callback_t callback )
767 {
768  Ecode_t retVal;
769 
770  if ( handle->initData.type == spidrvSlave )
771  {
773  }
774 
775  if ( ( retVal = TransferApiPrologue( handle, (void*)buffer, count ) )
777  {
778  return retVal;
779  }
780 
781  StartTransmitDMA( handle, buffer, count, callback );
782 
783  return ECODE_EMDRV_SPIDRV_OK;
784 }
785 
786 /***************************************************************************/
806  const void *buffer,
807  int count )
808 {
809  Ecode_t retVal;
810 
811  if ( handle->initData.type == spidrvSlave )
812  {
814  }
815 
816  if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)buffer, count ) )
818  {
819  return retVal;
820  }
821 
822  StartTransmitDMA( handle, buffer, count, BlockingComplete );
823 
824  WaitForTransferCompletion( handle );
825 
826  return handle->transferStatus;
827 }
828 
829 /***************************************************************************/
841 Ecode_t SPIDRV_SetBitrate( SPIDRV_Handle_t handle, uint32_t bitRate )
842 {
843  if ( handle == NULL )
844  {
846  }
847 
848  INT_Disable();
849  if ( handle->state != spidrvStateIdle )
850  {
851  INT_Enable();
853  }
854 
855  handle->initData.bitRate = bitRate;
856  USART_BaudrateSyncSet( handle->initData.port, 0, bitRate );
857  INT_Enable();
858 
859  return ECODE_EMDRV_SPIDRV_OK;
860 }
861 
862 /***************************************************************************/
874 Ecode_t SPIDRV_SetFramelength( SPIDRV_Handle_t handle, uint32_t frameLength )
875 {
876  if ( handle == NULL )
877  {
879  }
880 
881  frameLength -= 3;
882  if ( ( frameLength < _USART_FRAME_DATABITS_FOUR )
883  || ( frameLength > _USART_FRAME_DATABITS_SIXTEEN ) )
884  {
886  }
887 
888  INT_Disable();
889  if ( handle->state != spidrvStateIdle )
890  {
891  INT_Enable();
893  }
894 
895  handle->initData.frameLength = frameLength + 3;
896  handle->initData.port->FRAME = ( handle->initData.port->FRAME
898  | ( frameLength
900  INT_Enable();
901 
902  return ECODE_EMDRV_SPIDRV_OK;
903 }
904 
905 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
906 /***************************************************************************/
928  void *buffer,
929  int count,
930  SPIDRV_Callback_t callback,
931  int timeoutMs )
932 {
933  Ecode_t retVal;
934 
935  if ( handle->initData.type == spidrvMaster )
936  {
938  }
939 
940  if ( ( retVal = TransferApiPrologue( handle, buffer, count ) )
942  {
943  return retVal;
944  }
945 
946  if ( timeoutMs )
947  {
948  RTCDRV_StartTimer( handle->timer,
950  timeoutMs,
951  SlaveTimeout,
952  handle );
953  }
954 
955  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
956  {
957  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
958  {
959  return retVal;
960  }
961  }
962 
963  StartReceiveDMA( handle, buffer, count, callback );
964 
965  return ECODE_EMDRV_SPIDRV_OK;
966 }
967 
968 /***************************************************************************/
992  void *buffer,
993  int count,
994  int timeoutMs )
995 {
996  Ecode_t retVal;
997 
998  if ( handle->initData.type == spidrvMaster )
999  {
1001  }
1002 
1003  if ( ( retVal = TransferApiBlockingPrologue( handle, buffer, count ) )
1005  {
1006  return retVal;
1007  }
1008 
1009  if ( timeoutMs )
1010  {
1011  RTCDRV_StartTimer( handle->timer,
1013  timeoutMs,
1014  SlaveTimeout,
1015  handle );
1016  }
1017 
1018  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1019  {
1020  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1021  {
1022  return retVal;
1023  }
1024  }
1025 
1026  StartReceiveDMA( handle, buffer, count, BlockingComplete );
1027 
1028  WaitForTransferCompletion( handle );
1029 
1030  return handle->transferStatus;
1031 }
1032 
1033 /***************************************************************************/
1054  const void *txBuffer,
1055  void *rxBuffer,
1056  int count,
1057  SPIDRV_Callback_t callback,
1058  int timeoutMs )
1059 {
1060  Ecode_t retVal;
1061 
1062  if ( handle->initData.type == spidrvMaster )
1063  {
1065  }
1066 
1067  if ( ( retVal = TransferApiPrologue( handle, (void*)txBuffer, count ) )
1069  {
1070  return retVal;
1071  }
1072 
1073  if ( rxBuffer == NULL )
1074  {
1076  }
1077 
1078  if ( timeoutMs )
1079  {
1080  RTCDRV_StartTimer( handle->timer,
1082  timeoutMs,
1083  SlaveTimeout,
1084  handle );
1085  }
1086 
1087  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1088  {
1089  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1090  {
1091  return retVal;
1092  }
1093  }
1094 
1095  StartTransferDMA( handle, txBuffer, rxBuffer, count, callback );
1096 
1097  return ECODE_EMDRV_SPIDRV_OK;
1098 }
1099 
1100 /***************************************************************************/
1125  const void *txBuffer,
1126  void *rxBuffer,
1127  int count,
1128  int timeoutMs )
1129 {
1130  Ecode_t retVal;
1131 
1132  if ( handle->initData.type == spidrvMaster )
1133  {
1135  }
1136 
1137  if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)txBuffer, count ))
1139  {
1140  return retVal;
1141  }
1142 
1143  if ( rxBuffer == NULL )
1144  {
1146  }
1147 
1148  if ( timeoutMs )
1149  {
1150  RTCDRV_StartTimer( handle->timer,
1152  timeoutMs,
1153  SlaveTimeout,
1154  handle );
1155  }
1156 
1157  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1158  {
1159  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1160  {
1161  return retVal;
1162  }
1163  }
1164 
1165  StartTransferDMA( handle, txBuffer, rxBuffer, count, BlockingComplete );
1166 
1167  WaitForTransferCompletion( handle );
1168 
1169  return handle->transferStatus;
1170 }
1171 
1172 /***************************************************************************/
1194  const void *buffer,
1195  int count,
1196  SPIDRV_Callback_t callback,
1197  int timeoutMs )
1198 {
1199  Ecode_t retVal;
1200 
1201  if ( handle->initData.type == spidrvMaster )
1202  {
1204  }
1205 
1206  if ( ( retVal = TransferApiPrologue( handle, (void*)buffer, count ) )
1208  {
1209  return retVal;
1210  }
1211 
1212  if ( timeoutMs )
1213  {
1214  RTCDRV_StartTimer( handle->timer,
1216  timeoutMs,
1217  SlaveTimeout,
1218  handle );
1219  }
1220 
1221  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1222  {
1223  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1224  {
1225  return retVal;
1226  }
1227  }
1228 
1229  StartTransmitDMA( handle, buffer, count, callback );
1230 
1231  return ECODE_EMDRV_SPIDRV_OK;
1232 }
1233 
1234 /***************************************************************************/
1258  const void *buffer,
1259  int count,
1260  int timeoutMs )
1261 {
1262  Ecode_t retVal;
1263 
1264  if ( handle->initData.type == spidrvMaster )
1265  {
1267  }
1268 
1269  if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)buffer, count ) )
1271  {
1272  return retVal;
1273  }
1274 
1275  if ( timeoutMs )
1276  {
1277  RTCDRV_StartTimer( handle->timer,
1279  timeoutMs,
1280  SlaveTimeout,
1281  handle );
1282  }
1283 
1284  if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
1285  {
1286  if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
1287  {
1288  return retVal;
1289  }
1290  }
1291 
1292  StartTransmitDMA( handle, buffer, count, BlockingComplete );
1293 
1294  WaitForTransferCompletion( handle );
1295 
1296  return handle->transferStatus;
1297 }
1298 #endif
1299 
1301 
1302 /***************************************************************************/
1308 static void BlockingComplete( SPIDRV_Handle_t handle,
1309  Ecode_t transferStatus,
1310  int itemsTransferred )
1311 {
1312  (void)itemsTransferred;
1313 
1314  handle->transferStatus = transferStatus;
1315  handle->blockingCompleted = true;
1316 }
1317 
1318 /***************************************************************************/
1321 static Ecode_t ConfigGPIO( SPIDRV_Handle_t handle, bool enable )
1322 {
1323 #if defined( _USART_ROUTELOC0_MASK )
1324  SPIDRV_Init_t *initData;
1325 #else
1326  uint32_t location;
1327 #endif
1328  int mosiPin, misoPin, clkPin;
1329  int mosiPort, misoPort, clkPort;
1330 
1331 #if defined( _USART_ROUTELOC0_MASK )
1332  initData = &handle->initData;
1333 
1334  if ( 0 )
1335  {
1336 #if defined( USART0 )
1337  }
1338  else if ( handle->initData.port == USART0 )
1339  {
1340  mosiPort = AF_USART0_TX_PORT( initData->portLocationTx );
1341  misoPort = AF_USART0_RX_PORT( initData->portLocationRx );
1342  clkPort = AF_USART0_CLK_PORT( initData->portLocationClk );
1343  handle->csPort = AF_USART0_CS_PORT( initData->portLocationCs );
1344  mosiPin = AF_USART0_TX_PIN( initData->portLocationTx );
1345  misoPin = AF_USART0_RX_PIN( initData->portLocationRx );
1346  clkPin = AF_USART0_CLK_PIN( initData->portLocationClk );
1347  handle->csPin = AF_USART0_CS_PIN( initData->portLocationCs );
1348 #endif
1349 #if defined( USART1 )
1350  }
1351  else if ( handle->initData.port == USART1 )
1352  {
1353  mosiPort = AF_USART1_TX_PORT( initData->portLocationTx );
1354  misoPort = AF_USART1_RX_PORT( initData->portLocationRx );
1355  clkPort = AF_USART1_CLK_PORT( initData->portLocationClk );
1356  handle->csPort = AF_USART1_CS_PORT( initData->portLocationCs );
1357  mosiPin = AF_USART1_TX_PIN( initData->portLocationTx );
1358  misoPin = AF_USART1_RX_PIN( initData->portLocationRx );
1359  clkPin = AF_USART1_CLK_PIN( initData->portLocationClk );
1360  handle->csPin = AF_USART1_CS_PIN( initData->portLocationCs );
1361 #endif
1362 #if defined( USART2 )
1363  }
1364  else if ( handle->initData.port == USART2 )
1365  {
1366  mosiPort = AF_USART2_TX_PORT( initData->portLocationTx );
1367  misoPort = AF_USART2_RX_PORT( initData->portLocationRx );
1368  clkPort = AF_USART2_CLK_PORT( initData->portLocationClk );
1369  handle->csPort = AF_USART2_CS_PORT( initData->portLocationCs );
1370  mosiPin = AF_USART2_TX_PIN( initData->portLocationTx );
1371  misoPin = AF_USART2_RX_PIN( initData->portLocationRx );
1372  clkPin = AF_USART2_CLK_PIN( initData->portLocationClk );
1373  handle->csPin = AF_USART2_CS_PIN( initData->portLocationCs );
1374 #endif
1375 #if defined( USARTRF0 )
1376  }
1377  else if ( handle->initData.port == USARTRF0 )
1378  {
1379  mosiPort = AF_USARTRF0_TX_PORT( initData->portLocationTx );
1380  misoPort = AF_USARTRF0_RX_PORT( initData->portLocationRx );
1381  clkPort = AF_USARTRF0_CLK_PORT( initData->portLocationClk );
1382  handle->csPort = AF_USARTRF0_CS_PORT( initData->portLocationCs );
1383  mosiPin = AF_USARTRF0_TX_PIN( initData->portLocationTx );
1384  misoPin = AF_USARTRF0_RX_PIN( initData->portLocationRx );
1385  clkPin = AF_USARTRF0_CLK_PIN( initData->portLocationClk );
1386  handle->csPin = AF_USARTRF0_CS_PIN( initData->portLocationCs );
1387 #endif
1388 #if defined( USARTRF1 )
1389  }
1390  else if ( handle->initData.port == USARTRF1 )
1391  {
1392  mosiPort = AF_USARTRF1_TX_PORT( initData->portLocationTx );
1393  misoPort = AF_USARTRF1_RX_PORT( initData->portLocationRx );
1394  clkPort = AF_USARTRF1_CLK_PORT( initData->portLocationClk );
1395  handle->csPort = AF_USARTRF1_CS_PORT( initData->portLocationCs );
1396  mosiPin = AF_USARTRF1_TX_PIN( initData->portLocationTx );
1397  misoPin = AF_USARTRF1_RX_PIN( initData->portLocationRx );
1398  clkPin = AF_USARTRF1_CLK_PIN( initData->portLocationClk );
1399  handle->csPin = AF_USARTRF1_CS_PIN( initData->portLocationCs );
1400 #endif
1401  }
1402  else
1403  {
1405  }
1406 
1407 #else
1408  location = handle->initData.portLocation;
1409 
1410  if ( 0 )
1411  {
1412 #if defined( USART0 )
1413  }
1414  else if ( handle->initData.port == USART0 )
1415  {
1416  mosiPort = AF_USART0_TX_PORT( location );
1417  misoPort = AF_USART0_RX_PORT( location );
1418  clkPort = AF_USART0_CLK_PORT( location );
1419  handle->csPort = AF_USART0_CS_PORT( location );
1420  mosiPin = AF_USART0_TX_PIN( location );
1421  misoPin = AF_USART0_RX_PIN( location );
1422  clkPin = AF_USART0_CLK_PIN( location );
1423  handle->csPin = AF_USART0_CS_PIN( location );
1424 #endif
1425 #if defined( USART1 )
1426  }
1427  else if ( handle->initData.port == USART1 )
1428  {
1429  mosiPort = AF_USART1_TX_PORT( location );
1430  misoPort = AF_USART1_RX_PORT( location );
1431  clkPort = AF_USART1_CLK_PORT( location );
1432  handle->csPort = AF_USART1_CS_PORT( location );
1433  mosiPin = AF_USART1_TX_PIN( location );
1434  misoPin = AF_USART1_RX_PIN( location );
1435  clkPin = AF_USART1_CLK_PIN( location );
1436  handle->csPin = AF_USART1_CS_PIN( location );
1437 #endif
1438 #if defined( USART2 )
1439  }
1440  else if ( handle->initData.port == USART2 )
1441  {
1442  mosiPort = AF_USART2_TX_PORT( location );
1443  misoPort = AF_USART2_RX_PORT( location );
1444  clkPort = AF_USART2_CLK_PORT( location );
1445  handle->csPort = AF_USART2_CS_PORT( location );
1446  mosiPin = AF_USART2_TX_PIN( location );
1447  misoPin = AF_USART2_RX_PIN( location );
1448  clkPin = AF_USART2_CLK_PIN( location );
1449  handle->csPin = AF_USART2_CS_PIN( location );
1450 #endif
1451 #if defined( USARTRF0 )
1452  }
1453  else if ( handle->initData.port == USARTRF0 )
1454  {
1455  mosiPort = AF_USARTRF0_TX_PORT( location );
1456  misoPort = AF_USARTRF0_RX_PORT( location );
1457  clkPort = AF_USARTRF0_CLK_PORT( location );
1458  handle->csPort = AF_USARTRF0_CS_PORT( location );
1459  mosiPin = AF_USARTRF0_TX_PIN( location );
1460  misoPin = AF_USARTRF0_RX_PIN( location );
1461  clkPin = AF_USARTRF0_CLK_PIN( location );
1462  handle->csPin = AF_USARTRF0_CS_PIN( location );
1463 #endif
1464 #if defined( USARTRF1 )
1465  }
1466  else if ( handle->initData.port == USARTRF1 )
1467  {
1468  mosiPort = AF_USARTRF1_TX_PORT( location );
1469  misoPort = AF_USARTRF1_RX_PORT( location );
1470  clkPort = AF_USARTRF1_CLK_PORT( location );
1471  handle->csPort = AF_USARTRF1_CS_PORT( location );
1472  mosiPin = AF_USARTRF1_TX_PIN( location );
1473  misoPin = AF_USARTRF1_RX_PIN( location );
1474  clkPin = AF_USARTRF1_CLK_PIN( location );
1475  handle->csPin = AF_USARTRF1_CS_PIN( location );
1476 #endif
1477  }
1478  else
1479  {
1481  }
1482 #endif
1483 
1484  if ( enable )
1485  {
1486  if ( handle->initData.type == spidrvMaster )
1487  {
1488  GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin,
1489  gpioModePushPull, 0 );
1490  GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin,
1491  gpioModeInputPull, 0 );
1492 
1493  if ( ( handle->initData.clockMode == spidrvClockMode0 )
1494  || ( handle->initData.clockMode == spidrvClockMode1 ) )
1495  {
1496  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
1497  gpioModePushPull, 0 );
1498  }
1499  else
1500  {
1501  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
1502  gpioModePushPull, 1 );
1503  }
1504 
1505  if ( handle->initData.csControl == spidrvCsControlAuto )
1506  {
1507  GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
1508  gpioModePushPull, 1 );
1509  }
1510  }
1511  else
1512  {
1513  GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin,
1514  gpioModeInputPull, 0 );
1515  GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin,
1516  gpioModePushPull, 0 );
1517 
1518  if ( ( handle->initData.clockMode == spidrvClockMode0 )
1519  || ( handle->initData.clockMode == spidrvClockMode1 ) )
1520  {
1521  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
1522  gpioModeInputPull, 0 );
1523  }
1524  else
1525  {
1526  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
1527  gpioModeInputPull, 1 );
1528  }
1529 
1530  if ( handle->initData.csControl == spidrvCsControlAuto )
1531  {
1532  GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
1533  gpioModeInputPull, 1 );
1534  }
1535  }
1536  }
1537  else
1538  {
1539  GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin, gpioModeInputPull,0);
1540  GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin, gpioModeInputPull,0);
1541 
1542  if ( ( handle->initData.clockMode == spidrvClockMode0 )
1543  || ( handle->initData.clockMode == spidrvClockMode1 ) )
1544  {
1545  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin, gpioModeInputPull,0);
1546  }
1547  else
1548  {
1549  GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin, gpioModeInputPull,1);
1550  }
1551 
1552  if ( handle->initData.csControl == spidrvCsControlAuto )
1553  {
1554  GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
1555  gpioModeDisabled, 0);
1556  }
1557  }
1558 
1559  return ECODE_EMDRV_SPIDRV_OK;
1560 }
1561 
1562 /***************************************************************************/
1565 static bool RxDMAComplete( unsigned int channel,
1566  unsigned int sequenceNo,
1567  void *userParam )
1568 {
1569  SPIDRV_Handle_t handle;
1570  (void)channel;
1571  (void)sequenceNo;
1572 
1573  INT_Disable();
1574 
1575  handle = (SPIDRV_Handle_t)userParam;
1576 
1577  handle->transferStatus = ECODE_EMDRV_SPIDRV_OK;
1578  handle->state = spidrvStateIdle;
1579  handle->remaining = 0;
1580 
1581 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
1582  if ( handle->initData.type == spidrvSlave )
1583  {
1584  RTCDRV_StopTimer( handle->timer );
1585  }
1586 #endif
1587 
1588  if ( handle->userCallback != NULL )
1589  {
1590  handle->userCallback( handle, ECODE_EMDRV_SPIDRV_OK, handle->transferCount);
1591  }
1592 
1593  INT_Enable();
1594  return true;
1595 }
1596 
1597 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
1598 /***************************************************************************/
1601 static void SlaveTimeout( RTCDRV_TimerID_t id, void *user )
1602 {
1603  bool active, pending;
1604  SPIDRV_Handle_t handle;
1605  (void)id;
1606 
1607  handle = (SPIDRV_Handle_t)user;
1608 
1609  if ( handle->state == spidrvStateTransferring )
1610  {
1611  DMADRV_TransferActive( handle->rxDMACh, &active );
1612  if ( active )
1613  {
1614  // Stop running DMA's
1615  DMADRV_StopTransfer( handle->rxDMACh );
1616  DMADRV_StopTransfer( handle->txDMACh );
1617  DMADRV_TransferRemainingCount( handle->rxDMACh, &handle->remaining );
1618  }
1619  else
1620  {
1621  // DMA is either completed or not yet started
1622  DMADRV_TransferCompletePending( handle->txDMACh, &pending );
1623  if ( pending )
1624  {
1625  // We have a pending DMA interrupt, let the DMA handler do the rest
1626  return;
1627  }
1628  handle->remaining = handle->transferCount;
1629  }
1630  handle->transferStatus = ECODE_EMDRV_SPIDRV_TIMEOUT;
1631  handle->state = spidrvStateIdle;
1632 
1633  if ( handle->userCallback != NULL )
1634  {
1635  handle->userCallback( handle,
1637  handle->transferCount - handle->remaining );
1638  }
1639  }
1640 }
1641 #endif
1642 
1643 /***************************************************************************/
1646 static void StartReceiveDMA( SPIDRV_Handle_t handle,
1647  void *buffer,
1648  int count,
1649  SPIDRV_Callback_t callback )
1650 {
1651  void *rxPort, *txPort;
1652  DMADRV_DataSize_t size;
1653 
1654  handle->blockingCompleted = false;
1655  handle->transferCount = count;
1656  handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
1657  handle->userCallback = callback;
1658 
1659  if ( handle->initData.frameLength > 8 )
1660  {
1661  size = dmadrvDataSize2;
1662  }
1663  else
1664  {
1665  size = dmadrvDataSize1;
1666  }
1667 
1668  if ( handle->initData.frameLength > 8 )
1669  {
1670  rxPort = (void *)&(handle->initData.port->RXDOUBLE);
1671  txPort = (void *)&(handle->initData.port->TXDOUBLE);
1672  }
1673  else
1674  {
1675  rxPort = (void *)&(handle->initData.port->RXDATA);
1676  txPort = (void *)&(handle->initData.port->TXDATA);
1677  }
1678 
1679  // Start receive dma.
1680  DMADRV_PeripheralMemory( handle->rxDMACh,
1681  handle->rxDMASignal,
1682  (void*)buffer,
1683  rxPort,
1684  true,
1685  count,
1686  size,
1687  RxDMAComplete,
1688  handle );
1689 
1690  // Start transmit dma.
1691  DMADRV_MemoryPeripheral( handle->txDMACh,
1692  handle->txDMASignal,
1693  txPort,
1694  (void *)&(handle->initData.dummyTxValue),
1695  false,
1696  count,
1697  size,
1698  NULL,
1699  NULL );
1700 }
1701 
1702 /***************************************************************************/
1705 static void StartTransferDMA( SPIDRV_Handle_t handle,
1706  const void *txBuffer,
1707  void *rxBuffer,
1708  int count,
1709  SPIDRV_Callback_t callback )
1710 {
1711  void *rxPort, *txPort;
1712  DMADRV_DataSize_t size;
1713 
1714  handle->blockingCompleted = false;
1715  handle->transferCount = count;
1716  handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
1717  handle->userCallback = callback;
1718 
1719  if ( handle->initData.frameLength > 8 )
1720  {
1721  size = dmadrvDataSize2;
1722  }
1723  else
1724  {
1725  size = dmadrvDataSize1;
1726  }
1727 
1728  if ( handle->initData.frameLength > 8 )
1729  {
1730  rxPort = (void *)&(handle->initData.port->RXDOUBLE);
1731  txPort = (void *)&(handle->initData.port->TXDOUBLE);
1732  }
1733  else
1734  {
1735  rxPort = (void *)&(handle->initData.port->RXDATA);
1736  txPort = (void *)&(handle->initData.port->TXDATA);
1737  }
1738 
1739  // Start receive dma.
1740  DMADRV_PeripheralMemory( handle->rxDMACh,
1741  handle->rxDMASignal,
1742  rxBuffer,
1743  rxPort,
1744  true,
1745  count,
1746  size,
1747  RxDMAComplete,
1748  handle );
1749 
1750  // Start transmit dma.
1751  DMADRV_MemoryPeripheral( handle->txDMACh,
1752  handle->txDMASignal,
1753  txPort,
1754  (void*)txBuffer,
1755  true,
1756  count,
1757  size,
1758  NULL,
1759  NULL );
1760 }
1761 
1762 /***************************************************************************/
1765 static void StartTransmitDMA( SPIDRV_Handle_t handle,
1766  const void *buffer,
1767  int count,
1768  SPIDRV_Callback_t callback )
1769 {
1770  void *rxPort, *txPort;
1771  DMADRV_DataSize_t size;
1772 
1773  handle->blockingCompleted = false;
1774  handle->transferCount = count;
1775  handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
1776  handle->userCallback = callback;
1777 
1778  if ( handle->initData.frameLength > 8 )
1779  {
1780  size = dmadrvDataSize2;
1781  }
1782  else
1783  {
1784  size = dmadrvDataSize1;
1785  }
1786 
1787  if ( handle->initData.frameLength > 8 )
1788  {
1789  rxPort = (void *)&(handle->initData.port->RXDOUBLE);
1790  txPort = (void *)&(handle->initData.port->TXDOUBLE);
1791  }
1792  else
1793  {
1794  rxPort = (void *)&(handle->initData.port->RXDATA);
1795  txPort = (void *)&(handle->initData.port->TXDATA);
1796  }
1797 
1798  // Receive DMA runs only to get precise numbers for SPIDRV_GetTransferStatus()
1799  // Start receive dma.
1800  DMADRV_PeripheralMemory( handle->rxDMACh,
1801  handle->rxDMASignal,
1802  &(handle->dummyRx),
1803  rxPort,
1804  false,
1805  count,
1806  size,
1807  RxDMAComplete,
1808  handle );
1809 
1810  // Start transmit dma.
1811  DMADRV_MemoryPeripheral( handle->txDMACh,
1812  handle->txDMASignal,
1813  txPort,
1814  (void*)buffer,
1815  true,
1816  count,
1817  size,
1818  NULL,
1819  NULL );
1820 }
1821 
1822 /***************************************************************************/
1825 static Ecode_t TransferApiBlockingPrologue( SPIDRV_Handle_t handle,
1826  void *buffer,
1827  int count )
1828 {
1829  if ( handle == NULL )
1830  {
1832  }
1833 
1834  if (( buffer == NULL ) || ( count == 0 )|| ( count > DMADRV_MAX_XFER_COUNT ))
1835  {
1837  }
1838 
1839  INT_Disable();
1840  if ( handle->state != spidrvStateIdle )
1841  {
1842  INT_Enable();
1843  return ECODE_EMDRV_SPIDRV_BUSY;
1844  }
1845  handle->state = spidrvStateTransferring;
1846  INT_Enable();
1847 
1848  return ECODE_EMDRV_SPIDRV_OK;
1849 }
1850 
1851 /***************************************************************************/
1854 static Ecode_t TransferApiPrologue( SPIDRV_Handle_t handle,
1855  void *buffer,
1856  int count )
1857 {
1858  if ( handle == NULL )
1859  {
1861  }
1862 
1863  if (( buffer == NULL ) || ( count == 0 ) || ( count > DMADRV_MAX_XFER_COUNT ))
1864  {
1866  }
1867 
1868  INT_Disable();
1869  if ( handle->state != spidrvStateIdle )
1870  {
1871  INT_Enable();
1872  return ECODE_EMDRV_SPIDRV_BUSY;
1873  }
1874  handle->state = spidrvStateTransferring;
1875  INT_Enable();
1876 
1877  return ECODE_EMDRV_SPIDRV_OK;
1878 }
1879 
1880 /***************************************************************************/
1883 static void WaitForTransferCompletion( SPIDRV_Handle_t handle )
1884 {
1885  if ( INT_Disable() > 1 )
1886  {
1887  /* Interrupts are already disabled. */
1888  while ( handle->blockingCompleted == false )
1889  {
1890 #if defined( DMA_PRESENT ) && ( DMA_COUNT == 1 )
1891  DMA_IRQHandler();
1892 #elif defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 )
1893  LDMA_IRQHandler();
1894 #else
1895 #error "No valid DMA engine defined."
1896 #endif
1897  }
1898  INT_Enable();
1899  }
1900  else
1901  {
1902  INT_Enable();
1903  while ( handle->blockingCompleted == false );
1904  }
1905 }
1906 
1907 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
1908 /***************************************************************************/
1911 static Ecode_t WaitForIdleLine( SPIDRV_Handle_t handle )
1912 {
1913  while ( !GPIO_PinInGet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin )
1914  && ( handle->state != spidrvStateIdle ) );
1915 
1916  if ( handle->state == spidrvStateIdle )
1917  {
1918  return handle->transferStatus;
1919  }
1920 
1921  return ECODE_EMDRV_SPIDRV_OK;
1922 }
1923 #endif
1924 
1926 
1927 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/
#define ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE
Illegal SPI handle.
Definition: spidrv.h:47
#define USART1
Ecode_t SPIDRV_GetTransferStatus(SPIDRV_Handle_t handle, int *itemsTransferred, int *itemsRemaining)
Get the status of a SPI transfer.
Definition: spidrv.c:470
SPIDRV_Type_t type
SPI type, master or slave.
Definition: spidrv.h:140
DMADRV API definition.
Ecode_t SPIDRV_DeInit(SPIDRV_Handle_t handle)
Deinitialize a SPI driver instance.
Definition: spidrv.c:312
Ecode_t SPIDRV_AbortTransfer(SPIDRV_Handle_t handle)
Abort an ongoing SPI transfer.
Definition: spidrv.c:353
Trig on USART0_RXDATAV.
Definition: dmadrv.h:233
Trig on USART0_TXBL.
Definition: dmadrv.h:236
GPIO_Port_TypeDef
Definition: em_gpio.h:232
uint32_t RTCDRV_TimerID_t
Timer ID.
Definition: rtcdriver.h:49
Act as SPI slave.
Definition: spidrv.h:61
#define _USART_FRAME_DATABITS_SHIFT
#define ECODE_EMDRV_RTCDRV_OK
Success return value.
Definition: rtcdriver.h:41
Trig on USART1_RXDATAV.
Definition: dmadrv.h:260
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:1124
Ecode_t DMADRV_PeripheralMemory(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst, void *src, bool dstInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a peripheral to memory DMA transfer.
Definition: dmadrv.c:535
SPIDRV API definition.
Ecode_t SPIDRV_GetBitrate(SPIDRV_Handle_t handle, uint32_t *bitRate)
Get current SPI bus bitrate.
Definition: spidrv.c:406
void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init)
Init USART for synchronous mode.
Definition: em_usart.c:654
#define USART_CMD_CLEARRX
#define ECODE_EMDRV_SPIDRV_ABORTED
SPI transfer has been aborted.
Definition: spidrv.h:53
Ecode_t SPIDRV_MTransmitB(SPIDRV_Handle_t handle, const void *buffer, int count)
Start a SPI master blocking transmit transfer.
Definition: spidrv.c:805
Ecode_t DMADRV_TransferActive(unsigned int channelId, bool *active)
Check if a transfer is running.
Definition: dmadrv.c:681
Oneshot timer.
Definition: rtcdriver.h:69
#define _USART_FRAME_DATABITS_MASK
#define ECODE_EMDRV_SPIDRV_TIMER_ALLOC_ERROR
Unable to allocated timeout timer.
Definition: spidrv.h:50
#define ECODE_EMDRV_SPIDRV_MODE_ERROR
SPI master used slave API or vica versa.
Definition: spidrv.h:54
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:472
MSB bit is transmitted first.
Definition: spidrv.h:68
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:607
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:522
SPIDRV_BitOrder_t bitOrder
Bit order on SPI bus, MSB or LSB first.
Definition: spidrv.h:141
USART_TypeDef * port
The USART used for SPI.
Definition: spidrv.h:128
__STATIC_INLINE uint32_t INT_Enable(void)
Enable interrupts.
Definition: em_int.h:94
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:706
Ecode_t DMADRV_StopTransfer(unsigned int channelId)
Stop an ongoing DMA transfer.
Definition: dmadrv.c:641
Ecode_t RTCDRV_AllocateTimer(RTCDRV_TimerID_t *id)
Allocate timer.
Definition: rtcdriver.c:228
Halfword.
Definition: dmadrv.h:299
#define USART_CMD_CLEARTX
#define ECODE_EMDRV_SPIDRV_IDLE
No SPI transfer in progress.
Definition: spidrv.h:52
Ecode_t SPIDRV_MTransferB(SPIDRV_Handle_t handle, const void *txBuffer, void *rxBuffer, int count)
Start a SPI master blocking transfer.
Definition: spidrv.c:657
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
__IO uint32_t ROUTE
Definition: efm32gg_usart.h:64
Universal synchronous/asynchronous receiver/transmitter (USART/UART) peripheral API.
#define ECODE_EMDRV_SPIDRV_DMA_ALLOC_ERROR
Unable to allocated DMA channels.
Definition: spidrv.h:55
SPI mode 2: CLKPOL=1, CLKPHA=0.
Definition: spidrv.h:76
#define ECODE_EMDRV_SPIDRV_PARAM_ERROR
Illegal input parameter.
Definition: spidrv.h:48
uint8_t portLocation
Location number for SPI pins.
Definition: spidrv.h:135
Byte.
Definition: dmadrv.h:298
uint32_t bitRate
SPI bitrate.
Definition: spidrv.h:137
#define ECODE_EMDRV_SPIDRV_BUSY
The SPI port is busy.
Definition: spidrv.h:49
#define ECODE_EMDRV_SPIDRV_OK
Success return value.
Definition: spidrv.h:46
Ecode_t SPIDRV_SetFramelength(SPIDRV_Handle_t handle, uint32_t frameLength)
Set SPI framelength.
Definition: spidrv.c:874
Ecode_t DMADRV_TransferRemainingCount(unsigned int channelId, int *remaining)
Get number of items remaining in a transfer.
Definition: dmadrv.c:852
Trig on USART1_TXBL.
Definition: dmadrv.h:266
SPI mode 1: CLKPOL=0, CLKPHA=1.
Definition: spidrv.h:75
__IO uint32_t CTRL
Definition: efm32gg_usart.h:43
Interrupt enable/disable unit API.
Ecode_t RTCDRV_StopTimer(RTCDRV_TimerID_t id)
Stop a given timer.
Definition: rtcdriver.c:661
Ecode_t RTCDRV_Init(void)
Initialize RTCDRV driver.
Definition: rtcdriver.c:322
#define USART_ROUTE_TXPEN
#define USART0
void GPIO_PinModeSet(GPIO_Port_TypeDef port, unsigned int pin, GPIO_Mode_TypeDef mode, unsigned int out)
Set the mode for a GPIO pin.
Definition: em_gpio.c:226
Transfer is started when bus is idle (CS deasserted).
Definition: spidrv.h:91
General Purpose IO (GPIO) peripheral API.
Ecode_t RTCDRV_FreeTimer(RTCDRV_TimerID_t id)
Free timer.
Definition: rtcdriver.c:294
#define _USART_FRAME_DATABITS_FOUR
#define USART_ROUTE_CSPEN
#define DMADRV_MAX_XFER_COUNT
Maximum length of one DMA transfer.
Definition: dmadrv.h:88
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Definition: em_cmu.c:1369
Ecode_t DMADRV_Init(void)
Initialize DMADRV.
Definition: dmadrv.c:258
Ecode_t SPIDRV_SetBitrate(SPIDRV_Handle_t handle, uint32_t bitRate)
Set SPI bus bitrate.
Definition: spidrv.c:841
USART_ClockMode_TypeDef clockMode
Definition: em_usart.h:400
#define _USART_FRAME_DATABITS_SIXTEEN
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:763
#define _USART_ROUTE_LOCATION_SHIFT
#define USART2
#define ECODE_EMDRV_DMADRV_OK
Success return value.
Definition: dmadrv.h:51
void USART_Reset(USART_TypeDef *usart)
Reset USART/UART to same state as after a HW reset.
Definition: em_usart.c:876
Ecode_t DMADRV_DeInit(void)
Deinitialize DMADRV.
Definition: dmadrv.c:176
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:511
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:1053
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:1257
Ecode_t DMADRV_MemoryPeripheral(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst, void *src, bool srcInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a memory to peripheral DMA transfer.
Definition: dmadrv.c:402
SPI mode 0: CLKPOL=0, CLKPHA=0.
Definition: spidrv.h:74
Ecode_t SPIDRV_GetFramelength(SPIDRV_Handle_t handle, uint32_t *frameLength)
Get current SPI framelength.
Definition: spidrv.c:435
Trig on USART2_RXDATAV.
Definition: dmadrv.h:275
Ecode_t SPIDRV_Init(SPIDRV_Handle_t handle, SPIDRV_Init_t *initData)
Initialize a SPI driver instance.
Definition: spidrv.c:91
uint32_t Ecode_t
Typedef for API function errorcode return values.
Definition: ecode.h:31
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:1193
#define ECODE_EMDRV_SPIDRV_TIMEOUT
SPI transfer timeout.
Definition: spidrv.h:51
Ecode_t DMADRV_TransferCompletePending(unsigned int channelId, bool *pending)
Check if a transfer complete is pending.
Definition: dmadrv.c:733
CS controlled by SPI driver.
Definition: spidrv.h:83
Act as SPI master.
Definition: spidrv.h:60
__STATIC_INLINE uint32_t INT_Disable(void)
Disable interrupts.
Definition: em_int.h:71
#define USART_CTRL_AUTOCS
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:927
#define USART_ROUTE_RXPEN
Trig on USART2_TXBL.
Definition: dmadrv.h:281
#define USART_INITSYNC_DEFAULT
Definition: em_usart.h:442
uint32_t USART_BaudrateGet(USART_TypeDef *usart)
Get current baudrate for USART/UART.
Definition: em_usart.c:423
__STATIC_INLINE unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin)
Read the pad value for a single pin in a GPIO port.
Definition: em_gpio.h:675
void(* SPIDRV_Callback_t)(struct SPIDRV_HandleData *handle, Ecode_t transferStatus, int itemsTransferred)
SPIDRV transfer completion callback function.
Definition: spidrv.h:117
SPI mode 3: CLKPOL=1, CLKPHA=1.
Definition: spidrv.h:77
Ecode_t SPIDRV_SReceiveB(SPIDRV_Handle_t handle, void *buffer, int count, int timeoutMs)
Start a SPI slave blocking receive transfer.
Definition: spidrv.c:991
SPIDRV_HandleData_t * SPIDRV_Handle_t
SPI driver instance handle.
Definition: spidrv.h:177
SPIDRV_CsControl_t csControl
Select master mode chip select (CS) control scheme.
Definition: spidrv.h:143
SPIDRV_ClockMode_t clockMode
SPI mode, CLKPOL/CLKPHASE setting.
Definition: spidrv.h:142
Ecode_t SPIDRV_MReceiveB(SPIDRV_Handle_t handle, void *buffer, int count)
Start a SPI master blocking receive transfer.
Definition: spidrv.c:565
Ecode_t DMADRV_FreeChannel(unsigned int channelId)
Free an allocate (reserved) DMA channel.
Definition: dmadrv.c:223
#define USART_ROUTE_CLKPEN