Hi Scott,
Thanks for the optimisation effort.. I know what you mean when you say "I
wasn't going to do this.. but" That is exactly what happened when I wrote it
in the first place :)
{Quote hidden}> > I have implemented this in C and PIC assembler. The ASM
> code is designed to
> > work on a PIC12C508 so it will work for any PIC. I've
> simulated it and it
> > does work. 85 instruction cycles per message byte, but it
> can probably be
> > improved a little.
> >
> >
http://www.digitalnemesis.com/ash/projects/EmbeddedCRC16/default.htm
>
>
> This is the CRC algorithm we used 15 years ago at I used to work for.
> Nostalgia...
Hehe.. I knew I couldn't have been the first to do this :)
{Quote hidden}> The PIC routine has numerous opportunities for optimization.
> While I don't
> have time to go through each one, I can list a couple
>
> 1) Index = CRC16_High>>4;
> Index ^= CRC16_MessageByte>>4;
>
> SWAPF CRC16_High, W
> ANDLW 00FH
> MOVWF Index ; Index = CRC16_High >> 4
> SWAPF CRC16_MessageByte, W
> ANDLW 00FH
> XORWF Index, F ; Index = Index ^
> ;(CRC16_MessageByte >> 4)
>
> This can be written as:
>
> movf CRC16_High,w
> xorwf CRC16_MessageByte,w
> andlw 0x0f
That mask needs to be 0xF0 because we're after the two 4 bits.. Probably a
typo I'm sure.
{Quote hidden}> movwf Index,f ; don't swap yet...
>
>
> Then when index is needed:
>
> swapf Index,w
> call CRC16_Lookup
>
> and
> swapf Index,w
> iorlw 0x10
> call CRC16_Lookup
Looks good.. I'm adding it into a new version of the code..
{Quote hidden}> 2) Shift left 4.
> ; Shift the CRC Register left 4 bits
> SWAPF CRC16_High, W
> ANDLW 0F0H
> MOVWF Temp
> SWAPF CRC16_Low, W
> ANDLW 00FH
> IORWF Temp, W
> MOVWF CRC16_High ; CRC16_High =
> (CRC16_High << 4) |
> (CRC16_Low >> 4)
> SWAPF CRC16_Low, W
> ANDLW 0F0H
> MOVWF CRC16_Low ; CRC16_Low = CRC16_Low << 4
>
> This can be written more efficiently as:
>
> movlw 0x0f
> andwf hi,f
> swapf hi,f
>
> swapf lo,f
> andwf lo,w
> iorwf hi,f
> xorwf lo,f
Nice.. I like that :) a little more concise them mine :)
> 3) If space wasn't a major issue, I'd probably unroll the
> loop since only
> two iterations are performed. This saves about 9 or 10
> execution cycles at
> the cost of ~15 or 20 instructions.
Yes, I'd initially considered unrolling it, but opted for the loop to save
the limited ROM space on the '508, thinking that if peopled wanted they
could unroll it themselves :)
> 4) If space really wasn't a major issue, then you can combine the two
> tables into one. E.g.
>
> [ interesting table stuff snipped ]
Interesting approach.. probably makes the code a little too unreadable for
my liking for a piece of example code that others can use..
> [ Example code snipped ]
> ---
> This is untested, of course...
The problem with your code was you were shifting the CRC register before
extracting the top 4 bits to XOR with the message byte to create the lookup
index... Easy change in order of the code and it should be fine.
I've added a new version of the PIC code on the web site. This is now down
to 74 instructions per message byte, but if the loop is unrolled and the
complex table scheme from Scott was implemented I'm sure it would be lower.
http://www.digitalnemesis.com/ash/projects/EmbeddedCRC16/default.htm
Cheers,
Ash.
---
Ashley Roll
Digital Nemesis Pty Ltd
http://www.digitalnemesis.com
Mobile: +61 (0)417 705 718
--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics