diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libbsp/arm/atsam/libraries/libchip/source/qspi.c | 739 |
1 files changed, 739 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/qspi.c b/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/qspi.c new file mode 100644 index 0000000000..e279ff9da5 --- /dev/null +++ b/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/qspi.c @@ -0,0 +1,739 @@ +/* ---------------------------------------------------------------------------- */ +/* Atmel Microcontroller Software Support */ +/* SAM Software Package License */ +/* ---------------------------------------------------------------------------- */ +/* Copyright (c) 2015, Atmel Corporation */ +/* */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following condition is met: */ +/* */ +/* - Redistributions of source code must retain the above copyright notice, */ +/* this list of conditions and the disclaimer below. */ +/* */ +/* Atmel's name may not be used to endorse or promote products derived from */ +/* this software without specific prior written permission. */ +/* */ +/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ +/* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ +/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ +/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ +/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ +/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* ---------------------------------------------------------------------------- */ + +/** \addtogroup qspi_module Working with QSPI + * \ingroup peripherals_module + * The QSPI driver provides the interface to configure and use the QSPI + * peripheral. + * + * The Serial Peripheral Interface (QSPI) circuit is a synchronous serial + * data link that provides communication with external devices in Master + * or Slave Mode. + * + * To use the QSPI, the user has to follow these few steps: + * -# Enable the QSPI pins required by the application (see pio.h). + * -# Configure the QSPI using the \ref QSPI_Configure(). This enables the + * peripheral clock. The mode register is loaded with the given value. + * -# Configure all the necessary chip selects with \ref QSPI_ConfigureNPCS(). + * -# Enable the QSPI by calling \ref QSPI_Enable(). + * -# Send/receive data using \ref QSPI_Write() and \ref QSPI_Read(). Note that +* \ref QSPI_Read() + * must be called after \ref QSPI_Write() to retrieve the last value read. + * -# Send/receive data using the PDC with the \ref QSPI_WriteBuffer() and + * \ref QSPI_ReadBuffer() functions. + * -# Disable the QSPI by calling \ref QSPI_Disable(). + * + * For more accurate information, please look at the QSPI section of the + * Datasheet. + * + * Related files :\n + * \ref qspi.c\n + * \ref qspi.h.\n + */ +/*@{*/ +/*@}*/ + +/** + * \file + * + * Implementation of Serial Peripheral Interface (QSPI) controller. + * + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "chip.h" +#include "stdlib.h" +#include "string.h" + +#include <stdint.h> + + +#define SCRAMBLE_KEY 0x0BADDEAD +/*---------------------------------------------------------------------------- + * Internal functions + *----------------------------------------------------------------------------*/ + + + +/** + * \brief Configure QSPI/SPI mode + * + * \param pQspi Pointer to a Qspi instance. + */ +__STATIC_INLINE void QSPI_ConfigureMode(Qspi *pQspi, uint8_t dMode) +{ + assert(pQspi); + pQspi->QSPI_MR = dMode; +} + +/** + * \brief Configure mode register of QSPI + * + * \param pQspi Pointer to a Qspi instance. + */ +__STATIC_INLINE void QSPI_Configure(Qspi *pQspi, uint32_t dwConfiguration) +{ + assert(pQspi); + pQspi->QSPI_MR |= dwConfiguration; +} + + +/** + * \brief Configures a instruction address for QSPI in QSPI mode + * + * \param pQspi Pointer to a Qspi instance. + * \param dwAddr Instruction Address + */ +__STATIC_INLINE void QSPI_SetInstAddr(Qspi *pQspi, uint32_t dwAddr) +{ + assert(pQspi); + pQspi->QSPI_IAR = dwAddr; +} + + +/** + * \brief Configures instruction register with a given command for QSPI + * + * \param pQspi Pointer to a Qspi instance. + * \param dwInst Instruction Code + * \param dwOpt Instruction Code option + */ +__STATIC_INLINE void QSPI_SetInst(Qspi *pQspi, uint8_t dwInst, uint8_t dwOpt) +{ + assert(pQspi); + pQspi->QSPI_ICR = (dwInst | QSPI_ICR_OPT(dwOpt)); +} + +/** + * \brief Configures instruction frame register of QSPI + * + * \param pQspi Pointer to a Qspi instance. + * \param pInstFrame Instruction Frame configuration + */ +__STATIC_INLINE void QSPI_SetInstFrame(Qspi *pQspi, + QspiInstFrame_t *pInstFrame) +{ + assert(pQspi); + pQspi->QSPI_IFR = pInstFrame->InstFrame.val; +} + +/** + * \brief Reads the Instruction frame of QSPI + * + * \param pQspi Pointer to an Qspi instance. + */ +__STATIC_INLINE uint32_t QSPI_GetInstFrame(Qspi *pQspi) +{ + assert(pQspi); + return pQspi->QSPI_IFR; +} + +/** + * \brief Read QSPI RDR register for SPI mode + * + * \param pQspi Pointer to an Qspi instance. + */ +__STATIC_INLINE uint16_t QSPI_ReadSPI(Qspi *pQspi) +{ + assert(pQspi); + + while (!QSPI_GetStatus(pQspi, IsReceived)); + + return pQspi->QSPI_RDR; +} + + +/** + * \brief Write to QSPI Tx register in SPI mode + * + * \param pQspi Pointer to an Qspi instance. + * \param wData Data to transmit + */ +__STATIC_INLINE void QSPI_WriteSPI(Qspi *pQspi, uint16_t wData) +{ + assert(pQspi); + + /* Send data */ + while (!QSPI_GetStatus(pQspi, IsTxEmpty)); + + pQspi->QSPI_TDR = wData; + + while (!QSPI_GetStatus(pQspi, IsTxSent)); +} + +/** + * \brief Configures QSPI scrambling with a given Key + * + * \param pQspi Pointer to an Qspi instance. + * \param wKey Key for scramble/unscramble + * \param EnableFlag Enable/disable scramble + * \param Random Add random value with given key + */ +__STATIC_INLINE void QSPI_ScrambleData(Qspi *pQspi, uint32_t wKey, + uint8_t EnableFlag, uint8_t Random) +{ + assert(pQspi); + assert(EnableFlag < 2); + assert(Random < 2); + + if (EnableFlag) + pQspi->QSPI_SKR = wKey; + + pQspi->QSPI_SMR = (EnableFlag | (Random << 1)); +} + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ + +/** + * \brief Enables a QSPI peripheral. + * + * \param pQspi Pointer to a Qspi instance. + */ +void QSPI_Enable(Qspi *pQspi) +{ + assert(pQspi); + pQspi->QSPI_CR = QSPI_CR_QSPIEN; + + while (!(pQspi->QSPI_SR & QSPI_SR_QSPIENS)); +} + +/** + * \brief Disables a QSPI peripheral. + * + * \param pQspi Pointer to a Qspi instance. + */ +void QSPI_Disable(Qspi *pQspi) +{ + assert(pQspi); + pQspi->QSPI_CR = QSPI_CR_QSPIDIS; + + while (pQspi->QSPI_SR & QSPI_SR_QSPIENS); +} + +/** + * \brief Resets a QSPI peripheral. + * + * \param pQspi Pointer to a Qspi instance. + */ +void QSPI_SwReset(Qspi *pQspi) +{ + assert(pQspi); + pQspi->QSPI_CR = QSPI_CR_SWRST; +} + +/** + * \brief Enables one or more interrupt sources of a QSPI peripheral. + * + * \param pQspi Pointer to a Qspi instance. + * \param sources Bitwise OR of selected interrupt sources. + */ +QspidStatus_t QSPI_EnableIt(Qspi *pQspi, uint32_t dwSources) +{ + assert(pQspi); + pQspi->QSPI_IER = dwSources; + return QSPI_SUCCESS; +} + +/** + * \brief Disables one or more interrupt sources of a QSPI peripheral. + * + * \param pQspi Pointer to a Qspi instance. + * \param sources Bitwise OR of selected interrupt sources. + */ +QspidStatus_t QSPI_DisableIt(Qspi *pQspi, uint32_t dwSources) +{ + assert(pQspi); + pQspi->QSPI_IDR = dwSources; + return QSPI_SUCCESS; +} + +/** + * \brief Return the interrupt mask register. + * + * \return Qspi interrupt mask register. + */ +uint32_t QSPI_GetItMask(Qspi *pQspi) +{ + assert(pQspi); + return (pQspi->QSPI_IMR); +} + +/** + * \brief Returns enabled interrupt status + * + * \return Qspi interrupt mask register. + */ +uint32_t QSPI_GetEnabledItStatus(Qspi *pQspi) +{ + assert(pQspi); + return (pQspi->QSPI_IMR & QSPI_GetStatus(pQspi, (QspiStatus_t)0xFFFFFFFF)); +} + +/** + * \brief Get the current status register of the given QSPI peripheral. + * \note This resets the internal value of the status register, so further + * read may yield different values. + * \param pQspi Pointer to a Qspi instance. + * \param rStatus Compare status with given status bit + * \return QSPI status register. + */ +uint32_t QSPI_GetStatus(Qspi *pQspi, const QspiStatus_t rStatus) +{ + assert(pQspi); + return (pQspi->QSPI_SR & rStatus); +} + +/** + * \brief Configures peripheral clock of a QSPI/SPI peripheral. + * + * \param pQspi Pointer to an Qspi instance. + * \param dwConfiguration Desired clock configuration. + */ +void QSPI_ConfigureClock(Qspi *pQspi, QspiClockMode_t ClockMode, + uint32_t dwClockCfg) +{ + assert(pQspi); + pQspi->QSPI_SCR = ClockMode; + pQspi->QSPI_SCR |= dwClockCfg; +} + +/** + * \brief Configures QSPI/SPI + * + * \param pQspi Pointer to an Qspi instance. + * \param Mode Mode for QSPI or SPI + * \param dwConfiguration Config of SPI or QSPI mode + */ +QspidStatus_t QSPI_ConfigureInterface(Qspid_t *pQspid, QspiMode_t Mode, + uint32_t dwConfiguration) +{ + pQspid->pQspiHw = QSPI; + pQspid->qspiId = ID_QSPI; + + QSPI_Disable(pQspid->pQspiHw); + QSPI_SwReset(pQspid->pQspiHw); + + QSPI_ConfigureMode(pQspid->pQspiHw, Mode); + QSPI_Configure(pQspid->pQspiHw, dwConfiguration); + + return QSPI_SUCCESS; +} + + +/** + * \brief Ends ongoing transfer by releasing CS of QSPI peripheral. + * + * \param pQspi Pointer to an Qspi instance. + */ +QspidStatus_t QSPI_EndTransfer(Qspi *pQspi) +{ + assert(pQspi); + + while (!QSPI_GetStatus(pQspi, IsTxEmpty)); + + pQspi->QSPI_CR = QSPI_CR_LASTXFER; + + return QSPI_SUCCESS; +} + + +/*---------------------------------------------------------------------------- + * SPI functions + *----------------------------------------------------------------------------*/ +/** + * \brief Reads the data received by a SPI peripheral. This + * method must be called after a successful SPI_Write call. + * + * \param pQspid Pointer to a Qspi instance. + * \param pData Buffer to put read value + * \return Qspi status + */ +QspidStatus_t QSPI_SingleReadSPI(Qspid_t *pQspid, uint16_t *const pData) +{ + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + Qspi *pQspi = pQspid->pQspiHw; + uint32_t NumOfAttempt = 0; + uint16_t Dummy = 0xFF; + + for (;;) { + if (QSPI_GetStatus(pQspi, IsReceived)) { + *pData = QSPI_ReadSPI(pQspi); + QSPI_WriteSPI(pQspi, Dummy); + *pData = QSPI_ReadSPI(pQspi); + NumOfAttempt = 0; + Status = QSPI_SUCCESS; + } else { + if (NumOfAttempt > 0xFFFF) { + Status = QSPI_READ_ERROR; + TRACE_ERROR(" SPI Read Error \n\r"); + break; + } else { + Status = QSPI_READ_ERROR; + NumOfAttempt++; + } + } + } + + return Status; +} + +/** + * \brief Reads multiple data received by a SPI peripheral. This + * method must be called after a successful SPI_Write call. + * + * \param pQspid Pointer to a Qspi instance. + * \param pData Pointer to read buffer + * \param NumOfBytes Num of bytes to read + * + * \return Qspi status + */ +QspidStatus_t QSPI_MultiReadSPI(Qspid_t *pQspid, uint16_t *const pData, + uint32_t NumOfBytes) +{ + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + Qspi *pQspi = pQspid->pQspiHw; + uint32_t NumOfBytesRead = 0; + uint32_t NumOfAttempt = 0; + uint8_t *pwData = (uint8_t *)pData; + uint16_t Dummy = 0xFF; + + /* Dummy read and write to discard first bytes recvd and start + receiving new data*/ + Dummy = QSPI_ReadSPI(pQspi); + QSPI_WriteSPI(pQspi, Dummy); + + for (; NumOfBytesRead < NumOfBytes;) { + if (QSPI_GetStatus(pQspi, IsTxSent)) { + *pwData = QSPI_ReadSPI(pQspi); + + if (pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk) + pwData += sizeof(uint16_t); + else + pwData += sizeof(uint8_t); + + NumOfBytesRead++; + NumOfAttempt = 0; + Status = QSPI_SUCCESS; + QSPI_WriteSPI(pQspi, Dummy); + } else { + if (NumOfAttempt > 0xFFFF) { + Status = QSPI_READ_ERROR; + TRACE_ERROR(" SPI MultiRead Error \n\r"); + break; + } else { + Status = QSPI_READ_ERROR; + NumOfAttempt++; + } + } + } + + return Status; +} + +/** + * \brief Sends a single data through a SPI peripheral. + * + * \param pQspid Pointer to a Qspi instance. + * \param pData Pointer to Tx data + * + * \return Qspi status + */ +QspidStatus_t QSPI_SingleWriteSPI(Qspid_t *pQspid, uint16_t const *pData) +{ + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + Qspi *pQspi = pQspid->pQspiHw; + uint32_t NumOfAttempt = 0; + + for (;;) { + if (QSPI_GetStatus(pQspi, IsTxSent)) { + QSPI_WriteSPI(pQspi, *pData); + NumOfAttempt = 0; + Status = QSPI_SUCCESS; + break; + } else { + Status = QSPI_BUSY_SENDING; + NumOfAttempt++; + + if (NumOfAttempt > 0xFFFF) { + Status = QSPI_WRITE_ERROR; + TRACE_ERROR(" SPI Write Error \n\r"); + break; + } + } + } + + return Status; + +} + +/** + * \brief Sends multiple data through a SPI peripheral. + * + * \param pQspid Pointer to a Qspi instance. + * \param pData Pointer to a Tx buffer + * \param NumOfBytes Num of data to send. + */ +QspidStatus_t QSPI_MultiWriteSPI(Qspid_t *pQspid, uint16_t const *pData, + uint32_t NumOfBytes) +{ + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + Qspi *pQspi = pQspid->pQspiHw; + uint32_t NumOfBytesWrite = 0; + uint32_t NumOfAttempt = 0; + uint8_t *pwData = (uint8_t *)pData; + uint8_t Addr_Inc = 0; + + if (pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk) + Addr_Inc = sizeof(uint16_t); + else + Addr_Inc = sizeof(uint8_t); + + for (; NumOfBytesWrite < NumOfBytes;) { + if (QSPI_GetStatus(pQspi, IsTxEmpty)) { + QSPI_WriteSPI(pQspi, (uint16_t)*pwData); + pwData += Addr_Inc; + NumOfBytesWrite++; + NumOfAttempt = 0; + Status = QSPI_SUCCESS; + } else { + Status = QSPI_BUSY_SENDING; + NumOfAttempt++; + + if (NumOfAttempt > 0xFFFF) { + Status = QSPI_WRITE_ERROR; + TRACE_ERROR(" SPI Multi Write Error \n\r"); + break; + } + } + } + + return Status; + +} + +/*---------------------------------------------------------------------------- + * QSPI functions + *----------------------------------------------------------------------------*/ + +/** + * \brief Send an instruction over QSPI (oly a flash command no data) + * + * \param pQspi Pointer to an Qspi instance. + * \param KeepCfg To keep Instruction fram value or restes to zero + * + * \return Returns 1 if At least one instruction end has been detected since + * the last read of QSPI_SR.; otherwise + * returns 0. + */ +QspidStatus_t QSPI_SendCommand(Qspid_t *pQspid, uint8_t const KeepCfg) +{ + QspiInstFrame_t *const pFrame = pQspid->pQspiFrame; + QspiMemCmd_t pCommand = pQspid->qspiCommand; + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + + if (pFrame->InstFrame.bm.bAddrEn) + QSPI_SetInstAddr(pQspid->pQspiHw, pFrame->Addr); + + QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), + ((pCommand.Option >> QSPI_ICR_OPT_Pos) & 0xFF)); + QSPI_SetInstFrame(pQspid->pQspiHw, pFrame); + + memory_sync(); + + while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE)); + + // poll CR reg to know status if instruction has end + if (!KeepCfg) + pFrame->InstFrame.val = 0; + + return Status; +} + + + +/** + * \brief Send instruction over QSPI with data + * + * \param pQspi Pointer to an Qspi instance. + * \param KeepCfg To keep Instruction fram value or restes to zero + * + * \return Returns 1 if At least one instruction end has been detected + * since the last read of QSPI_SR.; otherwise returns 0. + */ +QspidStatus_t QSPI_SendCommandWithData(Qspid_t *pQspid, uint8_t const KeepCfg) +{ + QspiInstFrame_t *const pFrame = pQspid->pQspiFrame; + QspiMemCmd_t pCommand = pQspid->qspiCommand; + QspiBuffer_t pBuffer = pQspid->qspiBuffer; + uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR; + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + + //assert(pBuffer.pDataRx); + assert(pBuffer.pDataTx); + + QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), + (pCommand.Option & 0xFF)); + QSPI_SetInstFrame(pQspid->pQspiHw, pFrame); + + QSPI_GetInstFrame(pQspid->pQspiHw); + + // to synchronize system bus accesses + if (!KeepCfg) + pFrame->InstFrame.val = 0; + + memcpy(pQspiBuffer , pBuffer.pDataTx , pBuffer.TxDataSize); + memory_sync(); + QSPI_EndTransfer(pQspid->pQspiHw); + + // End transmission after all data has been sent + while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE)); + + // poll CR reg to know status if instruction has end + + return Status; +} + +/** + * \brief Send instruction over QSPI to read data + * + * \param pQspi Pointer to an Qspi instance. + * \param KeepCfg To keep Instruction from value or resets to zero + * + * \return Returns 1 if At least one instruction end has been detected + * since the last read of QSPI_SR.; otherwise returns 0. + */ +QspidStatus_t QSPI_ReadCommand(Qspid_t *pQspid, uint8_t const KeepCfg) +{ + QspiInstFrame_t *const pFrame = pQspid->pQspiFrame; + QspiMemCmd_t pCommand = pQspid->qspiCommand; + QspiBuffer_t pBuffer = pQspid->qspiBuffer; + uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR; + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + + assert(pBuffer.pDataRx); + + QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), + (pCommand.Option & 0xFF)); + QSPI_SetInstFrame(pQspid->pQspiHw, pFrame); + + QSPI_GetInstFrame(pQspid->pQspiHw); + + // to synchronize system bus accesses + if (!KeepCfg) + pFrame->InstFrame.val = 0; + + memcpy(pBuffer.pDataRx , pQspiBuffer, pBuffer.RxDataSize); + memory_sync(); + QSPI_EndTransfer(pQspid->pQspiHw); + + // End transmission after all data has been sent + while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE)); + + // poll CR reg to know status if instruction has end + + return Status; +} + +/** + * \brief Sends an instruction over QSPI and configures other related address +* like Addr , Frame and synchronise bus access before data read or write + * + * \param pQspi Pointer to an Qspi instance. + * \param KeepCfg To keep Instruction from value or resets to zero + * \param ScrambleFlag Enable or disable scramble on QSPI + * + * \return Returns 1 if At least one instruction end has been detected since + * the last read of QSPI_SR.; otherwise returns 0. + */ +QspidStatus_t QSPI_EnableMemAccess(Qspid_t *pQspid, uint8_t const KeepCfg, + uint8_t ScrambleFlag) +{ + QspiInstFrame_t *const pFrame = pQspid->pQspiFrame; + QspiMemCmd_t pCommand = pQspid->qspiCommand; + + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + + QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), + (pCommand.Option & 0xFF)); + + if (ScrambleFlag) + QSPI_ScrambleData(pQspid->pQspiHw, SCRAMBLE_KEY, ScrambleFlag, 1); + + QSPI_SetInstFrame(pQspid->pQspiHw, pFrame); + + QSPI_GetInstFrame(pQspid->pQspiHw); + + // to synchronize system bus accesses + if (!KeepCfg) + pFrame->InstFrame.val = 0; + + Status = QSPI_SUCCESS; + return Status; +} + +/** + * \brief Writes or reads the QSPI memory (0x80000000) to transmit or + * receive data from Flash memory + * \param pQspi Pointer to an Qspi instance. + * \param ReadWrite Flag to indicate read/write QSPI memory access + * + * \return Returns 1 if At least one instruction end has been detected since + * the last read of QSPI_SR.; otherwise returns 0. + */ +QspidStatus_t QSPI_ReadWriteMem(Qspid_t *pQspid, Access_t const ReadWrite) +{ + QspidStatus_t Status = QSPI_UNKNOWN_ERROR; + QspiInstFrame_t *const pFrame = pQspid->pQspiFrame; + uint32_t *pQspiMem = (uint32_t *)(QSPIMEM_ADDR | pFrame->Addr); + QspiBuffer_t pBuffer = pQspid->qspiBuffer; + + assert(((ReadWrite > CmdAccess) + && (ReadWrite <= WriteAccess)) ? true : false); + + if (ReadWrite == WriteAccess) + memcpy(pQspiMem, pBuffer.pDataTx , pBuffer.TxDataSize); + else + memcpy(pBuffer.pDataRx, pQspiMem, pBuffer.RxDataSize); + + memory_sync(); + QSPI_EndTransfer(pQspid->pQspiHw); + + // End transmission after all data has been sent + while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE)); + + // poll CR reg to know status if instruction has end + + Status = QSPI_SUCCESS; + return Status; +} |