SAMV71 Xplained Ultra Software Package 1.5

qspi.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
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,
00143                                         QspiInstFrame_t *pInstFrame)
00144 {
00145     assert(pQspi);
00146     pQspi->QSPI_IFR = pInstFrame->InstFrame.val;
00147 }
00148 
00149 /**
00150  * \brief Reads the Instruction frame of QSPI
00151  *
00152  * \param pQspi   Pointer to an Qspi instance.
00153  */
00154 __STATIC_INLINE uint32_t QSPI_GetInstFrame(Qspi *pQspi)
00155 {
00156     assert(pQspi);
00157     return pQspi->QSPI_IFR;
00158 }
00159 
00160 /**
00161  * \brief Read QSPI RDR register for SPI mode
00162  *
00163  * \param pQspi   Pointer to an Qspi instance.
00164  */
00165 __STATIC_INLINE uint16_t QSPI_ReadSPI(Qspi *pQspi)
00166 {
00167     assert(pQspi);
00168 
00169     while (!QSPI_GetStatus(pQspi, IsReceived));
00170 
00171     return  pQspi->QSPI_RDR;
00172 }
00173 
00174 
00175 /**
00176  * \brief Write to QSPI Tx register in SPI mode
00177  *
00178  * \param pQspi   Pointer to an Qspi instance.
00179  * \param wData   Data to transmit
00180  */
00181 __STATIC_INLINE void QSPI_WriteSPI(Qspi *pQspi, uint16_t wData)
00182 {
00183     assert(pQspi);
00184 
00185     /* Send data */
00186     while (!QSPI_GetStatus(pQspi, IsTxEmpty));
00187 
00188     pQspi->QSPI_TDR = wData;
00189 
00190     while (!QSPI_GetStatus(pQspi, IsTxSent));
00191 }
00192 
00193 /**
00194  * \brief Configures QSPI scrambling with a given Key
00195  *
00196  * \param pQspi         Pointer to an Qspi instance.
00197  * \param wKey          Key for scramble/unscramble
00198  * \param EnableFlag    Enable/disable scramble
00199  * \param Random        Add random value with given key
00200  */
00201 __STATIC_INLINE void QSPI_ScrambleData(Qspi *pQspi, uint32_t wKey,
00202                                         uint8_t EnableFlag, uint8_t Random)
00203 {
00204     assert(pQspi);
00205     assert(EnableFlag < 2);
00206     assert(Random < 2);
00207 
00208     if (EnableFlag)
00209         pQspi->QSPI_SKR = wKey;
00210 
00211     pQspi->QSPI_SMR = (EnableFlag | (Random << 1));
00212 }
00213 
00214 /*----------------------------------------------------------------------------
00215  *        Exported functions
00216  *----------------------------------------------------------------------------*/
00217 
00218 /**
00219  * \brief Enables a QSPI peripheral.
00220  *
00221  * \param pQspi  Pointer to a Qspi instance.
00222  */
00223 void QSPI_Enable(Qspi *pQspi)
00224 {
00225     assert(pQspi);
00226     pQspi->QSPI_CR = QSPI_CR_QSPIEN;
00227 
00228     while (!(pQspi->QSPI_SR & QSPI_SR_QSPIENS));
00229 }
00230 
00231 /**
00232  * \brief Disables a QSPI peripheral.
00233  *
00234  * \param pQspi  Pointer to a Qspi instance.
00235  */
00236 void QSPI_Disable(Qspi *pQspi)
00237 {
00238     assert(pQspi);
00239     pQspi->QSPI_CR = QSPI_CR_QSPIDIS;
00240 
00241     while (pQspi->QSPI_SR & QSPI_SR_QSPIENS);
00242 }
00243 
00244 /**
00245  * \brief Resets a QSPI peripheral.
00246  *
00247  * \param pQspi  Pointer to a Qspi instance.
00248  */
00249 void QSPI_SwReset(Qspi *pQspi)
00250 {
00251     assert(pQspi);
00252     pQspi->QSPI_CR = QSPI_CR_SWRST;
00253 }
00254 
00255 /**
00256  * \brief Enables one or more interrupt sources of a QSPI peripheral.
00257  *
00258  * \param pQspi  Pointer to a Qspi instance.
00259  * \param sources Bitwise OR of selected interrupt sources.
00260  */
00261 QspidStatus_t QSPI_EnableIt(Qspi *pQspi, uint32_t dwSources)
00262 {
00263     assert(pQspi);
00264     pQspi->QSPI_IER = dwSources;
00265     return QSPI_SUCCESS;
00266 }
00267 
00268 /**
00269  * \brief Disables one or more interrupt sources of a QSPI peripheral.
00270  *
00271  * \param pQspi  Pointer to a Qspi instance.
00272  * \param sources Bitwise OR of selected interrupt sources.
00273  */
00274 QspidStatus_t QSPI_DisableIt(Qspi *pQspi, uint32_t dwSources)
00275 {
00276     assert(pQspi);
00277     pQspi->QSPI_IDR = dwSources;
00278     return QSPI_SUCCESS;
00279 }
00280 
00281 /**
00282  * \brief Return the interrupt mask register.
00283  *
00284  * \return Qspi interrupt mask register.
00285  */
00286 uint32_t QSPI_GetItMask(Qspi *pQspi)
00287 {
00288     assert(pQspi);
00289     return (pQspi->QSPI_IMR);
00290 }
00291 
00292 /**
00293  * \brief Returns enabled interrupt status
00294  *
00295  * \return Qspi interrupt mask register.
00296  */
00297 uint32_t QSPI_GetEnabledItStatus(Qspi *pQspi)
00298 {
00299     assert(pQspi);
00300     return (pQspi->QSPI_IMR & QSPI_GetStatus(pQspi, (QspiStatus_t)0xFFFFFFFF));
00301 }
00302 
00303 /**
00304  * \brief Get the current status register of the given QSPI peripheral.
00305  * \note This resets the internal value of the status register, so further
00306  * read may yield different values.
00307  * \param pQspi   Pointer to a Qspi instance.
00308  * \param rStatus Compare status with given status bit
00309  * \return  QSPI status register.
00310  */
00311 uint32_t QSPI_GetStatus(Qspi *pQspi, const QspiStatus_t rStatus)
00312 {
00313     assert(pQspi);
00314     return (pQspi->QSPI_SR & rStatus);
00315 }
00316 
00317 /**
00318  * \brief Configures peripheral clock of a QSPI/SPI peripheral.
00319  *
00320  * \param pQspi   Pointer to an Qspi instance.
00321  * \param dwConfiguration  Desired clock configuration.
00322  */
00323 void QSPI_ConfigureClock(Qspi *pQspi, QspiClockMode_t ClockMode,
00324                           uint32_t dwClockCfg)
00325 {
00326     assert(pQspi);
00327     pQspi->QSPI_SCR = ClockMode;
00328     pQspi->QSPI_SCR |= dwClockCfg;
00329 }
00330 
00331 /**
00332  * \brief Configures QSPI/SPI
00333  *
00334  * \param pQspi             Pointer to an Qspi instance.
00335  * \param Mode              Mode for QSPI or SPI
00336  * \param dwConfiguration   Config of SPI or QSPI mode
00337  */
00338 QspidStatus_t QSPI_ConfigureInterface(Qspid_t *pQspid, QspiMode_t Mode,
00339                                        uint32_t dwConfiguration)
00340 {
00341     pQspid->pQspiHw = QSPI;
00342     pQspid->qspiId = ID_QSPI;
00343 
00344     QSPI_Disable(pQspid->pQspiHw);
00345     QSPI_SwReset(pQspid->pQspiHw);
00346 
00347     QSPI_ConfigureMode(pQspid->pQspiHw, Mode);
00348     QSPI_Configure(pQspid->pQspiHw, dwConfiguration);
00349 
00350     return QSPI_SUCCESS;
00351 }
00352 
00353 
00354 /**
00355  * \brief Ends ongoing transfer by releasing CS of QSPI peripheral.
00356  *
00357  * \param pQspi  Pointer to an Qspi instance.
00358  */
00359 QspidStatus_t QSPI_EndTransfer(Qspi *pQspi)
00360 {
00361     assert(pQspi);
00362 
00363     while (!QSPI_GetStatus(pQspi, IsTxEmpty));
00364 
00365     pQspi->QSPI_CR = QSPI_CR_LASTXFER;
00366 
00367     return QSPI_SUCCESS;
00368 }
00369 
00370 
00371 /*----------------------------------------------------------------------------
00372  *        SPI functions
00373  *----------------------------------------------------------------------------*/
00374 /**
00375  * \brief Reads the data received by a SPI peripheral. This
00376  * method must be called after a successful SPI_Write call.
00377  *
00378  * \param pQspid    Pointer to a Qspi instance.
00379  * \param pData     Buffer to put read value
00380  * \return Qspi status
00381  */
00382 QspidStatus_t QSPI_SingleReadSPI(Qspid_t *pQspid, uint16_t *const pData)
00383 {
00384     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00385     Qspi *pQspi = pQspid->pQspiHw;
00386     uint32_t NumOfAttempt = 0;
00387     uint16_t Dummy = 0xFF;
00388 
00389     for (;;) {
00390         if (QSPI_GetStatus(pQspi, IsReceived)) {
00391             *pData = QSPI_ReadSPI(pQspi);
00392             QSPI_WriteSPI(pQspi, Dummy);
00393             *pData = QSPI_ReadSPI(pQspi);
00394             NumOfAttempt = 0;
00395             Status = QSPI_SUCCESS;
00396         } else {
00397             if (NumOfAttempt > 0xFFFF) {
00398                 Status = QSPI_READ_ERROR;
00399                 TRACE_ERROR(" SPI Read Error \n\r");
00400                 break;
00401             } else {
00402                 Status = QSPI_READ_ERROR;
00403                 NumOfAttempt++;
00404             }
00405         }
00406     }
00407 
00408     return Status;
00409 }
00410 
00411 /**
00412  * \brief Reads multiple data received by a SPI peripheral. This
00413  * method must be called after a successful SPI_Write call.
00414  *
00415  * \param pQspid        Pointer to a Qspi instance.
00416  * \param pData         Pointer to read buffer
00417  * \param NumOfBytes    Num of bytes to read
00418  *
00419  * \return Qspi status
00420  */
00421 QspidStatus_t QSPI_MultiReadSPI(Qspid_t *pQspid, uint16_t *const pData,
00422                                  uint32_t NumOfBytes)
00423 {
00424     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00425     Qspi *pQspi = pQspid->pQspiHw;
00426     uint32_t NumOfBytesRead = 0;
00427     uint32_t NumOfAttempt = 0;
00428     uint8_t *pwData = (uint8_t *)pData;
00429     uint16_t Dummy = 0xFF;
00430 
00431     /* Dummy read  and write to discard  first bytes recvd and start
00432         receiving new data*/
00433     Dummy = QSPI_ReadSPI(pQspi);
00434     QSPI_WriteSPI(pQspi, Dummy);
00435 
00436     for (; NumOfBytesRead < NumOfBytes;) {
00437         if (QSPI_GetStatus(pQspi, IsTxSent)) {
00438             *pwData = QSPI_ReadSPI(pQspi);
00439 
00440             if (pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk)
00441                 pwData += sizeof(uint16_t);
00442             else
00443                 pwData += sizeof(uint8_t);
00444 
00445             NumOfBytesRead++;
00446             NumOfAttempt = 0;
00447             Status = QSPI_SUCCESS;
00448             QSPI_WriteSPI(pQspi, Dummy);
00449         } else {
00450             if (NumOfAttempt > 0xFFFF) {
00451                 Status = QSPI_READ_ERROR;
00452                 TRACE_ERROR(" SPI MultiRead Error \n\r");
00453                 break;
00454             } else {
00455                 Status = QSPI_READ_ERROR;
00456                 NumOfAttempt++;
00457             }
00458         }
00459     }
00460 
00461     return Status;
00462 }
00463 
00464 /**
00465  * \brief Sends a single data through a SPI peripheral.
00466  *
00467  * \param pQspid    Pointer to a Qspi instance.
00468  * \param pData     Pointer to Tx data
00469  *
00470  * \return Qspi status
00471  */
00472 QspidStatus_t QSPI_SingleWriteSPI(Qspid_t *pQspid, uint16_t const *pData)
00473 {
00474     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00475     Qspi *pQspi = pQspid->pQspiHw;
00476     uint32_t NumOfAttempt = 0;
00477 
00478     for (;;) {
00479         if (QSPI_GetStatus(pQspi, IsTxSent)) {
00480             QSPI_WriteSPI(pQspi, *pData);
00481             NumOfAttempt = 0;
00482             Status = QSPI_SUCCESS;
00483             break;
00484         } else {
00485             Status = QSPI_BUSY_SENDING;
00486             NumOfAttempt++;
00487 
00488             if (NumOfAttempt > 0xFFFF) {
00489                 Status = QSPI_WRITE_ERROR;
00490                 TRACE_ERROR(" SPI Write Error \n\r");
00491                 break;
00492             }
00493         }
00494     }
00495 
00496     return Status;
00497 
00498 }
00499 
00500 /**
00501  * \brief Sends multiple data through a SPI peripheral.
00502  *
00503  * \param pQspid        Pointer to a Qspi instance.
00504  * \param pData         Pointer to a Tx buffer
00505  * \param NumOfBytes    Num of data to send.
00506  */
00507 QspidStatus_t QSPI_MultiWriteSPI(Qspid_t *pQspid, uint16_t const *pData,
00508                                   uint32_t NumOfBytes)
00509 {
00510     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00511     Qspi *pQspi = pQspid->pQspiHw;
00512     uint32_t NumOfBytesWrite = 0;
00513     uint32_t NumOfAttempt = 0;
00514     uint8_t *pwData = (uint8_t *)pData;
00515     uint8_t Addr_Inc = 0;
00516 
00517     if (pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk)
00518         Addr_Inc = sizeof(uint16_t);
00519     else
00520         Addr_Inc = sizeof(uint8_t);
00521 
00522     for (; NumOfBytesWrite < NumOfBytes;) {
00523         if (QSPI_GetStatus(pQspi, IsTxEmpty)) {
00524             QSPI_WriteSPI(pQspi, (uint16_t)*pwData);
00525             pwData += Addr_Inc;
00526             NumOfBytesWrite++;
00527             NumOfAttempt = 0;
00528             Status = QSPI_SUCCESS;
00529         } else {
00530             Status = QSPI_BUSY_SENDING;
00531             NumOfAttempt++;
00532 
00533             if (NumOfAttempt > 0xFFFF) {
00534                 Status = QSPI_WRITE_ERROR;
00535                 TRACE_ERROR(" SPI Multi Write Error \n\r");
00536                 break;
00537             }
00538         }
00539     }
00540 
00541     return Status;
00542 
00543 }
00544 
00545 /*----------------------------------------------------------------------------
00546  *        QSPI functions
00547  *----------------------------------------------------------------------------*/
00548 
00549 /**
00550  * \brief Send an instruction over QSPI (oly a flash command no data)
00551  *
00552  * \param pQspi     Pointer to an Qspi instance.
00553  * \param KeepCfg   To keep Instruction fram value or restes to zero
00554  *
00555  * \return Returns 1 if At least one instruction end has been detected since
00556  * the last read of QSPI_SR.; otherwise
00557  * returns 0.
00558  */
00559 QspidStatus_t QSPI_SendCommand(Qspid_t *pQspid, uint8_t const KeepCfg)
00560 {
00561     QspiInstFrame_t  *const pFrame = pQspid->pQspiFrame;
00562     QspiMemCmd_t  pCommand = pQspid->qspiCommand;
00563     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00564 
00565     if (pFrame->InstFrame.bm.bAddrEn)
00566         QSPI_SetInstAddr(pQspid->pQspiHw, pFrame->Addr);
00567 
00568     QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
00569                  ((pCommand.Option >> QSPI_ICR_OPT_Pos) & 0xFF));
00570     QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
00571 
00572     memory_sync();
00573 
00574     while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
00575 
00576     // poll CR reg to know status if instruction has end
00577     if (!KeepCfg)
00578         pFrame->InstFrame.val = 0;
00579 
00580     return Status;
00581 }
00582 
00583 
00584 
00585 /**
00586  * \brief Send instruction over QSPI with data
00587  *
00588  * \param pQspi     Pointer to an Qspi instance.
00589  * \param KeepCfg   To keep Instruction fram value or restes to zero
00590  *
00591  * \return Returns 1 if At least one instruction end has been detected
00592  *  since the last read of QSPI_SR.; otherwise returns 0.
00593  */
00594 QspidStatus_t QSPI_SendCommandWithData(Qspid_t *pQspid, uint8_t const KeepCfg)
00595 {
00596     QspiInstFrame_t *const  pFrame = pQspid->pQspiFrame;
00597     QspiMemCmd_t  pCommand = pQspid->qspiCommand;
00598     QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
00599     uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR;
00600     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00601 
00602     //assert(pBuffer.pDataRx);
00603     assert(pBuffer.pDataTx);
00604 
00605     QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
00606                  (pCommand.Option & 0xFF));
00607     QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
00608 
00609     QSPI_GetInstFrame(pQspid->pQspiHw);
00610 
00611     // to synchronize system bus accesses
00612     if (!KeepCfg)
00613         pFrame->InstFrame.val = 0;
00614 
00615     memcpy(pQspiBuffer  , pBuffer.pDataTx ,  pBuffer.TxDataSize);
00616     memory_sync();
00617     QSPI_EndTransfer(pQspid->pQspiHw);
00618 
00619     // End transmission after all data has been sent
00620     while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
00621 
00622     // poll CR reg to know status if instruction has end
00623 
00624     return Status;
00625 }
00626 
00627 /**
00628  * \brief Send instruction over QSPI to read data
00629  *
00630  * \param pQspi     Pointer to an Qspi instance.
00631  * \param KeepCfg   To keep Instruction from value or resets to zero
00632  *
00633  * \return Returns 1 if At least one instruction end has been detected
00634  * since the last read of QSPI_SR.; otherwise returns 0.
00635  */
00636 QspidStatus_t QSPI_ReadCommand(Qspid_t *pQspid, uint8_t const KeepCfg)
00637 {
00638     QspiInstFrame_t *const  pFrame = pQspid->pQspiFrame;
00639     QspiMemCmd_t  pCommand = pQspid->qspiCommand;
00640     QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
00641     uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR;
00642     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00643 
00644     assert(pBuffer.pDataRx);
00645 
00646     QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
00647                  (pCommand.Option & 0xFF));
00648     QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
00649 
00650     QSPI_GetInstFrame(pQspid->pQspiHw);
00651 
00652     // to synchronize system bus accesses
00653     if (!KeepCfg)
00654         pFrame->InstFrame.val = 0;
00655 
00656     memcpy(pBuffer.pDataRx , pQspiBuffer,  pBuffer.RxDataSize);
00657     memory_sync();
00658     QSPI_EndTransfer(pQspid->pQspiHw);
00659 
00660     // End transmission after all data has been sent
00661     while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
00662 
00663     // poll CR reg to know status if instruction has end
00664 
00665     return Status;
00666 }
00667 
00668 /**
00669  * \brief Sends an instruction over QSPI and configures other related address
00670 *  like Addr , Frame and synchronise bus access before data read or write
00671  *
00672  * \param pQspi         Pointer to an Qspi instance.
00673  * \param KeepCfg       To keep Instruction from value or resets to zero
00674  * \param ScrambleFlag  Enable or disable scramble on QSPI
00675  *
00676  * \return Returns 1 if At least one instruction end has been detected since
00677  * the last read of QSPI_SR.; otherwise returns 0.
00678  */
00679 QspidStatus_t QSPI_EnableMemAccess(Qspid_t *pQspid, uint8_t const KeepCfg,
00680                                     uint8_t ScrambleFlag)
00681 {
00682     QspiInstFrame_t *const pFrame = pQspid->pQspiFrame;
00683     QspiMemCmd_t  pCommand = pQspid->qspiCommand;
00684 
00685     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00686 
00687     QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
00688                  (pCommand.Option & 0xFF));
00689 
00690     if (ScrambleFlag)
00691         QSPI_ScrambleData(pQspid->pQspiHw, SCRAMBLE_KEY, ScrambleFlag, 1);
00692 
00693     QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
00694 
00695     QSPI_GetInstFrame(pQspid->pQspiHw);
00696 
00697     // to synchronize system bus accesses
00698     if (!KeepCfg)
00699         pFrame->InstFrame.val = 0;
00700 
00701     Status = QSPI_SUCCESS;
00702     return Status;
00703 }
00704 
00705 /**
00706  * \brief Writes or reads the QSPI memory (0x80000000) to transmit or
00707  * receive data from Flash memory
00708  * \param pQspi         Pointer to an Qspi instance.
00709  * \param ReadWrite     Flag to indicate read/write QSPI memory access
00710  *
00711  * \return Returns 1 if At least one instruction end has been detected since
00712  * the last read of QSPI_SR.; otherwise returns 0.
00713  */
00714 QspidStatus_t QSPI_ReadWriteMem(Qspid_t *pQspid, Access_t const ReadWrite)
00715 {
00716     QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
00717     QspiInstFrame_t *const pFrame = pQspid->pQspiFrame;
00718     uint32_t *pQspiMem = (uint32_t *)(QSPIMEM_ADDR | pFrame->Addr);
00719     QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
00720 
00721     assert(((ReadWrite > CmdAccess)
00722               && (ReadWrite <= WriteAccess)) ? true : false);
00723 
00724     if (ReadWrite == WriteAccess)
00725         memcpy(pQspiMem, pBuffer.pDataTx , pBuffer.TxDataSize);
00726     else
00727         memcpy(pBuffer.pDataRx, pQspiMem, pBuffer.RxDataSize);
00728 
00729     memory_sync();
00730     QSPI_EndTransfer(pQspid->pQspiHw);
00731 
00732     // End transmission after all data has been sent
00733     while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
00734 
00735     // poll CR reg to know status if instruction has end
00736 
00737     Status = QSPI_SUCCESS;
00738     return Status;
00739 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines