SAMV71 Xplained Ultra Software Package 1.4

qspi.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, 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 /** \addtogroup qspi_module Working with QSPI
00031  * \ingroup peripherals_module
00032  * The QSPI driver provides the interface to configure and use the QSPI
00033  * peripheral.
00034  *
00035  * The Serial Peripheral Interface (QSPI) circuit is a synchronous serial
00036  * data link that provides communication with external devices in Master
00037  * or Slave Mode.
00038  *
00039  * To use the QSPI, the user has to follow these few steps:
00040  * -# Enable the QSPI pins required by the application (see pio.h).
00041  * -# Configure the QSPI using the \ref QSPI_Configure(). This enables the
00042  *    peripheral clock. The mode register is loaded with the given value.
00043  * -# Configure all the necessary chip selects with \ref QSPI_ConfigureNPCS().
00044  * -# Enable the QSPI by calling \ref QSPI_Enable().
00045  * -# Send/receive data using \ref QSPI_Write() and \ref QSPI_Read(). Note that
00046 *  \ref QSPI_Read()
00047  *    must be called after \ref QSPI_Write() to retrieve the last value read.
00048  * -# Send/receive data using the PDC with the \ref QSPI_WriteBuffer() and
00049  *    \ref QSPI_ReadBuffer() functions.
00050  * -# Disable the QSPI by calling \ref QSPI_Disable().
00051  *
00052  * For more accurate information, please look at the QSPI section of the
00053  * Datasheet.
00054  *
00055  * Related files :\n
00056  * \ref qspi.c\n
00057  * \ref qspi.h.\n
00058  */
00059 /*@{*/
00060 /*@}*/
00061 
00062 /**
00063  * \file
00064  *
00065  * Implementation of Serial Peripheral Interface (QSPI) controller.
00066  *
00067  */
00068 
00069 /*----------------------------------------------------------------------------
00070  *        Headers
00071  *----------------------------------------------------------------------------*/
00072 
00073 #include "chip.h"
00074 #include "stdlib.h"
00075 #include "string.h"   
00076 
00077 #include <stdint.h>
00078 
00079 
00080 #define SCRAMBLE_KEY    0x0BADDEAD
00081 /*----------------------------------------------------------------------------
00082  *        Internal functions
00083  *----------------------------------------------------------------------------*/
00084 
00085 
00086 
00087 /**
00088  * \brief Configure QSPI/SPI mode
00089  *
00090  * \param pQspi  Pointer to a Qspi instance.
00091  */
00092 __STATIC_INLINE void QSPI_ConfigureMode( Qspi *pQspi, uint8_t dMode )
00093 {
00094     assert(pQspi);
00095     pQspi->QSPI_MR =  dMode ;
00096 }
00097 
00098 /**
00099  * \brief Configure mode register of QSPI
00100  *
00101  * \param pQspi  Pointer to a Qspi instance.
00102  */
00103 __STATIC_INLINE void QSPI_Configure( Qspi *pQspi, uint32_t dwConfiguration )
00104 {
00105     assert(pQspi);
00106     pQspi->QSPI_MR |=  dwConfiguration ;
00107 }
00108 
00109 
00110 /**
00111  * \brief Configures a instruction address for QSPI in QSPI mode
00112  *
00113  * \param pQspi   Pointer to a Qspi instance.
00114  * \param dwAddr  Instruction Address
00115  */
00116 __STATIC_INLINE void QSPI_SetInstAddr( Qspi *pQspi,uint32_t dwAddr )
00117 {
00118     assert(pQspi);
00119     pQspi->QSPI_IAR = dwAddr ;
00120 }
00121 
00122 
00123 /**
00124  * \brief Configures instruction register with a given command for QSPI
00125  *
00126  * \param pQspi   Pointer to a Qspi instance.
00127  * \param dwInst  Instruction Code
00128  * \param dwOpt   Instruction Code option
00129  */
00130 __STATIC_INLINE void QSPI_SetInst( Qspi *pQspi, uint8_t dwInst, uint8_t dwOpt )
00131 {
00132     assert(pQspi);
00133     pQspi->QSPI_ICR = (dwInst | QSPI_ICR_OPT(dwOpt) );
00134 }
00135 
00136 /**
00137  * \brief Configures instruction frame register of QSPI
00138  *
00139  * \param pQspi         Pointer to a Qspi instance.
00140  * \param pInstFrame    Instruction Frame configuration
00141  */
00142 __STATIC_INLINE void QSPI_SetInstFrame( Qspi *pQspi, QspiInstFrame_t *pInstFrame)
00143 {
00144     assert(pQspi);
00145     pQspi->QSPI_IFR = pInstFrame->InstFrame.val;
00146 }
00147 
00148 /**
00149  * \brief Reads the Instruction frame of QSPI
00150  *
00151  * \param pQspi   Pointer to an Qspi instance.
00152  */
00153 __STATIC_INLINE uint32_t QSPI_GetInstFrame( Qspi *pQspi )
00154 {
00155     assert(pQspi);
00156     return pQspi->QSPI_IFR;
00157 }
00158 
00159 /**
00160  * \brief Read QSPI RDR register for SPI mode
00161  *
00162  * \param pQspi   Pointer to an Qspi instance.
00163  */
00164 __STATIC_INLINE uint16_t QSPI_ReadSPI( Qspi *pQspi )
00165 {
00166     assert(pQspi);
00167     while(!QSPI_GetStatus(pQspi, IsReceived));
00168     return  pQspi->QSPI_RDR;
00169 }
00170 
00171 
00172 /**
00173  * \brief Write to QSPI Tx register in SPI mode
00174  *
00175  * \param pQspi   Pointer to an Qspi instance.
00176  * \param wData   Data to transmit
00177  */
00178 __STATIC_INLINE void QSPI_WriteSPI( Qspi *pQspi, uint16_t wData )
00179 {
00180     assert(pQspi);
00181     /* Send data */
00182     while(!QSPI_GetStatus(pQspi, IsTxEmpty));
00183     pQspi->QSPI_TDR = wData ;
00184     while(!QSPI_GetStatus(pQspi, IsTxSent));
00185 }
00186 
00187 /**
00188  * \brief Configures QSPI scrambling with a given Key
00189  *
00190  * \param pQspi         Pointer to an Qspi instance.
00191  * \param wKey          Key for scramble/unscramble
00192  * \param EnableFlag    Enable/disable scramble
00193  * \param Random        Add random value with given key
00194  */
00195 __STATIC_INLINE void QSPI_ScrambleData( Qspi *pQspi, uint32_t wKey, 
00196         uint8_t EnableFlag, uint8_t Random )
00197 {
00198     assert(pQspi);
00199     assert(EnableFlag < 2);
00200     assert(Random < 2 );
00201     
00202     if(EnableFlag) {
00203       pQspi->QSPI_SKR = wKey;
00204     }
00205     pQspi->QSPI_SMR = ( EnableFlag | (Random << 1));
00206 }
00207 
00208 /*----------------------------------------------------------------------------
00209  *        Exported functions
00210  *----------------------------------------------------------------------------*/
00211 
00212 /**
00213  * \brief Enables a QSPI peripheral.
00214  *
00215  * \param pQspi  Pointer to a Qspi instance.
00216  */
00217 void QSPI_Enable( Qspi *pQspi )
00218 {
00219     assert(pQspi);
00220     pQspi->QSPI_CR = QSPI_CR_QSPIEN ;
00221     while(!(pQspi->QSPI_SR & QSPI_SR_QSPIENS));
00222 }
00223 
00224 /**
00225  * \brief Disables a QSPI peripheral.
00226  *
00227  * \param pQspi  Pointer to a Qspi instance.
00228  */
00229 void QSPI_Disable( Qspi *pQspi )
00230 {
00231     assert(pQspi);
00232     pQspi->QSPI_CR = QSPI_CR_QSPIDIS ;
00233     while(pQspi->QSPI_SR & QSPI_SR_QSPIENS);
00234 }
00235 
00236 /**
00237  * \brief Resets a QSPI peripheral.
00238  *
00239  * \param pQspi  Pointer to a Qspi instance.
00240  */
00241 void QSPI_SwReset( Qspi *pQspi )
00242 {
00243     assert(pQspi);
00244     pQspi->QSPI_CR = QSPI_CR_SWRST ;
00245 }
00246 
00247 /**
00248  * \brief Enables one or more interrupt sources of a QSPI peripheral.
00249  *
00250  * \param pQspi  Pointer to a Qspi instance.
00251  * \param sources Bitwise OR of selected interrupt sources.
00252  */
00253 QspidStatus_t QSPI_EnableIt( Qspi *pQspi, uint32_t dwSources )
00254 {
00255     assert(pQspi);
00256     pQspi->QSPI_IER = dwSources ;
00257     return QSPI_SUCCESS;
00258 }
00259 
00260 /**
00261  * \brief Disables one or more interrupt sources of a QSPI peripheral.
00262  *
00263  * \param pQspi  Pointer to a Qspi instance.
00264  * \param sources Bitwise OR of selected interrupt sources.
00265  */
00266 QspidStatus_t QSPI_DisableIt( Qspi *pQspi, uint32_t dwSources )
00267 {
00268     assert(pQspi);
00269     pQspi->QSPI_IDR = dwSources ;
00270     return QSPI_SUCCESS;
00271 }
00272 
00273 /**
00274  * \brief Return the interrupt mask register.
00275  *
00276  * \return Qspi interrupt mask register.
00277  */
00278 uint32_t QSPI_GetItMask( Qspi *pQspi )
00279 {
00280     assert(pQspi);
00281     return (pQspi->QSPI_IMR) ;
00282 }
00283 
00284 /**
00285  * \brief Returns enabled interrupt status
00286  *
00287  * \return Qspi interrupt mask register.
00288  */
00289 uint32_t QSPI_GetEnabledItStatus( Qspi *pQspi )
00290 {
00291     assert(pQspi);
00292     return (pQspi->QSPI_IMR & QSPI_GetStatus(pQspi, 0xFFFFFFFF) ) ;
00293 }
00294 
00295 /**
00296  * \brief Get the current status register of the given QSPI peripheral.
00297  * \note This resets the internal value of the status register, so further
00298  * read may yield different values.
00299  * \param pQspi   Pointer to a Qspi instance.
00300  * \param rStatus Compare status with given status bit
00301  * \return  QSPI status register.
00302  */
00303 uint32_t QSPI_GetStatus( Qspi *pQspi, const QspiStatus_t rStatus )
00304 {
00305     assert(pQspi);
00306     return (pQspi->QSPI_SR & rStatus) ;
00307 }
00308 
00309 /**
00310  * \brief Configures peripheral clock of a QSPI/SPI peripheral. 
00311  *
00312  * \param pQspi   Pointer to an Qspi instance.
00313  * \param dwConfiguration  Desired clock configuration.
00314  */
00315 void QSPI_ConfigureClock( Qspi *pQspi, QspiClockMode_t ClockMode, uint32_t dwClockCfg )
00316 {
00317     assert(pQspi);
00318     pQspi->QSPI_SCR = ClockMode ;
00319     pQspi->QSPI_SCR |= dwClockCfg ;
00320 }
00321 
00322 /**
00323  * \brief Configures QSPI/SPI 
00324  *
00325  * \param pQspi             Pointer to an Qspi instance.
00326  * \param Mode              Mode for QSPI or SPI 
00327  * \param dwConfiguration   Config of SPI or QSPI mode
00328  */
00329 QspidStatus_t QSPI_ConfigureInterface( Qspid_t *pQspid, QspiMode_t Mode, 
00330         uint32_t dwConfiguration)
00331 {    
00332     pQspid->pQspiHw = QSPI;
00333     pQspid->qspiId = ID_QSPI;    
00334     
00335     QSPI_Disable(pQspid->pQspiHw);
00336     QSPI_SwReset(pQspid->pQspiHw);
00337     
00338     QSPI_ConfigureMode(pQspid->pQspiHw, Mode);
00339     QSPI_Configure(pQspid->pQspiHw, dwConfiguration);  
00340     
00341     return QSPI_SUCCESS;
00342 }
00343 
00344 
00345 /**
00346  * \brief Ends ongoing transfer by releasing CS of QSPI peripheral.
00347  *
00348  * \param pQspi  Pointer to an Qspi instance.
00349  */
00350 QspidStatus_t QSPI_EndTransfer( Qspi *pQspi )
00351 {
00352     assert(pQspi);
00353     while(!QSPI_GetStatus(pQspi, IsTxEmpty));
00354     pQspi->QSPI_CR = QSPI_CR_LASTXFER ;
00355     
00356     return QSPI_SUCCESS;
00357 }
00358 
00359 
00360 /*----------------------------------------------------------------------------
00361  *        SPI functions
00362  *----------------------------------------------------------------------------*/
00363 /**
00364  * \brief Reads the data received by a SPI peripheral. This
00365  * method must be called after a successful SPI_Write call.
00366  *
00367  * \param pQspid    Pointer to a Qspi instance.
00368  * \param pData     Buffer to put read value
00369  * \return Qspi status
00370  */
00371 QspidStatus_t QSPI_SingleReadSPI( Qspid_t *pQspid, uint16_t* const pData )
00372 {
00373     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00374     Qspi *pQspi = pQspid->pQspiHw;
00375     uint32_t NumOfAttempt = 0;
00376     uint16_t Dummy= 0xFF;
00377     
00378     for(; ;) {
00379         if( QSPI_GetStatus(pQspi, IsReceived)) {
00380             *pData = QSPI_ReadSPI(pQspi) ;
00381             QSPI_WriteSPI(pQspi, Dummy);
00382             *pData = QSPI_ReadSPI(pQspi) ;
00383             NumOfAttempt = 0;
00384             Status = QSPI_SUCCESS;
00385         } else {
00386             if(NumOfAttempt > 0xFFFF) {
00387                 Status = QSPI_READ_ERROR;
00388                 TRACE_ERROR(" SPI Read Error \n\r");
00389                 break;
00390             } else { 
00391                 Status = QSPI_READ_ERROR;
00392                 NumOfAttempt++;
00393             }
00394         }
00395     }
00396     return Status;
00397 }
00398 
00399 /**
00400  * \brief Reads multiple data received by a SPI peripheral. This
00401  * method must be called after a successful SPI_Write call.
00402  *
00403  * \param pQspid        Pointer to a Qspi instance.
00404  * \param pData         Pointer to read buffer
00405  * \param NumOfBytes    Num of bytes to read
00406  * 
00407  * \return Qspi status
00408  */
00409 QspidStatus_t QSPI_MultiReadSPI( Qspid_t *pQspid, uint16_t* const pData, 
00410                             uint32_t NumOfBytes )
00411 {
00412     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00413     Qspi *pQspi = pQspid->pQspiHw;
00414     uint32_t NumOfBytesRead = 0;
00415     uint32_t NumOfAttempt = 0;
00416     uint8_t *pwData = (uint8_t *)pData;
00417     uint16_t Dummy=0xFF;
00418     
00419     /* Dummy read  and write to discard  first bytes recvd and start 
00420         receiving new data*/
00421     Dummy = QSPI_ReadSPI(pQspi) ;
00422     QSPI_WriteSPI(pQspi, Dummy);
00423     for(; NumOfBytesRead < NumOfBytes;) {
00424         if( QSPI_GetStatus(pQspi, IsTxSent)) {
00425             *pwData= QSPI_ReadSPI(pQspi) ;
00426             if(pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk) {
00427                 pwData += sizeof(uint16_t);
00428             } else {
00429                 pwData += sizeof(uint8_t);
00430             }
00431             NumOfBytesRead++;
00432             NumOfAttempt = 0;
00433             Status = QSPI_SUCCESS;
00434             QSPI_WriteSPI(pQspi, Dummy);
00435         } else {
00436             if(NumOfAttempt > 0xFFFF) {
00437                 Status = QSPI_READ_ERROR;
00438                 TRACE_ERROR(" SPI MultiRead Error \n\r");
00439                 break;
00440             } else { 
00441                 Status = QSPI_READ_ERROR;
00442                 NumOfAttempt++;
00443             }
00444         }
00445     }
00446     return Status;
00447 }
00448 
00449 /**
00450  * \brief Sends a single data through a SPI peripheral.
00451  *
00452  * \param pQspid    Pointer to a Qspi instance.
00453  * \param pData     Pointer to Tx data
00454  * 
00455  * \return Qspi status
00456  */
00457 QspidStatus_t QSPI_SingleWriteSPI( Qspid_t *pQspid, uint16_t const *pData )
00458 {
00459     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00460     Qspi *pQspi = pQspid->pQspiHw;
00461     uint32_t NumOfAttempt = 0;
00462     
00463     for(;;) {
00464         if( QSPI_GetStatus(pQspi, IsTxSent)) {
00465             QSPI_WriteSPI(pQspi, *pData);
00466             NumOfAttempt = 0;
00467             Status = QSPI_SUCCESS;
00468             break;
00469         } else {
00470             Status = QSPI_BUSY_SENDING;
00471             NumOfAttempt++;
00472             if(NumOfAttempt > 0xFFFF) {
00473                 Status = QSPI_WRITE_ERROR;
00474                 TRACE_ERROR(" SPI Write Error \n\r");
00475                 break;
00476             }
00477         }
00478     }
00479     return Status;
00480     
00481 }
00482 
00483 /**
00484  * \brief Sends multiple data through a SPI peripheral. 
00485  *
00486  * \param pQspid        Pointer to a Qspi instance.
00487  * \param pData         Pointer to a Tx buffer 
00488  * \param NumOfBytes    Num of data to send.
00489  */
00490 QspidStatus_t QSPI_MultiWriteSPI( Qspid_t *pQspid, uint16_t const *pData, 
00491                                 uint32_t NumOfBytes )
00492 {
00493     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00494     Qspi *pQspi = pQspid->pQspiHw;
00495     uint32_t NumOfBytesWrite = 0;
00496     uint32_t NumOfAttempt = 0;
00497     uint8_t *pwData = (uint8_t *)pData;
00498     uint8_t Addr_Inc = 0;
00499     
00500     if(pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk) {
00501         Addr_Inc = sizeof(uint16_t);
00502     } else {
00503         Addr_Inc = sizeof(uint8_t);
00504     }
00505     
00506     for(; NumOfBytesWrite < NumOfBytes; NumOfBytesWrite++) {
00507         if( QSPI_GetStatus(pQspi, IsTxEmpty)) {
00508             QSPI_WriteSPI(pQspi, (uint16_t )*pwData);
00509             pwData += Addr_Inc;
00510             NumOfAttempt = 0;
00511             Status = QSPI_SUCCESS;
00512         } else {
00513             Status = QSPI_BUSY_SENDING;
00514             NumOfAttempt++;
00515             if(NumOfAttempt > 0xFFFF) {
00516                 Status = QSPI_WRITE_ERROR;
00517                 TRACE_ERROR(" SPI Multi Write Error \n\r");
00518                 break;
00519             }
00520         }
00521     }
00522     return Status;
00523     
00524 }
00525 
00526 /*----------------------------------------------------------------------------
00527  *        QSPI functions
00528  *----------------------------------------------------------------------------*/
00529 
00530 /**
00531  * \brief Send an instruction over QSPI (oly a flash command no data)
00532  *
00533  * \param pQspi     Pointer to an Qspi instance.
00534  * \param KeepCfg   To keep Instruction fram value or restes to zero
00535  *
00536  * \return Returns 1 if At least one instruction end has been detected since 
00537  * the last read of QSPI_SR.; otherwise
00538  * returns 0.
00539  */
00540 QspidStatus_t QSPI_SendCommand( Qspid_t *pQspid, uint8_t const KeepCfg)
00541 {  
00542     QspiInstFrame_t*  const pFrame = pQspid->pQspiFrame;
00543     QspiMemCmd_t  pCommand = pQspid->qspiCommand;
00544     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00545     
00546     if( pFrame->InstFrame.bm.bAddrEn)
00547     {
00548       QSPI_SetInstAddr(pQspid->pQspiHw, pFrame->Addr);
00549     }
00550     QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), 
00551             ( (pCommand.Option >> QSPI_ICR_OPT_Pos) & 0xFF));
00552     QSPI_SetInstFrame(pQspid->pQspiHw, pFrame );
00553     
00554     memory_sync(); 
00555     while(!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));            
00556     // poll CR reg to know status if instruction has end
00557     if(!KeepCfg) {
00558       pFrame->InstFrame.val = 0;
00559     }
00560     return Status;
00561 }
00562 
00563 
00564 
00565 /**
00566  * \brief Send instruction over QSPI with data
00567  *
00568  * \param pQspi     Pointer to an Qspi instance.
00569  * \param KeepCfg   To keep Instruction fram value or restes to zero
00570  *
00571  * \return Returns 1 if At least one instruction end has been detected 
00572  *  since the last read of QSPI_SR.; otherwise returns 0.
00573  */
00574 QspidStatus_t QSPI_SendCommandWithData( Qspid_t *pQspid, uint8_t const KeepCfg)
00575 {  
00576     QspiInstFrame_t* const  pFrame = pQspid->pQspiFrame;
00577     QspiMemCmd_t  pCommand = pQspid->qspiCommand;
00578     QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
00579     uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR;
00580     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00581    
00582     //assert(pBuffer.pDataRx);
00583     assert(pBuffer.pDataTx);
00584         
00585     QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), (pCommand.Option & 0xFF) );
00586     QSPI_SetInstFrame(pQspid->pQspiHw, pFrame );
00587     
00588     QSPI_GetInstFrame(pQspid->pQspiHw); 
00589     // to synchronize system bus accesses
00590     if(!KeepCfg) {
00591       pFrame->InstFrame.val = 0;
00592     }
00593     
00594     memcpy(pQspiBuffer  ,pBuffer.pDataTx ,  pBuffer.TxDataSize ); 
00595     memory_sync();
00596     QSPI_EndTransfer(pQspid->pQspiHw ) ; 
00597     // End transmission after all data has been sent
00598     while(!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE)); 
00599     // poll CR reg to know status if instruction has end
00600     
00601     return Status;
00602 }
00603 
00604 /**
00605  * \brief Send instruction over QSPI to read data
00606  *
00607  * \param pQspi     Pointer to an Qspi instance.
00608  * \param KeepCfg   To keep Instruction from value or resets to zero
00609  *
00610  * \return Returns 1 if At least one instruction end has been detected 
00611  * since the last read of QSPI_SR.; otherwise returns 0.
00612  */
00613 QspidStatus_t QSPI_ReadCommand( Qspid_t *pQspid, uint8_t const KeepCfg)
00614 {  
00615     QspiInstFrame_t* const  pFrame = pQspid->pQspiFrame;
00616     QspiMemCmd_t  pCommand = pQspid->qspiCommand;
00617     QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
00618     uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR;
00619     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00620     
00621     assert(pBuffer.pDataRx);
00622       
00623     QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), 
00624             (pCommand.Option & 0xFF) );
00625     QSPI_SetInstFrame(pQspid->pQspiHw, pFrame );
00626     
00627     QSPI_GetInstFrame(pQspid->pQspiHw);
00628         // to synchronize system bus accesses   
00629     if(!KeepCfg) {
00630       pFrame->InstFrame.val = 0;
00631     }
00632     memcpy(pBuffer.pDataRx , pQspiBuffer,  pBuffer.RxDataSize ); 
00633     memory_sync();
00634     QSPI_EndTransfer(pQspid->pQspiHw ) ;                   
00635     // End transmission after all data has been sent
00636     while(!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));             
00637     // poll CR reg to know status if instruction has end
00638     
00639     return Status;
00640 }
00641 
00642 /**
00643  * \brief Sends an instruction over QSPI and configures other related address
00644 *  like Addr , Frame and synchronise bus access before data read or write
00645  *
00646  * \param pQspi         Pointer to an Qspi instance.
00647  * \param KeepCfg       To keep Instruction from value or resets to zero
00648  * \param ScrambleFlag  Enable or disable scramble on QSPI
00649  *
00650  * \return Returns 1 if At least one instruction end has been detected since 
00651  * the last read of QSPI_SR.; otherwise returns 0.
00652  */
00653 QspidStatus_t QSPI_EnableMemAccess( Qspid_t *pQspid, uint8_t const KeepCfg, 
00654                                     uint8_t ScrambleFlag)
00655 {  
00656     QspiInstFrame_t* const pFrame = pQspid->pQspiFrame;
00657     QspiMemCmd_t  pCommand = pQspid->qspiCommand;
00658         
00659     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00660      
00661     QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), 
00662             (pCommand.Option & 0xFF) );
00663     
00664     if(ScrambleFlag) {
00665       QSPI_ScrambleData(pQspid->pQspiHw, SCRAMBLE_KEY, ScrambleFlag, 1);
00666     }
00667     
00668     QSPI_SetInstFrame(pQspid->pQspiHw, pFrame );
00669     
00670     QSPI_GetInstFrame(pQspid->pQspiHw);
00671     // to synchronize system bus accesses   
00672     if(!KeepCfg) {
00673       pFrame->InstFrame.val = 0;
00674     } 
00675     Status = QSPI_SUCCESS;
00676     return Status;
00677 }
00678 
00679 /**
00680  * \brief Writes or reads the QSPI memory (0x80000000) to transmit or 
00681  * receive data from Flash memory
00682  * \param pQspi         Pointer to an Qspi instance.
00683  * \param ReadWrite     Flag to indicate read/write QSPI memory access
00684  *
00685  * \return Returns 1 if At least one instruction end has been detected since 
00686  * the last read of QSPI_SR.; otherwise returns 0.
00687  */
00688 QspidStatus_t QSPI_ReadWriteMem( Qspid_t *pQspid, Access_t const ReadWrite)
00689 {  
00690     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00691     QspiInstFrame_t* const pFrame = pQspid->pQspiFrame;
00692     uint32_t *pQspiMem = (uint32_t *)( QSPIMEM_ADDR | pFrame->Addr);
00693     QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
00694     
00695     assert( ( (ReadWrite > CmdAccess) && (ReadWrite <= WriteAccess) ) ? true: false );
00696     if (ReadWrite == WriteAccess) {
00697       memcpy(pQspiMem, pBuffer.pDataTx , pBuffer.TxDataSize ); 
00698     } else {
00699       memcpy(pBuffer.pDataRx, pQspiMem, pBuffer.RxDataSize ); 
00700     }
00701     memory_sync();
00702     QSPI_EndTransfer(pQspid->pQspiHw ) ;
00703     // End transmission after all data has been sent
00704     while(!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
00705     // poll CR reg to know status if instruction has end
00706     
00707     Status = QSPI_SUCCESS;
00708     return Status;
00709 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines