SAMV71 Xplained Ultra Software Package 1.3

qspi_dma.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2013, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 
00030 /**
00031  * \addtogroup qspi_dma_module QSPI xDMA driver
00032  * \ingroup peripherals_module
00033  *
00034  *
00035  */
00036 
00037 /**
00038  * \file
00039  *
00040  * Implementation for the SPI Flash with xDMA driver.
00041  *
00042  */
00043 
00044 
00045 /*----------------------------------------------------------------------------
00046  *        Headers
00047  *----------------------------------------------------------------------------*/
00048 
00049 #include "chip.h"
00050 
00051 /*----------------------------------------------------------------------------
00052  *        Definitions
00053  *----------------------------------------------------------------------------*/
00054 
00055 /** xDMA support */
00056 
00057 /** xDMA Link List size for SPI transmission*/
00058 #define DMA_QSPI_LLI     2
00059 
00060 /*-----------------------------------------------------------------------------
00061  *        QSPI DMA Local functions
00062  *----------------------------------------------------------------------------*/
00063 
00064 /**
00065  * \brief SPI xDMA Rx callback
00066  * Invoked on SPi DMA reception done.
00067  * \param channel DMA channel.
00068  * \param pArg Pointer to callback argument - Pointer to Spid instance.   
00069  */ 
00070 static void QSPID_Spi_Cb(uint32_t channel, QspiDma_t* pArg)
00071 {
00072     Qspi *pQspiHw = pArg->Qspid.pQspiHw;
00073     if (channel != pArg->RxChNum)
00074         return;
00075     /* Release the semaphore */
00076     ReleaseMutex(pArg->progress); 
00077     QSPI_EndTransfer(pQspiHw); 
00078     memory_sync();
00079 }
00080 
00081 
00082 /**
00083  * \brief QSPI xDMA Tx callback
00084  * Invoked on QSPi DMA Write done.
00085  * \param channel DMA channel.
00086  * \param pArg Pointer to callback argument - Pointer to Spid instance.
00087  */ 
00088 static void QSPID_qspiTx_Cb(uint32_t channel, QspiDma_t* pArg)
00089 {
00090     Qspi *pQspiHw = pArg->Qspid.pQspiHw;
00091     if (channel != pArg->TxChNum)
00092         return;
00093     /* Release the semaphore */
00094     ReleaseMutex(pArg->progress);
00095     QSPI_EndTransfer(pQspiHw);
00096     while(!QSPI_GetStatus(pArg->Qspid.pQspiHw, IsEofInst )); 
00097     memory_sync();
00098 }
00099 
00100 
00101 /**
00102  * \brief QSPI xDMA Rx callback
00103  * Invoked on SPi DMA reception done.
00104  * \param channel DMA channel.
00105  * \param pArg Pointer to callback argument - Pointer to Spid instance.   
00106  */ 
00107 static void QSPID_qspiRx_Cb(uint32_t channel, QspiDma_t* pArg)
00108 {
00109     Qspi *pQspiHw = pArg->Qspid.pQspiHw;
00110     if (channel != pArg->RxChNum)
00111         return;
00112     /* Release the semaphore */
00113     ReleaseMutex(pArg->progress); 
00114     QSPI_EndTransfer(pQspiHw);
00115     while(!QSPI_GetStatus(pArg->Qspid.pQspiHw, IsEofInst )); 
00116     memory_sync();
00117 }
00118 
00119 /**
00120  * \brief Configures the DMA for QSPI
00121  *
00122  * \param pQspidma  Pointer to QSPI DMA structure
00123  * \param Addr      Address to Read or write of QSPI flash memory
00124  * \param pBuffer   Pointer input/output buffer
00125  * \param ReadWrite Read or write memory flag
00126  * \returns 0 if the dma multibuffer configuration successfully; otherwise returns
00127  * QSPID_ERROR_XXX.
00128  */
00129 static uint8_t QSPID_configureQpsiDma(QspiDma_t *pQspidma, uint32_t Addr, 
00130             QspiBuffer_t *pBuffer, Access_t const ReadWrite)
00131 {
00132     sXdmadCfg xdmadCfg, xdmadRxCfg,xdmadTxCfg;
00133     uint8_t chanNum;
00134     uint8_t qspi_id =  pQspidma->Qspid.qspiId;
00135     Qspi *pQspiHw = pQspidma->Qspid.pQspiHw;
00136     uint32_t xdmaCndc, xdmaInt, BurstSize, ChannelWidth;
00137     
00138     
00139     /* Setup DMA  for QSPI */ 
00140     
00141     if(pQspidma->Qspid.qspiMode == QSPI_MR_SMM_SPI) {
00142     // SPI mode  
00143     /* SPI TX DMA config */
00144         xdmadTxCfg.mbr_sa   =   (uint32_t)pBuffer->pDataTx;
00145         xdmadTxCfg.mbr_da   =   (uint32_t)&pQspiHw->QSPI_TDR;
00146         xdmadTxCfg.mbr_ubc  =   (pBuffer->TxDataSize);
00147     
00148         xdmadTxCfg.mbr_cfg =  XDMAC_CC_TYPE_PER_TRAN |
00149                             XDMAC_CC_MBSIZE_SINGLE |
00150                             XDMAC_CC_DSYNC_MEM2PER |
00151                             XDMAC_CC_CSIZE_CHK_1 |
00152                             XDMAC_CC_DWIDTH_BYTE|
00153                             XDMAC_CC_SIF_AHB_IF0 |
00154                             XDMAC_CC_DIF_AHB_IF1 |
00155                             XDMAC_CC_SAM_INCREMENTED_AM |
00156                             XDMAC_CC_DAM_FIXED_AM |
00157                             XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00158                                 ( qspi_id, XDMAD_TRANSFER_TX ));
00159     
00160         xdmadTxCfg.mbr_bc = 0;
00161         xdmadTxCfg.mbr_sus = 0;
00162         xdmadTxCfg.mbr_dus =0;
00163 
00164         /* SPI RX DMA config */
00165     
00166         xdmadRxCfg.mbr_da  =  (uint32_t)pBuffer->pDataRx;
00167         xdmadRxCfg.mbr_sa  =  (uint32_t)&pQspiHw->QSPI_RDR;
00168         xdmadRxCfg.mbr_ubc =   (pBuffer->RxDataSize);
00169         xdmadRxCfg.mbr_cfg =    XDMAC_CC_TYPE_PER_TRAN |
00170                               XDMAC_CC_MBSIZE_SINGLE |
00171                               XDMAC_CC_DSYNC_PER2MEM |
00172                               XDMAC_CC_CSIZE_CHK_1 |
00173                               XDMAC_CC_DWIDTH_BYTE|
00174                               XDMAC_CC_SIF_AHB_IF1 |
00175                               XDMAC_CC_DIF_AHB_IF0 |
00176                               XDMAC_CC_SAM_FIXED_AM |
00177                               XDMAC_CC_DAM_INCREMENTED_AM |
00178                               XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00179                                 ( qspi_id, XDMAD_TRANSFER_RX ));
00180 
00181         xdmadRxCfg.mbr_bc = 0;
00182         xdmadRxCfg.mbr_sus = 0;
00183         xdmadRxCfg.mbr_dus =0; 
00184         xdmaCndc = 0;
00185     /* Put all interrupts on for non LLI list setup of DMA */
00186         xdmaInt =  (XDMAC_CIE_BIE   |
00187                    XDMAC_CIE_RBIE  |
00188                    XDMAC_CIE_WBIE  |
00189                    XDMAC_CIE_ROIE);
00190     
00191         memory_barrier();
00192         if (XDMAD_ConfigureTransfer
00193         ( pQspidma->pXdmad, pQspidma->RxChNum, &xdmadRxCfg, xdmaCndc, 0, xdmaInt))
00194         return QSPID_ERROR;
00195 
00196         if (XDMAD_ConfigureTransfer
00197             ( pQspidma->pXdmad, pQspidma->TxChNum, &xdmadTxCfg, xdmaCndc, 0, xdmaInt))
00198             return QSPID_ERROR;
00199     return 0;
00200      
00201     } else {
00202         if(ReadWrite == WriteAccess) {
00203             xdmadCfg.mbr_sa = (uint32_t)pBuffer->pDataTx;
00204             xdmadCfg.mbr_da = (uint32_t)( QSPIMEM_ADDR | Addr);
00205             xdmadCfg.mbr_ubc =  (pBuffer->TxDataSize);
00206             chanNum =  pQspidma->TxChNum;
00207             ChannelWidth = XDMAC_CC_DWIDTH_BYTE;
00208             BurstSize = XDMAC_CC_MBSIZE_SIXTEEN;
00209         } else if(ReadWrite == ReadAccess) {
00210             xdmadCfg.mbr_da = (uint32_t)pBuffer->pDataRx;
00211             xdmadCfg.mbr_sa = (uint32_t)( QSPIMEM_ADDR | Addr);
00212             xdmadCfg.mbr_ubc =  ((pBuffer->RxDataSize>>2) + 1);
00213             chanNum =  pQspidma->RxChNum;
00214             ChannelWidth = XDMAC_CC_DWIDTH_WORD;
00215             BurstSize = XDMAC_CC_MBSIZE_SIXTEEN;
00216         } else {
00217             TRACE_ERROR(" QSPI error \n\r");
00218             return 1;
00219         }
00220 
00221         xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN |
00222                     XDMAC_CC_MEMSET_NORMAL_MODE |
00223                     BurstSize |
00224                     ChannelWidth |
00225                     XDMAC_CC_SIF_AHB_IF1 |
00226                     XDMAC_CC_DIF_AHB_IF1 |
00227                     XDMAC_CC_SAM_INCREMENTED_AM |
00228                     XDMAC_CC_DAM_INCREMENTED_AM ;
00229     
00230         xdmadCfg.mbr_bc = 0;
00231         xdmadCfg.mbr_sus = 0;
00232         xdmadCfg.mbr_dus =0;
00233 
00234         xdmaCndc = 0;
00235 
00236 
00237     /* Put all interrupts on for non LLI list setup of DMA */
00238         xdmaInt =  (XDMAC_CIE_BIE   |
00239                    XDMAC_CIE_RBIE  |
00240                    XDMAC_CIE_WBIE  |
00241                    XDMAC_CIE_ROIE);
00242       
00243         memory_barrier();
00244         if (XDMAD_ConfigureTransfer( pQspidma->pXdmad, chanNum, &xdmadCfg, xdmaCndc, 0, xdmaInt))
00245             return QSPID_ERROR;
00246         return 0;
00247     }
00248 }
00249 
00250 /*----------------------------------------------------------------------------
00251  *        Exported functions
00252  *----------------------------------------------------------------------------*/
00253 /**
00254  * \brief Initializes the pQspidma structure and the corresponding QSPI & DMA .
00255  * hardware select value.
00256  *
00257  * \param pQspidma  Pointer to a QspiDma_t instance.
00258  * \param Mode      Associated SPI peripheral.
00259  * \param dwConf    QSPI peripheral configuration.
00260  * \param pXdmad    Pointer to a Xdmad instance. 
00261  */
00262 uint32_t QSPID_Configure( QspiDma_t *pQspidma, QspiMode_t Mode, 
00263         uint32_t dwConf, sXdmad* pXdmad)
00264 {
00265     /* Initialize the QSPI structure */
00266     
00267     QSPI_ConfigureInterface(&pQspidma->Qspid, Mode, dwConf);
00268     
00269     pQspidma->Qspid.qspiCommand.Instruction = 0;
00270     pQspidma->Qspid.qspiCommand.Option = 0;
00271     
00272     pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
00273     pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
00274     
00275     pQspidma->pXdmad = pXdmad;
00276     
00277     /* XDMA Driver initialize */
00278     XDMAD_Initialize(  pQspidma->pXdmad, 0 );
00279     
00280     /* Configure and enable interrupt  */
00281     NVIC_ClearPendingIRQ(XDMAC_IRQn);
00282     NVIC_SetPriority( XDMAC_IRQn ,1);
00283     NVIC_EnableIRQ(XDMAC_IRQn);
00284     
00285     
00286     return QSPI_SUCCESS;
00287 }
00288 
00289 
00290 
00291 /**
00292  * \brief Enables a QSPI Rx channel. This function will allocate a dma Rx 
00293  *  channel for QSPI
00294  *
00295  * \param pQspidma  Pointer to a Spid instance.
00296 
00297  * \returns 0 if the transfer has been started successfully; otherwise returns
00298  * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is not
00299  * valid.
00300  */
00301 uint32_t QSPID_EnableQspiRxChannel(QspiDma_t *pQspidma)
00302 {
00303     static uint16_t DmaChannel;
00304 
00305     /* Try to get the semaphore */
00306     if (pQspidma->RxChNum != QSPID_CH_NOT_ENABLED) {
00307         return QSPID_ERROR_LOCK;
00308     }
00309     
00310     /* Allocate a DMA channel */
00311     DmaChannel = XDMAD_AllocateChannel( 
00312             pQspidma->pXdmad, XDMAD_TRANSFER_MEMORY, XDMAD_TRANSFER_MEMORY);
00313     if ( DmaChannel == XDMAD_ALLOC_FAILED ){
00314         return QSPID_ERROR;
00315     }
00316 
00317     pQspidma->RxChNum = DmaChannel;
00318     /* Setup callbacks*/
00319     XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum, 
00320             (XdmadTransferCallback)QSPID_qspiRx_Cb, pQspidma);
00321     
00322     if (XDMAD_PrepareChannel( pQspidma->pXdmad, pQspidma->RxChNum ))
00323         return QSPID_ERROR;
00324     return 0;
00325 }
00326 
00327 
00328 /**
00329  * \brief Enables a QSPI Tx channel. This function will allocate a dma Tx 
00330  * channel for QSPI
00331  *
00332  * \param pQspidma  Pointer to a Spid instance.
00333 
00334  * \returns 0 if the transfer has been started successfully; otherwise returns
00335  * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is 
00336  * not valid.
00337  */
00338 uint32_t QSPID_EnableQspiTxChannel(QspiDma_t *pQspidma)
00339 {
00340     static uint16_t DmaChannel;
00341 
00342     /* Try to get the  semaphore */
00343     if (pQspidma->TxChNum != QSPID_CH_NOT_ENABLED) {
00344         return QSPID_ERROR_LOCK;
00345     }
00346     /* Allocate a DMA channel */
00347     DmaChannel = XDMAD_AllocateChannel( pQspidma->pXdmad, 
00348             XDMAD_TRANSFER_MEMORY, XDMAD_TRANSFER_MEMORY);
00349     if ( DmaChannel == XDMAD_ALLOC_FAILED ) {
00350             return QSPID_ERROR;
00351     }
00352     
00353     pQspidma->TxChNum = DmaChannel;
00354     /* Setup callbacks  */
00355     XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum, 
00356             (XdmadTransferCallback)QSPID_qspiTx_Cb, pQspidma);
00357     
00358     if (XDMAD_PrepareChannel( pQspidma->pXdmad, pQspidma->TxChNum ))
00359         return QSPID_ERROR;
00360     
00361     return 0;
00362 }
00363 
00364 
00365 /**
00366  * \brief Enables a QSPI SPI Rx channel. This function will allocate a dma 
00367  *  Rx channel for QSPI SPI mode
00368  *
00369  * \param pQspidma  Pointer to a Spid instance.
00370 
00371  * \returns 0 if the transfer has been started successfully; otherwise returns
00372  * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is 
00373  * not valid.
00374  */
00375 uint32_t QSPID_EnableSpiChannel(QspiDma_t *pQspidma)
00376 {
00377     static uint16_t DmaChannel;
00378 
00379     /* Try to get the semaphore */
00380     if (pQspidma->RxChNum != QSPID_CH_NOT_ENABLED) {
00381         return QSPID_ERROR_LOCK;
00382     }
00383     
00384     /* Try to get the  semaphore */
00385     if (pQspidma->TxChNum != QSPID_CH_NOT_ENABLED) {
00386         return QSPID_ERROR_LOCK;
00387     }
00388        
00389     /* Allocate a DMA channel */
00390     DmaChannel = XDMAD_AllocateChannel
00391         ( pQspidma->pXdmad, pQspidma->Qspid.qspiId, XDMAD_TRANSFER_MEMORY);
00392     if ( DmaChannel == XDMAD_ALLOC_FAILED ) {
00393         return QSPID_ERROR;
00394     }
00395 
00396     pQspidma->RxChNum = DmaChannel;
00397     
00398     /* Allocate a DMA channel */
00399     DmaChannel = XDMAD_AllocateChannel( pQspidma->pXdmad, 
00400             XDMAD_TRANSFER_MEMORY, pQspidma->Qspid.qspiId);
00401     if ( DmaChannel == XDMAD_ALLOC_FAILED ) {
00402         return QSPID_ERROR;
00403     }
00404     
00405     pQspidma->TxChNum = DmaChannel;
00406     
00407     /* Setup callbacks*/
00408     XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum, 
00409             (XdmadTransferCallback)QSPID_Spi_Cb, pQspidma);
00410     if (XDMAD_PrepareChannel( pQspidma->pXdmad, pQspidma->RxChNum ))
00411         return QSPID_ERROR;
00412     
00413     /* Setup callbacks for SPI0/1 TX (ignored) */
00414     XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum, NULL, NULL);
00415     if ( XDMAD_PrepareChannel( pQspidma->pXdmad, pQspidma->TxChNum ))
00416         return QSPID_ERROR;
00417     
00418     return 0;
00419 }
00420 
00421 
00422 /**
00423  * \brief Disables a QSPI Rx channel. This function will de-allocate previous 
00424  *  allocated dma Rx channel for QSPI
00425  *
00426  * \param pQspidma  Pointer to a Spid instance.
00427 
00428  * \returns 0 if the transfer has been started successfully; otherwise returns
00429  * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is 
00430  * not valid.
00431  */
00432 uint32_t QSPID_DisableQspiRxChannel(QspiDma_t *pQspidma)
00433 {    
00434   
00435     XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->RxChNum);
00436     XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->RxChNum);
00437     
00438     XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum, NULL, NULL);    
00439     
00440     
00441      /* Free allocated DMA channel for QSPI RX. */
00442     XDMAD_FreeChannel( pQspidma->pXdmad, pQspidma->RxChNum);
00443     
00444     pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
00445     
00446     return 0;
00447 }
00448 
00449 
00450 
00451 /**
00452  * \brief Disables a QSPI Tx channel. This function will de-allocate previous 
00453  * allocated dma Tx channel for QSPI
00454  *
00455  * \param pQspidma  Pointer to a Spid instance.
00456 
00457  * \returns 0 if the transfer has been started successfully; otherwise returns
00458  * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is 
00459  * not valid.
00460  */
00461 uint32_t QSPID_DisableQspiTxChannel(QspiDma_t *pQspidma)
00462 {    
00463   
00464     XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->TxChNum);
00465     XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->TxChNum);
00466     
00467     XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum, NULL, NULL);
00468     
00469      /* Free allocated DMA channel for QSPI TX. */
00470     XDMAD_FreeChannel( pQspidma->pXdmad, pQspidma->TxChNum);
00471     
00472     pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
00473     
00474     return 0;
00475 }
00476 
00477 
00478 /**
00479  * \brief Disables a QSPI SPI Rx and Tx channels. This function will 
00480  *  de-allocate privious allocated dma Rx, Txchannel for QSPI in SPI mode
00481  *
00482  * \param pQspidma  Pointer to a Spid instance.
00483 
00484  * \returns 0 if the transfer has been started successfully; otherwise returns
00485  * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is 
00486  * not valid.
00487  */
00488 uint32_t QSPID_DisableSpiChannel(QspiDma_t *pQspidma)
00489 {    
00490   
00491     XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->RxChNum);
00492     //XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->TxChNum);
00493     XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->RxChNum);
00494     XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->TxChNum);
00495     
00496     XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum, NULL, NULL);
00497     
00498      /* Free allocated DMA channel for QSPI RX. */
00499     XDMAD_FreeChannel( pQspidma->pXdmad, pQspidma->RxChNum);
00500      
00501     XDMAD_FreeChannel( pQspidma->pXdmad, pQspidma->TxChNum);
00502     
00503     pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
00504     pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
00505     
00506     return 0;
00507 }
00508 
00509 
00510 /**
00511  * \brief Starts a QSPI read or write operation. 
00512  *
00513  * \param pQspidma  Pointer to a Qspid instance.
00514  * \param ReadWrite Defines the memory access type
00515  * \returns 0 if the transfer has been started successfully; otherwise returns
00516  * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is 
00517  * not valid.
00518  */
00519 uint32_t QSPID_ReadWriteQSPI(QspiDma_t *pQspidma, Access_t const ReadWrite)
00520 { 
00521     QspiBuffer_t *pBuffer = &pQspidma->Qspid.qspiBuffer;
00522     uint8_t chanNum;
00523     uint32_t semTimer = 0x7FF;
00524     
00525     //assert(pBuffer->pDataTx);
00526     
00527     if (pQspidma->progress) {
00528         return QSPID_ERROR_LOCK;
00529     }
00530     LockMutex(pQspidma->progress, semTimer);
00531     if(ReadWrite == WriteAccess) {
00532       chanNum =  pQspidma->TxChNum; 
00533     } else if(ReadWrite == ReadAccess) {
00534       chanNum =  pQspidma->RxChNum;
00535     } else {
00536       TRACE_ERROR("%s QSPI Access Error\n\r", __FUNCTION__);
00537     }
00538     
00539     if (QSPID_configureQpsiDma
00540             ( pQspidma, pQspidma->Qspid.pQspiFrame->Addr, pBuffer, ReadWrite) )
00541         return QSPID_ERROR_LOCK;
00542     
00543     SCB_CleanInvalidateDCache();
00544     /* Start DMA 0(RX) && 1(TX) */
00545     if (XDMAD_StartTransfer( pQspidma->pXdmad,chanNum )) 
00546         return QSPID_ERROR_LOCK;
00547     return 0;
00548 }
00549 
00550 /**
00551  * \brief Starts a SPI master transfer. This is a non blocking function. It will
00552  *  return as soon as the transfer is started.
00553  *
00554  * \param pSpid  Pointer to a Spid instance.
00555  * \param pCommand Pointer to the SPI command to execute.
00556  * \returns 0 if the transfer has been started successfully; otherwise returns
00557  * SPID_ERROR_LOCK is the driver is in use, or SPID_ERROR if the command is not
00558  * valid.
00559  */
00560 uint32_t QSPID_ReadWriteSPI(QspiDma_t *pQspidma, Access_t const ReadWrite)
00561 {
00562     QspiBuffer_t *pBuffer = &pQspidma->Qspid.qspiBuffer;
00563     uint32_t semTimer = 0x7FF;
00564     
00565     assert(pBuffer->pDataRx);
00566     assert(pBuffer->pDataTx);
00567     
00568     /* Try to get the dataflash semaphore */
00569     if (pQspidma->progress) {
00570 
00571         return QSPID_ERROR_LOCK;
00572     }
00573     
00574     LockMutex(pQspidma->progress, semTimer);
00575     
00576     
00577     if (QSPID_configureQpsiDma
00578             ( pQspidma, pQspidma->Qspid.pQspiFrame->Addr, pBuffer, ReadWrite) )
00579         return QSPID_ERROR_LOCK;
00580     
00581     SCB_CleanInvalidateDCache();
00582    
00583     /* Start DMA 0(RX) && 1(TX) */
00584     if (XDMAD_StartTransfer(  pQspidma->pXdmad, pQspidma->RxChNum )) 
00585         return QSPID_ERROR_LOCK;
00586     if (XDMAD_StartTransfer(  pQspidma->pXdmad, pQspidma->TxChNum  )) 
00587         return QSPID_ERROR_LOCK;
00588     return 0;
00589 }
00590 
00591 /**
00592  * \brief Check if the QSPI driver is busy.
00593  *
00594  * \param pSpid  Pointer to a Spid instance.
00595  * \returns 1 if the SPI driver is currently busy executing a command; otherwise
00596  */
00597 uint32_t QSPID_IsBusy(volatile uint8_t *QspiSemaphore)
00598 {    
00599     if( Is_LockFree(QspiSemaphore) ) {
00600       return 1;
00601     } else {
00602       return 0;
00603     }
00604 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines