00001
00016 #include <string.h>
00017
00018 #include "em_device.h"
00019 #include "em_gpio.h"
00020 #include "em_int.h"
00021 #include "em_usart.h"
00022
00023 #include "dmactrl.h"
00024 #include "spidrv.h"
00025
00027
00028 static bool spidrvIsInitialized = false;
00029
00030 static void BlockingComplete( SPIDRV_Handle_t handle,
00031 Ecode_t transferStatus,
00032 int itemsTransferred );
00033
00034 static Ecode_t ConfigGPIO( SPIDRV_Handle_t handle, bool enable );
00035
00036 static void RxDMAComplete( unsigned int channel,
00037 bool primary,
00038 void *user );
00039
00040 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00041 static void SlaveTimeout( RTCDRV_TimerID_t id,
00042 void *user );
00043 #endif
00044
00045 static void StartReceiveDMA( SPIDRV_Handle_t handle,
00046 void *buffer,
00047 int count,
00048 SPIDRV_Callback_t callback );
00049
00050 static void StartTransferDMA( SPIDRV_Handle_t handle,
00051 const void *txBuffer,
00052 void *rxBuffer,
00053 int count,
00054 SPIDRV_Callback_t callback );
00055
00056 static void StartTransmitDMA( SPIDRV_Handle_t handle,
00057 const void *buffer,
00058 int count,
00059 SPIDRV_Callback_t callback );
00060
00061 static Ecode_t TransferApiPrologue( SPIDRV_Handle_t handle,
00062 void *buffer,
00063 int count );
00064
00065 static Ecode_t TransferApiBlockingPrologue( SPIDRV_Handle_t handle,
00066 void *buffer,
00067 int count );
00068
00069 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00070 static Ecode_t WaitForIdleLine( SPIDRV_Handle_t handle );
00071 #endif
00072
00074
00075
00089 Ecode_t SPIDRV_Init( SPIDRV_Handle_t handle, SPIDRV_Init_t *initData )
00090 {
00091 Ecode_t retVal;
00092 DMA_Init_TypeDef dmaInit;
00093 DMA_CfgChannel_TypeDef dmaChannelCfg;
00094 uint32_t rxDmaSrcSelect, txDmaSrcSelect;
00095 USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT;
00096
00097 if ( handle == NULL ) {
00098 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00099 }
00100
00101 if ( initData == NULL ) {
00102 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00103 }
00104
00105 memset( handle, 0, sizeof( SPIDRV_HandleData_t ) );
00106
00107 if ( 0 ) {
00108 #if defined( USART0 )
00109 } else if ( initData->port == USART0 ) {
00110 handle->usartClock = cmuClock_USART0;
00111 txDmaSrcSelect = DMAREQ_USART0_TXBL;
00112 rxDmaSrcSelect = DMAREQ_USART0_RXDATAV;
00113 #endif
00114 #if defined( USART1 )
00115 } else if ( initData->port == USART1 ) {
00116 handle->usartClock = cmuClock_USART1;
00117 txDmaSrcSelect = DMAREQ_USART1_TXBL;
00118 rxDmaSrcSelect = DMAREQ_USART1_RXDATAV;
00119 #endif
00120 #if defined( USART2 )
00121 } else if ( initData->port == USART2 ) {
00122 handle->usartClock = cmuClock_USART2;
00123 txDmaSrcSelect = DMAREQ_USART2_TXBL;
00124 rxDmaSrcSelect = DMAREQ_USART2_RXDATAV;
00125 #endif
00126 } else {
00127 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00128 }
00129
00130 handle->initData = *initData;
00131
00132 if ( initData->bitOrder == spidrvBitOrderMsbFirst ) {
00133 usartInit.msbf = true;
00134 }
00135
00136 if ( initData->clockMode == spidrvClockMode0 ) {
00137 usartInit.clockMode = usartClockMode0;
00138 } else if ( initData->clockMode == spidrvClockMode1 ) {
00139 usartInit.clockMode = usartClockMode1;
00140 } else if ( initData->clockMode == spidrvClockMode2 ) {
00141 usartInit.clockMode = usartClockMode2;
00142 } else if ( initData->clockMode == spidrvClockMode3 ) {
00143 usartInit.clockMode = usartClockMode3;
00144 } else {
00145 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00146 }
00147
00148 if ( initData->type == spidrvSlave ) {
00149 usartInit.master = false;
00150 usartInit.baudrate = 1000;
00151 } else {
00152 usartInit.baudrate = initData->bitRate;
00153 }
00154
00155 CMU_ClockEnable( cmuClock_HFPER, true );
00156 CMU_ClockEnable( cmuClock_GPIO, true );
00157 CMU_ClockEnable( cmuClock_DMA, true );
00158 CMU_ClockEnable( handle->usartClock, true );
00159 USART_InitSync( initData->port, &usartInit );
00160
00161 if ( ( initData->type == spidrvMaster )
00162 && ( initData->csControl == spidrvCsControlAuto ) ) {
00163 initData->port->CTRL |= USART_CTRL_AUTOCS;
00164 }
00165
00166 if ( ( initData->type == spidrvMaster )
00167 && ( initData->csControl == spidrvCsControlApplication ) ) {
00168 initData->port->ROUTE = USART_ROUTE_TXPEN
00169 | USART_ROUTE_RXPEN
00170 | USART_ROUTE_CLKPEN
00171 | (initData->portLocation
00172 << _USART_ROUTE_LOCATION_SHIFT );
00173 } else {
00174 initData->port->ROUTE = USART_ROUTE_TXPEN
00175 | USART_ROUTE_RXPEN
00176 | USART_ROUTE_CLKPEN
00177 | USART_ROUTE_CSPEN
00178 | (initData->portLocation
00179 << _USART_ROUTE_LOCATION_SHIFT );
00180 }
00181
00182 if ( ( retVal = ConfigGPIO( handle, true ) ) != ECODE_EMDRV_SPIDRV_OK ) {
00183 return retVal;
00184 }
00185
00186 INT_Disable();
00187 if ( ! spidrvIsInitialized ) {
00188 spidrvIsInitialized = true;
00189 INT_Enable();
00190
00191
00192
00193
00194 NVIC_SetPriority( DMA_IRQn, EMDRV_SPIDRV_DMA_IRQ_PRIORITY );
00195 dmaInit.hprot = 0;
00196 dmaInit.controlBlock = dmaControlBlock;
00197 DMA_Init( &dmaInit );
00198
00199 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00200 RTCDRV_Init();
00201 #endif
00202 } else {
00203 INT_Enable();
00204 }
00205
00206 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00207 if ( initData->type == spidrvSlave ) {
00208 if ( RTCDRV_AllocateTimer( &handle->timer ) != ECODE_EMDRV_RTCDRV_OK ) {
00209 return ECODE_EMDRV_SPIDRV_TIMER_ALLOC_ERROR;
00210 }
00211 }
00212 #endif
00213
00214
00215 dmaChannelCfg.highPri = false;
00216
00217 dmaChannelCfg.enableInt = false;
00218 dmaChannelCfg.select = txDmaSrcSelect;
00219 dmaChannelCfg.cb = NULL;
00220 DMA_CfgChannel( initData->txDMACh, &dmaChannelCfg );
00221
00222 dmaChannelCfg.enableInt = true;
00223 dmaChannelCfg.select = rxDmaSrcSelect;
00224 handle->rxDmaCbData.cbFunc = RxDMAComplete;
00225 dmaChannelCfg.cb = &(handle->rxDmaCbData);
00226 handle->rxDmaCbData.userPtr = (void*)handle;
00227 DMA_CfgChannel( initData->rxDMACh, &dmaChannelCfg );
00228
00229 return ECODE_EMDRV_SPIDRV_OK;
00230 }
00231
00232
00242 Ecode_t SPIDRV_DeInit( SPIDRV_Handle_t handle )
00243 {
00244 if ( handle == NULL ) {
00245 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00246 }
00247
00248
00249 DMA_ChannelEnable( handle->initData.rxDMACh, false );
00250 DMA_ChannelEnable( handle->initData.txDMACh, false );
00251
00252 ConfigGPIO( handle, false );
00253
00254 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00255 if ( handle->initData.type == spidrvSlave ) {
00256 RTCDRV_StopTimer( handle->timer );
00257 RTCDRV_FreeTimer( handle->timer );
00258 }
00259 #endif
00260
00261 USART_Reset( handle->initData.port );
00262 CMU_ClockEnable( handle->usartClock, false );
00263
00264 return ECODE_EMDRV_SPIDRV_OK;
00265 }
00266
00267
00277 Ecode_t SPIDRV_AbortTransfer( SPIDRV_Handle_t handle )
00278 {
00279 if ( handle == NULL ) {
00280 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00281 }
00282
00283 INT_Disable();
00284 if ( handle->state == spidrvStateIdle ) {
00285 INT_Enable();
00286 return ECODE_EMDRV_SPIDRV_IDLE;
00287 }
00288
00289 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00290 if ( handle->initData.type == spidrvSlave ) {
00291 RTCDRV_StopTimer( handle->timer );
00292 }
00293 #endif
00294
00295
00296 DMA_ChannelEnable( handle->initData.rxDMACh, false );
00297 DMA_ChannelEnable( handle->initData.txDMACh, false );
00298 handle->remaining = 1 + ( ( dmaControlBlock[ handle->initData.rxDMACh ].CTRL
00299 & _DMA_CTRL_N_MINUS_1_MASK )
00300 >> _DMA_CTRL_N_MINUS_1_SHIFT );
00301
00302 handle->transferStatus = ECODE_EMDRV_SPIDRV_ABORTED;
00303 handle->state = spidrvStateIdle;
00304 handle->transferStatus = ECODE_EMDRV_SPIDRV_ABORTED;
00305 handle->blockingCompleted = true;
00306
00307 if ( handle->userCallback != NULL ) {
00308 handle->userCallback( handle,
00309 ECODE_EMDRV_SPIDRV_ABORTED,
00310 handle->transferCount - handle->remaining );
00311 }
00312 INT_Enable();
00313
00314 return ECODE_EMDRV_SPIDRV_OK;
00315 }
00316
00317
00329 Ecode_t SPIDRV_GetBitrate( SPIDRV_Handle_t handle, uint32_t *bitRate )
00330 {
00331 if ( handle == NULL ) {
00332 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00333 }
00334
00335 if ( bitRate == NULL ) {
00336 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00337 }
00338
00339 *bitRate = USART_BaudrateGet( handle->initData.port );
00340
00341 return ECODE_EMDRV_SPIDRV_OK;
00342 }
00343
00344
00356 Ecode_t SPIDRV_GetFramelength( SPIDRV_Handle_t handle, uint32_t *frameLength )
00357 {
00358 if ( handle == NULL ) {
00359 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00360 }
00361
00362 if ( frameLength == NULL ) {
00363 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00364 }
00365
00366 *frameLength = handle->initData.frameLength;
00367
00368 return ECODE_EMDRV_SPIDRV_OK;
00369 }
00370
00371
00389 Ecode_t SPIDRV_GetTransferStatus( SPIDRV_Handle_t handle,
00390 int *itemsTransferred,
00391 int *itemsRemaining )
00392 {
00393 int remaining;
00394
00395 if ( handle == NULL ) {
00396 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00397 }
00398
00399 if ( ( itemsTransferred == NULL ) || ( itemsRemaining == NULL ) )
00400 {
00401 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00402 }
00403
00404 INT_Disable();
00405 if ( handle->state == spidrvStateIdle ) {
00406 remaining = handle->remaining;
00407 } else {
00408 remaining = 1 + ( ( dmaControlBlock[ handle->initData.rxDMACh ].CTRL
00409 & _DMA_CTRL_N_MINUS_1_MASK )
00410 >> _DMA_CTRL_N_MINUS_1_SHIFT );
00411 }
00412 INT_Enable();
00413
00414 *itemsTransferred = handle->transferCount - remaining;
00415 *itemsRemaining = remaining;
00416
00417 return ECODE_EMDRV_SPIDRV_OK;
00418 }
00419
00420
00439 Ecode_t SPIDRV_MReceive( SPIDRV_Handle_t handle,
00440 void *buffer,
00441 int count,
00442 SPIDRV_Callback_t callback )
00443 {
00444 Ecode_t retVal;
00445
00446 if ( handle->initData.type == spidrvSlave ) {
00447 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00448 }
00449
00450 if ( ( retVal = TransferApiPrologue( handle, buffer, count ) )
00451 != ECODE_EMDRV_SPIDRV_OK ) {
00452 return retVal;
00453 }
00454
00455 StartReceiveDMA( handle, buffer, count, callback );
00456
00457 return ECODE_EMDRV_SPIDRV_OK;
00458 }
00459
00460
00480 Ecode_t SPIDRV_MReceiveB( SPIDRV_Handle_t handle,
00481 void *buffer,
00482 int count )
00483 {
00484 Ecode_t retVal;
00485
00486 if ( handle->initData.type == spidrvSlave ) {
00487 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00488 }
00489
00490 if ( ( retVal = TransferApiBlockingPrologue( handle, buffer, count ) )
00491 != ECODE_EMDRV_SPIDRV_OK ) {
00492 return retVal;
00493 }
00494
00495 StartReceiveDMA( handle, buffer, count, BlockingComplete );
00496
00497 while ( handle->blockingCompleted == false );
00498
00499 return handle->transferStatus;
00500 }
00501
00502
00520 Ecode_t SPIDRV_MTransfer( SPIDRV_Handle_t handle,
00521 const void *txBuffer,
00522 void *rxBuffer,
00523 int count,
00524 SPIDRV_Callback_t callback )
00525 {
00526 Ecode_t retVal;
00527
00528 if ( handle->initData.type == spidrvSlave ) {
00529 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00530 }
00531
00532 if ( ( retVal = TransferApiPrologue( handle, (void*)txBuffer, count ) )
00533 != ECODE_EMDRV_SPIDRV_OK ) {
00534 return retVal;
00535 }
00536
00537 if ( rxBuffer == NULL ) {
00538 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00539 }
00540
00541 StartTransferDMA( handle, txBuffer, rxBuffer, count, callback );
00542
00543 return ECODE_EMDRV_SPIDRV_OK;
00544 }
00545
00546
00567 Ecode_t SPIDRV_MTransferB( SPIDRV_Handle_t handle,
00568 const void *txBuffer,
00569 void *rxBuffer,
00570 int count )
00571 {
00572 Ecode_t retVal;
00573
00574 if ( handle->initData.type == spidrvSlave ) {
00575 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00576 }
00577
00578 if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)txBuffer, count ))
00579 != ECODE_EMDRV_SPIDRV_OK ) {
00580 return retVal;
00581 }
00582
00583 if ( rxBuffer == NULL ) {
00584 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00585 }
00586
00587 StartTransferDMA( handle, txBuffer, rxBuffer, count, BlockingComplete );
00588
00589 while ( handle->blockingCompleted == false );
00590
00591 return handle->transferStatus;
00592 }
00593
00594
00613 Ecode_t SPIDRV_MTransferSingleItemB( SPIDRV_Handle_t handle,
00614 uint32_t txValue,
00615 void *rxValue )
00616 {
00617 void *pRx;
00618 uint32_t rxBuffer;
00619
00620 if ( handle->initData.type == spidrvSlave ) {
00621 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00622 }
00623
00624 if ( handle == NULL ) {
00625 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00626 }
00627
00628 if ( INT_Disable() > 1 )
00629 {
00630 INT_Enable();
00631 return ECODE_EMDRV_SPIDRV_ILLEGAL_OPERATION;
00632 }
00633
00634 if ( handle->state != spidrvStateIdle ) {
00635 INT_Enable();
00636 return ECODE_EMDRV_SPIDRV_BUSY;
00637 }
00638 handle->state = spidrvStateTransferring;
00639 INT_Enable();
00640
00641 if ( ( pRx = rxValue ) == NULL ) {
00642 pRx = &rxBuffer;
00643 }
00644
00645 StartTransferDMA( handle, &txValue, pRx, 1, BlockingComplete );
00646
00647 while ( handle->blockingCompleted == false );
00648
00649 return handle->transferStatus;
00650 }
00651
00652
00671 Ecode_t SPIDRV_MTransmit( SPIDRV_Handle_t handle,
00672 const void *buffer,
00673 int count,
00674 SPIDRV_Callback_t callback )
00675 {
00676 Ecode_t retVal;
00677
00678 if ( handle->initData.type == spidrvSlave ) {
00679 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00680 }
00681
00682 if ( ( retVal = TransferApiPrologue( handle, (void*)buffer, count ) )
00683 != ECODE_EMDRV_SPIDRV_OK ) {
00684 return retVal;
00685 }
00686
00687 StartTransmitDMA( handle, buffer, count, callback );
00688
00689 return ECODE_EMDRV_SPIDRV_OK;
00690 }
00691
00692
00711 Ecode_t SPIDRV_MTransmitB( SPIDRV_Handle_t handle,
00712 const void *buffer,
00713 int count )
00714 {
00715 Ecode_t retVal;
00716
00717 if ( handle->initData.type == spidrvSlave ) {
00718 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00719 }
00720
00721 if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)buffer, count ) )
00722 != ECODE_EMDRV_SPIDRV_OK ) {
00723 return retVal;
00724 }
00725
00726 StartTransmitDMA( handle, buffer, count, BlockingComplete );
00727
00728 while ( handle->blockingCompleted == false );
00729
00730 return handle->transferStatus;
00731 }
00732
00733
00745 Ecode_t SPIDRV_SetBitrate( SPIDRV_Handle_t handle, uint32_t bitRate )
00746 {
00747 if ( handle == NULL ) {
00748 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00749 }
00750
00751 INT_Disable();
00752 if ( handle->state != spidrvStateIdle ) {
00753 INT_Enable();
00754 return ECODE_EMDRV_SPIDRV_BUSY;
00755 }
00756
00757 handle->initData.bitRate = bitRate;
00758 USART_BaudrateSyncSet( handle->initData.port, 0, bitRate );
00759 INT_Enable();
00760
00761 return ECODE_EMDRV_SPIDRV_OK;
00762 }
00763
00764
00776 Ecode_t SPIDRV_SetFramelength( SPIDRV_Handle_t handle, uint32_t frameLength )
00777 {
00778 if ( handle == NULL ) {
00779 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00780 }
00781
00782 frameLength -= 3;
00783 if ( ( frameLength < _USART_FRAME_DATABITS_FOUR )
00784 || ( frameLength > _USART_FRAME_DATABITS_SIXTEEN ) ) {
00785 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00786 }
00787
00788 INT_Disable();
00789 if ( handle->state != spidrvStateIdle ) {
00790 INT_Enable();
00791 return ECODE_EMDRV_SPIDRV_BUSY;
00792 }
00793
00794 handle->initData.frameLength = frameLength + 3;
00795 handle->initData.port->FRAME = ( handle->initData.port->FRAME
00796 & ~_USART_FRAME_DATABITS_MASK )
00797 | ( frameLength
00798 << _USART_FRAME_DATABITS_SHIFT );
00799 INT_Enable();
00800
00801 return ECODE_EMDRV_SPIDRV_OK;
00802 }
00803
00804 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00805
00826 Ecode_t SPIDRV_SReceive( SPIDRV_Handle_t handle,
00827 void *buffer,
00828 int count,
00829 SPIDRV_Callback_t callback,
00830 int timeoutMs )
00831 {
00832 Ecode_t retVal;
00833
00834 if ( handle->initData.type == spidrvMaster ) {
00835 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00836 }
00837
00838 if ( ( retVal = TransferApiPrologue( handle, buffer, count ) )
00839 != ECODE_EMDRV_SPIDRV_OK ) {
00840 return retVal;
00841 }
00842
00843 if ( timeoutMs ) {
00844 RTCDRV_StartTimer( handle->timer,
00845 rtcdrvTimerTypeOneshot,
00846 timeoutMs,
00847 SlaveTimeout,
00848 handle );
00849 }
00850
00851 if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed ) {
00852 if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK ) {
00853 return retVal;
00854 }
00855 }
00856
00857 StartReceiveDMA( handle, buffer, count, callback );
00858
00859 return ECODE_EMDRV_SPIDRV_OK;
00860 }
00861
00862
00885 Ecode_t SPIDRV_SReceiveB( SPIDRV_Handle_t handle,
00886 void *buffer,
00887 int count,
00888 int timeoutMs )
00889 {
00890 Ecode_t retVal;
00891
00892 if ( handle->initData.type == spidrvMaster ) {
00893 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00894 }
00895
00896 if ( ( retVal = TransferApiBlockingPrologue( handle, buffer, count ) )
00897 != ECODE_EMDRV_SPIDRV_OK ) {
00898 return retVal;
00899 }
00900
00901 if ( timeoutMs ) {
00902 RTCDRV_StartTimer( handle->timer,
00903 rtcdrvTimerTypeOneshot,
00904 timeoutMs,
00905 SlaveTimeout,
00906 handle );
00907 }
00908
00909 if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed ) {
00910 if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK ) {
00911 return retVal;
00912 }
00913 }
00914
00915 StartReceiveDMA( handle, buffer, count, BlockingComplete );
00916
00917 while ( handle->blockingCompleted == false );
00918
00919 return handle->transferStatus;
00920 }
00921
00922
00942 Ecode_t SPIDRV_STransfer( SPIDRV_Handle_t handle,
00943 const void *txBuffer,
00944 void *rxBuffer,
00945 int count,
00946 SPIDRV_Callback_t callback,
00947 int timeoutMs )
00948 {
00949 Ecode_t retVal;
00950
00951 if ( handle->initData.type == spidrvMaster ) {
00952 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00953 }
00954
00955 if ( ( retVal = TransferApiPrologue( handle, (void*)txBuffer, count ) )
00956 != ECODE_EMDRV_SPIDRV_OK ) {
00957 return retVal;
00958 }
00959
00960 if ( rxBuffer == NULL ) {
00961 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00962 }
00963
00964 if ( timeoutMs ) {
00965 RTCDRV_StartTimer( handle->timer,
00966 rtcdrvTimerTypeOneshot,
00967 timeoutMs,
00968 SlaveTimeout,
00969 handle );
00970 }
00971
00972 if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed ) {
00973 if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK ) {
00974 return retVal;
00975 }
00976 }
00977
00978 StartTransferDMA( handle, txBuffer, rxBuffer, count, callback );
00979
00980 return ECODE_EMDRV_SPIDRV_OK;
00981 }
00982
00983
01007 Ecode_t SPIDRV_STransferB( SPIDRV_Handle_t handle,
01008 const void *txBuffer,
01009 void *rxBuffer,
01010 int count,
01011 int timeoutMs )
01012 {
01013 Ecode_t retVal;
01014
01015 if ( handle->initData.type == spidrvMaster ) {
01016 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
01017 }
01018
01019 if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)txBuffer, count ))
01020 != ECODE_EMDRV_SPIDRV_OK ) {
01021 return retVal;
01022 }
01023
01024 if ( rxBuffer == NULL ) {
01025 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01026 }
01027
01028 if ( timeoutMs ) {
01029 RTCDRV_StartTimer( handle->timer,
01030 rtcdrvTimerTypeOneshot,
01031 timeoutMs,
01032 SlaveTimeout,
01033 handle );
01034 }
01035
01036 if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed ) {
01037 if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK ) {
01038 return retVal;
01039 }
01040 }
01041
01042 StartTransferDMA( handle, txBuffer, rxBuffer, count, BlockingComplete );
01043
01044 while ( handle->blockingCompleted == false );
01045
01046 return handle->transferStatus;
01047 }
01048
01049
01070 Ecode_t SPIDRV_STransmit( SPIDRV_Handle_t handle,
01071 const void *buffer,
01072 int count,
01073 SPIDRV_Callback_t callback,
01074 int timeoutMs )
01075 {
01076 Ecode_t retVal;
01077
01078 if ( handle->initData.type == spidrvMaster ) {
01079 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
01080 }
01081
01082 if ( ( retVal = TransferApiPrologue( handle, (void*)buffer, count ) )
01083 != ECODE_EMDRV_SPIDRV_OK ) {
01084 return retVal;
01085 }
01086
01087 if ( timeoutMs ) {
01088 RTCDRV_StartTimer( handle->timer,
01089 rtcdrvTimerTypeOneshot,
01090 timeoutMs,
01091 SlaveTimeout,
01092 handle );
01093 }
01094
01095 if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed ) {
01096 if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK ) {
01097 return retVal;
01098 }
01099 }
01100
01101 StartTransmitDMA( handle, buffer, count, callback );
01102
01103 return ECODE_EMDRV_SPIDRV_OK;
01104 }
01105
01106
01129 Ecode_t SPIDRV_STransmitB( SPIDRV_Handle_t handle,
01130 const void *buffer,
01131 int count,
01132 int timeoutMs )
01133 {
01134 Ecode_t retVal;
01135
01136 if ( handle->initData.type == spidrvMaster ) {
01137 return ECODE_EMDRV_SPIDRV_MODE_ERROR;
01138 }
01139
01140 if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)buffer, count ) )
01141 != ECODE_EMDRV_SPIDRV_OK ) {
01142 return retVal;
01143 }
01144
01145 if ( timeoutMs ) {
01146 RTCDRV_StartTimer( handle->timer,
01147 rtcdrvTimerTypeOneshot,
01148 timeoutMs,
01149 SlaveTimeout,
01150 handle );
01151 }
01152
01153 if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed ) {
01154 if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK ) {
01155 return retVal;
01156 }
01157 }
01158
01159 StartTransmitDMA( handle, buffer, count, BlockingComplete );
01160
01161 while ( handle->blockingCompleted == false );
01162
01163 return handle->transferStatus;
01164 }
01165 #endif
01166
01168
01169
01175 static void BlockingComplete( SPIDRV_Handle_t handle,
01176 Ecode_t transferStatus,
01177 int itemsTransferred )
01178 {
01179 (void)itemsTransferred;
01180
01181 handle->transferStatus = transferStatus;
01182 handle->blockingCompleted = true;
01183 }
01184
01185
01188 static Ecode_t ConfigGPIO( SPIDRV_Handle_t handle, bool enable )
01189 {
01190 uint32_t location;
01191 int mosiPin, misoPin, clkPin;
01192 int mosiPort, misoPort, clkPort;
01193
01194 location = handle->initData.portLocation;
01195
01196 if ( 0 ) {
01197 #if defined( USART0 )
01198 } else if ( handle->initData.port == USART0 ) {
01199 mosiPort = AF_USART0_TX_PORT( location );
01200 misoPort = AF_USART0_RX_PORT( location );
01201 clkPort = AF_USART0_CLK_PORT( location );
01202 handle->csPort = AF_USART0_CS_PORT( location );
01203 mosiPin = AF_USART0_TX_PIN( location );
01204 misoPin = AF_USART0_RX_PIN( location );
01205 clkPin = AF_USART0_CLK_PIN( location );
01206 handle->csPin = AF_USART0_CS_PIN( location );
01207 #endif
01208 #if defined( USART1 )
01209 } else if ( handle->initData.port == USART1 ) {
01210 mosiPort = AF_USART1_TX_PORT( location );
01211 misoPort = AF_USART1_RX_PORT( location );
01212 clkPort = AF_USART1_CLK_PORT( location );
01213 handle->csPort = AF_USART1_CS_PORT( location );
01214 mosiPin = AF_USART1_TX_PIN( location );
01215 misoPin = AF_USART1_RX_PIN( location );
01216 clkPin = AF_USART1_CLK_PIN( location );
01217 handle->csPin = AF_USART1_CS_PIN( location );
01218 #endif
01219 #if defined( USART2 )
01220 } else if ( handle->initData.port == USART2 ) {
01221 mosiPort = AF_USART2_TX_PORT( location );
01222 misoPort = AF_USART2_RX_PORT( location );
01223 clkPort = AF_USART2_CLK_PORT( location );
01224 handle->csPort = AF_USART2_CS_PORT( location );
01225 mosiPin = AF_USART2_TX_PIN( location );
01226 misoPin = AF_USART2_RX_PIN( location );
01227 clkPin = AF_USART2_CLK_PIN( location );
01228 handle->csPin = AF_USART2_CS_PIN( location );
01229 #endif
01230 } else {
01231 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01232 }
01233
01234 if ( enable ) {
01235 if ( handle->initData.type == spidrvMaster ) {
01236 GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin,
01237 gpioModePushPull, 0 );
01238 GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin,
01239 gpioModeInputPull, 0 );
01240
01241 if ( ( handle->initData.clockMode == spidrvClockMode0 )
01242 || ( handle->initData.clockMode == spidrvClockMode1 ) ) {
01243 GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
01244 gpioModePushPull, 0 );
01245 } else {
01246 GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
01247 gpioModePushPull, 1 );
01248 }
01249
01250 GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
01251 gpioModePushPull, 1 );
01252 } else {
01253 GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin,
01254 gpioModeInputPull, 0 );
01255 GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin,
01256 gpioModePushPull, 0 );
01257
01258 if ( ( handle->initData.clockMode == spidrvClockMode0 )
01259 || ( handle->initData.clockMode == spidrvClockMode1 ) ) {
01260 GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
01261 gpioModeInputPull, 0 );
01262 } else {
01263 GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
01264 gpioModeInputPull, 1 );
01265 }
01266
01267 GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
01268 gpioModeInputPull, 1 );
01269 }
01270 } else {
01271 GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin, gpioModeInputPull,0);
01272 GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin, gpioModeInputPull,0);
01273
01274 if ( ( handle->initData.clockMode == spidrvClockMode0 )
01275 || ( handle->initData.clockMode == spidrvClockMode1 ) ) {
01276 GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin, gpioModeInputPull,0);
01277 } else {
01278 GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin, gpioModeInputPull,1);
01279 }
01280
01281 GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
01282 gpioModeDisabled, 0);
01283 }
01284
01285 return ECODE_EMDRV_SPIDRV_OK;
01286 }
01287
01288
01291 static void RxDMAComplete( unsigned int channel, bool primary, void *user )
01292 {
01293 SPIDRV_Handle_t handle;
01294 (void)channel;
01295 (void)primary;
01296
01297 INT_Disable();
01298
01299 handle = (SPIDRV_Handle_t)user;
01300
01301 handle->transferStatus = ECODE_EMDRV_SPIDRV_OK;
01302 handle->state = spidrvStateIdle;
01303 handle->remaining = 0;
01304
01305 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
01306 if ( handle->initData.type == spidrvSlave ) {
01307 RTCDRV_StopTimer( handle->timer );
01308 }
01309 #endif
01310
01311 if ( handle->userCallback != NULL ) {
01312 handle->userCallback( handle, ECODE_EMDRV_SPIDRV_OK, handle->transferCount);
01313 }
01314
01315 INT_Enable();
01316 }
01317
01318 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
01319
01322 static void SlaveTimeout( RTCDRV_TimerID_t id, void *user )
01323 {
01324 SPIDRV_Handle_t handle;
01325 (void)id;
01326
01327 handle = (SPIDRV_Handle_t)user;
01328
01329 if ( handle->state == spidrvStateTransferring ) {
01330 if ( DMA_ChannelEnabled( handle->initData.rxDMACh ) ) {
01331
01332 DMA_ChannelEnable( handle->initData.rxDMACh, false );
01333 DMA_ChannelEnable( handle->initData.txDMACh, false );
01334 handle->remaining = 1 +
01335 ( ( dmaControlBlock[ handle->initData.rxDMACh ].CTRL
01336 & _DMA_CTRL_N_MINUS_1_MASK )
01337 >> _DMA_CTRL_N_MINUS_1_SHIFT );
01338 } else {
01339
01340 if ( DMA->IF & ( 1 << handle->initData.rxDMACh ) ) {
01341
01342 return;
01343 }
01344 handle->remaining = handle->transferCount;
01345 }
01346 handle->transferStatus = ECODE_EMDRV_SPIDRV_TIMEOUT;
01347 handle->state = spidrvStateIdle;
01348
01349 if ( handle->userCallback != NULL ) {
01350 handle->userCallback( handle,
01351 ECODE_EMDRV_SPIDRV_TIMEOUT,
01352 handle->transferCount - handle->remaining );
01353 }
01354 }
01355 }
01356 #endif
01357
01358
01361 static void StartReceiveDMA( SPIDRV_Handle_t handle,
01362 void *buffer,
01363 int count,
01364 SPIDRV_Callback_t callback )
01365 {
01366 void *rxPort, *txPort;
01367 DMA_CfgDescr_TypeDef cfgDesc;
01368
01369 handle->blockingCompleted = false;
01370 handle->transferCount = count;
01371 handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
01372 handle->userCallback = callback;
01373
01374 if ( handle->initData.frameLength > 8 ) {
01375 cfgDesc.size = dmaDataSize2;
01376 } else {
01377 cfgDesc.size = dmaDataSize1;
01378 }
01379 cfgDesc.arbRate = dmaArbitrate1;
01380 cfgDesc.hprot = 0;
01381
01382 cfgDesc.srcInc = dmaDataIncNone;
01383 if ( handle->initData.frameLength > 8 ) {
01384 cfgDesc.dstInc = dmaDataInc2;
01385 rxPort = (void *)&(handle->initData.port->RXDOUBLE);
01386 txPort = (void *)&(handle->initData.port->TXDOUBLE);
01387 } else {
01388 cfgDesc.dstInc = dmaDataInc1;
01389 rxPort = (void *)&(handle->initData.port->RXDATA);
01390 txPort = (void *)&(handle->initData.port->TXDATA);
01391 }
01392 DMA_CfgDescr( handle->initData.rxDMACh, true, &cfgDesc );
01393
01394 cfgDesc.dstInc = dmaDataIncNone;
01395 DMA_CfgDescr( handle->initData.txDMACh, true, &cfgDesc );
01396
01397 DMA_ActivateBasic( handle->initData.rxDMACh,
01398 true,
01399 false,
01400 buffer,
01401 rxPort,
01402 count - 1 );
01403
01404 DMA_ActivateBasic( handle->initData.txDMACh,
01405 true,
01406 false,
01407 txPort,
01408 (void *)&(handle->initData.dummyTxValue),
01409 count - 1 );
01410 }
01411
01412
01415 static void StartTransferDMA( SPIDRV_Handle_t handle,
01416 const void *txBuffer,
01417 void *rxBuffer,
01418 int count,
01419 SPIDRV_Callback_t callback )
01420 {
01421 void *rxPort, *txPort;
01422 DMA_CfgDescr_TypeDef cfgDesc;
01423
01424 handle->blockingCompleted = false;
01425 handle->transferCount = count;
01426 handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
01427 handle->userCallback = callback;
01428
01429 if ( handle->initData.frameLength > 8 ) {
01430 cfgDesc.size = dmaDataSize2;
01431 } else {
01432 cfgDesc.size = dmaDataSize1;
01433 }
01434 cfgDesc.arbRate = dmaArbitrate1;
01435 cfgDesc.hprot = 0;
01436
01437 if ( handle->initData.frameLength > 8 ) {
01438 cfgDesc.srcInc = dmaDataInc2;
01439 txPort = (void *)&(handle->initData.port->TXDOUBLE);
01440 } else {
01441 cfgDesc.srcInc = dmaDataInc1;
01442 txPort = (void *)&(handle->initData.port->TXDATA);
01443 }
01444 cfgDesc.dstInc = dmaDataIncNone;
01445 DMA_CfgDescr( handle->initData.txDMACh, true, &cfgDesc );
01446
01447 cfgDesc.srcInc = dmaDataIncNone;
01448 if ( handle->initData.frameLength > 8 ) {
01449 cfgDesc.dstInc = dmaDataInc2;
01450 rxPort = (void *)&(handle->initData.port->RXDOUBLE);
01451 } else {
01452 cfgDesc.dstInc = dmaDataInc1;
01453 rxPort = (void *)&(handle->initData.port->RXDATA);
01454 }
01455 DMA_CfgDescr( handle->initData.rxDMACh, true, &cfgDesc );
01456
01457 DMA_ActivateBasic( handle->initData.rxDMACh,
01458 true,
01459 false,
01460 rxBuffer,
01461 rxPort,
01462 count - 1 );
01463
01464 DMA_ActivateBasic( handle->initData.txDMACh,
01465 true,
01466 false,
01467 txPort,
01468 (void*)txBuffer,
01469 count - 1 );
01470 }
01471
01472
01475 static void StartTransmitDMA( SPIDRV_Handle_t handle,
01476 const void *buffer,
01477 int count,
01478 SPIDRV_Callback_t callback )
01479 {
01480 void *rxPort, *txPort;
01481 DMA_CfgDescr_TypeDef cfgDesc;
01482
01483 handle->blockingCompleted = false;
01484 handle->transferCount = count;
01485 handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
01486 handle->userCallback = callback;
01487
01488 if ( handle->initData.frameLength > 8 ) {
01489 cfgDesc.size = dmaDataSize2;
01490 } else {
01491 cfgDesc.size = dmaDataSize1;
01492 }
01493 cfgDesc.arbRate = dmaArbitrate1;
01494 cfgDesc.hprot = 0;
01495
01496 if ( handle->initData.frameLength > 8 ) {
01497 cfgDesc.srcInc = dmaDataInc2;
01498 rxPort = (void *)&(handle->initData.port->RXDOUBLE);
01499 txPort = (void *)&(handle->initData.port->TXDOUBLE);
01500 } else {
01501 cfgDesc.srcInc = dmaDataInc1;
01502 rxPort = (void *)&(handle->initData.port->RXDATA);
01503 txPort = (void *)&(handle->initData.port->TXDATA);
01504 }
01505 cfgDesc.dstInc = dmaDataIncNone;
01506 DMA_CfgDescr( handle->initData.txDMACh, true, &cfgDesc );
01507
01508 cfgDesc.srcInc = dmaDataIncNone;
01509 DMA_CfgDescr( handle->initData.rxDMACh, true, &cfgDesc );
01510
01511
01512 DMA_ActivateBasic( handle->initData.rxDMACh,
01513 true,
01514 false,
01515 (void *)&(handle->dummyRx),
01516 rxPort,
01517 count - 1 );
01518
01519 DMA_ActivateBasic( handle->initData.txDMACh,
01520 true,
01521 false,
01522 txPort,
01523 (void*)buffer,
01524 count - 1 );
01525 }
01526
01527
01530 static Ecode_t TransferApiBlockingPrologue( SPIDRV_Handle_t handle,
01531 void *buffer,
01532 int count )
01533 {
01534 if ( handle == NULL ) {
01535 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
01536 }
01537
01538 if ( ( buffer == NULL ) || ( count == 0 ) ) {
01539 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01540 }
01541
01542 if ( INT_Disable() > 1 )
01543 {
01544 INT_Enable();
01545 return ECODE_EMDRV_SPIDRV_ILLEGAL_OPERATION;
01546 }
01547
01548 if ( handle->state != spidrvStateIdle ) {
01549 INT_Enable();
01550 return ECODE_EMDRV_SPIDRV_BUSY;
01551 }
01552 handle->state = spidrvStateTransferring;
01553 INT_Enable();
01554
01555 return ECODE_EMDRV_SPIDRV_OK;
01556 }
01557
01558
01561 static Ecode_t TransferApiPrologue( SPIDRV_Handle_t handle,
01562 void *buffer,
01563 int count )
01564 {
01565 if ( handle == NULL ) {
01566 return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
01567 }
01568
01569 if ( ( buffer == NULL ) || ( count == 0 ) ) {
01570 return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01571 }
01572
01573 INT_Disable();
01574 if ( handle->state != spidrvStateIdle ) {
01575 INT_Enable();
01576 return ECODE_EMDRV_SPIDRV_BUSY;
01577 }
01578 handle->state = spidrvStateTransferring;
01579 INT_Enable();
01580
01581 return ECODE_EMDRV_SPIDRV_OK;
01582 }
01583
01584 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
01585
01588 static Ecode_t WaitForIdleLine( SPIDRV_Handle_t handle )
01589 {
01590 while ( !GPIO_PinInGet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin )
01591 && ( handle->state != spidrvStateIdle ) );
01592
01593 if ( handle->state == spidrvStateIdle ) {
01594 return handle->transferStatus;
01595 }
01596
01597 return ECODE_EMDRV_SPIDRV_OK;
01598 }
01599 #endif
01600
01602
01603