/****************************************************************************** * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ #include #include "platform.h" #include "types.h" #include "post.h" /* The version string */ #pragma DATA_SECTION(post_version, ".version") #pragma DATA_ALIGN(post_version, 16) char post_version[] = POST_VERSION; /****************************************************************************** * Function: post_display_led_error ******************************************************************************/ void post_display_led_error ( POST_TEST_ID test_id ) { uint8_t led_status[POST_MAX_NUM_LED]; uint32_t i; memset(led_status, POST_LED_ON, POST_MAX_NUM_LED); while (TRUE) { for (i = 0; i < POST_MAX_NUM_LED; i++) { if (post_led_status[test_id][i] == POST_LED_BLINK) { if (led_status[i] == POST_LED_ON) { led_status[i] = POST_LED_OFF; } else { led_status[i] = POST_LED_ON; } platform_led(i, (PLATFORM_LED_OP)led_status[i], PLATFORM_USER_LED_CLASS); } else { platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS); } } platform_delay(POST_LED_BLINK_DELAY); /* POST in the while(1) loop to display the LED error status */ } } /****************************************************************************** * Function: post_write_uart ******************************************************************************/ Bool post_write_uart ( char* msg ) { uint32_t i; uint32_t msg_len = strlen(msg); /* Write the message to the UART */ for (i = 0; i < msg_len; i++) { if (platform_uart_write(msg[i]) != Platform_EOK) { return FALSE; } } return TRUE; } /****************************************************************************** * Function: post_display_status ******************************************************************************/ void post_display_status ( POST_TEST_ID test_id, Bool test_passed ) { uint32_t i; char *msg; char msg1[40] = "\r\n\r\nPOST "; char msg2[] = " test passed!"; char msg3[] = " test failed!"; msg = strcat(msg1, post_status[test_id]); switch (test_id) { case POST_TEST_IN_PROGRESS: case POST_TEST_COMPLETE: /* Form the POST status message to write to the UART */ if (post_write_uart(msg) != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } for (i = 0; i < POST_MAX_NUM_LED; i++) { if (platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS) != Platform_EOK) { post_write_uart("POST LED test failed \r\n"); } } break; default: /* Form the POST status message to write to the UART */ if (test_passed) { msg = strcat(msg, msg2); if (post_write_uart(msg) != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } } else { msg = strcat(msg, msg3); if (post_write_uart(msg) != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } post_display_led_error(test_id); /* Never return from this function */ } break; } } /****************************************************************************** * Function: post_test_external_memory ******************************************************************************/ Bool post_test_external_memory ( void ) { Bool test_passed = TRUE; if(platform_external_memory_test(0, 0) != Platform_EOK) { test_passed = FALSE; } return test_passed; } /****************************************************************************** * Function: post_test_eeprom ******************************************************************************/ Bool post_test_eeprom ( void ) { uint8_t test_buf[POST_EEPROM_TEST_READ_LENGTH]; Bool test_passed = TRUE; PLATFORM_DEVICE_info *p_device; p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0); if (p_device == NULL) { return FALSE; } if(platform_device_read(p_device->handle, POST_EEPROM_TEST_READ_ADDRESS, test_buf, POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK) { test_passed = FALSE; } platform_device_close(p_device->handle); return test_passed; } /****************************************************************************** * Function: post_test_nand ******************************************************************************/ Bool post_test_nand ( void ) { uint8_t test_buf[POST_NAND_TEST_READ_LENGTH]; Bool test_passed = TRUE; uint32_t addr; PLATFORM_DEVICE_info *p_device; p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0); if (p_device == NULL) { return FALSE; } addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size; if(platform_device_read(p_device->handle, addr, test_buf, POST_NAND_TEST_READ_LENGTH) != Platform_EOK) { test_passed = FALSE; } platform_device_close(p_device->handle); return test_passed; } /****************************************************************************** * Function: post_test_nor ******************************************************************************/ Bool post_test_nor ( void ) { uint8_t test_buf[POST_NOR_TEST_READ_LENGTH]; Bool test_passed = TRUE; PLATFORM_DEVICE_info *p_device; p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0); if (p_device == NULL) { return FALSE; } if(platform_device_read(p_device->handle, POST_NOR_TEST_READ_ADDR, test_buf, POST_NOR_TEST_READ_LENGTH) != Platform_EOK) { test_passed = FALSE; } platform_device_close(p_device->handle); return test_passed; } void post_hex_to_string ( uint32_t hex, uint32_t nibbles, char *msg ) { int32_t i; uint8_t nibble; for (i = (nibbles-1); i >= 0; i--) { nibble = hex & 0xf; if (nibble <= 0x9) { nibble += '0'; } else { nibble += ('A' - 0xa); } msg[i] = nibble; hex = hex >> 4; } msg[nibbles] = 0; } Bool post_serial_num_isvalid ( char c ) { if ( ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) ) { return TRUE; } else { return FALSE; } } /****************************************************************************** * Function: post_write_serial_no ******************************************************************************/ void post_write_serial_no ( void ) { uint32_t i, j; uint8_t msg[20], msg2[2]; PLATFORM_DEVICE_info *p_device; /* Check if user key in the passcode "ti" to enter board serial number */ if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK) { return; } if (msg[0] != 't') { return; } if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK) { return; } if (msg[0] != 'i') { return; } /* Passcode verified, prompt the user to enter serial number */ p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0); if (p_device == NULL) { return; } 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"); i = 0; msg2[1] = 0; while (TRUE) { if (platform_uart_read(&msg[i], POST_UART_READ_TIMEOUT) != Platform_EOK) { platform_device_close(p_device->handle); post_write_uart("\r\n\r\nSerial number input time out!"); return; } if (msg[i] == '\r') { break; } if ((i < POST_MAX_SN_SIZE) && post_serial_num_isvalid(msg[i])) { msg2[0] = msg[i]; post_write_uart((char *)msg2); i++; } } if (i < POST_MAX_SN_SIZE) { for (j = i; j < POST_MAX_SN_SIZE; j++) { msg[j] = 0xff; } } if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK) { post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! "); } else { post_write_uart("\r\n\r\nFailed to program the serial number to EEPROM!"); } platform_device_close(p_device->handle); } /****************************************************************************** * Function: main function for POST ******************************************************************************/ void main ( void ) { platform_init_flags init_flags; platform_init_config init_config; POST_TEST_ID test_id = POST_TEST_IN_PROGRESS; Bool test_passed = TRUE; uint32_t reset_type; int32_t i; char msg[9]; uint8_t mac_addr[6]; platform_info info; uint32_t sa_enable; /* Turn on all the platform initialize flags */ memset(&init_config, 0, sizeof(platform_init_config)); memset(&init_flags, 0x01, sizeof(platform_init_flags)); /* Initialize the platform */ if (platform_init(&init_flags, &init_config) != Platform_EOK) { switch (platform_errno) { case PLATFORM_ERRNO_PLL_SETUP: test_id = POST_TEST_PLL_INIT; break; case PLATFORM_ERRNO_NAND: test_id = POST_TEST_NAND_INIT; break; case PLATFORM_ERRNO_NOR: test_id = POST_TEST_NOR_INIT; break; default: test_id = POST_TEST_GENERAL; break; } test_passed = FALSE; } platform_uart_init(); platform_uart_set_baudrate(POST_UART_BAUDRATE); if (test_id != POST_TEST_PLL_INIT) { if (post_write_uart("\r\n\r\n") != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } platform_get_info(&info); /* Display the board name */ post_write_uart(info.board_name); /* Display the POST version */ post_write_uart(POST_EVM_VERSION_MSG); post_write_uart(post_version); post_hex_to_string(info.board_rev, 4, msg); post_write_uart("\r\n\r\nFPGA Version: "); post_write_uart(msg); if (info.serial_nbr[0] != 0) { post_write_uart("\r\n\r\nBoard Serial Number: "); post_write_uart(info.serial_nbr); } /* Display the EFUSE MAC address */ platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_addr); post_write_uart("\r\n\r\nEFUSE MAC ID is: "); for (i = 0; i < 6; i++) { post_hex_to_string(info.emac.efuse_mac_address[i], 2, msg); msg[2] = ' '; msg[3] = 0; post_write_uart(msg); } sa_enable = *(volatile uint32_t *)0x20c0004; sa_enable &= 0x1; if (sa_enable) { post_write_uart("\r\n\r\nSA is enabled on this board."); } else { post_write_uart("\r\n\r\nSA is disabled on this board."); } /* Read the PLL Reset Type Status register and display on UART */ reset_type = PLL_CTRL_REG_RSTYPE; post_hex_to_string(reset_type, 8, msg); post_write_uart("\r\n\r\nPLL Reset Type Status Register: 0x"); post_write_uart(msg); } /* Display test in progress UART/LED status or init error */ post_display_status(test_id, test_passed); test_passed = post_test_external_memory(); post_display_status(POST_TEST_DDR, test_passed); test_passed = post_test_eeprom(); post_display_status(POST_TEST_EEPROM, test_passed); test_passed = post_test_nor(); post_display_status(POST_TEST_NOR, test_passed); test_passed = post_test_nand(); post_display_status(POST_TEST_NAND, test_passed); post_display_status(POST_TEST_COMPLETE, TRUE); post_write_serial_no(); }