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.
Calculate/check USB crc16
-
- Junior Member
- Posts: 7
- Joined: Wed Jul 12, 2017 3:44 pm
-
Verified
- XCore Legend
- Posts: 1080
- Joined: Thu Dec 10, 2009 9:20 pm
- Location: Bristol, UK
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
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