[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-libc-dev] XMEGA hardware CRC calculation
From: |
Simone Zamboni |
Subject: |
Re: [avr-libc-dev] XMEGA hardware CRC calculation |
Date: |
Sun, 03 Oct 2010 13:38:57 +0200 |
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] Re: How many bits wide is __data_load_end?, David Brown, 2010/10/02
Re: [avr-libc-dev] How many bits wide is __data_load_end?, Joerg Wunsch, 2010/10/03