Bob Paddock wrote: > > For this to work, on the possibly invalid assumption of standard CRC > processes, in the XMega, you need to calculate the > CRC for the application section minus the last three bytes, in an > external program. The put the resultant three bytes as the > last three bytes in the XMega application space. > Yes, this is the basic procedure for every CRC calculation and that's why it is so useful in software integrity check, the CRC bytes will be part of the code itself.
Bob Paddock wrote: > > See this thread on AVRFreaks for some of the needed code for the > external program. > http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=80405 > Did you get that code from Atmel? It is basically the same code I get from Atmel support, this is the PC version taking an octet stream and the length of data to compute as input: #define CRC_XMEGA_INIT 0UL #define CRC_XEMGA_POLY 0x0080001BUL /* Polynomial for use with Xmega 'A' devices */ uint32_t CRC_XMEGA_org( uint8_t *data_stream, uint32_t len ) { uint32_t data, tmp_A, tmp_B; uint32_t crc = CRC_XMEGA_INIT; for( uint32_t i = 0; i < len; i += 2 ) { tmp_A = crc << 1; tmp_A &= 0x00FFFFFEUL; /* Always act as 24-bit variable */ if ( (tmp_B = crc & 0x00800000UL) > 0 ) tmp_B = 0x00FFFFFFUL; data = *data_stream++; data |= *data_stream++ << 8; crc = (tmp_A ^ data) ^ (tmp_B & CRC_XEMGA_POLY); crc = crc & 0x00FFFFFFUL; } return crc; } Here is the first issue: the code reads one word at a time but if we have to take out the 3 bytes for the CRC from our flash (let's suppose we use full app section CRC) we end with an odd number of bytes to compute. Do we need to add a byte valued to 0 at the end? This is the above CRC calculation function reworked by me to make it more 'CRC computation like': #define CRC_XMEGA_INIT 0UL #define CRC_XEMGA_POLY 0x0080001BUL /* Polynomial for use with Xmega 'A' devices */ uint32_t CRC_XMEGA( uint8_t *data_stream, uint32_t len ) { uint32_t data; uint32_t crc = CRC_XMEGA_INIT; for( uint32_t i = 0; i < len; i += 2 ) { /* Load 16 bits of data from the stream */ data = *data_stream++; data |= *data_stream++ << 8; /* Process 16 bits at a time: this should be a loop to process all 16 bits one at a time, not all together. This is done if we have a precomputed table based on the polynomial but here we don't have one. Seems not to generate a valid CRC. */ crc = ((crc << 1) ^ data); // Shift 1 bit and XOR with input data? if (crc & 0x01000000UL) { // Is there a reminder? (bit 24) crc ^= CRC_XEMGA_POLY; // Divide data with polynomial crc = crc & 0x00FFFFFFUL; // Truncate data to 24bits } } return crc; } These function, even if it seems very different from the ATMEL one, produces the same result. I can't understand how they process 16 bits at a time without doing a loop through all bits or using a precomputed table. I'm not a math guru but this seems to broke the mathematical principles at the base of CRC calculations. If you can test this and find out what's wrong and maybe make it works, it would be a very nice thing and perhaps we could add the routine to the avr-libc help to make it available to everyone. Bob Paddock wrote: > > > P.S. The last ATXMEGA128A1 die is revision H you were wrongly referring > > to datasheet revision J. > > I was referring to die revision J. That is what Atmel said they would > fix the CRC Rage problem in. > That makes my laugh! They are stuck on rev.H with plenty of errors to fix for two years and they expect to solve the CRC problem not in the next revision but in the one after? When they expect to release the J revision, in 2013 or later? Come on, I have firmwares full of patches and tricks to overcome XMEGA faults! Not last the A/D noise: I had to implement a software low pass filter to obtain some usable readings. _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev