1 \r
2 /*\r
3 * Copyright (c) 2014-2017, Texas Instruments Incorporated\r
4 * All rights reserved.\r
5 *\r
6 * Redistribution and use in source and binary forms, with or without\r
7 * modification, are permitted provided that the following conditions\r
8 * are met:\r
9 *\r
10 * * Redistributions of source code must retain the above copyright\r
11 * notice, this list of conditions and the following disclaimer.\r
12 *\r
13 * * Redistributions in binary form must reproduce the above copyright\r
14 * notice, this list of conditions and the following disclaimer in the\r
15 * documentation and/or other materials provided with the distribution.\r
16 *\r
17 * * Neither the name of Texas Instruments Incorporated nor the names of\r
18 * its contributors may be used to endorse or promote products derived\r
19 * from this software without specific prior written permission.\r
20 *\r
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
31 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
32 */\r
33 \r
34 /* TI-RTOS Header files */\r
35 #include <ti/drv/uart/UART_stdio.h>\r
36 #include <ti/csl/soc/am572x/src/cslr_control_core_pad_io.h>\r
37 #include <ti/csl/soc/am65xx/src/cslr_soc.h>\r
38 #include <stdlib.h>\r
39 \r
40 #include <ti/drv/gpio/GPIO.h>\r
41 #include <ti/drv/spi/SPI.h>\r
42 #include <ti/drv/spi/soc/SPI_soc.h>\r
43 #if !defined(SOC_AM65XX)\r
44 #include <ti/drv/gpio/soc/GPIO_soc.h>\r
45 #else\r
46 #include "diag_common_cfg.h"\r
47 #endif\r
48 #include "board.h"\r
49 #include "board_cfg.h"\r
50 \r
51 /**********************************************************************\r
52 ************************** Macros ************************************\r
53 **********************************************************************/\r
54 /* Board specific definitions */\r
55 #if defined (SOC_AM437x)\r
56 #define MCSPI_INSTANCE (2U)\r
57 #endif\r
58 #if defined (SOC_AM572x) || defined (SOC_AM571x) || defined (SOC_AM574x)\r
59 #define MCSPI_INSTANCE (3U)\r
60 #endif\r
61 #ifdef iceAMIC110\r
62 #define MCSPI_INSTANCE (1U)\r
63 #endif\r
64 #if defined (SOC_AM65XX)\r
65 #define MCSPI_INSTANCE (1U)\r
66 #endif\r
67 \r
68 /* GPIO pin value definitions */\r
69 #define GPIO_PIN_VAL_LOW (0U)\r
70 #define GPIO_PIN_VAL_HIGH (1U)\r
71 \r
72 #ifdef iceAMIC110\r
73 #define CSL_MCSPI_PER_CNT (1U)\r
74 #elif defined(SOC_AM65XX)\r
75 #define CSL_MCSPI_PER_CNT (5U)\r
76 #else\r
77 #define CSL_MCSPI_PER_CNT (4U)\r
78 #endif\r
79 #define CSL_QSPI_PER_CNT 1U\r
80 \r
81 /**********************************************************************\r
82 ************************** Internal functions ************************\r
83 **********************************************************************/\r
84 /* Board init function */\r
85 extern void Board_initSPI(void);\r
86 \r
87 int8_t BoardDiag_mcspiFuctionalTest(void);\r
88 \r
89 void AppDelay(uint32_t delayVal);\r
90 \r
91 /* Function to control load signal to the industrial input module */\r
92 void LoadData(void);\r
93 \r
94 #ifdef iceAMIC110\r
95 #define BUFF_SIZE (256U)\r
96 #define MAX_BUFF_SIZE (260U)\r
97 #define FLASH_TEST_SECTOR (0x800000U)\r
98 #define FLASH_READ_CMD (0x03U)\r
99 #define FLASH_WRITE_CMD (0x02U)\r
100 #define FLASH_SECT_ERASE_CMD (0x20U)\r
101 #define FLASH_READ_STS_CMD (0x05U)\r
102 #define FLASH_WE_CMD (0x06U)\r
103 /* Buffer containing the known data that needs to be written to flash */\r
104 uint8_t txBuf[MAX_BUFF_SIZE];\r
105 /* Buffer containing the received data */\r
106 uint8_t rxBuf[MAX_BUFF_SIZE] ;\r
107 uint8_t verifyBuf[BUFF_SIZE];\r
108 #endif\r
109 \r
110 /* Function to verify data */\r
111 bool VerifyData(uint8_t *expData, uint8_t *rxData, uint32_t length);\r
112 \r
113 /**********************************************************************\r
114 ************************** Global Variables **************************\r
115 **********************************************************************/\r
116 \r
117 \r
118 extern const SPI_Config SPI_config[];\r
119 \r
120 #define BOARD_IDK_SPI_LD_PIN (0U)\r
121 \r
122 /*\r
123 * ======== test function ========\r
124 */\r
125 \r
126 #ifndef iceAMIC110\r
127 int spi_test()\r
128 {\r
129 SPI_Params spiParams; /* SPI params structure */\r
130 SPI_Handle handle; /* SPI handle */\r
131 SPI_Transaction transaction; /* SPI transaction */\r
132 bool retVal = false; /* return value */\r
133 int index;\r
134 char p = 'r';\r
135 SPI_v1_HWAttrs spiCfg;\r
136 \r
137 /* Buffer containing the known data that needs to be written to flash */\r
138 uint8_t txBuf[1U];\r
139 \r
140 /* Buffer containing the received data */\r
141 uint8_t rxBuf[1U] = {0xFFU};\r
142 \r
143 /* Transfer length */\r
144 uint32_t transferLength;\r
145 \r
146 for (index=0; index<CSL_MCSPI_PER_CNT; index++)\r
147 {\r
148 SPI_socGetInitCfg(index, &spiCfg);\r
149 spiCfg.enableIntr = false;\r
150 #if defined(SOC_AM65XX)\r
151 spiCfg.chNum = 1;\r
152 #endif\r
153 SPI_socSetInitCfg(index, &spiCfg);\r
154 }\r
155 \r
156 #if !defined(SOC_AM65XX)\r
157 for (index=CSL_MCSPI_PER_CNT; index<CSL_MCSPI_PER_CNT+CSL_QSPI_PER_CNT; index++)\r
158 {\r
159 ((QSPI_HwAttrs *)SPI_config[index].hwAttrs)->intrEnable = false;\r
160 }\r
161 #endif\r
162 \r
163 /* Init GPIO driver */\r
164 GPIO_init();\r
165 \r
166 /* Init SPI driver */\r
167 SPI_init();\r
168 \r
169 /* Default SPI configuration parameters */\r
170 SPI_Params_init(&spiParams);\r
171 spiParams.frameFormat = SPI_POL1_PHA0;\r
172 \r
173 /* Open QSPI driver */\r
174 handle = SPI_open((MCSPI_INSTANCE - 1U), &spiParams);\r
175 \r
176 do {\r
177 \r
178 /* Load data */\r
179 LoadData();\r
180 /* Initiate transfer */\r
181 txBuf[0] = 0xAAU;\r
182 transferLength = 1U;\r
183 transaction.count = transferLength;\r
184 transaction.txBuf = &txBuf[0];\r
185 transaction.rxBuf = &rxBuf[0];\r
186 retVal = SPI_transfer(handle, &transaction);\r
187 AppDelay(100000);\r
188 \r
189 if(false == retVal)\r
190 {\r
191 UART_printf("\nError occurred in spi transfer \n");\r
192 UART_printf("Data received: %x\n", rxBuf[0]);\r
193 UART_printf("Status code returned by LLD is: %d\n", (int) transaction.status);\r
194 p = 'n';\r
195 }\r
196 else\r
197 {\r
198 UART_printf("Data transferred: %x\n", txBuf[0]);\r
199 \r
200 #if defined(SOC_AM65XX)\r
201 UART_printf("Data received: %x\n", rxBuf[0]);\r
202 \r
203 if(rxBuf[0] == 0x55)\r
204 {\r
205 p = 'y';\r
206 }\r
207 else\r
208 {\r
209 p = 'n';\r
210 }\r
211 #else\r
212 UART_printf("Data received: %x\n", rxBuf[0]);\r
213 UART_printf("Press 'y' to verify pass, 'r' to read again,\n");\r
214 UART_printf("or any other character to indicate failure: ");\r
215 UART_scanFmt("%c", &p);\r
216 UART_printf("User input: %c\n", p);\r
217 #endif\r
218 }\r
219 if (p == 'r') UART_printf("\nReading again\n");\r
220 } while (p == 'r');\r
221 \r
222 if ( (p == 'y') || (p == 'Y') ) {\r
223 UART_printf("\nTest PASSED!\n");\r
224 return 0;\r
225 }\r
226 else {\r
227 UART_printf("\nTest FAILED!\n");\r
228 return -1;\r
229 }\r
230 \r
231 SPI_close(handle);\r
232 \r
233 }\r
234 \r
235 /*\r
236 * ======== Function to control load signal to load data ========\r
237 */\r
238 void LoadData(void)\r
239 {\r
240 GPIO_write(BOARD_IDK_SPI_LD_PIN, GPIO_PIN_VAL_LOW);\r
241 AppDelay(10000);\r
242 GPIO_write(BOARD_IDK_SPI_LD_PIN, GPIO_PIN_VAL_HIGH);\r
243 AppDelay(10000);\r
244 }\r
245 \r
246 #else /* #ifndef iceAMIC110 */\r
247 \r
248 /* Function to erase a flash sector */\r
249 static int spi_erase_sector(SPI_Handle handle, uint32_t sector)\r
250 {\r
251 bool retVal = false;\r
252 SPI_Transaction transaction;\r
253 \r
254 /* Write Enable */\r
255 txBuf[0] = FLASH_WE_CMD;\r
256 transaction.count = 1U;\r
257 transaction.txBuf = &txBuf[0];\r
258 transaction.rxBuf = &rxBuf[0];\r
259 retVal = SPI_transfer(handle, &transaction);\r
260 if(retVal == false)\r
261 {\r
262 UART_printf("Write Enable Failed \n");\r
263 SPI_close(handle);\r
264 return -1;\r
265 }\r
266 \r
267 /* Sector erase */\r
268 txBuf[0] = FLASH_SECT_ERASE_CMD;\r
269 txBuf[1] = (sector >> 16) & 0xFF;\r
270 txBuf[2] = (sector >> 8) & 0xFF;\r
271 txBuf[3] = sector & 0xFF;\r
272 transaction.count = 4U;\r
273 retVal = SPI_transfer(handle, &transaction);\r
274 if(retVal == false)\r
275 {\r
276 UART_printf("Sector erase Failed \n");\r
277 SPI_close(handle);\r
278 return -1;\r
279 }\r
280 \r
281 /* Check for Flash Busy */\r
282 do{\r
283 txBuf[0] = FLASH_READ_STS_CMD;\r
284 txBuf[1] = 0xFFU;\r
285 transaction.count = 2U;\r
286 retVal = SPI_transfer(handle, &transaction);\r
287 } while(rxBuf[1] & 0x01);\r
288 \r
289 return 0;\r
290 }\r
291 \r
292 int spi_flash_test(void)\r
293 {\r
294 SPI_Params spiParams; /* SPI params structure */\r
295 SPI_Handle handle; /* SPI handle */\r
296 SPI_Transaction transaction; /* SPI transaction */\r
297 bool retVal = false; /* return value */\r
298 int i;\r
299 \r
300 for (i=0; i<CSL_MCSPI_PER_CNT; i++)\r
301 {\r
302 ((SPI_v1_HWAttrs *)SPI_config[i].hwAttrs)->enableIntr = false;\r
303 ((SPI_v1_HWAttrs *)SPI_config[i].hwAttrs)->chNum = 0;\r
304 }\r
305 \r
306 /* Init SPI driver */\r
307 SPI_init();\r
308 \r
309 /* Default SPI configuration parameters */\r
310 SPI_Params_init(&spiParams);\r
311 \r
312 /* Open QSPI driver */\r
313 handle = SPI_open((MCSPI_INSTANCE - 1U), &spiParams);\r
314 \r
315 for(i = 4; i < MAX_BUFF_SIZE; i++)\r
316 {\r
317 txBuf[i] = 0x0U;\r
318 }\r
319 \r
320 /* Erase flash sector before write */\r
321 spi_erase_sector(handle, FLASH_TEST_SECTOR);\r
322 \r
323 transaction.txBuf = &txBuf[0];\r
324 transaction.rxBuf = &rxBuf[0];\r
325 \r
326 /* Write Enable */\r
327 txBuf[0] = FLASH_WE_CMD;\r
328 transaction.count = 1U;\r
329 retVal = SPI_transfer(handle, &transaction);\r
330 if(retVal == false)\r
331 {\r
332 UART_printf("Write Enable Failed \n");\r
333 SPI_close(handle);\r
334 return -1;\r
335 }\r
336 \r
337 /* Write to SPI Flash */\r
338 txBuf[0] = FLASH_WRITE_CMD;\r
339 txBuf[1] = (FLASH_TEST_SECTOR >> 16) & 0xFF;\r
340 txBuf[2] = (FLASH_TEST_SECTOR >> 8) & 0xFF;\r
341 txBuf[3] = (FLASH_TEST_SECTOR) & 0xFF;\r
342 transaction.count = MAX_BUFF_SIZE;\r
343 for(i=4; i<MAX_BUFF_SIZE; i++)\r
344 {\r
345 txBuf[i] = i - 4;\r
346 verifyBuf[i-4] = txBuf[i];\r
347 }\r
348 \r
349 retVal = SPI_transfer(handle, &transaction);\r
350 if(retVal == true)\r
351 UART_printf("SPI Write Successful \n");\r
352 else\r
353 {\r
354 UART_printf("SPI Write Failed \n");\r
355 SPI_close(handle);\r
356 return -1;\r
357 }\r
358 \r
359 /* Read from SPI flash */\r
360 txBuf[0] = FLASH_READ_CMD;\r
361 txBuf[1] = (FLASH_TEST_SECTOR >> 16) & 0xFF;\r
362 txBuf[2] = (FLASH_TEST_SECTOR >> 8) & 0xFF;\r
363 txBuf[3] = (FLASH_TEST_SECTOR) & 0xFF;\r
364 transaction.count = MAX_BUFF_SIZE;\r
365 retVal = SPI_transfer(handle, &transaction);\r
366 \r
367 if(retVal == true)\r
368 {\r
369 UART_printf("SPI Read Successful \n");\r
370 }\r
371 else\r
372 {\r
373 UART_printf("SPI Read Failed \n");\r
374 SPI_close(handle);\r
375 return -1;\r
376 }\r
377 \r
378 if(VerifyData(&verifyBuf[0],&rxBuf[4],BUFF_SIZE) == true)\r
379 {\r
380 UART_printf("Data Read matches with Data written\n");\r
381 UART_printf("SPI Flash Test Passed!\n");\r
382 }\r
383 else\r
384 {\r
385 UART_printf("SPI Flash Test Failed!\n");\r
386 SPI_close(handle);\r
387 return -1;\r
388 }\r
389 \r
390 /* Erase flash sector after the test */\r
391 spi_erase_sector(handle, FLASH_TEST_SECTOR);\r
392 \r
393 SPI_close(handle);\r
394 \r
395 return 0;\r
396 }\r
397 #endif /* #ifndef iceAMIC110 */\r
398 #ifdef DIAG_STRESS_TEST\r
399 /**\r
400 * \brief The function performs the mcspi Diagnostic\r
401 * stress test.\r
402 *\r
403 * \return int8_t\r
404 * 0 - in case of success\r
405 * -1 - in case of failure.\r
406 *\r
407 */\r
408 int8_t BoardDiag_mcspiStressTest(void)\r
409 {\r
410 int8_t ret = 0;\r
411 char rdBuf = 'y';\r
412 uint32_t iteration;\r
413 uint32_t passCount = 0;\r
414 uint32_t failCount = 0;\r
415 \r
416 UART_printf("\n\nRunning mcspi Test in Stress Mode for %d Number of Times...\n", DIAG_STRESS_TEST_ITERATIONS);\r
417 UART_printf("Enter 'b' in Serial Console to Terminate the Test\n\n");\r
418 \r
419 for(iteration = 1; iteration <= DIAG_STRESS_TEST_ITERATIONS; iteration++)\r
420 {\r
421 ret = BoardDiag_mcspiFuctionalTest();\r
422 if (ret == 0)\r
423 {\r
424 UART_printf("\n\n\n\nIteration : %d mcspi Test Passed\n",iteration);\r
425 passCount++;\r
426 }\r
427 else\r
428 {\r
429 UART_printf("\n\n\n\nmcspi Test Failed at iteration - %d\n",iteration);\r
430 failCount++;\r
431 }\r
432 \r
433 /* Check if there a input from console to break the test */\r
434 rdBuf = (char)BoardDiag_getUserInput(BOARD_UART_INSTANCE);\r
435 if((rdBuf == 'b') || (rdBuf == 'B'))\r
436 {\r
437 UART_printf("Received Test Termination... Exiting the Test\n");\r
438 iteration++;\r
439 break;\r
440 }\r
441 }\r
442 \r
443 UART_printf("\n\nMcspi Stress Test Status\n");\r
444 UART_printf("===================================\n");\r
445 UART_printf("Number of Times Executed - %d\n", (iteration - 1));\r
446 UART_printf("Pass Count - %d\n", passCount);\r
447 UART_printf("Fail Count - %d\n", failCount);\r
448 \r
449 if((iteration != 0) && (failCount == 0))\r
450 {\r
451 UART_printf("Overall Status - PASS\n\n\n" );\r
452 }\r
453 else\r
454 {\r
455 UART_printf("Overall Status - FAIL\n\n\n" );\r
456 ret = -1;\r
457 }\r
458 \r
459 return ret;\r
460 }\r
461 #endif\r
462 \r
463 \r
464 /**\r
465 * \brief The function performs the mcspi Diagnostic\r
466 * functional test.\r
467 *\r
468 * \return int8_t\r
469 * 0 - in case of success\r
470 * -1 - in case of failure.\r
471 *\r
472 */\r
473 int8_t BoardDiag_mcspiFuctionalTest(void)\r
474 {\r
475 int8_t ret = 0;\r
476 \r
477 UART_printf("\n*********************************************\n"); \r
478 UART_printf ("* MCSPI Test *\n");\r
479 UART_printf ("*********************************************\n");\r
480 \r
481 UART_printf("\nTesting MCSPI...\n");\r
482 \r
483 #ifdef iceAMIC110\r
484 return spi_flash_test();\r
485 #else\r
486 ret = spi_test();\r
487 return ret;\r
488 #endif\r
489 }\r
490 \r
491 #if defined(SOC_AM65XX)\r
492 #if !defined (__aarch64__)\r
493 void enableMAINSPI()\r
494 {\r
495 SPI_v1_HWAttrs spiCfg;\r
496 \r
497 SPI_socGetInitCfg((MCSPI_INSTANCE-1), &spiCfg);\r
498 \r
499 spiCfg.baseAddr = CSL_MCSPI0_CFG_BASE;\r
500 spiCfg.enableIntr = 0;\r
501 \r
502 SPI_socSetInitCfg((MCSPI_INSTANCE-1), &spiCfg);\r
503 }\r
504 #endif\r
505 #endif\r
506 \r
507 /*\r
508 * ======== main ========\r
509 */\r
510 #ifndef SPI_BOOT_FRAMEWORK\r
511 int main(void)\r
512 {\r
513 Board_initCfg boardCfg;\r
514 int8_t ret = 0;\r
515 \r
516 #ifdef PDK_RAW_BOOT\r
517 boardCfg = BOARD_INIT_MODULE_CLOCK |\r
518 BOARD_INIT_PINMUX_CONFIG |\r
519 BOARD_INIT_UART_STDIO;\r
520 #else\r
521 boardCfg = BOARD_INIT_UART_STDIO;\r
522 #endif\r
523 \r
524 Board_init(boardCfg);\r
525 \r
526 #if defined(SOC_AM65XX)\r
527 #if !defined (__aarch64__)\r
528 enableMAINSPI();\r
529 #endif\r
530 #endif\r
531 \r
532 #ifdef DIAG_STRESS_TEST\r
533 ret = BoardDiag_mcspiStressTest();\r
534 #else\r
535 ret = BoardDiag_mcspiFuctionalTest();\r
536 #endif\r
537 if(ret == 0)\r
538 {\r
539 UART_printf("\n mcspi Test Passed\n");\r
540 }\r
541 else\r
542 {\r
543 UART_printf("\n mcspi Test Failed\n");\r
544 }\r
545 \r
546 return ret;\r
547 }\r
548 \r
549 /*\r
550 * ======== AppDelay ========\r
551 */\r
552 void AppDelay(uint32_t delayVal)\r
553 {\r
554 uint32_t cnt = 0;\r
555 while(cnt < delayVal)\r
556 {\r
557 asm("");\r
558 cnt++;\r
559 }\r
560 }\r
561 #endif\r
562 \r
563 \r
564 /*\r
565 * ======== CompareData ========\r
566 */\r
567 bool VerifyData(uint8_t *expData, uint8_t *rxData, uint32_t length)\r
568 {\r
569 uint32_t idx = 0;\r
570 uint32_t match = 1;\r
571 bool retVal = false;\r
572 for(idx = 0; ((idx < length) && (match != 0)); idx++)\r
573 {\r
574 if(*expData != *rxData) match = 0;\r
575 expData++;\r
576 rxData++;\r
577 }\r
578 if(match == 1) retVal = true;\r
579 \r
580 return retVal;\r
581 }\r