> I have an AT25F1024, so the problem is not with the ID but it is not > working. I can programm ascii file without any error, but programming > binary file does not work. I posted a message about this on the > arm.cirrus.com forums : > http://arm.cirrus.com/forum/viewtopic.php?t=765 I suppose it's not something as easy as u-boot.bin being over 128K. Do you know where it fails, is it the same area all the time? Perhaps you may want to verify that the spi interface on your board is setup the same way as it is on the eval board. I had a BDI probe available to me when I implemented u-boot on the eval board. I was able to dump the MAC internal ram and see what the bootrom was copying out of spi flash. See the patch below that shows the changes I made to the download.c. If you are using the same atmel flash part, the flasher.S don't need to change. > > Anyhow, either the download utility, BDI flash programmer or linux mtd > > device driver can be used to update SPI flash. > > > If the flasher.S routine worked with your board and don't with mine, > then it will probably will be the same with your u-boot modification. Yes, but debugging u-boot spi writes is a lot easier, since you have a console to print debug info to. > > In my spi_write function I poll waiting on the Write in Progress bit. > > When it's zero that means the data is written. > Yes, sorry, I meant you were not waiting for the tx fifo to empty. > for example instead of > spi_tx_wait(); > spi_rx_clear(); > > you have > udelay(1000); > spi_rx_clear(); > > Since the SPI part looks quite sensitive to me, I am looking at every > detail, trying to know why it is not working with the board I am working > on. I don't remember now why I did it that way. It makes sense to do call spi_tx_wait() to make sure the command get's written. I'll implement the change and try it out. - Ben --- download.c_old 2005-10-26 17:44:15.000000000 -0400 +++ download.c 2006-04-06 11:32:01.000000000 -0400 @@ -24,6 +24,14 @@ #include <unistd.h> #endif +unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len); +#define CFG_ENV_SIZE 0x400 +#define ENV_DATA_OFFSET 4 +#define ENV_BASE_ADDRESS 0x20000 +#define MAC_PREFIX "00:E0:A7" // IPC reserved 802.3 mac address +char tmp_buf[CFG_ENV_SIZE]; + + //********************************************************************** ****** // // lSerialPort is the serial port which is being used. @@ -586,8 +594,8 @@ Usage(void) { fprintf(stderr, "\ -Usage: download {-b <baud>} {-h} {-n <number>} {-o <offset>} {-p <port>}\n\ - {-s} {-t <type>} {-v} <filename>\n\ +Usage: download {-b <baud>} {-h} {-n <SeqNum>} {-p <port>}\n\ + {-o} {-v} <filename>\n\ \n\ Downloads a program image into the NOR FLASH of a Cirrus Logic EP73xx or\n\ EP93xx board, or into the serial EEPROM of a EP93xx board. The Intel B3\n\ @@ -617,22 +625,12 @@ #endif fprintf(stderr, "\ \n\ - -s Program the EEPROM instead of the NOR FLASH (only valid for\n\ - an EP93xx).\n\ -\n\ - -t Specifies the board type, used in conjunction with -n\n\ - (default is \"9312\"). Valid values are 9301, 9302, 9307,\n\ - 9312, or 9315.\n\ -\n\ -v Prints the version of this program.\n\ \n\ When -n is used to specify the board number, the board type and number are\n\ used together to generate the Ethernet MAC address. This information is\n\ -placed at offset 0x1000 in the EEPROM; the 32 bytes of file data at that\n\ -position will be overwritten (or the data will be padded with zeros up to\n\ -that offset). It is valid to not specify a file when the Ethernet MAC\n\ -address is being programmed, in which case the first 0x1000 bytes of the\n\ -EEPROM will be filled with zeros.\n\ +placed at offset 0x20000 in the EEPROM; It is valid to not specify a file\n\ +when the Ethernet MAC address is being programmed.\n\ \n"); } @@ -648,10 +646,10 @@ int main(int argc, char *argv[]) { - long lPort = 1, lRate = 115200, lFileSize, lIdx, lLoop, lSum, lOffset = 0; - long lType = 9312, lNumber; + long lPort = 1, lRate = 115200, lFileSize, lTotalSize, lIdx, lLoop, lSum, lOffset = 0; + long lType = 9307, lNumber; char cChar, cFirstChar, cRateChar, cBuffer[1024], *pcString; - int bError = 0, bEEPROM = 0, bMAC = 0, bHaveFile = 0; + int bError = 0, bEEPROM = 1, bMAC = 0, bHaveFile = 0; FILE *pFile; // @@ -737,12 +735,12 @@ // // Get the board number from the command line. // - lNumber = atoi(optarg); + lNumber = strtol(optarg, NULL, 16); // // Make sure that the specified board number is valid. // - if((lNumber < 1) || (lNumber > 65535)) + if(lNumber == 0) { // // Tell the user that the board number is invalid. @@ -760,6 +758,9 @@ return(1); } + printf("Using MAC Address "MAC_PREFIX":%02X:%02X:%02X\n", + (lNumber >> 16) & 0xff, (lNumber >> 8) & 0xff, lNumber & 0xff);; + // // Indicate that the EEPROM is to be programmed, and that we // have a MAC address. @@ -845,6 +846,7 @@ break; } +#if 0 // // See if this argument is "-s". // @@ -898,6 +900,7 @@ // break; } +#endif // // See if this argument is "-v". @@ -965,6 +968,10 @@ // return(1); } + if(!bMAC) + { + fprintf(stderr, "\nWarning: Board MAC address will not be modified!\n\n"); + } // // Open the serial port to be used. @@ -995,7 +1002,17 @@ // fseek(pFile, 0, SEEK_END); lFileSize = ftell(pFile); + if (lFileSize > ENV_BASE_ADDRESS) + { + fprintf(stderr, "File is too big for environment\n"); + ClosePort(lPort); + return(1); + } fseek(pFile, 0, SEEK_SET); + + lTotalSize = lFileSize; + if (bMAC) + lTotalSize = ENV_BASE_ADDRESS + CFG_ENV_SIZE; //0x20400; } else { @@ -1003,14 +1020,16 @@ // Only the MAC address is to be programmed, so set the file size to // the size of the board info structure. // - lOffset = 0; - lFileSize = 0x1020; + lOffset = ENV_BASE_ADDRESS; + lFileSize = CFG_ENV_SIZE; //0x400; + lTotalSize = lFileSize; } // // Round the file size up to the next 1K boundary. // lFileSize = (lFileSize + 1023) & ~1023; + lTotalSize = (lTotalSize + 1023) & ~1023; // // Program the initial baud rate of 9600, 8 data bits, and no parity. @@ -1196,6 +1215,8 @@ return(1); } +printf("program 0x%x bytes starting from offset 0x%x\n", lTotalSize, lOffset); + // // Send the starting offset. // @@ -1207,10 +1228,10 @@ // // Send the length of the data file. // - SendChar((char)(lFileSize & 0xFF)); - SendChar((char)((lFileSize >> 8) & 0xFF)); - SendChar((char)((lFileSize >> 16) & 0xFF)); - SendChar((char)((lFileSize >> 24) & 0xFF)); + SendChar((char)(lTotalSize & 0xFF)); + SendChar((char)((lTotalSize >> 8) & 0xFF)); + SendChar((char)((lTotalSize >> 16) & 0xFF)); + SendChar((char)((lTotalSize >> 24) & 0xFF)); // // Tell the user that we are erasing the FLASH. @@ -1268,12 +1289,12 @@ // // Send the actual data in the file. // - for(lIdx = 0; lIdx < lFileSize; lIdx += 1024) + for(lIdx = 0; lIdx < lTotalSize; lIdx += 1024) { // // See if the data should come from a file. // - if(bHaveFile) + if((bHaveFile) && (lIdx < lFileSize)) { // // Read the next 1K block from the file. @@ -1293,58 +1314,55 @@ // See if the Ethernet MAC address is to be programmed, and the correct // memory location has been reached. // - if(bMAC && (lIdx == 0x1000)) + if(bMAC && ((lOffset + lIdx) == ENV_BASE_ADDRESS)) { + char *env[] = { + "ethaddr="MAC_PREFIX":00:00:00\0", + "bootcmd=dhcp; echo Using MAC ${ethaddr} IP ${ipaddr}; " \ + "setenv bootargs root=/dev/nfs nfsroot=${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootm\0", + "bootdelay=0\0", + "baudrate=57600\0", + "dhcp_vendor-class-identifier=IPCPTU\0", + NULL}; + char *end; + int i = 0, n; + + memset(tmp_buf, 0, CFG_ENV_SIZE); + end = tmp_buf; + while(env[i] != NULL) + { + int n; + + n = strlen(env[i]); + strncpy(end, env[i], n); + end += n; + *end++ = '\0'; + + //printf("\t%s\n", env[i]); + i++; + } + sprintf(&tmp_buf[17], "%02X:%02X:%02X", + (lNumber >> 16) & 0xff, (lNumber >> 8) & 0xff, lNumber & 0xff); +#if 0 + for(i=0; i<end-tmp_buf; i++) + { + printf("%02x", tmp_buf[i]); + if ((i % 16) == 0) + printf("\n"); + else if ((i % 4) == 0) + printf(" "); + } +#endif + // - // The first four bytes should be "EMAC", the tag to indicate a - // Ethernet MAC block. + // The first 4 bytes are crc, followed by u-boot environment. // - cBuffer[0] = 'E'; - cBuffer[1] = 'M'; - cBuffer[2] = 'A'; - cBuffer[3] = 'C'; - - // - // The next six bytes are the Ethernet MAC address. - // - cBuffer[4] = 0x00; - cBuffer[5] = 0xdc; - cBuffer[6] = 0x6c; - cBuffer[7] = lType - 9300; - cBuffer[8] = lNumber / 256; - cBuffer[9] = lNumber & 255; - - // - // The next six bytes are reserved. - // - cBuffer[10] = 0x00; - cBuffer[11] = 0x00; - cBuffer[12] = 0x00; - cBuffer[13] = 0x00; - cBuffer[14] = 0x00; - cBuffer[15] = 0x00; - - // - // The next 16 bytes are the string name for this board. - // - cBuffer[16] = 'e'; - cBuffer[17] = 'd'; - cBuffer[18] = 'b'; - cBuffer[19] = '0' + (lType / 1000); - cBuffer[20] = '0' + ((lType / 100) % 10); - cBuffer[21] = '0' + ((lType / 10) % 10); - cBuffer[22] = '0' + (lType % 10); - cBuffer[23] = '-'; - cBuffer[24] = '0' + (lNumber / 10000); - cBuffer[25] = '0' + ((lNumber / 1000) % 10); - cBuffer[26] = '0' + ((lNumber / 100) % 10); - cBuffer[27] = '0' + ((lNumber / 10) % 10); - cBuffer[28] = '0' + (lNumber % 10); - cBuffer[29] = 0x00; - cBuffer[30] = 0x00; - cBuffer[31] = 0x00; + cBuffer[4] = 0x01; // flag (not used?) + memcpy(&cBuffer[ENV_DATA_OFFSET], tmp_buf, end-tmp_buf); + *(unsigned long *)cBuffer = crc32(0, tmp_buf, CFG_ENV_SIZE-ENV_DATA_OFFSET); } + // // If we could not read 1K from the file, then fill the remainder of // the buffer with zeros. @@ -1446,7 +1464,7 @@ // Print out our progress. // printf("\b\b\b\b\b%3d%%)", - (((lIdx + 1024) / 1024) * 100) / (lFileSize / 1024)); + (((lIdx + 1024) / 1024) * 100) / (lTotalSize / 1024)); } printf("\r \r"); @@ -1526,3 +1544,87 @@ return(1); } } + + +/* U-Boot CRC32 stuff */ +/* ======================================================================== */ + +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +const unsigned long crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + + +/* ======================================================================== = */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ======================================================================== = */ +unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len) +{ + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} DISCLAIMER: Important Notice ************************************************* This e-mail may contain information that is confidential, privileged or otherwise protected from disclosure. If you are not an intended recipient of this e-mail, do not duplicate or redistribute it by any means. Please delete it and any attachments and notify the sender that you have received it in error. Unintended recipients are prohibited from taking action on the basis of information in this e-mail.E-mail messages may contain computer viruses or other defects, may not be accurately replicated on other systems, or may be intercepted, deleted or interfered with without the knowledge of the sender or the intended recipient. If you are not comfortable with the risks associated with e-mail messages, you may decide not to use e-mail to communicate with IPC. IPC reserves the right, to the extent and under circumstances permitted by applicable law, to retain, monitor and intercept e-mail messages to and from its systems.