]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - psdk_cust/pdk_k2g_1_0_1_1_eng/packages/ti/board/src/idkAM572x/device/qspi_flash.c
PASDK-258:Update PDK eng to 1.0.1.1. Using build number to differentiate PDK eng...
[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_1_eng / packages / ti / board / src / idkAM572x / device / qspi_flash.c
1 /**
2  *  \file   S25FL.c
3  *
4  *  \brief  Flash specific driver implementation.
5  *
6  */
8 /*
9  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the
21  * distribution.
22  *
23  * Neither the name of Texas Instruments Incorporated nor the names of
24  * its contributors may be used to endorse or promote products derived
25  * from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39  */
41 #include "qspi_flash.h"
42 #include <ti/drv/spi/SPI.h>
43 #include <ti/drv/spi/soc/QSPI_v1.h>
46 /*!
47  *  @brief Flash object containing flash attributes.
48  */
49 S25FL_Object s25flObject = {NULL,
50                             4,
51                             S25FL_FLASH_SECTOR_SIZE,
52                             S25FL_FLASH_BLOCK_SIZE,
53                             S25FL_FLASH_DEVICE_SIZE,
54                             S25FL_FLASH_DEVICE_ID};
57 static bool SF25FL_ConfigMode_Write(uint32_t dstOffstAddr,
58                                     unsigned char* srcAddr,
59                                     uint32_t length,
60                                     S25FL_Handle flashHandle);
62 /*
63  *  ======== SF25FL_close ========
64  */
65 void SF25FL_close(S25FL_Handle handle)
66 {
67     SPI_close(handle->spiHandle);
68 }
70 /*
71  *  ======== SF25FL_open ========
72  */
73 S25FL_Handle SF25FL_open(unsigned int index, SPI_Params *params)
74 {
75     S25FL_Handle s25flHandle;
77     s25flHandle = &s25flObject;
79     /* Open SPI driver for SF25FL */
80     s25flHandle->spiHandle = SPI_open(index, params);
82     return s25flHandle;
83 }
85 /*
86  *  ======== SF25FL_bufferWrite ========
87  */
88 bool SF25FL_bufferWrite(S25FL_Handle flashHandle,
89                         S25FL_Transaction* flashTransaction)
90 {
91     bool retVal = false;                        /* return value */
92     SPI_Handle handle = flashHandle->spiHandle; /* SPI handle */
93     SPI_Transaction transaction;                /* SPI transaction structure */
94     unsigned int idx;                           /* index */
95     uint32_t dstOffstAddr;                      /* Flash offset address */
96     unsigned char *srcAddr;                     /* Address of data buffer */
97     uint32_t length;                            /* data length in bytes */
98     unsigned int transferType;
99     unsigned char transferCmd;
100     QSPI_v1_Object  *object;
102     /* Get the pointer to the object and hwAttrs */
103     object = handle->object;
105     /* Copy flash transaction parameters to local variables */
106     dstOffstAddr = flashTransaction->address;
107     srcAddr = flashTransaction->data;
108     length = flashTransaction->dataSize;
110     if(QSPI_OPER_MODE_CFG == object->qspiMode)
111     {
112         /*
113          * Config mode write supports 256 bytes at a time. So if the length is
114          * greater than 256, then multiple transactions have to be performed till
115          * all the bytes are written.
116          */
117         while(length > 256)
118         {
119             SF25FL_ConfigMode_Write(dstOffstAddr, srcAddr, 256, flashHandle);
120             dstOffstAddr = dstOffstAddr + (256 / 4);
121             srcAddr += 256;
122             length -= 256;
123         }
124         if(length > 0)
125         {
126             SF25FL_ConfigMode_Write(dstOffstAddr, srcAddr, length, flashHandle);
127         }
128     }
131     if(QSPI_OPER_MODE_MMAP == object->qspiMode)
132     {
133         if(dstOffstAddr > 0xFFFFFFU)
134         {
135             /* Enter 32 bit addressing mode */
136             S25FLFlash_Enable4ByteAddrMode(flashHandle, true);
137         }
139         for(idx = 0; idx < length; idx++)
140         {
141             /* Write enable */
142             S25FLFlash_WriteEnable(flashHandle);
144             /* Perform the transfer */
145             transaction.txBuf = (unsigned char *)dstOffstAddr;
146             transaction.rxBuf = srcAddr;
147             transaction.count = 1;
149             transferType = SPI_TRANSACTION_TYPE_WRITE;
150             transferCmd  = QSPI_LIB_CMD_PAGE_PRG;
151             SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
152             SPI_control(handle, SPI_V1_CMD_MMAP_TRANSFER_CMD, (void *)&transferCmd);
153             retVal = SPI_transfer(handle, &transaction);
155             /* Check flash status for completion */
156             while ((FlashStatus(flashHandle) & 0x1U));
158             dstOffstAddr += 1;
159             srcAddr += 1;
160         }
162         if(dstOffstAddr > 0xFFFFFFU)
163         {
164             /* Exit 4 byte addressing mode */
165             S25FLFlash_Enable4ByteAddrMode(flashHandle, false);
166         }
167     }
169     return retVal;
174 bool SF25FL_bufferRead(S25FL_Handle flashHandle,
175                        S25FL_Transaction* flashTransaction)
177     bool retVal = false;                        /* return value */
178     SPI_Handle handle = flashHandle->spiHandle; /* SPI handle */
179     unsigned char writeVal[4];               /* data to be written */
180     SPI_Transaction transaction;             /* SPI transaction structure */
181     uint32_t addrLengthInBytes = 3U;         /* Flash address length in bytes */
182     uint32_t readCmd;                        /* Read command */
183     uint32_t numDummyBits;                   /* Number of dummy bits */
184     uint32_t frameLength;                    /* Frame length */
185     uint32_t dstOffstAddr;                   /* Flash offset address */
186     unsigned char *srcAddr;                  /* Address of data buffer */
187     uint32_t length;                         /* data length in bytes */
188     unsigned int *tempPtr = (unsigned int *)&writeVal[0];  /* temp pointer */
189     unsigned int frmLength;
190     unsigned int transferType;
191     unsigned char transferCmd;
192     QSPI_v1_Object  *object;
194     /* Get the pointer to the object and hwAttrs */
195     object = handle->object;
197     /* Copy flash transaction parameters to local variables */
198     dstOffstAddr = (uint32_t)flashTransaction->data;
199     srcAddr = (unsigned char *)flashTransaction->address;
200     length = flashTransaction->dataSize;
202     if(QSPI_OPER_MODE_CFG == object->qspiMode)
203     {
204         addrLengthInBytes = 3U;
205         if(srcAddr > (unsigned char *)0xFFFFFF)
206         {
207             /* Enter 32 bit addressing mode */
208             S25FLFlash_Enable4ByteAddrMode(flashHandle, true);
209             addrLengthInBytes = 4;
210         }
212         switch(object->rxLines)
213         {
214             case QSPI_RX_LINES_SINGLE:
215             {
216                 readCmd = QSPI_LIB_CMD_READ_SINGLE;
217                 numDummyBits = 0U;
219                 /* total transaction frame length in number of words (bytes)*/
220                 frameLength = length + 1 + addrLengthInBytes;
221                 break;
222             }
224             case QSPI_RX_LINES_DUAL:
225             {
226                 readCmd = QSPI_LIB_CMD_READ_DUAL;
227                 numDummyBits = 8U;
229                 /* total transaction frame length in number of words (bytes)*/
230                 frameLength = length + 1 + 1 + addrLengthInBytes;
231                 break;
232             }
234             case QSPI_RX_LINES_QUAD:
235             {
236                 readCmd = QSPI_LIB_CMD_READ_QUAD;
237                 numDummyBits = 8U;
239                 /* total transaction frame length in number of words (bytes)*/
240                 frameLength = length + 1 + 1 + addrLengthInBytes;
241                 break;
242             }
244             default:
245             break;
246         }
248         /* total transaction frame length */
249         frmLength = frameLength;
250         SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, (void *)&frmLength);
252         /* Write read command */
253         writeVal[0] = readCmd;
254         transaction.txBuf = (unsigned char *)&writeVal[0];
255         transaction.rxBuf = NULL;
256         transaction.count = 1;
258         transferType = SPI_TRANSACTION_TYPE_WRITE;
259         SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
260         retVal = SPI_transfer(handle, &transaction);
262         /* Write dummy bits for fast read if required */
263         if(0 != numDummyBits)
264         {
265             writeVal[0] = 0U;
266             transaction.txBuf = (unsigned char *)&writeVal[0];
267             transaction.rxBuf = NULL;
268             transaction.count = (numDummyBits >> 3);      /* In bytes */
270         transferType = SPI_TRANSACTION_TYPE_WRITE;
271         SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
272             retVal = SPI_transfer(handle, &transaction);
273         }
275         /* Write Address Bytes */
276         *tempPtr = (unsigned int)srcAddr;
277         transaction.txBuf = (unsigned char *)tempPtr;
278         transaction.rxBuf = NULL;
279         transaction.count = addrLengthInBytes;
281         transferType = SPI_TRANSACTION_TYPE_WRITE;
282         SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
283         retVal = SPI_transfer(handle, &transaction);
285         /* Read the actual flash data */
286         transaction.txBuf = NULL;
287         transaction.rxBuf = (unsigned char *)dstOffstAddr;
288         transaction.count = length;
290         transferType = SPI_TRANSACTION_TYPE_READ;
291         SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
292         retVal = SPI_transfer(handle, &transaction);
294         if(srcAddr > (unsigned char *)0xFFFFFF)
295         {
296             /* Exit 32 bit addressing mode */
297             S25FLFlash_Enable4ByteAddrMode(flashHandle, false);
298             addrLengthInBytes = 3;
299         }
300     }
302     if(QSPI_OPER_MODE_MMAP == object->qspiMode)
303     {
304         if(srcAddr > (unsigned char *)0xFFFFFF)
305         {
306             /* Enter 32 bit addressing mode */
307             S25FLFlash_Enable4ByteAddrMode(flashHandle, true);
308         }
310         switch(object->rxLines)
311         {
312             case QSPI_RX_LINES_SINGLE:
313             {
314                 readCmd = QSPI_LIB_CMD_READ_SINGLE;
315                 break;
316             }
318             case QSPI_RX_LINES_DUAL:
319             {
320                 readCmd = QSPI_LIB_CMD_READ_DUAL;
321                 break;
322             }
324             case QSPI_RX_LINES_QUAD:
325             {
326                 readCmd = QSPI_LIB_CMD_READ_QUAD;
327                 break;
328             }
330             default:
331             break;
332         }
334         /* Perform the transfer */
335         transaction.txBuf = srcAddr;
336         transaction.rxBuf = (uint8_t *)dstOffstAddr;
337         transaction.count = length;
339         transferType = SPI_TRANSACTION_TYPE_READ;
340         transferCmd  = (unsigned char)readCmd;
341         SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
342         SPI_control(handle, SPI_V1_CMD_MMAP_TRANSFER_CMD, (void *)&transferCmd);
343         retVal = SPI_transfer(handle, &transaction);
345         if(srcAddr > (unsigned char *)0xFFFFFF)
346         {
347             /* Exit 32 bit addressing mode */
348             S25FLFlash_Enable4ByteAddrMode(flashHandle, false);
349         }
350     }
352     return retVal;
356 bool S25FLFlash_WriteEnable(S25FL_Handle flashHandle)
358     SPI_Handle handle = flashHandle->spiHandle; /* SPI handle */
359     bool retVal = false;                /* return value */
360     unsigned char writeVal;             /* data to be written */
361     SPI_Transaction transaction;        /* SPI transaction structure */
362     unsigned int operMode;              /* temp variable to hold mode */
363     unsigned int rxLines;               /* temp variable to hold rx lines */
364     unsigned int frmLength;
365     unsigned int transferType;
366     QSPI_v1_Object  *object;
367     unsigned int rxLinesArg;
369     /* Get the pointer to the object and hwAttrs */
370     object = handle->object;
372     /* These operations require the qspi to be configured in the following mode
373        only: tx/rx single line and config mode. */
375     /* Save the current mode and rxLine configurations */
376     operMode = object->qspiMode;
377     rxLines  = object->rxLines;
379     /* Update the mode and rxLines with the required values */
380     SPI_control(handle, SPI_V1_CMD_SETCONFIGMODE, NULL);
382     rxLinesArg = QSPI_RX_LINES_SINGLE;
383     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLinesArg);
385     /* transaction frame length in words (bytes) */
386     frmLength = 1;
387     SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, (void *)&frmLength);
389     /* Write enable command */
390     writeVal = QSPI_LIB_CMD_WRITE_ENABLE;
392     /* Update transaction parameters */
393     transaction.txBuf = (unsigned char *)&writeVal;
394     transaction.rxBuf = NULL;
395     transaction.count  = 1;
397     transferType = SPI_TRANSACTION_TYPE_WRITE;
398     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
400     retVal = SPI_transfer(handle, &transaction);
402     /* Restore operating mode and rx Lines */
403     object->qspiMode = operMode;
404     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLines);
406     return retVal;
410 bool S25FLFlash_Enable4ByteAddrMode(S25FL_Handle flashHandle,
411                                     bool enable4ByteMode)
413     SPI_Handle handle = flashHandle->spiHandle; /* SPI handle */
414     bool retVal = false;             /* return value */
415     unsigned char writeVal;          /* data to be written */
416     SPI_Transaction transaction;     /* SPI transaction structure */
417     unsigned int operMode;           /* temp variable to hold mode */
418     unsigned int rxLines;            /* temp variable to hold rx lines */
419     unsigned int transferType;
420     QSPI_v1_Object  *object;
421     unsigned int rxLinesArg;
423     /* Get the pointer to the object and hwAttrs */
424     object = handle->object;
426     /* These operations require the qspi to be configured in the following mode
427        only: tx/rx single line and config mode. */
429     /* Save the current mode and rxLine configurations */
430     operMode = object->qspiMode;
431     rxLines  = object->rxLines;
434     /* Update the mode and rxLines with the required values */
435     SPI_control(handle, SPI_V1_CMD_SETCONFIGMODE, NULL);
436     rxLinesArg = QSPI_RX_LINES_SINGLE;
437     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLinesArg);
439     /* Command to control the 4 byte mode */
440     if (true == enable4ByteMode)
441     {
442         writeVal = QSPI_LIB_CMD_ENTER_4_BYTE_ADDR;
443     }
444     else
445     {
446         writeVal = QSPI_LIB_CMD_EXIT_4_BYTE_ADDR;
447     }
449     /* Write 4 byte enable/disable command to flash */
450     transaction.count = 1U;                    /* Frame length in bytes */
451     transaction.txBuf = (unsigned char *)&writeVal;  /* Value to be written */
452     transaction.rxBuf = NULL;                  /* Nothing to read */
453     transaction.arg   = NULL;                  /* Not applicable */
455     transferType = SPI_TRANSACTION_TYPE_WRITE;
456     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
459     retVal = SPI_transfer(handle, &transaction);
461     /* Restore operating mode and rx Lines */
462     object->qspiMode = operMode;
463     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLines);
465     return retVal;
469 uint32_t FlashStatus(S25FL_Handle flashHandle)
471     SPI_Handle handle = flashHandle->spiHandle; /* SPI handle */
472     bool retVal = false;             /* return value */
473     unsigned char writeVal;          /* data to be written */
474     SPI_Transaction transaction;     /* SPI transaction structure */
475     uint32_t rxData = 0U;            /* received data */
476     unsigned int operMode;           /* temp variable to hold mode */
477     unsigned int rxLines;            /* temp variable to hold rx lines */
478     unsigned int frmLength;
479     unsigned int transferType;
480     QSPI_v1_Object  *object;
481     unsigned int rxLinesArg;
483     /* Get the pointer to the object and hwAttrs */
484     object = handle->object;
486     /* These operations require the qspi to be configured in the following mode
487        only: tx/rx single line and config mode. */
489     /* Save the current mode and rxLine configurations */
490     operMode = object->qspiMode;
491     rxLines  = object->rxLines;
493     /* Update the mode and rxLines with the required values */
494     SPI_control(handle, SPI_V1_CMD_SETCONFIGMODE, NULL);
496     rxLinesArg = QSPI_RX_LINES_SINGLE;
497     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLinesArg);
499     /* Total transaction frame length in words (bytes) */
500     frmLength = 1 + 1;
501     SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, (void *)&frmLength);
503     /* Write Address Bytes */
504     writeVal = QSPI_LIB_CMD_READ_STATUS_REG;
505     transaction.txBuf = (unsigned char *)&writeVal;
506     transaction.rxBuf = NULL;
507     transaction.count = 1U;
509     transferType = SPI_TRANSACTION_TYPE_WRITE;
510     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
512     retVal = SPI_transfer(handle, &transaction);
514     if(retVal == false)
515     {
516         /* Error */
517     }
519     /* Read the status register */
520     transaction.txBuf = NULL;
521     transaction.rxBuf = (unsigned char *)&rxData;
522     transaction.count = 1U;
524     transferType = SPI_TRANSACTION_TYPE_READ;
525     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
527     retVal = SPI_transfer(handle, &transaction);
529     if(retVal == false)
530     {
531         /* Error */
532     }
534     /* Restore operating mode and rx Lines */
535     object->qspiMode = operMode;
536     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLines);
538     return (rxData & 0xFF);
542 bool S25FLFlash_QuadModeEnable(S25FL_Handle flashHandle)
544     SPI_Transaction transaction;                /* SPI transaction structure */
545     SPI_Handle handle = flashHandle->spiHandle; /* SPI handle */
546     unsigned char writeVal = 0U;    /* data to be written */
547     uint32_t norStatus;             /* flash status value */
548     uint32_t configReg;             /* configuration register value */
549     uint32_t data;                  /* data to be written */
550     bool retVal = false;            /* return value */
551     unsigned int operMode;          /* temp variable to hold mode */
552     unsigned int rxLines;           /* temp variable to hold rx lines */
553     unsigned int frmLength;
554     unsigned int transferType;
555     QSPI_v1_Object  *object;
556     unsigned int rxLinesArg;
558     /* Get the pointer to the object and hwAttrs */
559     object = handle->object;
561     /* These operations require the qspi to be configured in the following mode
562        only: tx/rx single line and config mode. */
564     /* Save the current mode and rxLine configurations */
565     operMode = object->qspiMode;
566     rxLines  = object->rxLines;
568     /* Update the mode and rxLines with the required values */
569     SPI_control(handle, SPI_V1_CMD_SETCONFIGMODE, NULL);
571     rxLinesArg = QSPI_RX_LINES_SINGLE;
572     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLinesArg);
574     /* Set transfer length in bytes: Reading status register */
575     frmLength = 1 + 1;
576     SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, (void *)&frmLength);
578     /* Read Status register */
579     writeVal = QSPI_LIB_CMD_READ_STATUS_REG;
580     transaction.txBuf = (unsigned char *)&writeVal;
581     transaction.rxBuf = NULL;
582     transaction.count = 1;
584     transferType = SPI_TRANSACTION_TYPE_WRITE;
585     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
587     retVal = SPI_transfer(handle, &transaction);
589     transaction.txBuf = NULL;
590     transaction.rxBuf = (unsigned char *)&norStatus;
591     transaction.count = 1;
593     transferType = SPI_TRANSACTION_TYPE_READ;
594     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
596     retVal = SPI_transfer(handle, &transaction);
598     /* Set transfer length in bytes: Reading status register */
599     frmLength = 1 + 1;
600     SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, (void *)&frmLength);
602     /* Read command register */
603     writeVal = QSPI_LIB_CMD_QUAD_RD_CMD_REG;
604     transaction.txBuf = (unsigned char *)&writeVal;
605     transaction.rxBuf = NULL;
606     transaction.count = 1;
608     transferType = SPI_TRANSACTION_TYPE_WRITE;
609     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
611     retVal = SPI_transfer(handle, &transaction);
613     transaction.txBuf = NULL;
614     transaction.rxBuf = (unsigned char *)&configReg;
615     transaction.count = 1;
617     transferType = SPI_TRANSACTION_TYPE_READ;
618     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
620     retVal = SPI_transfer(handle, &transaction);
622     /* Set 2nd bit of configuration register to 1 to enable quad mode */
623     configReg |= (QSPI_FLASH_QUAD_ENABLE_VALUE << QSPI_FLASH_QUAD_ENABLE_BIT);
624     data = (QSPI_LIB_CMD_WRITE_STATUS_REG << 16) | (norStatus << 8) | configReg;
626     /* Set transfer length in bytes */
627     frmLength = 1;
628     SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, (void *)&frmLength);
631     transaction.txBuf = (unsigned char *)&data;
632     transaction.rxBuf = NULL;
633     transaction.count = 3;
635     transferType = SPI_TRANSACTION_TYPE_WRITE;
636     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
638     retVal = SPI_transfer(handle, &transaction);
640     /* Wait till the status register is being written */
641     while (1U == (FlashStatus(flashHandle) & 0x1U));
643     /* Restore operating mode and rx Lines */
644     object->qspiMode = operMode;
645     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLines);
647     return retVal;
651 bool S25FLFlash_BlockErase(S25FL_Handle flashHandle, unsigned int blockNumber)
653     uint32_t eraseAddr;    /* Flash erase address */
654     uint32_t writeVal;     /* data to be written */
655     SPI_Handle handle = flashHandle->spiHandle;  /* SPI handle */
656     SPI_Transaction transaction;         /* SPI transaction structure */
657     unsigned int addrLenInBytes = 3;     /* address length in bytes */
658     bool retVal = false;                 /* return value */
659     unsigned int operMode;               /* temp variable to hold mode */
660     unsigned int rxLines;                /* temp variable to hold rx lines */
661     unsigned int frmLength;
662     unsigned int transferType;
663     QSPI_v1_Object  *object;
664     unsigned int rxLinesArg;
665     uint32_t tempAddr;
667     /* Get the pointer to the object and hwAttrs */
668     object = handle->object;
670     /* Compute flash erase address based on the block size */
671     eraseAddr = blockNumber * flashHandle->blockSize;
673     /* These operations require the qspi to be configured in the following mode
674        only: tx/rx single line and config mode. */
676     /* Save the current mode and rxLine configurations */
677     operMode = object->qspiMode;
678     rxLines  = object->rxLines;
680     /* Update the mode and rxLines with the required values */
681     SPI_control(handle, SPI_V1_CMD_SETCONFIGMODE, NULL);
683     rxLinesArg = QSPI_RX_LINES_SINGLE;
684     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLinesArg);
686     if(eraseAddr > 0xFFFFFF)
687     {
688         /* Enter 4 byte addressing mode */
689         S25FLFlash_Enable4ByteAddrMode(flashHandle, true);
690         addrLenInBytes = 4;
691     }
693     tempAddr = ((eraseAddr & 0xFF000000) >> 24) |
694                ((eraseAddr & 0x00FF0000) >> 8)  |
695                ((eraseAddr & 0x0000FF00) << 8)  |
696                ((eraseAddr & 0x000000FF) << 24);
698     if(addrLenInBytes == 3)
699     {
700         tempAddr = (tempAddr >> 8) & 0x00FFFFFF;
701     }
703     /* Flash write enable */
704     S25FLFlash_WriteEnable(flashHandle);
707     /*total transaction frame length */
708     frmLength = 1 + addrLenInBytes;
709     SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, ((void *)&frmLength));
711     /* Block erase command */
712     writeVal = QSPI_LIB_CMD_BLOCK_ERASE;
713     transaction.txBuf = (unsigned char *)&writeVal;
714     transaction.rxBuf = NULL;
715     transaction.count = 1;
717     transferType = SPI_TRANSACTION_TYPE_WRITE;
718     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
721     retVal = SPI_transfer(handle, &transaction);
723     /* Send erase address */
724     writeVal = tempAddr;
725     transaction.txBuf = (unsigned char *)&writeVal;
726     transaction.rxBuf = NULL;
727     transaction.count = addrLenInBytes;
729     transferType = SPI_TRANSACTION_TYPE_WRITE;
730     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
733     retVal = SPI_transfer(handle, &transaction);
735     /* Check flash status for write completion */
736     while (1U == (FlashStatus(flashHandle) & 0x1U));
738     if(eraseAddr > 0xFFFFFF)
739     {
740         /* Exit 4 byte addressing mode */
741         S25FLFlash_Enable4ByteAddrMode(flashHandle, false);
742         addrLenInBytes = 3;
743     }
745     /* Restore operating mode and rx Lines */
746     object->qspiMode = operMode;
747     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLines);
749     return retVal;
753 void FlashPrintId(S25FL_Handle flashHandle)
755     uint32_t writeVal;               /* data to be written */
756     SPI_Handle handle = flashHandle->spiHandle;  /* SPI handle */
757     SPI_Transaction transaction;     /* SPI transaction structure */
758     bool retVal = false;             /* return value */
759     unsigned char mfgId = 0;         /* manufacture ID value */
760     unsigned char deviceId = 0;      /* device ID value */
761     unsigned int operMode;           /* temp variable to hold mode */
762     unsigned int rxLines;            /* temp variable to hold rx lines */
763     unsigned int frmLength;
764     unsigned int transferType;
765     QSPI_v1_Object  *object;
766     unsigned int rxLinesArg;
768     /* Get the pointer to the object and hwAttrs */
769     object = handle->object;
771     /* These operations require the qspi to be configured in the following mode
772        only: tx/rx single line and config mode. */
774     /* Save the current mode and rxLine configurations */
775     operMode = object->qspiMode;
776     rxLines  = object->rxLines;
778     /* Update the mode and rxLines with the required values */
779     SPI_control(handle, SPI_V1_CMD_SETCONFIGMODE, NULL);
781     rxLinesArg = QSPI_RX_LINES_SINGLE;
782     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLinesArg);
784     /* Total transaction frame length in bytes */
785     frmLength = 1 + 3 + 2;   /* cmd + address + read data */
786     SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, (void *)&frmLength);
788     /* Write Command */
789     writeVal = QSPI_LIB_CMD_READ_MFG_ID;
790     transaction.txBuf = (unsigned char *)&writeVal;
791     transaction.rxBuf = NULL;
792     transaction.count = 1;
794     transferType = SPI_TRANSACTION_TYPE_WRITE;
795     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
797     retVal = SPI_transfer(handle, &transaction);
799     if(retVal == false)
800     {
801         /* Error */
802     }
804     /* Write Address Bytes */
805     writeVal = 0x0U;
806     transaction.txBuf = (unsigned char *)&writeVal;
807     transaction.rxBuf = NULL;
808     transaction.count = 3;
810     transferType = SPI_TRANSACTION_TYPE_WRITE;
811     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
814     retVal = SPI_transfer(handle, &transaction);
817     /* Read Manufacturer ID
818      * The manufacturer ID is of 1 byte(8 bits)
819      */
820     transaction.txBuf = NULL;
821     transaction.rxBuf = &mfgId;
822     transaction.count = 1;
824     transferType = SPI_TRANSACTION_TYPE_READ;
825     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
827     retVal = SPI_transfer(handle, &transaction);
829     /* Read Device ID */
830     transaction.txBuf = NULL;
831     transaction.rxBuf = &deviceId;
832     transaction.count = 1;
834     transferType = SPI_TRANSACTION_TYPE_READ;
835     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
838     retVal = SPI_transfer(handle, &transaction);
840     /* Note - This ID is the device ID of the flash device.
841      * This ID is read from the flash
842      */
844     /* Restore operating mode and rx Lines */
845     object->qspiMode = operMode;
846     SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLines);
849 static bool SF25FL_ConfigMode_Write(uint32_t dstOffstAddr,
850                                     unsigned char* srcAddr,
851                                     uint32_t length,
852                                     S25FL_Handle flashHandle)
854     bool retVal = false;                        /* return value */
855     SPI_Handle handle = flashHandle->spiHandle; /* SPI handle */
856     uint32_t addrLengthInBytes = 3U;            /* Flash addr length in bytes */
857     unsigned int frmLength;
858     unsigned char writeVal[4];                  /* data to be written to QSPI */
859     SPI_Transaction transaction;                /* SPI transaction structure */
860     unsigned int transferType;
863     addrLengthInBytes = 3U;        /* Flash address length in bytes */
865     /* Extract address word length from the flash's destination offst addr*/
866     if(dstOffstAddr > 0xFFFFFF)
867     {
868         /* Enter 32 bit addressing mode */
869         S25FLFlash_Enable4ByteAddrMode(flashHandle, true);
870         addrLengthInBytes = 4;
871     }
873     /* Write Enable */
874     S25FLFlash_WriteEnable(flashHandle);
876     /* total transaction frame length in number of words (bytes)*/
877     frmLength = 1 + addrLengthInBytes + length;
878     SPI_control(handle, SPI_V1_CMD_SETFRAMELENGTH, ((void *)&frmLength));
880     /* Send Flash write command */
881     writeVal[0] = QSPI_LIB_CMD_PAGE_PRG;   /* Flash write command */
882     transaction.txBuf = (unsigned char *)&writeVal[0];
883     transaction.rxBuf = NULL;
884     transaction.count = 1U;
886     transferType = SPI_TRANSACTION_TYPE_WRITE;
887     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
888     retVal = SPI_transfer(handle, &transaction);
890     /* Send flash address offset to which data has to be written */
891     transaction.txBuf = (unsigned char *)dstOffstAddr;
892     transaction.rxBuf = NULL;
893     transaction.count = addrLengthInBytes;
895     transferType = SPI_TRANSACTION_TYPE_WRITE;
896     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
897     retVal = SPI_transfer(handle, &transaction);
899     /* Write buffer data to flash */
900     transaction.txBuf = (unsigned char *)srcAddr;
901     transaction.rxBuf = NULL;
902     transaction.count = length;
904     transferType = SPI_TRANSACTION_TYPE_WRITE;
905     SPI_control(handle, SPI_V1_CMD_TRANSFERMODE_RW, (void *)&transferType);
906     retVal = SPI_transfer(handle, &transaction);
908     /* Check flash status for write completion */
909     while ((FlashStatus(flashHandle) & 0x1U));
911     if(dstOffstAddr > 0xFFFFFF)
912     {
913         /* Exit 32 bit addressing mode */
914         S25FLFlash_Enable4ByteAddrMode(flashHandle, false);
915         addrLengthInBytes = 3;
916     }
918     return retVal;