spidrv.c

Go to the documentation of this file.
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 "dmadrv.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 bool     RxDMAComplete(    unsigned int channel,
00037                                   unsigned int sequenceNo,
00038                                   void *userParam );
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 static void     WaitForTransferCompletion( SPIDRV_Handle_t handle );
00070 
00071 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00072 static Ecode_t  WaitForIdleLine(  SPIDRV_Handle_t handle );
00073 #endif
00074 
00076 
00077 /***************************************************************************/
00091 Ecode_t SPIDRV_Init( SPIDRV_Handle_t handle, SPIDRV_Init_t *initData )
00092 {
00093   Ecode_t retVal;
00094   USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT;
00095 
00096   if ( handle == NULL )
00097   {
00098     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00099   }
00100 
00101   if ( initData == NULL )
00102   {
00103     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00104   }
00105 
00106   memset( handle, 0, sizeof( SPIDRV_HandleData_t ) );
00107 
00108   if ( 0 )
00109   {
00110 #if defined( USART0 )
00111   }
00112   else if ( initData->port == USART0 )
00113   {
00114     handle->usartClock  = cmuClock_USART0;
00115     handle->txDMASignal = dmadrvPeripheralSignal_USART0_TXBL;
00116     handle->rxDMASignal = dmadrvPeripheralSignal_USART0_RXDATAV;
00117 #endif
00118 #if defined( USART1 )
00119   }
00120   else if ( initData->port == USART1 )
00121   {
00122     handle->usartClock  = cmuClock_USART1;
00123     handle->txDMASignal = dmadrvPeripheralSignal_USART1_TXBL;
00124     handle->rxDMASignal = dmadrvPeripheralSignal_USART1_RXDATAV;
00125 #endif
00126 #if defined( USART2 )
00127   }
00128   else if ( initData->port == USART2 )
00129   {
00130     handle->usartClock  = cmuClock_USART2;
00131     handle->txDMASignal = dmadrvPeripheralSignal_USART2_TXBL;
00132     handle->rxDMASignal = dmadrvPeripheralSignal_USART2_RXDATAV;
00133 #endif
00134 #if defined( USARTRF0 )
00135   }
00136   else if ( initData->port == USARTRF0 )
00137   {
00138     handle->usartClock  = cmuClock_USARTRF0;
00139     handle->txDMASignal = dmadrvPeripheralSignal_USARTRF0_TXBL;
00140     handle->rxDMASignal = dmadrvPeripheralSignal_USARTRF0_RXDATAV;
00141 #endif
00142   }
00143   else
00144   {
00145     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00146   }
00147 
00148   handle->initData = *initData;
00149 
00150   if ( initData->bitOrder == spidrvBitOrderMsbFirst )
00151   {
00152     usartInit.msbf = true;
00153   }
00154 
00155   if ( initData->clockMode == spidrvClockMode0 )
00156   {
00157     usartInit.clockMode = usartClockMode0;
00158   }
00159   else if ( initData->clockMode == spidrvClockMode1 )
00160   {
00161     usartInit.clockMode = usartClockMode1;
00162   }
00163   else if ( initData->clockMode == spidrvClockMode2 )
00164   {
00165     usartInit.clockMode = usartClockMode2;
00166   }
00167   else if ( initData->clockMode == spidrvClockMode3 )
00168   {
00169     usartInit.clockMode = usartClockMode3;
00170   }
00171   else
00172   {
00173     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00174   }
00175 
00176   if ( initData->type == spidrvSlave )
00177   {
00178     usartInit.master = false;
00179     usartInit.baudrate = 1000;      // Dummy value needed by USART_InitSync()
00180   }
00181   else
00182   {
00183     usartInit.baudrate = initData->bitRate;
00184   }
00185 
00186   CMU_ClockEnable( cmuClock_HFPER, true );
00187   CMU_ClockEnable( cmuClock_GPIO, true );
00188   CMU_ClockEnable( handle->usartClock, true );
00189   USART_InitSync(  initData->port, &usartInit );
00190 
00191   if ( ( initData->type == spidrvMaster )
00192        && ( initData->csControl == spidrvCsControlAuto ) )
00193   {
00194     initData->port->CTRL |= USART_CTRL_AUTOCS;
00195   }
00196 
00197   if ( initData->csControl == spidrvCsControlAuto )
00198   {
00199     // SPI 4 wire mode
00200 #if defined( USART_ROUTEPEN_TXPEN )
00201     initData->port->ROUTEPEN = USART_ROUTEPEN_TXPEN
00202                                | USART_ROUTEPEN_RXPEN
00203                                | USART_ROUTEPEN_CLKPEN
00204                                | USART_ROUTEPEN_CSPEN;
00205 
00206     initData->port->ROUTELOC0 = ( initData->port->ROUTELOC0 &
00207                                   ~( _USART_ROUTELOC0_TXLOC_MASK
00208                                      | _USART_ROUTELOC0_RXLOC_MASK
00209                                      | _USART_ROUTELOC0_CLKLOC_MASK
00210                                      | _USART_ROUTELOC0_CSLOC_MASK ) )
00211                                 | ( initData->portLocationTx  << _USART_ROUTELOC0_TXLOC_SHIFT  )
00212                                 | ( initData->portLocationRx  << _USART_ROUTELOC0_RXLOC_SHIFT  )
00213                                 | ( initData->portLocationClk << _USART_ROUTELOC0_CLKLOC_SHIFT )
00214                                 | ( initData->portLocationCs  << _USART_ROUTELOC0_CSLOC_SHIFT  );
00215 #else
00216     initData->port->ROUTE = USART_ROUTE_TXPEN
00217                             | USART_ROUTE_RXPEN
00218                             | USART_ROUTE_CLKPEN
00219                             | USART_ROUTE_CSPEN
00220                             | (initData->portLocation
00221                               << _USART_ROUTE_LOCATION_SHIFT );
00222 #endif
00223   }
00224   else
00225   {
00226     // SPI 3 wire mode
00227 #if defined( USART_ROUTEPEN_TXPEN )
00228     initData->port->ROUTEPEN = USART_ROUTEPEN_TXPEN
00229                                | USART_ROUTEPEN_RXPEN
00230                                | USART_ROUTEPEN_CLKPEN;
00231 
00232     initData->port->ROUTELOC0 = ( initData->port->ROUTELOC0 &
00233                                   ~( _USART_ROUTELOC0_TXLOC_MASK
00234                                      | _USART_ROUTELOC0_RXLOC_MASK
00235                                      | _USART_ROUTELOC0_CLKLOC_MASK ) )
00236                                 | ( initData->portLocationTx  << _USART_ROUTELOC0_TXLOC_SHIFT  )
00237                                 | ( initData->portLocationRx  << _USART_ROUTELOC0_RXLOC_SHIFT  )
00238                                 | ( initData->portLocationClk << _USART_ROUTELOC0_CLKLOC_SHIFT );
00239 #else
00240     initData->port->ROUTE = USART_ROUTE_TXPEN
00241                             | USART_ROUTE_RXPEN
00242                             | USART_ROUTE_CLKPEN
00243                             | (initData->portLocation
00244                               << _USART_ROUTE_LOCATION_SHIFT );
00245 #endif
00246   }
00247 
00248   if ( ( retVal = ConfigGPIO( handle, true ) ) != ECODE_EMDRV_SPIDRV_OK )
00249   {
00250     return retVal;
00251   }
00252 
00253   INT_Disable();
00254   if ( ! spidrvIsInitialized )
00255   {
00256     spidrvIsInitialized = true;
00257     INT_Enable();
00258 
00259 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00260     RTCDRV_Init();
00261 #endif
00262   }
00263   else
00264   {
00265     INT_Enable();
00266   }
00267 
00268 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00269   if ( initData->type == spidrvSlave )
00270   {
00271     if ( RTCDRV_AllocateTimer( &handle->timer ) != ECODE_EMDRV_RTCDRV_OK )
00272     {
00273       return ECODE_EMDRV_SPIDRV_TIMER_ALLOC_ERROR;
00274     }
00275   }
00276 #endif
00277 
00278   // Initialize DMA.
00279   DMADRV_Init();
00280 
00281   if ( DMADRV_AllocateChannel(&handle->txDMACh,NULL) != ECODE_EMDRV_DMADRV_OK )
00282   {
00283     return ECODE_EMDRV_SPIDRV_DMA_ALLOC_ERROR;
00284   }
00285 
00286   if ( DMADRV_AllocateChannel(&handle->rxDMACh,NULL) != ECODE_EMDRV_DMADRV_OK )
00287   {
00288     return ECODE_EMDRV_SPIDRV_DMA_ALLOC_ERROR;
00289   }
00290 
00291   return ECODE_EMDRV_SPIDRV_OK;
00292 }
00293 
00294 /***************************************************************************/
00304 Ecode_t SPIDRV_DeInit( SPIDRV_Handle_t handle )
00305 {
00306   if ( handle == NULL )
00307   {
00308     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00309   }
00310 
00311   // Stop DMA's.
00312   DMADRV_StopTransfer( handle->rxDMACh );
00313   DMADRV_StopTransfer( handle->txDMACh );
00314 
00315   ConfigGPIO( handle, false );
00316 
00317 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00318   if ( handle->initData.type == spidrvSlave )
00319   {
00320     RTCDRV_StopTimer( handle->timer );
00321     RTCDRV_FreeTimer( handle->timer );
00322   }
00323 #endif
00324 
00325   USART_Reset( handle->initData.port );
00326   CMU_ClockEnable( handle->usartClock, false );
00327 
00328   DMADRV_FreeChannel( handle->txDMACh );
00329   DMADRV_FreeChannel( handle->rxDMACh );
00330   DMADRV_DeInit();
00331 
00332   return ECODE_EMDRV_SPIDRV_OK;
00333 }
00334 
00335 /***************************************************************************/
00345 Ecode_t SPIDRV_AbortTransfer( SPIDRV_Handle_t handle )
00346 {
00347   if ( handle == NULL )
00348   {
00349     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00350   }
00351 
00352   INT_Disable();
00353   if ( handle->state == spidrvStateIdle )
00354   {
00355     INT_Enable();
00356     return ECODE_EMDRV_SPIDRV_IDLE;
00357   }
00358 
00359 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00360   if ( handle->initData.type == spidrvSlave )
00361   {
00362     RTCDRV_StopTimer( handle->timer );
00363   }
00364 #endif
00365 
00366   // Stop DMA's.
00367   DMADRV_StopTransfer( handle->rxDMACh );
00368   DMADRV_StopTransfer( handle->txDMACh );
00369   DMADRV_TransferRemainingCount( handle->rxDMACh, &handle->remaining );
00370   handle->transferStatus    = ECODE_EMDRV_SPIDRV_ABORTED;
00371   handle->state             = spidrvStateIdle;
00372   handle->transferStatus    = ECODE_EMDRV_SPIDRV_ABORTED;
00373   handle->blockingCompleted = true;
00374 
00375   if ( handle->userCallback != NULL )
00376   {
00377     handle->userCallback( handle,
00378                           ECODE_EMDRV_SPIDRV_ABORTED,
00379                           handle->transferCount - handle->remaining );
00380   }
00381   INT_Enable();
00382 
00383   return ECODE_EMDRV_SPIDRV_OK;
00384 }
00385 
00386 /***************************************************************************/
00398 Ecode_t SPIDRV_GetBitrate( SPIDRV_Handle_t handle, uint32_t *bitRate )
00399 {
00400   if ( handle == NULL )
00401   {
00402     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00403   }
00404 
00405   if ( bitRate == NULL )
00406   {
00407     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00408   }
00409 
00410   *bitRate = USART_BaudrateGet( handle->initData.port );
00411 
00412   return ECODE_EMDRV_SPIDRV_OK;
00413 }
00414 
00415 /***************************************************************************/
00427 Ecode_t SPIDRV_GetFramelength( SPIDRV_Handle_t handle, uint32_t *frameLength )
00428 {
00429   if ( handle == NULL )
00430   {
00431     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00432   }
00433 
00434   if ( frameLength == NULL )
00435   {
00436     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00437   }
00438 
00439   *frameLength = handle->initData.frameLength;
00440 
00441   return ECODE_EMDRV_SPIDRV_OK;
00442 }
00443 
00444 /***************************************************************************/
00462 Ecode_t SPIDRV_GetTransferStatus( SPIDRV_Handle_t handle,
00463                                   int *itemsTransferred,
00464                                   int *itemsRemaining )
00465 {
00466   int remaining;
00467 
00468   if ( handle == NULL )
00469   {
00470     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00471   }
00472 
00473   if ( ( itemsTransferred == NULL ) || ( itemsRemaining == NULL ) )
00474   {
00475     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00476   }
00477 
00478   INT_Disable();
00479   if ( handle->state == spidrvStateIdle )
00480   {
00481     remaining = handle->remaining;
00482   }
00483   else
00484   {
00485     DMADRV_TransferRemainingCount( handle->rxDMACh, &remaining );
00486   }
00487   INT_Enable();
00488 
00489   *itemsTransferred = handle->transferCount - remaining;
00490   *itemsRemaining   = remaining;
00491 
00492   return ECODE_EMDRV_SPIDRV_OK;
00493 }
00494 
00495 /***************************************************************************/
00514 Ecode_t SPIDRV_MReceive( SPIDRV_Handle_t handle,
00515                          void *buffer,
00516                          int count,
00517                          SPIDRV_Callback_t callback )
00518 {
00519   Ecode_t retVal;
00520 
00521   if ( handle->initData.type == spidrvSlave )
00522   {
00523     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00524   }
00525 
00526   if ( ( retVal = TransferApiPrologue( handle, buffer, count ) )
00527        != ECODE_EMDRV_SPIDRV_OK )
00528   {
00529     return retVal;
00530   }
00531 
00532   StartReceiveDMA( handle, buffer, count, callback );
00533 
00534   return ECODE_EMDRV_SPIDRV_OK;
00535 }
00536 
00537 /***************************************************************************/
00557 Ecode_t SPIDRV_MReceiveB( SPIDRV_Handle_t handle,
00558                           void *buffer,
00559                           int count )
00560 {
00561   Ecode_t retVal;
00562 
00563   if ( handle->initData.type == spidrvSlave )
00564   {
00565     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00566   }
00567 
00568   if ( ( retVal = TransferApiBlockingPrologue( handle, buffer, count ) )
00569        != ECODE_EMDRV_SPIDRV_OK )
00570   {
00571     return retVal;
00572   }
00573 
00574   StartReceiveDMA( handle, buffer, count, BlockingComplete );
00575 
00576   WaitForTransferCompletion( handle );
00577 
00578   return handle->transferStatus;
00579 }
00580 
00581 /***************************************************************************/
00599 Ecode_t SPIDRV_MTransfer( SPIDRV_Handle_t handle,
00600                           const void *txBuffer,
00601                           void *rxBuffer,
00602                           int count,
00603                           SPIDRV_Callback_t callback )
00604 {
00605   Ecode_t retVal;
00606 
00607   if ( handle->initData.type == spidrvSlave )
00608   {
00609     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00610   }
00611 
00612   if ( ( retVal = TransferApiPrologue( handle, (void*)txBuffer, count ) )
00613        != ECODE_EMDRV_SPIDRV_OK )
00614   {
00615     return retVal;
00616   }
00617 
00618   if ( rxBuffer == NULL )
00619   {
00620     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00621   }
00622 
00623   StartTransferDMA( handle, txBuffer, rxBuffer, count, callback );
00624 
00625   return ECODE_EMDRV_SPIDRV_OK;
00626 }
00627 
00628 /***************************************************************************/
00649 Ecode_t SPIDRV_MTransferB( SPIDRV_Handle_t handle,
00650                            const void *txBuffer,
00651                            void *rxBuffer,
00652                            int count )
00653 {
00654   Ecode_t retVal;
00655 
00656   if ( handle->initData.type == spidrvSlave )
00657   {
00658     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00659   }
00660 
00661   if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)txBuffer, count ))
00662        != ECODE_EMDRV_SPIDRV_OK )
00663   {
00664     return retVal;
00665   }
00666 
00667   if ( rxBuffer == NULL )
00668   {
00669     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00670   }
00671 
00672   StartTransferDMA( handle, txBuffer, rxBuffer, count, BlockingComplete );
00673 
00674   WaitForTransferCompletion( handle );
00675 
00676   return handle->transferStatus;
00677 }
00678 
00679 /***************************************************************************/
00698 Ecode_t SPIDRV_MTransferSingleItemB( SPIDRV_Handle_t handle,
00699                                      uint32_t txValue,
00700                                      void *rxValue )
00701 {
00702   void *pRx;
00703   uint32_t rxBuffer;
00704 
00705   if ( handle->initData.type == spidrvSlave )
00706   {
00707     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00708   }
00709 
00710   if ( handle == NULL )
00711   {
00712     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00713   }
00714 
00715   INT_Disable();
00716   if ( handle->state != spidrvStateIdle )
00717   {
00718     INT_Enable();
00719     return ECODE_EMDRV_SPIDRV_BUSY;
00720   }
00721   handle->state = spidrvStateTransferring;
00722   INT_Enable();
00723 
00724   if ( ( pRx = rxValue ) == NULL )
00725   {
00726     pRx = &rxBuffer;
00727   }
00728 
00729   StartTransferDMA( handle, &txValue, pRx, 1, BlockingComplete );
00730 
00731   WaitForTransferCompletion( handle );
00732 
00733   return handle->transferStatus;
00734 }
00735 
00736 /***************************************************************************/
00755 Ecode_t SPIDRV_MTransmit( SPIDRV_Handle_t handle,
00756                           const void *buffer,
00757                           int count,
00758                           SPIDRV_Callback_t callback )
00759 {
00760   Ecode_t retVal;
00761 
00762   if ( handle->initData.type == spidrvSlave )
00763   {
00764     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00765   }
00766 
00767   if ( ( retVal = TransferApiPrologue( handle, (void*)buffer, count ) )
00768        != ECODE_EMDRV_SPIDRV_OK )
00769   {
00770     return retVal;
00771   }
00772 
00773   StartTransmitDMA( handle, buffer, count, callback );
00774 
00775   return ECODE_EMDRV_SPIDRV_OK;
00776 }
00777 
00778 /***************************************************************************/
00797 Ecode_t SPIDRV_MTransmitB( SPIDRV_Handle_t handle,
00798                            const void *buffer,
00799                            int count )
00800 {
00801   Ecode_t retVal;
00802 
00803   if ( handle->initData.type == spidrvSlave )
00804   {
00805     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00806   }
00807 
00808   if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)buffer, count ) )
00809        != ECODE_EMDRV_SPIDRV_OK )
00810   {
00811     return retVal;
00812   }
00813 
00814   StartTransmitDMA( handle, buffer, count, BlockingComplete );
00815 
00816   WaitForTransferCompletion( handle );
00817 
00818   return handle->transferStatus;
00819 }
00820 
00821 /***************************************************************************/
00833 Ecode_t SPIDRV_SetBitrate( SPIDRV_Handle_t handle, uint32_t bitRate )
00834 {
00835   if ( handle == NULL )
00836   {
00837     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00838   }
00839 
00840   INT_Disable();
00841   if ( handle->state != spidrvStateIdle )
00842   {
00843     INT_Enable();
00844     return ECODE_EMDRV_SPIDRV_BUSY;
00845   }
00846 
00847   handle->initData.bitRate = bitRate;
00848   USART_BaudrateSyncSet( handle->initData.port, 0, bitRate );
00849   INT_Enable();
00850 
00851   return ECODE_EMDRV_SPIDRV_OK;
00852 }
00853 
00854 /***************************************************************************/
00866 Ecode_t SPIDRV_SetFramelength( SPIDRV_Handle_t handle, uint32_t frameLength )
00867 {
00868   if ( handle == NULL )
00869   {
00870     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
00871   }
00872 
00873   frameLength -= 3;
00874   if ( ( frameLength < _USART_FRAME_DATABITS_FOUR )
00875        || ( frameLength > _USART_FRAME_DATABITS_SIXTEEN ) )
00876   {
00877     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
00878   }
00879 
00880   INT_Disable();
00881   if ( handle->state != spidrvStateIdle )
00882   {
00883     INT_Enable();
00884     return ECODE_EMDRV_SPIDRV_BUSY;
00885   }
00886 
00887   handle->initData.frameLength = frameLength + 3;
00888   handle->initData.port->FRAME = ( handle->initData.port->FRAME
00889                                    & ~_USART_FRAME_DATABITS_MASK )
00890                                   | ( frameLength
00891                                       << _USART_FRAME_DATABITS_SHIFT );
00892   INT_Enable();
00893 
00894   return ECODE_EMDRV_SPIDRV_OK;
00895 }
00896 
00897 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
00898 /***************************************************************************/
00919 Ecode_t SPIDRV_SReceive( SPIDRV_Handle_t handle,
00920                          void *buffer,
00921                          int count,
00922                          SPIDRV_Callback_t callback,
00923                          int timeoutMs )
00924 {
00925   Ecode_t retVal;
00926 
00927   if ( handle->initData.type == spidrvMaster )
00928   {
00929     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00930   }
00931 
00932   if ( ( retVal = TransferApiPrologue( handle, buffer, count ) )
00933        != ECODE_EMDRV_SPIDRV_OK )
00934   {
00935     return retVal;
00936   }
00937 
00938   if ( timeoutMs )
00939   {
00940     RTCDRV_StartTimer( handle->timer,
00941                        rtcdrvTimerTypeOneshot,
00942                        timeoutMs,
00943                        SlaveTimeout,
00944                        handle );
00945   }
00946 
00947   if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
00948   {
00949     if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
00950     {
00951       return retVal;
00952     }
00953   }
00954 
00955   StartReceiveDMA( handle, buffer, count, callback );
00956 
00957   return ECODE_EMDRV_SPIDRV_OK;
00958 }
00959 
00960 /***************************************************************************/
00983 Ecode_t SPIDRV_SReceiveB( SPIDRV_Handle_t handle,
00984                           void *buffer,
00985                           int count,
00986                           int timeoutMs )
00987 {
00988   Ecode_t retVal;
00989 
00990   if ( handle->initData.type == spidrvMaster )
00991   {
00992     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
00993   }
00994 
00995   if ( ( retVal = TransferApiBlockingPrologue( handle, buffer, count ) )
00996        != ECODE_EMDRV_SPIDRV_OK )
00997   {
00998     return retVal;
00999   }
01000 
01001   if ( timeoutMs )
01002   {
01003     RTCDRV_StartTimer( handle->timer,
01004                        rtcdrvTimerTypeOneshot,
01005                        timeoutMs,
01006                        SlaveTimeout,
01007                        handle );
01008   }
01009 
01010   if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
01011   {
01012     if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
01013     {
01014       return retVal;
01015     }
01016   }
01017 
01018   StartReceiveDMA( handle, buffer, count, BlockingComplete );
01019 
01020   WaitForTransferCompletion( handle );
01021 
01022   return handle->transferStatus;
01023 }
01024 
01025 /***************************************************************************/
01045 Ecode_t SPIDRV_STransfer( SPIDRV_Handle_t handle,
01046                           const void *txBuffer,
01047                           void *rxBuffer,
01048                           int count,
01049                           SPIDRV_Callback_t callback,
01050                           int timeoutMs )
01051 {
01052   Ecode_t retVal;
01053 
01054   if ( handle->initData.type == spidrvMaster )
01055   {
01056     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
01057   }
01058 
01059   if ( ( retVal = TransferApiPrologue( handle, (void*)txBuffer, count ) )
01060        != ECODE_EMDRV_SPIDRV_OK )
01061   {
01062     return retVal;
01063   }
01064 
01065   if ( rxBuffer == NULL )
01066   {
01067     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01068   }
01069 
01070   if ( timeoutMs )
01071   {
01072     RTCDRV_StartTimer( handle->timer,
01073                        rtcdrvTimerTypeOneshot,
01074                        timeoutMs,
01075                        SlaveTimeout,
01076                        handle );
01077   }
01078 
01079   if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
01080   {
01081     if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
01082     {
01083       return retVal;
01084     }
01085   }
01086 
01087   StartTransferDMA( handle, txBuffer, rxBuffer, count, callback );
01088 
01089   return ECODE_EMDRV_SPIDRV_OK;
01090 }
01091 
01092 /***************************************************************************/
01116 Ecode_t SPIDRV_STransferB( SPIDRV_Handle_t handle,
01117                            const void *txBuffer,
01118                            void *rxBuffer,
01119                            int count,
01120                            int timeoutMs )
01121 {
01122   Ecode_t retVal;
01123 
01124   if ( handle->initData.type == spidrvMaster )
01125   {
01126     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
01127   }
01128 
01129   if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)txBuffer, count ))
01130        != ECODE_EMDRV_SPIDRV_OK )
01131   {
01132     return retVal;
01133   }
01134 
01135   if ( rxBuffer == NULL )
01136   {
01137     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01138   }
01139 
01140   if ( timeoutMs )
01141   {
01142     RTCDRV_StartTimer( handle->timer,
01143                        rtcdrvTimerTypeOneshot,
01144                        timeoutMs,
01145                        SlaveTimeout,
01146                        handle );
01147   }
01148 
01149   if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
01150   {
01151     if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
01152     {
01153       return retVal;
01154     }
01155   }
01156 
01157   StartTransferDMA( handle, txBuffer, rxBuffer, count, BlockingComplete );
01158 
01159   WaitForTransferCompletion( handle );
01160 
01161   return handle->transferStatus;
01162 }
01163 
01164 /***************************************************************************/
01185 Ecode_t SPIDRV_STransmit( SPIDRV_Handle_t handle,
01186                           const void *buffer,
01187                           int count,
01188                           SPIDRV_Callback_t callback,
01189                           int timeoutMs )
01190 {
01191   Ecode_t retVal;
01192 
01193   if ( handle->initData.type == spidrvMaster )
01194   {
01195     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
01196   }
01197 
01198   if ( ( retVal = TransferApiPrologue( handle, (void*)buffer, count ) )
01199        != ECODE_EMDRV_SPIDRV_OK )
01200   {
01201     return retVal;
01202   }
01203 
01204   if ( timeoutMs )
01205   {
01206     RTCDRV_StartTimer( handle->timer,
01207                        rtcdrvTimerTypeOneshot,
01208                        timeoutMs,
01209                        SlaveTimeout,
01210                        handle );
01211   }
01212 
01213   if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
01214   {
01215     if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
01216     {
01217       return retVal;
01218     }
01219   }
01220 
01221   StartTransmitDMA( handle, buffer, count, callback );
01222 
01223   return ECODE_EMDRV_SPIDRV_OK;
01224 }
01225 
01226 /***************************************************************************/
01249 Ecode_t SPIDRV_STransmitB( SPIDRV_Handle_t handle,
01250                            const void *buffer,
01251                            int count,
01252                            int timeoutMs )
01253 {
01254   Ecode_t retVal;
01255 
01256   if ( handle->initData.type == spidrvMaster )
01257   {
01258     return ECODE_EMDRV_SPIDRV_MODE_ERROR;
01259   }
01260 
01261   if ( ( retVal = TransferApiBlockingPrologue( handle, (void*)buffer, count ) )
01262        != ECODE_EMDRV_SPIDRV_OK )
01263   {
01264     return retVal;
01265   }
01266 
01267   if ( timeoutMs )
01268   {
01269     RTCDRV_StartTimer( handle->timer,
01270                        rtcdrvTimerTypeOneshot,
01271                        timeoutMs,
01272                        SlaveTimeout,
01273                        handle );
01274   }
01275 
01276   if ( handle->initData.slaveStartMode == spidrvSlaveStartDelayed )
01277   {
01278     if ( ( retVal = WaitForIdleLine( handle ) ) != ECODE_EMDRV_SPIDRV_OK )
01279     {
01280       return retVal;
01281     }
01282   }
01283 
01284   StartTransmitDMA( handle, buffer, count, BlockingComplete );
01285 
01286   WaitForTransferCompletion( handle );
01287 
01288   return handle->transferStatus;
01289 }
01290 #endif
01291 
01293 
01294 /***************************************************************************/
01300 static void BlockingComplete( SPIDRV_Handle_t handle,
01301                               Ecode_t transferStatus,
01302                               int itemsTransferred )
01303 {
01304   (void)itemsTransferred;
01305 
01306   handle->transferStatus    = transferStatus;
01307   handle->blockingCompleted = true;
01308 }
01309 
01310 /***************************************************************************/
01313 static Ecode_t ConfigGPIO( SPIDRV_Handle_t handle, bool enable )
01314 {
01315 #if defined( _USART_ROUTELOC0_MASK )
01316   SPIDRV_Init_t *initData;
01317 #else
01318   uint32_t location;
01319 #endif
01320   int mosiPin, misoPin, clkPin;
01321   int mosiPort, misoPort, clkPort;
01322 
01323 #if defined( _USART_ROUTELOC0_MASK )
01324   initData = &handle->initData;
01325 
01326   if ( 0 )
01327   {
01328 #if defined( USART0 )
01329   }
01330   else if ( handle->initData.port == USART0 )
01331   {
01332     mosiPort       = AF_USART0_TX_PORT(  initData->portLocationTx  );
01333     misoPort       = AF_USART0_RX_PORT(  initData->portLocationRx  );
01334     clkPort        = AF_USART0_CLK_PORT( initData->portLocationClk );
01335     handle->csPort = AF_USART0_CS_PORT(  initData->portLocationCs  );
01336     mosiPin        = AF_USART0_TX_PIN(   initData->portLocationTx  );
01337     misoPin        = AF_USART0_RX_PIN(   initData->portLocationRx  );
01338     clkPin         = AF_USART0_CLK_PIN(  initData->portLocationClk );
01339     handle->csPin  = AF_USART0_CS_PIN(   initData->portLocationCs  );
01340 #endif
01341 #if defined( USART1 )
01342   }
01343   else if ( handle->initData.port == USART1 )
01344   {
01345     mosiPort       = AF_USART1_TX_PORT(  initData->portLocationTx  );
01346     misoPort       = AF_USART1_RX_PORT(  initData->portLocationRx  );
01347     clkPort        = AF_USART1_CLK_PORT( initData->portLocationClk );
01348     handle->csPort = AF_USART1_CS_PORT(  initData->portLocationCs  );
01349     mosiPin        = AF_USART1_TX_PIN(   initData->portLocationTx  );
01350     misoPin        = AF_USART1_RX_PIN(   initData->portLocationRx  );
01351     clkPin         = AF_USART1_CLK_PIN(  initData->portLocationClk );
01352     handle->csPin  = AF_USART1_CS_PIN(   initData->portLocationCs  );
01353 #endif
01354 #if defined( USART2 )
01355   }
01356   else if ( handle->initData.port == USART2 )
01357   {
01358     mosiPort       = AF_USART2_TX_PORT(  initData->portLocationTx  );
01359     misoPort       = AF_USART2_RX_PORT(  initData->portLocationRx  );
01360     clkPort        = AF_USART2_CLK_PORT( initData->portLocationClk );
01361     handle->csPort = AF_USART2_CS_PORT(  initData->portLocationCs  );
01362     mosiPin        = AF_USART2_TX_PIN(   initData->portLocationTx  );
01363     misoPin        = AF_USART2_RX_PIN(   initData->portLocationRx  );
01364     clkPin         = AF_USART2_CLK_PIN(  initData->portLocationClk );
01365     handle->csPin  = AF_USART2_CS_PIN(   initData->portLocationCs  );
01366 #endif
01367 #if defined( USARTRF0 )
01368   }
01369   else if ( handle->initData.port == USARTRF0 )
01370   {
01371     mosiPort       = AF_USARTRF0_TX_PORT(  initData->portLocationTx  );
01372     misoPort       = AF_USARTRF0_RX_PORT(  initData->portLocationRx  );
01373     clkPort        = AF_USARTRF0_CLK_PORT( initData->portLocationClk );
01374     handle->csPort = AF_USARTRF0_CS_PORT(  initData->portLocationCs  );
01375     mosiPin        = AF_USARTRF0_TX_PIN(   initData->portLocationTx  );
01376     misoPin        = AF_USARTRF0_RX_PIN(   initData->portLocationRx  );
01377     clkPin         = AF_USARTRF0_CLK_PIN(  initData->portLocationClk );
01378     handle->csPin  = AF_USARTRF0_CS_PIN(   initData->portLocationCs  );
01379 #endif
01380   }
01381   else
01382   {
01383     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01384   }
01385 
01386 #else
01387   location = handle->initData.portLocation;
01388 
01389   if ( 0 )
01390   {
01391 #if defined( USART0 )
01392   }
01393   else if ( handle->initData.port == USART0 )
01394   {
01395     mosiPort       = AF_USART0_TX_PORT(  location );
01396     misoPort       = AF_USART0_RX_PORT(  location );
01397     clkPort        = AF_USART0_CLK_PORT( location );
01398     handle->csPort = AF_USART0_CS_PORT(  location );
01399     mosiPin        = AF_USART0_TX_PIN(   location );
01400     misoPin        = AF_USART0_RX_PIN(   location );
01401     clkPin         = AF_USART0_CLK_PIN(  location );
01402     handle->csPin  = AF_USART0_CS_PIN(   location );
01403 #endif
01404 #if defined( USART1 )
01405   }
01406   else if ( handle->initData.port == USART1 )
01407   {
01408     mosiPort       = AF_USART1_TX_PORT(  location );
01409     misoPort       = AF_USART1_RX_PORT(  location );
01410     clkPort        = AF_USART1_CLK_PORT( location );
01411     handle->csPort = AF_USART1_CS_PORT(  location );
01412     mosiPin        = AF_USART1_TX_PIN(   location );
01413     misoPin        = AF_USART1_RX_PIN(   location );
01414     clkPin         = AF_USART1_CLK_PIN(  location );
01415     handle->csPin  = AF_USART1_CS_PIN(   location );
01416 #endif
01417 #if defined( USART2 )
01418   }
01419   else if ( handle->initData.port == USART2 )
01420   {
01421     mosiPort       = AF_USART2_TX_PORT(  location );
01422     misoPort       = AF_USART2_RX_PORT(  location );
01423     clkPort        = AF_USART2_CLK_PORT( location );
01424     handle->csPort = AF_USART2_CS_PORT(  location );
01425     mosiPin        = AF_USART2_TX_PIN(   location );
01426     misoPin        = AF_USART2_RX_PIN(   location );
01427     clkPin         = AF_USART2_CLK_PIN(  location );
01428     handle->csPin  = AF_USART2_CS_PIN(   location );
01429 #endif
01430 #if defined( USARTRF0 )
01431   }
01432   else if ( handle->initData.port == USARTRF0 )
01433   {
01434     mosiPort       = AF_USARTRF0_TX_PORT(  location );
01435     misoPort       = AF_USARTRF0_RX_PORT(  location );
01436     clkPort        = AF_USARTRF0_CLK_PORT( location );
01437     handle->csPort = AF_USARTRF0_CS_PORT(  location );
01438     mosiPin        = AF_USARTRF0_TX_PIN(   location );
01439     misoPin        = AF_USARTRF0_RX_PIN(   location );
01440     clkPin         = AF_USARTRF0_CLK_PIN(  location );
01441     handle->csPin  = AF_USARTRF0_CS_PIN(   location );
01442 #endif
01443   }
01444   else
01445   {
01446     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01447   }
01448 #endif
01449 
01450   if ( enable )
01451   {
01452     if ( handle->initData.type == spidrvMaster )
01453     {
01454       GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin,
01455                        gpioModePushPull, 0 );
01456       GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin,
01457                        gpioModeInputPull, 0 );
01458 
01459       if (    ( handle->initData.clockMode == spidrvClockMode0 )
01460            || ( handle->initData.clockMode == spidrvClockMode1 ) )
01461       {
01462         GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
01463                          gpioModePushPull, 0 );
01464       }
01465       else
01466       {
01467         GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
01468                          gpioModePushPull, 1 );
01469       }
01470 
01471       if ( handle->initData.csControl == spidrvCsControlAuto )
01472       {
01473         GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
01474                          gpioModePushPull, 1 );
01475       }
01476     }
01477     else
01478     {
01479       GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin,
01480                        gpioModeInputPull, 0 );
01481       GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin,
01482                        gpioModePushPull, 0 );
01483 
01484       if (    ( handle->initData.clockMode == spidrvClockMode0 )
01485            || ( handle->initData.clockMode == spidrvClockMode1 ) )
01486       {
01487         GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
01488                          gpioModeInputPull, 0 );
01489       }
01490       else
01491       {
01492         GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin,
01493                          gpioModeInputPull, 1 );
01494       }
01495 
01496       if ( handle->initData.csControl == spidrvCsControlAuto )
01497       {
01498         GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
01499                          gpioModeInputPull, 1 );
01500       }
01501     }
01502   }
01503   else
01504   {
01505     GPIO_PinModeSet( (GPIO_Port_TypeDef)mosiPort, mosiPin, gpioModeInputPull,0);
01506     GPIO_PinModeSet( (GPIO_Port_TypeDef)misoPort, misoPin, gpioModeInputPull,0);
01507 
01508     if (    ( handle->initData.clockMode == spidrvClockMode0 )
01509          || ( handle->initData.clockMode == spidrvClockMode1 ) )
01510     {
01511       GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin, gpioModeInputPull,0);
01512     }
01513     else
01514     {
01515       GPIO_PinModeSet( (GPIO_Port_TypeDef)clkPort, clkPin, gpioModeInputPull,1);
01516     }
01517 
01518     if ( handle->initData.csControl == spidrvCsControlAuto )
01519     {
01520       GPIO_PinModeSet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin,
01521                        gpioModeDisabled, 0);
01522     }
01523   }
01524 
01525   return ECODE_EMDRV_SPIDRV_OK;
01526 }
01527 
01528 /***************************************************************************/
01531 static bool RxDMAComplete( unsigned int channel,
01532                            unsigned int sequenceNo,
01533                            void *userParam )
01534 {
01535   SPIDRV_Handle_t handle;
01536   (void)channel;
01537   (void)sequenceNo;
01538 
01539   INT_Disable();
01540 
01541   handle = (SPIDRV_Handle_t)userParam;
01542 
01543   handle->transferStatus = ECODE_EMDRV_SPIDRV_OK;
01544   handle->state          = spidrvStateIdle;
01545   handle->remaining      = 0;
01546 
01547 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
01548   if ( handle->initData.type == spidrvSlave )
01549   {
01550     RTCDRV_StopTimer( handle->timer );
01551   }
01552 #endif
01553 
01554   if ( handle->userCallback != NULL )
01555   {
01556     handle->userCallback( handle, ECODE_EMDRV_SPIDRV_OK, handle->transferCount);
01557   }
01558 
01559   INT_Enable();
01560   return true;
01561 }
01562 
01563 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
01564 /***************************************************************************/
01567 static void SlaveTimeout( RTCDRV_TimerID_t id, void *user )
01568 {
01569   bool active, pending;
01570   SPIDRV_Handle_t handle;
01571   (void)id;
01572 
01573   handle = (SPIDRV_Handle_t)user;
01574 
01575   if ( handle->state == spidrvStateTransferring )
01576   {
01577     DMADRV_TransferActive( handle->rxDMACh, &active );
01578     if ( active )
01579     {
01580       // Stop running DMA's
01581       DMADRV_StopTransfer( handle->rxDMACh );
01582       DMADRV_StopTransfer( handle->txDMACh );
01583       DMADRV_TransferRemainingCount( handle->rxDMACh, &handle->remaining );
01584     }
01585     else
01586     {
01587       // DMA is either completed or not yet started
01588       DMADRV_TransferCompletePending( handle->txDMACh, &pending );
01589       if ( pending )
01590       {
01591           // We have a pending DMA interrupt, let the DMA handler do the rest
01592           return;
01593       }
01594       handle->remaining = handle->transferCount;
01595     }
01596     handle->transferStatus = ECODE_EMDRV_SPIDRV_TIMEOUT;
01597     handle->state          = spidrvStateIdle;
01598 
01599     if ( handle->userCallback != NULL )
01600     {
01601       handle->userCallback( handle,
01602                             ECODE_EMDRV_SPIDRV_TIMEOUT,
01603                             handle->transferCount - handle->remaining );
01604     }
01605   }
01606 }
01607 #endif
01608 
01609 /***************************************************************************/
01612 static void StartReceiveDMA( SPIDRV_Handle_t handle,
01613                              void *buffer,
01614                              int count,
01615                              SPIDRV_Callback_t callback )
01616 {
01617   void *rxPort, *txPort;
01618   DMADRV_DataSize_t size;
01619 
01620   handle->blockingCompleted  = false;
01621   handle->transferCount      = count;
01622   handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
01623   handle->userCallback       = callback;
01624 
01625   if ( handle->initData.frameLength > 8 )
01626   {
01627     size = dmadrvDataSize2;
01628   }
01629   else
01630   {
01631     size = dmadrvDataSize1;
01632   }
01633 
01634   if ( handle->initData.frameLength > 8 )
01635   {
01636     rxPort = (void *)&(handle->initData.port->RXDOUBLE);
01637     txPort = (void *)&(handle->initData.port->TXDOUBLE);
01638   }
01639   else
01640   {
01641     rxPort = (void *)&(handle->initData.port->RXDATA);
01642     txPort = (void *)&(handle->initData.port->TXDATA);
01643   }
01644 
01645   // Start receive dma.
01646   DMADRV_PeripheralMemory( handle->rxDMACh,
01647                            handle->rxDMASignal,
01648                            (void*)buffer,
01649                            rxPort,
01650                            true,
01651                            count,
01652                            size,
01653                            RxDMAComplete,
01654                            handle );
01655 
01656   // Start transmit dma.
01657   DMADRV_MemoryPeripheral( handle->txDMACh,
01658                            handle->txDMASignal,
01659                            txPort,
01660                            (void *)&(handle->initData.dummyTxValue),
01661                            false,
01662                            count,
01663                            size,
01664                            NULL,
01665                            NULL );
01666 }
01667 
01668 /***************************************************************************/
01671 static void StartTransferDMA( SPIDRV_Handle_t handle,
01672                               const void *txBuffer,
01673                               void *rxBuffer,
01674                               int count,
01675                               SPIDRV_Callback_t callback )
01676 {
01677   void *rxPort, *txPort;
01678   DMADRV_DataSize_t size;
01679 
01680   handle->blockingCompleted  = false;
01681   handle->transferCount      = count;
01682   handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
01683   handle->userCallback       = callback;
01684 
01685   if ( handle->initData.frameLength > 8 )
01686   {
01687     size = dmadrvDataSize2;
01688   }
01689   else
01690   {
01691     size = dmadrvDataSize1;
01692   }
01693 
01694   if ( handle->initData.frameLength > 8 )
01695   {
01696     rxPort = (void *)&(handle->initData.port->RXDOUBLE);
01697     txPort = (void *)&(handle->initData.port->TXDOUBLE);
01698   }
01699   else
01700   {
01701     rxPort = (void *)&(handle->initData.port->RXDATA);
01702     txPort = (void *)&(handle->initData.port->TXDATA);
01703   }
01704 
01705   // Start receive dma.
01706   DMADRV_PeripheralMemory( handle->rxDMACh,
01707                            handle->rxDMASignal,
01708                            rxBuffer,
01709                            rxPort,
01710                            true,
01711                            count,
01712                            size,
01713                            RxDMAComplete,
01714                            handle );
01715 
01716   // Start transmit dma.
01717   DMADRV_MemoryPeripheral( handle->txDMACh,
01718                            handle->txDMASignal,
01719                            txPort,
01720                            (void*)txBuffer,
01721                            true,
01722                            count,
01723                            size,
01724                            NULL,
01725                            NULL );
01726 }
01727 
01728 /***************************************************************************/
01731 static void StartTransmitDMA( SPIDRV_Handle_t handle,
01732                                const void *buffer,
01733                                int count,
01734                                SPIDRV_Callback_t callback )
01735 {
01736   void *rxPort, *txPort;
01737   DMADRV_DataSize_t size;
01738 
01739   handle->blockingCompleted  = false;
01740   handle->transferCount      = count;
01741   handle->initData.port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
01742   handle->userCallback       = callback;
01743 
01744   if ( handle->initData.frameLength > 8 )
01745   {
01746     size = dmadrvDataSize2;
01747   }
01748   else
01749   {
01750     size = dmadrvDataSize1;
01751   }
01752 
01753   if ( handle->initData.frameLength > 8 )
01754   {
01755     rxPort = (void *)&(handle->initData.port->RXDOUBLE);
01756     txPort = (void *)&(handle->initData.port->TXDOUBLE);
01757   }
01758   else
01759   {
01760     rxPort = (void *)&(handle->initData.port->RXDATA);
01761     txPort = (void *)&(handle->initData.port->TXDATA);
01762   }
01763 
01764   // Receive DMA runs only to get precise numbers for SPIDRV_GetTransferStatus()
01765   // Start receive dma.
01766   DMADRV_PeripheralMemory( handle->rxDMACh,
01767                            handle->rxDMASignal,
01768                            &(handle->dummyRx),
01769                            rxPort,
01770                            false,
01771                            count,
01772                            size,
01773                            RxDMAComplete,
01774                            handle );
01775 
01776   // Start transmit dma.
01777   DMADRV_MemoryPeripheral( handle->txDMACh,
01778                            handle->txDMASignal,
01779                            txPort,
01780                            (void*)buffer,
01781                            true,
01782                            count,
01783                            size,
01784                            NULL,
01785                            NULL );
01786 }
01787 
01788 /***************************************************************************/
01791 static Ecode_t TransferApiBlockingPrologue( SPIDRV_Handle_t handle,
01792                                             void *buffer,
01793                                             int count )
01794 {
01795   if ( handle == NULL )
01796   {
01797     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
01798   }
01799 
01800   if (( buffer == NULL ) || ( count == 0 )|| ( count > DMADRV_MAX_XFER_COUNT ))
01801   {
01802     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01803   }
01804 
01805   INT_Disable();
01806   if ( handle->state != spidrvStateIdle )
01807   {
01808     INT_Enable();
01809     return ECODE_EMDRV_SPIDRV_BUSY;
01810   }
01811   handle->state = spidrvStateTransferring;
01812   INT_Enable();
01813 
01814   return ECODE_EMDRV_SPIDRV_OK;
01815 }
01816 
01817 /***************************************************************************/
01820 static Ecode_t TransferApiPrologue( SPIDRV_Handle_t handle,
01821                                     void *buffer,
01822                                     int count )
01823 {
01824   if ( handle == NULL )
01825   {
01826     return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE;
01827   }
01828 
01829   if (( buffer == NULL ) || ( count == 0 ) || ( count > DMADRV_MAX_XFER_COUNT ))
01830   {
01831     return ECODE_EMDRV_SPIDRV_PARAM_ERROR;
01832   }
01833 
01834   INT_Disable();
01835   if ( handle->state != spidrvStateIdle )
01836   {
01837     INT_Enable();
01838     return ECODE_EMDRV_SPIDRV_BUSY;
01839   }
01840   handle->state = spidrvStateTransferring;
01841   INT_Enable();
01842 
01843   return ECODE_EMDRV_SPIDRV_OK;
01844 }
01845 
01846 /***************************************************************************/
01849 static void WaitForTransferCompletion( SPIDRV_Handle_t handle )
01850 {
01851   if ( INT_Disable() > 1 )
01852   {
01853     /* Interrupts are already disabled. */
01854     while ( handle->blockingCompleted == false )
01855     {
01856 #if defined( DMA_PRESENT ) && ( DMA_COUNT == 1 )
01857       DMA_IRQHandler();
01858 #elif defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 )
01859       LDMA_IRQHandler();
01860 #else
01861 #error "No valid DMA engine defined."
01862 #endif
01863     }
01864     INT_Enable();
01865   }
01866   else
01867   {
01868     INT_Enable();
01869     while ( handle->blockingCompleted == false );
01870   }
01871 }
01872 
01873 #if defined( EMDRV_SPIDRV_INCLUDE_SLAVE )
01874 /***************************************************************************/
01877 static Ecode_t WaitForIdleLine( SPIDRV_Handle_t handle )
01878 {
01879   while ( !GPIO_PinInGet( (GPIO_Port_TypeDef)handle->csPort, handle->csPin )
01880           && ( handle->state != spidrvStateIdle ) );
01881 
01882   if ( handle->state == spidrvStateIdle )
01883   {
01884     return handle->transferStatus;
01885   }
01886 
01887   return ECODE_EMDRV_SPIDRV_OK;
01888 }
01889 #endif
01890 
01892 
01893 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/