[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_1_eng / packages / ti / board / src / idkAM571x / 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;
170 }
174 bool SF25FL_bufferRead(S25FL_Handle flashHandle,
175 S25FL_Transaction* flashTransaction)
176 {
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;
353 }
356 bool S25FLFlash_WriteEnable(S25FL_Handle flashHandle)
357 {
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;
407 }
410 bool S25FLFlash_Enable4ByteAddrMode(S25FL_Handle flashHandle,
411 bool enable4ByteMode)
412 {
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;
466 }
469 uint32_t FlashStatus(S25FL_Handle flashHandle)
470 {
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);
539 }
542 bool S25FLFlash_QuadModeEnable(S25FL_Handle flashHandle)
543 {
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;
648 }
651 bool S25FLFlash_BlockErase(S25FL_Handle flashHandle, unsigned int blockNumber)
652 {
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;
750 }
753 void FlashPrintId(S25FL_Handle flashHandle)
754 {
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);
847 }
849 static bool SF25FL_ConfigMode_Write(uint32_t dstOffstAddr,
850 unsigned char* srcAddr,
851 uint32_t length,
852 S25FL_Handle flashHandle)
853 {
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;
919 }