af1585c0c5d0a134bb3e7405624f1a1c5020bd83
[processor-sdk/pdk.git] / packages / ti / drv / spi / test / qspi_flash / src / main_qspi_flash_test.c
1 /**
2 * \file main_flash_read_test.c
3 *
4 * \brief Example application main file. This application will write and read
5 * the data to/from nor flash through qspi interface.
6 *
7 */
9 /*
10 * Copyright (C) 2014-2019 Texas Instruments Incorporated - http://www.ti.com/
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the
22 * distribution.
23 *
24 * Neither the name of Texas Instruments Incorporated nor the names of
25 * its contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 */
42 #include <ti/osal/osal.h>
43 #include <ti/osal/TaskP.h>
45 /* TI-RTOS Header files */
46 #include <ti/csl/soc.h>
47 #include <ti/drv/spi/SPI.h>
48 #include <ti/drv/spi/soc/QSPI_v1.h>
49 #include "SPI_log.h"
51 /* Flash header file */
52 #include <ti/drv/spi/test/qspi_flash/src/Flash_S25FL/S25FL.h>
54 #include <ti/board/board.h>
56 #ifdef SPI_DMA_ENABLE
57 #include <ti/osal/CacheP.h>
58 /* EDMA3 Header files */
59 #if defined(SOC_TPR12) || defined (SOC_AWR294X)
60 #include <ti/drv/edma/edma.h>
61 #else
62 #include <ti/sdo/edma3/drv/edma3_drv.h>
63 #include <ti/sdo/edma3/rm/edma3_rm.h>
64 #include <ti/sdo/edma3/rm/sample/bios6_edma3_rm_sample.h>
65 #endif
66 #endif
68 /**********************************************************************
69 ************************** Macros ************************************
70 **********************************************************************/
71 #define QSPI_PER_CNT (1U)
72 #define QSPI_INSTANCE (1U)
74 #if defined (SOC_AM335x) || defined (SOC_AM437x)
75 #define QSPI_OFFSET (5U)
76 #endif
77 #if defined(SOC_AM574x) || defined (SOC_AM572x) || defined (SOC_AM571x)
78 #define QSPI_OFFSET (4U)
79 #endif
80 #if defined(SOC_TPR12) || defined (SOC_AWR294X)
81 #define QSPI_OFFSET (0U)
82 #endif
84 #define QSPI_TEST_LENGTH (75U) /* read/write test data size in 32-bit words */
85 #if defined(SOC_TPR12) || defined (SOC_AWR294X)
86 /* Test dma transfer of more than 32K length. */
87 #define QSPI_TEST_LENGTH_MMAP (16000U) /* read/write test data size in 32-bit words */
88 #else
89 #define QSPI_TEST_LENGTH_MMAP (75U) /* read/write test data size in 32-bit words */
90 #endif
92 /* Tx and Rx Buffer length should be max of transfer length with min length of 1024. */
93 #define QSPI_TEST_LENGTH_BUFLEN CSL_MAX(1024, CSL_MAX(QSPI_TEST_LENGTH, QSPI_TEST_LENGTH_MMAP))
95 /* Unit test IDs */
96 #define QSPI_TEST_ID_CMD 0 /* Command mode test */
97 #define QSPI_TEST_ID_MMAP 1 /* Memory map with DMA disabled mode test */
98 #define QSPI_TEST_ID_MMAP_DMA 2 /* Memory map with DMA enabled mode test */
100 #if defined (USE_BIOS) || defined (FREERTOS)
101 #define APP_TSK_STACK_MAIN (16U * 1024U)
102 #endif
104 /* Define the SPI test interface */
105 typedef struct QSPI_Tests_s
106 {
107 bool (*testFunc)(void *);
108 int32_t testId;
109 bool intrMode;
110 bool dmaMode;
111 bool mmapMode;
112 char testDesc[80];
114 } QSPI_Tests;
116 /**********************************************************************
117 ************************** Internal functions ************************
118 **********************************************************************/
120 /* Function to generate known data */
121 static void GeneratePattern(uint8_t *txBuf, uint8_t *rxBuf, uint32_t length);
123 /* Data compare function */
124 bool VerifyData(unsigned char *expData,
125 unsigned char *rxData,
126 unsigned int length);
128 #if defined(SOC_AM574x) || defined (SOC_AM571x) || defined (SOC_AM572x)
129 void QSPI_board_crossbarInit(void);
130 #endif
132 #ifdef SPI_DMA_ENABLE
133 #if defined(SOC_TPR12) || defined (SOC_AWR294X)
134 static EDMA_Handle QSPIApp_edmaInit(void);
135 #else
136 static EDMA3_RM_Handle QSPIApp_edmaInit(void);
137 #endif
138 #endif
140 /**********************************************************************
141 ************************** Global Variables **************************
142 **********************************************************************/
144 #if defined (USE_BIOS) || defined (FREERTOS)
145 static uint8_t gAppTskStackMain[APP_TSK_STACK_MAIN] __attribute__((aligned(32)));
146 #endif
148 /* Buffer containing the known data that needs to be written to flash */
149 #if (defined(_TMS320C6X) || defined (__TI_ARM_V7M4__))
150 #pragma DATA_ALIGN (txBuf, 128)
151 uint32_t txBuf[QSPI_TEST_LENGTH_BUFLEN];
152 #pragma DATA_ALIGN (rxBuf, 128)
153 uint32_t rxBuf[QSPI_TEST_LENGTH_BUFLEN];
154 #else
155 uint32_t txBuf[QSPI_TEST_LENGTH_BUFLEN] __attribute__((aligned(128)));
156 uint32_t rxBuf[QSPI_TEST_LENGTH_BUFLEN] __attribute__((aligned(128)));
157 #endif
159 unsigned int addrValue = 0x000000U;
161 /* hardware attributes */
162 extern QSPI_HwAttrs qspiInitCfg[QSPI_PER_CNT];
164 /* transfer length */
165 uint32_t transferLength = 0;
167 #ifdef SPI_DMA_ENABLE
168 /**
169 * \brief Function to initialize the edma driver and get the handle to the
170 * edma driver;
171 */
172 #if defined (SOC_TPR12) || defined (SOC_AWR294X)
173 EDMA_Handle gEdmaHandle = NULL;
175 static EDMA_Handle QSPIApp_edmaInit(void)
176 {
177 uint32_t edma3Id = EDMA_DRV_INST_MSS_A;
178 EDMA_instanceInfo_t instanceInfo;
179 int32_t errorCode;
181 gEdmaHandle = EDMA_getHandle(edma3Id, &instanceInfo);
182 if(gEdmaHandle == NULL)
183 {
184 EDMA3CCInitParams initParam;
186 EDMA3CCInitParams_init(&initParam);
187 initParam.initParamSet = TRUE;
188 if (EDMA_init(edma3Id, &initParam) != EDMA_NO_ERROR)
189 {
190 printf("EDMA_init failed \n");
191 return(gEdmaHandle);
192 }
193 /* Open DMA driver instance 0 for SPI test */
194 gEdmaHandle = EDMA_open(edma3Id, &errorCode, &instanceInfo);
195 if(gEdmaHandle == NULL)
196 {
197 printf("Open DMA driver failed with error=%d\n \n", errorCode);
198 return(gEdmaHandle);
199 }
200 }
202 return(gEdmaHandle);
203 }
204 #else
205 EDMA3_RM_Handle gEdmaHandle = NULL;
207 static EDMA3_RM_Handle QSPIApp_edmaInit(void)
208 {
209 EDMA3_DRV_Result edmaResult = EDMA3_DRV_E_INVALID_PARAM;
210 uint32_t edma3Id;
212 if (gEdmaHandle != NULL)
213 {
214 return (gEdmaHandle);
215 }
217 edma3Id = 0;
218 gEdmaHandle = (EDMA3_RM_Handle)edma3init(edma3Id, &edmaResult);
220 return(gEdmaHandle);
221 }
222 #endif
223 #endif
225 void QSPI_test_print_test_desc(QSPI_Tests *test)
226 {
227 char testId[16] = {0, };
229 /* Print unit test ID */
230 sprintf(testId, "%d", test->testId);
231 SPI_log("\r\n QSPI UT %s\r\n", testId);
233 /* Print test description */
234 SPI_log("\r\n %s\r\n", test->testDesc);
235 }
237 /*
238 * ======== QSPI init config ========
239 */
240 static void QSPI_initConfig(uint32_t instance, QSPI_Tests *test)
241 {
242 QSPI_HwAttrs *cfg = &qspiInitCfg[instance];
243 bool intrMode = test->intrMode;
244 #ifdef SPI_DMA_ENABLE
245 bool dmaMode = test->dmaMode;
246 #endif
248 if (intrMode == true)
249 {
250 /* polling mode */
251 cfg->intrEnable = true;
252 }
253 else
254 {
255 /* interrupt mode */
256 cfg->intrEnable = false;
257 }
259 #ifdef SPI_DMA_ENABLE
260 if (dmaMode == true)
261 {
262 cfg->edmaHandle = QSPIApp_edmaInit();
263 cfg->dmaEnable = true;
264 }
265 else
266 #endif
267 {
268 cfg->edmaHandle = NULL;
269 cfg->dmaEnable = false;
270 }
271 }
273 /**
274 * @b Description
275 * @n
276 * Utility function which converts a local GEM L2 memory address
277 * to global memory address.
278 *
279 * @param[in] addr
280 * Local address to be converted
281 *
282 * @retval
283 * Computed L2 global Address
284 */
285 #ifdef SPI_DMA_ENABLE
286 static uintptr_t l2_global_address (uintptr_t addr)
287 {
288 #if defined (SOC_TPR12) || defined (SOC_AWR294X)
289 return ((uintptr_t)CSL_locToGlobAddr(addr));
290 #else
291 return addr;
292 #endif
293 }
294 #endif
296 static bool QSPI_test_func (void *arg)
297 {
298 QSPI_Tests *test = (QSPI_Tests *)arg;
299 SPI_Params spiParams;
300 S25FL_Handle flashHandle; /* Flash handle */
301 uint32_t blockNumber = 0U; /* Block number */
302 S25FL_Transaction flashTransaction; /* Flash transaction structure */
303 SPI_Handle handle; /* SPI handle */
304 QSPI_HwAttrs *hwAttrs; /* QSPI hardware attributes */
305 bool retVal = true; /* return value */
306 uint32_t rxLines;
307 uint32_t qspiMode;
309 QSPI_initConfig(0, test);
311 /* Default SPI configuration parameters */
312 SPI_Params_init(&spiParams);
314 /* Open QSPI driver */
315 flashHandle = SF25FL_open(((QSPI_INSTANCE - 1)+(QSPI_OFFSET)), &spiParams);
317 /* Extract hardware attributes */
318 handle = flashHandle->spiHandle;
319 hwAttrs = (QSPI_HwAttrs *)handle->hwAttrs;
321 /* Print flash Id */
322 FlashPrintId(flashHandle);
324 for (rxLines = QSPI_RX_LINES_SINGLE; rxLines < (QSPI_RX_LINES_QUAD + 1); rxLines++)
325 {
326 if (test->mmapMode)
327 {
328 qspiMode = QSPI_OPER_MODE_MMAP;
329 SPI_control(handle, SPI_V1_CMD_SETMEMMORYMAPMODE, (void *)&qspiMode);
330 }
331 else
332 {
333 qspiMode = QSPI_OPER_MODE_CFG;
334 SPI_control(handle, SPI_V1_CMD_SETCONFIGMODE, (void *)&qspiMode);
335 }
337 SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLines);
339 /* Erase block, to which data has to be written */
340 S25FLFlash_BlockErase(flashHandle, blockNumber);
342 /* Set the transfer length in number of 32 bit words */
344 if (test->mmapMode)
345 {
346 transferLength = QSPI_TEST_LENGTH_MMAP;
347 }
348 else
349 {
350 transferLength = QSPI_TEST_LENGTH;
351 }
353 /* Generate the data */
354 GeneratePattern((uint8_t *)&txBuf[0], (uint8_t *)&rxBuf[0], transferLength);
356 #ifdef SPI_DMA_ENABLE
357 if (test->dmaMode)
358 {
359 CacheP_wbInv((void *)rxBuf, (int32_t)sizeof(rxBuf));
360 CacheP_wbInv((void *)txBuf, (int32_t)sizeof(txBuf));
361 }
362 #endif
364 /* Update transaction parameters */
365 #ifdef SPI_DMA_ENABLE
366 if (test->dmaMode)
367 {
368 flashTransaction.data = (uint8_t *)l2_global_address((uintptr_t)&txBuf[0]);
369 }
370 else
371 #endif
372 {
373 flashTransaction.data = (uint8_t *)&txBuf[0];
374 }
376 if (test->mmapMode)
377 {
378 flashTransaction.address = addrValue;
379 }
380 else
381 {
382 /*
383 * For CFG Mode,flashTransaction.address should be assigned with the
384 * address of the variable which contains the flash offset value
385 */
386 flashTransaction.address = (uint32_t)&addrValue;
387 }
388 flashTransaction.dataSize = transferLength * 4; /* In bytes */
390 /* Write buffer to flash */
391 retVal = SF25FL_bufferWrite(flashHandle, &flashTransaction);
393 if(QSPI_RX_LINES_QUAD == hwAttrs->rxLines)
394 {
395 S25FLFlash_QuadModeEnable(flashHandle);
396 }
398 /* Update transaction parameters */
399 #ifdef SPI_DMA_ENABLE
400 if (test->dmaMode)
401 {
402 flashTransaction.data = (uint8_t *)l2_global_address((uintptr_t)&rxBuf[0]);
403 }
404 else
405 #endif
406 {
407 flashTransaction.data = (uint8_t *)&rxBuf[0];
408 }
410 if (test->mmapMode)
411 {
412 flashTransaction.address = addrValue;
413 }
414 else
415 {
416 /*
417 * For CFG Mode,flashTransaction.address should be assigned with the
418 * address of the variable which contains the flash offset value
419 */
420 flashTransaction.address = (uint32_t)&addrValue;
421 }
422 flashTransaction.dataSize = transferLength * 4; /* In bytes */
424 /* Read data from flash */
425 retVal = SF25FL_bufferRead(flashHandle, &flashTransaction);
427 /* Verify Data */
428 retVal = VerifyData((unsigned char *)&txBuf[0], (unsigned char *)&rxBuf[0],
429 transferLength);
431 if (retVal == false)
432 {
433 break;
434 }
435 }
437 SF25FL_close(flashHandle);
439 return (retVal);
440 }
442 QSPI_Tests qspi_tests[] =
443 {
444 /* testFunc testID intrMode dmaMode mmapMode testDesc */
445 {QSPI_test_func, QSPI_TEST_ID_CMD, true, false, false, "\r\n QSPI flash command mode test", },
446 {QSPI_test_func, QSPI_TEST_ID_MMAP, false, false, true, "\r\n QSPI flash memory map mode test", },
447 #ifdef SPI_DMA_ENABLE
448 {QSPI_test_func, QSPI_TEST_ID_MMAP_DMA, false, true, true, "\r\n QSPI flash memory map mode with DMA enabled test", },
449 #endif
450 {NULL, },
451 };
453 /*
454 * ======== test function ========
455 */
456 #if defined (USE_BIOS) || defined (FREERTOS)
457 void spi_test(void* arg0, void* arg1)
458 #else
459 void spi_test()
460 #endif
461 {
462 uint32_t i;
463 QSPI_Tests *test;
464 bool testFail = false;
466 /* Init SPI driver */
467 SPI_init();
469 for (i = 0; ; i++)
470 {
471 test = &qspi_tests[i];
472 if (test->testFunc == NULL)
473 break;
475 QSPI_test_print_test_desc(test);
476 if (test->testFunc((void *)test) == true)
477 {
478 SPI_log("\r\n %s have passed\r\n", test->testDesc);
479 }
480 else
481 {
482 SPI_log("\r\n %s have failed\r\n", test->testDesc);
483 testFail = true;
484 break;
485 }
486 }
488 if(true == testFail)
489 {
490 SPI_log("\n All tests have failed. \n");
491 }
492 else
493 {
494 SPI_log("\n All tests have passed. \n");
495 }
497 while(1);
498 }
500 /*
501 * ======== main ========
502 */
503 int main(void)
504 {
505 /* Call board init functions */
506 Board_initCfg boardCfg;
508 #if defined (USE_BIOS) || defined (FREERTOS)
509 TaskP_Params taskParams;
511 OS_init();
513 /* Initialize the Task Parameters. */
514 TaskP_Params_init(&taskParams);
515 taskParams.stack = gAppTskStackMain;
516 taskParams.stacksize = sizeof (gAppTskStackMain);
518 TaskP_create(spi_test, &taskParams);
519 #endif
521 boardCfg = BOARD_INIT_PINMUX_CONFIG |
522 BOARD_INIT_MODULE_CLOCK |
523 BOARD_INIT_UART_STDIO;
524 Board_init(boardCfg);
526 #if defined (SOC_AM571x) || defined (SOC_AM572x) || defined(SOC_AM574x)
527 QSPI_board_crossbarInit();
528 #endif
530 #if defined (USE_BIOS) || defined (FREERTOS)
531 OS_start();
532 #else
533 spi_test();
534 #endif
536 return (0);
537 }
539 /*
540 * ======== Board_initQSPI ========
541 */
542 #if defined (SOC_AM571x) || defined (SOC_AM572x) || defined(SOC_AM574x)
543 void QSPI_board_crossbarInit(void) {
544 #ifndef __ARM_ARCH_7A__
545 CSL_XbarIrqCpuId cpu;
546 uint32_t cpuEvent;
547 uint32_t xbarIndex;
548 #endif
549 #ifdef C66X
550 /* Configure xbar connect for MCSPI3: DSP_IRQ_38 mapped to MCSPI3 intr */
551 cpu = CSL_XBAR_IRQ_CPU_ID_DSP1;
552 cpuEvent = 38;
553 xbarIndex = cpuEvent - 31;
555 /* Configure xbar */
556 CSL_xbarIrqConfigure (cpu, xbarIndex, CSL_XBAR_QSPI_IRQ);
558 #elif __ARM_ARCH_7A__
559 /* Configure xbar connect for QSPI: MPU_IRQ_35 mapped to QSPI intr */
560 *(unsigned int*)0x4A002A80 = (unsigned int)(0x0157001D);
562 #else
564 /* Configure xbar connect for MCSPI3: DSP_IRQ_38 mapped to MCSPI3 intr */
565 cpu = CSL_XBAR_IRQ_CPU_ID_IPU1;
566 cpuEvent = 62;
567 xbarIndex = cpuEvent - 22;
569 /* Configure xbar */
570 CSL_xbarIrqConfigure (cpu, xbarIndex, CSL_XBAR_QSPI_IRQ);
571 #endif
573 }
574 #endif
576 /*
577 * ======== CompareData ========
578 */
579 bool VerifyData(unsigned char *expData,
580 unsigned char *rxData,
581 unsigned int length)
582 {
583 unsigned int idx = 0;
584 unsigned int match = 1;
585 bool retVal = false;
586 unsigned int lenInBytes = length * 4;
588 for(idx = 0; ((idx < lenInBytes) && (match != 0)); idx++)
589 {
590 if(*expData != *rxData) match = 0;
591 expData++;
592 rxData++;
593 }
595 if(match == 1) retVal = true;
597 return retVal;
598 }
600 /*
601 * ======== GeneratePattern ========
602 */
603 static void GeneratePattern(uint8_t *txBuf, uint8_t *rxBuf, uint32_t length)
604 {
605 unsigned int idx;
606 unsigned int lenInBytes = length * 4;
608 for(idx = 0; idx < lenInBytes; idx++)
609 {
610 txBuf[idx] = (uint8_t)idx;
611 rxBuf[idx] = (uint8_t)0U;
612 }
613 }