source: rtems/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/qspi.c @ e1eeb883

5
Last change on this file since e1eeb883 was e1eeb883, checked in by Sebastian Huber <sebastian.huber@…>, on 01/12/16 at 14:34:31

bsp/atsam: Import SAM Software Package

Import selected files of the "SAM V71 / V70 / E70 / S70 Software
Package" obtained from the "SAMV71-XULT GNU Software Package 1.5".

Converted files via dos2unix before import.

Update #2529.

  • Property mode set to 100644
File size: 20.1 KB
Line 
1/* ---------------------------------------------------------------------------- */
2/*                  Atmel Microcontroller Software Support                      */
3/*                       SAM Software Package License                           */
4/* ---------------------------------------------------------------------------- */
5/* Copyright (c) 2015, Atmel Corporation                                        */
6/*                                                                              */
7/* All rights reserved.                                                         */
8/*                                                                              */
9/* Redistribution and use in source and binary forms, with or without           */
10/* modification, are permitted provided that the following condition is met:    */
11/*                                                                              */
12/* - Redistributions of source code must retain the above copyright notice,     */
13/* this list of conditions and the disclaimer below.                            */
14/*                                                                              */
15/* Atmel's name may not be used to endorse or promote products derived from     */
16/* this software without specific prior written permission.                     */
17/*                                                                              */
18/* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
19/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
20/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
21/* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
22/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
23/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
24/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
25/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
26/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
27/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
28/* ---------------------------------------------------------------------------- */
29
30/** \addtogroup qspi_module Working with QSPI
31 * \ingroup peripherals_module
32 * The QSPI driver provides the interface to configure and use the QSPI
33 * peripheral.
34 *
35 * The Serial Peripheral Interface (QSPI) circuit is a synchronous serial
36 * data link that provides communication with external devices in Master
37 * or Slave Mode.
38 *
39 * To use the QSPI, the user has to follow these few steps:
40 * -# Enable the QSPI pins required by the application (see pio.h).
41 * -# Configure the QSPI using the \ref QSPI_Configure(). This enables the
42 *    peripheral clock. The mode register is loaded with the given value.
43 * -# Configure all the necessary chip selects with \ref QSPI_ConfigureNPCS().
44 * -# Enable the QSPI by calling \ref QSPI_Enable().
45 * -# Send/receive data using \ref QSPI_Write() and \ref QSPI_Read(). Note that
46*  \ref QSPI_Read()
47 *    must be called after \ref QSPI_Write() to retrieve the last value read.
48 * -# Send/receive data using the PDC with the \ref QSPI_WriteBuffer() and
49 *    \ref QSPI_ReadBuffer() functions.
50 * -# Disable the QSPI by calling \ref QSPI_Disable().
51 *
52 * For more accurate information, please look at the QSPI section of the
53 * Datasheet.
54 *
55 * Related files :\n
56 * \ref qspi.c\n
57 * \ref qspi.h.\n
58 */
59/*@{*/
60/*@}*/
61
62/**
63 * \file
64 *
65 * Implementation of Serial Peripheral Interface (QSPI) controller.
66 *
67 */
68
69/*----------------------------------------------------------------------------
70 *        Headers
71 *----------------------------------------------------------------------------*/
72
73#include "chip.h"
74#include "stdlib.h"
75#include "string.h"
76
77#include <stdint.h>
78
79
80#define SCRAMBLE_KEY    0x0BADDEAD
81/*----------------------------------------------------------------------------
82 *        Internal functions
83 *----------------------------------------------------------------------------*/
84
85
86
87/**
88 * \brief Configure QSPI/SPI mode
89 *
90 * \param pQspi  Pointer to a Qspi instance.
91 */
92__STATIC_INLINE void QSPI_ConfigureMode(Qspi *pQspi, uint8_t dMode)
93{
94        assert(pQspi);
95        pQspi->QSPI_MR =  dMode;
96}
97
98/**
99 * \brief Configure mode register of QSPI
100 *
101 * \param pQspi  Pointer to a Qspi instance.
102 */
103__STATIC_INLINE void QSPI_Configure(Qspi *pQspi, uint32_t dwConfiguration)
104{
105        assert(pQspi);
106        pQspi->QSPI_MR |=  dwConfiguration;
107}
108
109
110/**
111 * \brief Configures a instruction address for QSPI in QSPI mode
112 *
113 * \param pQspi   Pointer to a Qspi instance.
114 * \param dwAddr  Instruction Address
115 */
116__STATIC_INLINE void QSPI_SetInstAddr(Qspi *pQspi, uint32_t dwAddr)
117{
118        assert(pQspi);
119        pQspi->QSPI_IAR = dwAddr;
120}
121
122
123/**
124 * \brief Configures instruction register with a given command for QSPI
125 *
126 * \param pQspi   Pointer to a Qspi instance.
127 * \param dwInst  Instruction Code
128 * \param dwOpt   Instruction Code option
129 */
130__STATIC_INLINE void QSPI_SetInst(Qspi *pQspi, uint8_t dwInst, uint8_t dwOpt)
131{
132        assert(pQspi);
133        pQspi->QSPI_ICR = (dwInst | QSPI_ICR_OPT(dwOpt));
134}
135
136/**
137 * \brief Configures instruction frame register of QSPI
138 *
139 * \param pQspi         Pointer to a Qspi instance.
140 * \param pInstFrame    Instruction Frame configuration
141 */
142__STATIC_INLINE void QSPI_SetInstFrame(Qspi *pQspi,
143                                                                                QspiInstFrame_t *pInstFrame)
144{
145        assert(pQspi);
146        pQspi->QSPI_IFR = pInstFrame->InstFrame.val;
147}
148
149/**
150 * \brief Reads the Instruction frame of QSPI
151 *
152 * \param pQspi   Pointer to an Qspi instance.
153 */
154__STATIC_INLINE uint32_t QSPI_GetInstFrame(Qspi *pQspi)
155{
156        assert(pQspi);
157        return pQspi->QSPI_IFR;
158}
159
160/**
161 * \brief Read QSPI RDR register for SPI mode
162 *
163 * \param pQspi   Pointer to an Qspi instance.
164 */
165__STATIC_INLINE uint16_t QSPI_ReadSPI(Qspi *pQspi)
166{
167        assert(pQspi);
168
169        while (!QSPI_GetStatus(pQspi, IsReceived));
170
171        return  pQspi->QSPI_RDR;
172}
173
174
175/**
176 * \brief Write to QSPI Tx register in SPI mode
177 *
178 * \param pQspi   Pointer to an Qspi instance.
179 * \param wData   Data to transmit
180 */
181__STATIC_INLINE void QSPI_WriteSPI(Qspi *pQspi, uint16_t wData)
182{
183        assert(pQspi);
184
185        /* Send data */
186        while (!QSPI_GetStatus(pQspi, IsTxEmpty));
187
188        pQspi->QSPI_TDR = wData;
189
190        while (!QSPI_GetStatus(pQspi, IsTxSent));
191}
192
193/**
194 * \brief Configures QSPI scrambling with a given Key
195 *
196 * \param pQspi         Pointer to an Qspi instance.
197 * \param wKey          Key for scramble/unscramble
198 * \param EnableFlag    Enable/disable scramble
199 * \param Random        Add random value with given key
200 */
201__STATIC_INLINE void QSPI_ScrambleData(Qspi *pQspi, uint32_t wKey,
202                                                                                uint8_t EnableFlag, uint8_t Random)
203{
204        assert(pQspi);
205        assert(EnableFlag < 2);
206        assert(Random < 2);
207
208        if (EnableFlag)
209                pQspi->QSPI_SKR = wKey;
210
211        pQspi->QSPI_SMR = (EnableFlag | (Random << 1));
212}
213
214/*----------------------------------------------------------------------------
215 *        Exported functions
216 *----------------------------------------------------------------------------*/
217
218/**
219 * \brief Enables a QSPI peripheral.
220 *
221 * \param pQspi  Pointer to a Qspi instance.
222 */
223void QSPI_Enable(Qspi *pQspi)
224{
225        assert(pQspi);
226        pQspi->QSPI_CR = QSPI_CR_QSPIEN;
227
228        while (!(pQspi->QSPI_SR & QSPI_SR_QSPIENS));
229}
230
231/**
232 * \brief Disables a QSPI peripheral.
233 *
234 * \param pQspi  Pointer to a Qspi instance.
235 */
236void QSPI_Disable(Qspi *pQspi)
237{
238        assert(pQspi);
239        pQspi->QSPI_CR = QSPI_CR_QSPIDIS;
240
241        while (pQspi->QSPI_SR & QSPI_SR_QSPIENS);
242}
243
244/**
245 * \brief Resets a QSPI peripheral.
246 *
247 * \param pQspi  Pointer to a Qspi instance.
248 */
249void QSPI_SwReset(Qspi *pQspi)
250{
251        assert(pQspi);
252        pQspi->QSPI_CR = QSPI_CR_SWRST;
253}
254
255/**
256 * \brief Enables one or more interrupt sources of a QSPI peripheral.
257 *
258 * \param pQspi  Pointer to a Qspi instance.
259 * \param sources Bitwise OR of selected interrupt sources.
260 */
261QspidStatus_t QSPI_EnableIt(Qspi *pQspi, uint32_t dwSources)
262{
263        assert(pQspi);
264        pQspi->QSPI_IER = dwSources;
265        return QSPI_SUCCESS;
266}
267
268/**
269 * \brief Disables one or more interrupt sources of a QSPI peripheral.
270 *
271 * \param pQspi  Pointer to a Qspi instance.
272 * \param sources Bitwise OR of selected interrupt sources.
273 */
274QspidStatus_t QSPI_DisableIt(Qspi *pQspi, uint32_t dwSources)
275{
276        assert(pQspi);
277        pQspi->QSPI_IDR = dwSources;
278        return QSPI_SUCCESS;
279}
280
281/**
282 * \brief Return the interrupt mask register.
283 *
284 * \return Qspi interrupt mask register.
285 */
286uint32_t QSPI_GetItMask(Qspi *pQspi)
287{
288        assert(pQspi);
289        return (pQspi->QSPI_IMR);
290}
291
292/**
293 * \brief Returns enabled interrupt status
294 *
295 * \return Qspi interrupt mask register.
296 */
297uint32_t QSPI_GetEnabledItStatus(Qspi *pQspi)
298{
299        assert(pQspi);
300        return (pQspi->QSPI_IMR & QSPI_GetStatus(pQspi, (QspiStatus_t)0xFFFFFFFF));
301}
302
303/**
304 * \brief Get the current status register of the given QSPI peripheral.
305 * \note This resets the internal value of the status register, so further
306 * read may yield different values.
307 * \param pQspi   Pointer to a Qspi instance.
308 * \param rStatus Compare status with given status bit
309 * \return  QSPI status register.
310 */
311uint32_t QSPI_GetStatus(Qspi *pQspi, const QspiStatus_t rStatus)
312{
313        assert(pQspi);
314        return (pQspi->QSPI_SR & rStatus);
315}
316
317/**
318 * \brief Configures peripheral clock of a QSPI/SPI peripheral.
319 *
320 * \param pQspi   Pointer to an Qspi instance.
321 * \param dwConfiguration  Desired clock configuration.
322 */
323void QSPI_ConfigureClock(Qspi *pQspi, QspiClockMode_t ClockMode,
324                                                  uint32_t dwClockCfg)
325{
326        assert(pQspi);
327        pQspi->QSPI_SCR = ClockMode;
328        pQspi->QSPI_SCR |= dwClockCfg;
329}
330
331/**
332 * \brief Configures QSPI/SPI
333 *
334 * \param pQspi             Pointer to an Qspi instance.
335 * \param Mode              Mode for QSPI or SPI
336 * \param dwConfiguration   Config of SPI or QSPI mode
337 */
338QspidStatus_t QSPI_ConfigureInterface(Qspid_t *pQspid, QspiMode_t Mode,
339                                                                           uint32_t dwConfiguration)
340{
341        pQspid->pQspiHw = QSPI;
342        pQspid->qspiId = ID_QSPI;
343
344        QSPI_Disable(pQspid->pQspiHw);
345        QSPI_SwReset(pQspid->pQspiHw);
346
347        QSPI_ConfigureMode(pQspid->pQspiHw, Mode);
348        QSPI_Configure(pQspid->pQspiHw, dwConfiguration);
349
350        return QSPI_SUCCESS;
351}
352
353
354/**
355 * \brief Ends ongoing transfer by releasing CS of QSPI peripheral.
356 *
357 * \param pQspi  Pointer to an Qspi instance.
358 */
359QspidStatus_t QSPI_EndTransfer(Qspi *pQspi)
360{
361        assert(pQspi);
362
363        while (!QSPI_GetStatus(pQspi, IsTxEmpty));
364
365        pQspi->QSPI_CR = QSPI_CR_LASTXFER;
366
367        return QSPI_SUCCESS;
368}
369
370
371/*----------------------------------------------------------------------------
372 *        SPI functions
373 *----------------------------------------------------------------------------*/
374/**
375 * \brief Reads the data received by a SPI peripheral. This
376 * method must be called after a successful SPI_Write call.
377 *
378 * \param pQspid    Pointer to a Qspi instance.
379 * \param pData     Buffer to put read value
380 * \return Qspi status
381 */
382QspidStatus_t QSPI_SingleReadSPI(Qspid_t *pQspid, uint16_t *const pData)
383{
384        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
385        Qspi *pQspi = pQspid->pQspiHw;
386        uint32_t NumOfAttempt = 0;
387        uint16_t Dummy = 0xFF;
388
389        for (;;) {
390                if (QSPI_GetStatus(pQspi, IsReceived)) {
391                        *pData = QSPI_ReadSPI(pQspi);
392                        QSPI_WriteSPI(pQspi, Dummy);
393                        *pData = QSPI_ReadSPI(pQspi);
394                        NumOfAttempt = 0;
395                        Status = QSPI_SUCCESS;
396                } else {
397                        if (NumOfAttempt > 0xFFFF) {
398                                Status = QSPI_READ_ERROR;
399                                TRACE_ERROR(" SPI Read Error \n\r");
400                                break;
401                        } else {
402                                Status = QSPI_READ_ERROR;
403                                NumOfAttempt++;
404                        }
405                }
406        }
407
408        return Status;
409}
410
411/**
412 * \brief Reads multiple data received by a SPI peripheral. This
413 * method must be called after a successful SPI_Write call.
414 *
415 * \param pQspid        Pointer to a Qspi instance.
416 * \param pData         Pointer to read buffer
417 * \param NumOfBytes    Num of bytes to read
418 *
419 * \return Qspi status
420 */
421QspidStatus_t QSPI_MultiReadSPI(Qspid_t *pQspid, uint16_t *const pData,
422                                                                 uint32_t NumOfBytes)
423{
424        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
425        Qspi *pQspi = pQspid->pQspiHw;
426        uint32_t NumOfBytesRead = 0;
427        uint32_t NumOfAttempt = 0;
428        uint8_t *pwData = (uint8_t *)pData;
429        uint16_t Dummy = 0xFF;
430
431        /* Dummy read  and write to discard  first bytes recvd and start
432            receiving new data*/
433        Dummy = QSPI_ReadSPI(pQspi);
434        QSPI_WriteSPI(pQspi, Dummy);
435
436        for (; NumOfBytesRead < NumOfBytes;) {
437                if (QSPI_GetStatus(pQspi, IsTxSent)) {
438                        *pwData = QSPI_ReadSPI(pQspi);
439
440                        if (pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk)
441                                pwData += sizeof(uint16_t);
442                        else
443                                pwData += sizeof(uint8_t);
444
445                        NumOfBytesRead++;
446                        NumOfAttempt = 0;
447                        Status = QSPI_SUCCESS;
448                        QSPI_WriteSPI(pQspi, Dummy);
449                } else {
450                        if (NumOfAttempt > 0xFFFF) {
451                                Status = QSPI_READ_ERROR;
452                                TRACE_ERROR(" SPI MultiRead Error \n\r");
453                                break;
454                        } else {
455                                Status = QSPI_READ_ERROR;
456                                NumOfAttempt++;
457                        }
458                }
459        }
460
461        return Status;
462}
463
464/**
465 * \brief Sends a single data through a SPI peripheral.
466 *
467 * \param pQspid    Pointer to a Qspi instance.
468 * \param pData     Pointer to Tx data
469 *
470 * \return Qspi status
471 */
472QspidStatus_t QSPI_SingleWriteSPI(Qspid_t *pQspid, uint16_t const *pData)
473{
474        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
475        Qspi *pQspi = pQspid->pQspiHw;
476        uint32_t NumOfAttempt = 0;
477
478        for (;;) {
479                if (QSPI_GetStatus(pQspi, IsTxSent)) {
480                        QSPI_WriteSPI(pQspi, *pData);
481                        NumOfAttempt = 0;
482                        Status = QSPI_SUCCESS;
483                        break;
484                } else {
485                        Status = QSPI_BUSY_SENDING;
486                        NumOfAttempt++;
487
488                        if (NumOfAttempt > 0xFFFF) {
489                                Status = QSPI_WRITE_ERROR;
490                                TRACE_ERROR(" SPI Write Error \n\r");
491                                break;
492                        }
493                }
494        }
495
496        return Status;
497
498}
499
500/**
501 * \brief Sends multiple data through a SPI peripheral.
502 *
503 * \param pQspid        Pointer to a Qspi instance.
504 * \param pData         Pointer to a Tx buffer
505 * \param NumOfBytes    Num of data to send.
506 */
507QspidStatus_t QSPI_MultiWriteSPI(Qspid_t *pQspid, uint16_t const *pData,
508                                                                  uint32_t NumOfBytes)
509{
510        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
511        Qspi *pQspi = pQspid->pQspiHw;
512        uint32_t NumOfBytesWrite = 0;
513        uint32_t NumOfAttempt = 0;
514        uint8_t *pwData = (uint8_t *)pData;
515        uint8_t Addr_Inc = 0;
516
517        if (pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk)
518                Addr_Inc = sizeof(uint16_t);
519        else
520                Addr_Inc = sizeof(uint8_t);
521
522        for (; NumOfBytesWrite < NumOfBytes;) {
523                if (QSPI_GetStatus(pQspi, IsTxEmpty)) {
524                        QSPI_WriteSPI(pQspi, (uint16_t)*pwData);
525                        pwData += Addr_Inc;
526                        NumOfBytesWrite++;
527                        NumOfAttempt = 0;
528                        Status = QSPI_SUCCESS;
529                } else {
530                        Status = QSPI_BUSY_SENDING;
531                        NumOfAttempt++;
532
533                        if (NumOfAttempt > 0xFFFF) {
534                                Status = QSPI_WRITE_ERROR;
535                                TRACE_ERROR(" SPI Multi Write Error \n\r");
536                                break;
537                        }
538                }
539        }
540
541        return Status;
542
543}
544
545/*----------------------------------------------------------------------------
546 *        QSPI functions
547 *----------------------------------------------------------------------------*/
548
549/**
550 * \brief Send an instruction over QSPI (oly a flash command no data)
551 *
552 * \param pQspi     Pointer to an Qspi instance.
553 * \param KeepCfg   To keep Instruction fram value or restes to zero
554 *
555 * \return Returns 1 if At least one instruction end has been detected since
556 * the last read of QSPI_SR.; otherwise
557 * returns 0.
558 */
559QspidStatus_t QSPI_SendCommand(Qspid_t *pQspid, uint8_t const KeepCfg)
560{
561        QspiInstFrame_t  *const pFrame = pQspid->pQspiFrame;
562        QspiMemCmd_t  pCommand = pQspid->qspiCommand;
563        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
564
565        if (pFrame->InstFrame.bm.bAddrEn)
566                QSPI_SetInstAddr(pQspid->pQspiHw, pFrame->Addr);
567
568        QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
569                                 ((pCommand.Option >> QSPI_ICR_OPT_Pos) & 0xFF));
570        QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
571
572        memory_sync();
573
574        while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
575
576        // poll CR reg to know status if instruction has end
577        if (!KeepCfg)
578                pFrame->InstFrame.val = 0;
579
580        return Status;
581}
582
583
584
585/**
586 * \brief Send instruction over QSPI with data
587 *
588 * \param pQspi     Pointer to an Qspi instance.
589 * \param KeepCfg   To keep Instruction fram value or restes to zero
590 *
591 * \return Returns 1 if At least one instruction end has been detected
592 *  since the last read of QSPI_SR.; otherwise returns 0.
593 */
594QspidStatus_t QSPI_SendCommandWithData(Qspid_t *pQspid, uint8_t const KeepCfg)
595{
596        QspiInstFrame_t *const  pFrame = pQspid->pQspiFrame;
597        QspiMemCmd_t  pCommand = pQspid->qspiCommand;
598        QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
599        uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR;
600        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
601
602        //assert(pBuffer.pDataRx);
603        assert(pBuffer.pDataTx);
604
605        QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
606                                 (pCommand.Option & 0xFF));
607        QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
608
609        QSPI_GetInstFrame(pQspid->pQspiHw);
610
611        // to synchronize system bus accesses
612        if (!KeepCfg)
613                pFrame->InstFrame.val = 0;
614
615        memcpy(pQspiBuffer  , pBuffer.pDataTx ,  pBuffer.TxDataSize);
616        memory_sync();
617        QSPI_EndTransfer(pQspid->pQspiHw);
618
619        // End transmission after all data has been sent
620        while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
621
622        // poll CR reg to know status if instruction has end
623
624        return Status;
625}
626
627/**
628 * \brief Send instruction over QSPI to read data
629 *
630 * \param pQspi     Pointer to an Qspi instance.
631 * \param KeepCfg   To keep Instruction from value or resets to zero
632 *
633 * \return Returns 1 if At least one instruction end has been detected
634 * since the last read of QSPI_SR.; otherwise returns 0.
635 */
636QspidStatus_t QSPI_ReadCommand(Qspid_t *pQspid, uint8_t const KeepCfg)
637{
638        QspiInstFrame_t *const  pFrame = pQspid->pQspiFrame;
639        QspiMemCmd_t  pCommand = pQspid->qspiCommand;
640        QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
641        uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR;
642        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
643
644        assert(pBuffer.pDataRx);
645
646        QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
647                                 (pCommand.Option & 0xFF));
648        QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
649
650        QSPI_GetInstFrame(pQspid->pQspiHw);
651
652        // to synchronize system bus accesses
653        if (!KeepCfg)
654                pFrame->InstFrame.val = 0;
655
656        memcpy(pBuffer.pDataRx , pQspiBuffer,  pBuffer.RxDataSize);
657        memory_sync();
658        QSPI_EndTransfer(pQspid->pQspiHw);
659
660        // End transmission after all data has been sent
661        while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
662
663        // poll CR reg to know status if instruction has end
664
665        return Status;
666}
667
668/**
669 * \brief Sends an instruction over QSPI and configures other related address
670*  like Addr , Frame and synchronise bus access before data read or write
671 *
672 * \param pQspi         Pointer to an Qspi instance.
673 * \param KeepCfg       To keep Instruction from value or resets to zero
674 * \param ScrambleFlag  Enable or disable scramble on QSPI
675 *
676 * \return Returns 1 if At least one instruction end has been detected since
677 * the last read of QSPI_SR.; otherwise returns 0.
678 */
679QspidStatus_t QSPI_EnableMemAccess(Qspid_t *pQspid, uint8_t const KeepCfg,
680                                                                        uint8_t ScrambleFlag)
681{
682        QspiInstFrame_t *const pFrame = pQspid->pQspiFrame;
683        QspiMemCmd_t  pCommand = pQspid->qspiCommand;
684
685        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
686
687        QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
688                                 (pCommand.Option & 0xFF));
689
690        if (ScrambleFlag)
691                QSPI_ScrambleData(pQspid->pQspiHw, SCRAMBLE_KEY, ScrambleFlag, 1);
692
693        QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
694
695        QSPI_GetInstFrame(pQspid->pQspiHw);
696
697        // to synchronize system bus accesses
698        if (!KeepCfg)
699                pFrame->InstFrame.val = 0;
700
701        Status = QSPI_SUCCESS;
702        return Status;
703}
704
705/**
706 * \brief Writes or reads the QSPI memory (0x80000000) to transmit or
707 * receive data from Flash memory
708 * \param pQspi         Pointer to an Qspi instance.
709 * \param ReadWrite     Flag to indicate read/write QSPI memory access
710 *
711 * \return Returns 1 if At least one instruction end has been detected since
712 * the last read of QSPI_SR.; otherwise returns 0.
713 */
714QspidStatus_t QSPI_ReadWriteMem(Qspid_t *pQspid, Access_t const ReadWrite)
715{
716        QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
717        QspiInstFrame_t *const pFrame = pQspid->pQspiFrame;
718        uint32_t *pQspiMem = (uint32_t *)(QSPIMEM_ADDR | pFrame->Addr);
719        QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
720
721        assert(((ReadWrite > CmdAccess)
722                          && (ReadWrite <= WriteAccess)) ? true : false);
723
724        if (ReadWrite == WriteAccess)
725                memcpy(pQspiMem, pBuffer.pDataTx , pBuffer.TxDataSize);
726        else
727                memcpy(pBuffer.pDataRx, pQspiMem, pBuffer.RxDataSize);
728
729        memory_sync();
730        QSPI_EndTransfer(pQspid->pQspiHw);
731
732        // End transmission after all data has been sent
733        while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
734
735        // poll CR reg to know status if instruction has end
736
737        Status = QSPI_SUCCESS;
738        return Status;
739}
Note: See TracBrowser for help on using the repository browser.