Calculate/check USB crc16

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
zoran4afc
Junior Member
Posts: 7
Joined: Wed Jul 12, 2017 3:44 pm

Calculate/check USB crc16

Post by zoran4afc »

Hello,

I am trying to create assembler code to calculate USB crc16.
My problem is that I don't understand how to properly call assembler crc8 instructions in chain.

My try:

ldc r7, 0x8408 // polynomial x16+x12+x5+x0 bit reversed
ldc r3, 0xffff // initial value
ldc r5, 0

crc8 r3, r4, r3, r7 // ???

zhcrc16_loop1:
bf r1, zhcrc16_loop2 // loop

ld8u r3, r0[r5] // take the next byte
add r0, r0, 1 // increment pointer

crc8 r3, r4, r3, r7 // ???

sub r1, r1, 1 // decrement length
bu zhcrc16_loop1 // loop again

zhcrc16_loop2:
ldc r0, 0xffff
and r0, r3, r0 // result crc16 value in r0


Thanks for looking into it.
User avatar
Ross
Verified
XCore Legend
Posts: 1080
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

For speed the XMOS USB code handles the data in words - it branches based on "tail length" before the main loop i.e. space/time tradeoff. The word aligned case is shown below:

I guess you can ignore the "out" instructions if you are just interested in generation.

ldc r9, 0xa001 // CRC16 poly
ldc r7, 0xf335 // TX Crc init

....


.align 64.
.skip 0
TxTail0:
ldw r6, r8[r4] // Load first data word
add r4, r4, 1 // Buffer index increment
XUD_IN_TxPid_Tail0:
outpw res[TXD], r11, 8 // Output PID to port
out res[TXD], r6 // Output first data word
crc32 r7, r6, r9 // Run CRC
bf r4, TxLoop0End
TxLoop0:
ldw r6, r8[r4] // Load last data word
add r4, r4, 1
TxLoop0_Out:
out res[TXD], r6 // Output last data word
crc32 r7, r6, r9
bt r4, TxLoop0
TxLoop0End: // Word aligned data (just output CRC)
crc32 r7, r4, r9 // R4: 0 (from bt)
not r7, r7

XUD_IN_TxCrc_Tail0:
outpw res[TXD], r7, 16 // Output CRC
bu DoneTail

Below is a the next case with a single "tail" byte

.align 64
.skip 0
TxTail1:
ldw r6, r8[r4] // Load first data word
add r4, r4, 1 // Buffer index increment
XUD_IN_TxPid_Tail1:
outpw res[TXD], r11, 8 // Out PID
out res[TXD], r6
crc32 r7, r6, r9
bf r4, TxLoop1End
TxLoop1:
ldw r6, r8[r4] // Load last data word
add r4, r4, 1
out res[TXD], r6
crc32 r7, r6, r9
bt r4, TxLoop1
TxLoop1End:
ldw r6, r8[r4] // Load last data word
outpw res[TXD], r6, 8
crc8 r7, r6, r6, r9
crc32 r7, r4, r9 // r4: 0 (from bf)
not r7, r7


Hope that provides some help
Technical Director @ XMOS. Opinions expressed are my own