2902574a9e300f90fe1b792bdcd07d7a0c7b9b53
1 /******************************************************************************
2 * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 *****************************************************************************/
34 #include <string.h>
35 #include "platform.h"
36 #include "types.h"
37 #include "post.h"
39 /* The version string */
40 #pragma DATA_SECTION(post_version, ".version")
41 #pragma DATA_ALIGN(post_version, 16)
42 char post_version[] = POST_VERSION;
44 /******************************************************************************
45 * Function: post_display_led_error
46 ******************************************************************************/
47 void
48 post_display_led_error
49 (
50 POST_TEST_ID test_id
51 )
52 {
53 uint8_t led_status[POST_MAX_NUM_LED];
54 uint32_t i;
56 memset(led_status, POST_LED_ON, POST_MAX_NUM_LED);
57 while (TRUE)
58 {
59 for (i = 0; i < POST_MAX_NUM_LED; i++)
60 {
61 if (post_led_status[test_id][i] == POST_LED_BLINK)
62 {
63 if (led_status[i] == POST_LED_ON)
64 {
65 led_status[i] = POST_LED_OFF;
66 }
67 else
68 {
69 led_status[i] = POST_LED_ON;
70 }
71 platform_led(i, (PLATFORM_LED_OP)led_status[i], PLATFORM_USER_LED_CLASS);
72 }
73 else
74 {
75 platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS);
76 }
77 }
78 platform_delay(POST_LED_BLINK_DELAY);
79 /* POST in the while(1) loop to display the LED error status */
80 }
81 }
83 /******************************************************************************
84 * Function: post_write_uart
85 ******************************************************************************/
86 Bool
87 post_write_uart
88 (
89 char* msg
90 )
91 {
92 uint32_t i;
93 uint32_t msg_len = strlen(msg);
95 /* Write the message to the UART */
96 for (i = 0; i < msg_len; i++)
97 {
98 if (platform_uart_write(msg[i]) != Platform_EOK)
99 {
100 return FALSE;
101 }
102 }
104 return TRUE;
105 }
107 /******************************************************************************
108 * Function: post_display_status
109 ******************************************************************************/
110 void
111 post_display_status
112 (
113 POST_TEST_ID test_id,
114 Bool test_passed
115 )
116 {
117 uint32_t i;
118 char *msg;
119 char msg1[40] = "\r\n\r\nPOST ";
120 char msg2[] = " test passed!";
121 char msg3[] = " test failed!";
123 msg = strcat(msg1, post_status[test_id]);
124 switch (test_id)
125 {
126 case POST_TEST_IN_PROGRESS:
127 case POST_TEST_COMPLETE:
128 /* Form the POST status message to write to the UART */
129 if (post_write_uart(msg) != TRUE)
130 {
131 post_display_led_error(POST_TEST_UART); /* Never return from this function */
132 }
134 for (i = 0; i < POST_MAX_NUM_LED; i++)
135 {
136 if (platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS) != Platform_EOK)
137 {
138 post_write_uart("POST LED test failed \r\n");
139 }
140 }
141 break;
143 default:
144 /* Form the POST status message to write to the UART */
145 if (test_passed)
146 {
147 msg = strcat(msg, msg2);
148 if (post_write_uart(msg) != TRUE)
149 {
150 post_display_led_error(POST_TEST_UART); /* Never return from this function */
151 }
152 }
153 else
154 {
155 msg = strcat(msg, msg3);
156 if (post_write_uart(msg) != TRUE)
157 {
158 post_display_led_error(POST_TEST_UART); /* Never return from this function */
159 }
160 post_display_led_error(test_id); /* Never return from this function */
161 }
162 break;
163 }
164 }
166 /******************************************************************************
167 * Function: post_test_external_memory
168 ******************************************************************************/
169 Bool
170 post_test_external_memory
171 (
172 void
173 )
174 {
175 Bool test_passed = TRUE;
177 if(platform_external_memory_test(0, 0) != Platform_EOK)
178 {
179 test_passed = FALSE;
180 }
182 return test_passed;
183 }
185 /******************************************************************************
186 * Function: post_test_eeprom
187 ******************************************************************************/
188 Bool
189 post_test_eeprom
190 (
191 void
192 )
193 {
194 uint8_t test_buf[POST_EEPROM_TEST_READ_LENGTH];
195 Bool test_passed = TRUE;
196 PLATFORM_DEVICE_info *p_device;
198 p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0);
199 if (p_device == NULL)
200 {
201 return FALSE;
202 }
204 if(platform_device_read(p_device->handle,
205 POST_EEPROM_TEST_READ_ADDRESS,
206 test_buf,
207 POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK)
208 {
209 test_passed = FALSE;
210 }
212 platform_device_close(p_device->handle);
213 return test_passed;
214 }
216 /******************************************************************************
217 * Function: post_test_nand
218 ******************************************************************************/
219 Bool
220 post_test_nand
221 (
222 void
223 )
224 {
225 uint8_t test_buf[POST_NAND_TEST_READ_LENGTH];
226 Bool test_passed = TRUE;
227 uint32_t addr;
228 PLATFORM_DEVICE_info *p_device;
230 p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0);
231 if (p_device == NULL)
232 {
233 return FALSE;
234 }
236 addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size;
237 if(platform_device_read(p_device->handle,
238 addr,
239 test_buf,
240 POST_NAND_TEST_READ_LENGTH) != Platform_EOK)
241 {
242 test_passed = FALSE;
243 }
245 platform_device_close(p_device->handle);
246 return test_passed;
247 }
249 /******************************************************************************
250 * Function: post_test_nor
251 ******************************************************************************/
252 Bool
253 post_test_nor
254 (
255 void
256 )
257 {
258 uint8_t test_buf[POST_NOR_TEST_READ_LENGTH];
259 Bool test_passed = TRUE;
260 PLATFORM_DEVICE_info *p_device;
262 p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0);
263 if (p_device == NULL)
264 {
265 return FALSE;
266 }
268 if(platform_device_read(p_device->handle,
269 POST_NOR_TEST_READ_ADDR,
270 test_buf,
271 POST_NOR_TEST_READ_LENGTH) != Platform_EOK)
272 {
273 test_passed = FALSE;
274 }
276 platform_device_close(p_device->handle);
277 return test_passed;
278 }
280 void
281 post_hex_to_string
282 (
283 uint32_t hex,
284 uint32_t nibbles,
285 char *msg
286 )
287 {
288 int32_t i;
289 uint8_t nibble;
291 for (i = (nibbles-1); i >= 0; i--)
292 {
293 nibble = hex & 0xf;
294 if (nibble <= 0x9)
295 {
296 nibble += '0';
297 }
298 else
299 {
300 nibble += ('A' - 0xa);
301 }
303 msg[i] = nibble;
304 hex = hex >> 4;
305 }
306 msg[nibbles] = 0;
307 }
309 Bool
310 post_serial_num_isvalid
311 (
312 char c
313 )
314 {
315 if (
316 ((c >= '0') && (c <= '9')) ||
317 ((c >= 'a') && (c <= 'z')) ||
318 ((c >= 'A') && (c <= 'Z'))
319 )
320 {
321 return TRUE;
322 }
323 else
324 {
325 return FALSE;
326 }
327 }
329 /******************************************************************************
330 * Function: post_write_serial_no
331 ******************************************************************************/
332 void
333 post_write_serial_no
334 (
335 void
336 )
337 {
338 uint32_t i, j;
339 uint8_t msg[20], msg2[2];
340 PLATFORM_DEVICE_info *p_device;
342 /* Check if user key in the passcode "ti" to enter board serial number */
343 if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
344 {
345 return;
346 }
347 if (msg[0] != 't')
348 {
349 return;
350 }
352 if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
353 {
354 return;
355 }
356 if (msg[0] != 'i')
357 {
358 return;
359 }
361 /* Passcode verified, prompt the user to enter serial number */
362 p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0);
363 if (p_device == NULL)
364 {
365 return;
366 }
368 post_write_uart("\r\n\r\nPlease enter the 10 digit serial number for this board, and then press ENTER key:\r\n\r\n");
370 i = 0;
371 msg2[1] = 0;
372 while (TRUE)
373 {
374 if (platform_uart_read(&msg[i], POST_UART_READ_TIMEOUT) != Platform_EOK)
375 {
376 platform_device_close(p_device->handle);
377 post_write_uart("\r\n\r\nSerial number input time out!");
378 return;
379 }
381 if (msg[i] == '\r')
382 {
383 break;
384 }
385 if ((i < POST_MAX_SN_SIZE) && post_serial_num_isvalid(msg[i]))
386 {
387 msg2[0] = msg[i];
388 post_write_uart((char *)msg2);
389 i++;
390 }
391 }
393 if (i < POST_MAX_SN_SIZE)
394 {
395 for (j = i; j < POST_MAX_SN_SIZE; j++)
396 {
397 msg[j] = 0xff;
398 }
399 }
401 if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK)
402 {
403 post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! ");
404 }
405 else
406 {
407 post_write_uart("\r\n\r\nFailed to program the serial number to EEPROM!");
408 }
409 platform_device_close(p_device->handle);
411 }
413 /******************************************************************************
414 * Function: main function for POST
415 ******************************************************************************/
416 void
417 main
418 (
419 void
420 )
421 {
422 platform_init_flags init_flags;
423 platform_init_config init_config;
424 POST_TEST_ID test_id = POST_TEST_IN_PROGRESS;
425 Bool test_passed = TRUE;
426 uint32_t reset_type;
427 int32_t i;
428 char msg[9];
429 uint8_t mac_addr[6];
430 platform_info info;
431 uint32_t sa_enable;
433 /* Turn on all the platform initialize flags */
434 memset(&init_config, 0, sizeof(platform_init_config));
435 memset(&init_flags, 0x01, sizeof(platform_init_flags));
437 /* Initialize the platform */
438 if (platform_init(&init_flags, &init_config) != Platform_EOK)
439 {
440 switch (platform_errno)
441 {
442 case PLATFORM_ERRNO_PLL_SETUP:
443 test_id = POST_TEST_PLL_INIT;
444 break;
445 case PLATFORM_ERRNO_NAND:
446 test_id = POST_TEST_NAND_INIT;
447 break;
448 case PLATFORM_ERRNO_NOR:
449 test_id = POST_TEST_NOR_INIT;
450 break;
451 default:
452 test_id = POST_TEST_GENERAL;
453 break;
454 }
455 test_passed = FALSE;
456 }
458 platform_uart_init();
459 platform_uart_set_baudrate(POST_UART_BAUDRATE);
460 if (test_id != POST_TEST_PLL_INIT)
461 {
462 if (post_write_uart("\r\n\r\n") != TRUE)
463 {
464 post_display_led_error(POST_TEST_UART); /* Never return from this function */
465 }
467 platform_get_info(&info);
469 /* Display the board name */
470 post_write_uart(info.board_name);
472 /* Display the POST version */
473 post_write_uart(POST_EVM_VERSION_MSG);
474 post_write_uart(post_version);
476 post_hex_to_string(info.board_rev, 4, msg);
477 post_write_uart("\r\n\r\nFPGA Version: ");
478 post_write_uart(msg);
480 if (info.serial_nbr[0] != 0)
481 {
482 post_write_uart("\r\n\r\nBoard Serial Number: ");
483 post_write_uart(info.serial_nbr);
484 }
486 /* Display the EFUSE MAC address */
487 platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_addr);
488 post_write_uart("\r\n\r\nEFUSE MAC ID is: ");
489 for (i = 0; i < 6; i++)
490 {
491 post_hex_to_string(info.emac.efuse_mac_address[i], 2, msg);
492 msg[2] = ' ';
493 msg[3] = 0;
494 post_write_uart(msg);
495 }
497 sa_enable = *(volatile uint32_t *)0x20c0000;
498 sa_enable &= 0x1;
500 if (sa_enable)
501 {
502 post_write_uart("\r\n\r\nSA is enabled on this board.");
503 }
504 else
505 {
506 post_write_uart("\r\n\r\nSA is disabled on this board.");
507 }
509 /* Read the PLL Reset Type Status register and display on UART */
510 reset_type = PLL_CTRL_REG_RSTYPE;
511 post_hex_to_string(reset_type, 8, msg);
512 post_write_uart("\r\n\r\nPLL Reset Type Status Register: 0x");
513 post_write_uart(msg);
514 }
516 /* Display test in progress UART/LED status or init error */
517 post_display_status(test_id, test_passed);
519 test_passed = post_test_external_memory();
520 post_display_status(POST_TEST_DDR, test_passed);
522 test_passed = post_test_eeprom();
523 post_display_status(POST_TEST_EEPROM, test_passed);
525 test_passed = post_test_nor();
526 post_display_status(POST_TEST_NOR, test_passed);
528 test_passed = post_test_nand();
529 post_display_status(POST_TEST_NAND, test_passed);
531 post_display_status(POST_TEST_COMPLETE, TRUE);
533 post_write_serial_no();
534 }