I'm trying to emulate a radio control head (for a Simoco SRM9000) which communicates via MAP27. I'm having some trouble trying to achieve it. I think my main problem is calculating the CRC. I found a CRC routine in the library here, but it produces very different results to what I'm expecting. Even the lookup table it uses is different to the one in the MAP27 spec. I tried changing the tables over but I still get different results.
Does anyone have any experience with CRC or MAP27 in assembly? I see there is a MAP27 protocol in the libraries too, but alas it's in C. I guess the other options is to finally learn how to combine C and ASM.
Here's the asm library code I found to generate the CRC.
; ********************************** ; * * ; * Fast lookup table driven * ; * 16 bit CRC Routine for * ; * ATMEL AVR microcontrollers * ; * * ; * 17-Oct-2002 * ; * * ; * By Anthony Barrett * ; * * ; ********************************** ; ; Y (r28, R29) points to data in SRAM, r18 = data size in bytes. ; CRC result is returned in r16 (low byte) & r17 (high byte). ; Uses regisisters: r0, r1, r2, r16, r17, r18, r19, r28, r29, r30, r31 Calc16CRC: push R0 push R1 push R2 push R19 push R30 push R31 clr r16 clr r17 clr r1 CRCLoop: ld r2, Y+ mov r19, r17 eor r19, r2 ldi ZL, low(2 * CRC16Tab) ldi ZH, high(2 * CRC16Tab) add ZL, r19 adc ZH, r1 add ZL, r19 adc ZH, r1 lpm mov r17, r16 mov r16, r0 adiw ZL, 1 lpm eor r17, r0 dec r18 brne CRCLoop pop R31 pop R30 pop R19 pop R2 pop R1 pop R0 ret ;High speed 16 bit CRC lookup table: ;Polynomial: x^12 + x^5 + 1 CRC16Tab: ;this table comes from the MAP27 spec sheet v1.5 .dw $0000, $C1C0, $81C1, $4001, $01C3, $C003, $8002, $41C2, $01C6, $C006, $8007, $41C7, $0005, $C1C5, $81C4, $4004 .dw $01CC, $C00C, $800D, $41CD, $000F, $C1CF, $81CE, $400E, $000A, $C1CA, $81CB, $400B, $01C9, $C009, $8008, $41C8 .dw $01D8, $C018, $8019, $41D9, $001B, $C1DB, $81DA, $401A, $001E, $C1DE, $81DF, $401F, $01DD, $C01D, $801C, $41DC .dw $0014, $C1D4, $81D5, $4015, $01D7, $C017, $8016, $41D6, $01D2, $C012, $8013, $41D3, $0011, $C1D1, $81D0, $4010 .dw $01F0, $C030, $8031, $41F1, $0033, $C1F3, $81F2, $4032, $0036, $C1F6, $81F7, $4037, $01F5, $C035, $8034, $41F4 .dw $003C, $C1FC, $81FD, $403D, $01FF, $C03F, $803E, $41FE, $01FA, $C03A, $803B, $41FB, $0039, $C1F9, $81F8, $4038 .dw $0028, $C1E8, $81E9, $4029, $01EB, $C02B, $802A, $41EA, $01EE, $C02E, $802F, $41EF, $002D, $C1ED, $81EC, $402C .dw $01E4, $C024, $8025, $41E5, $0027, $C1E7, $81E6, $4026, $0022, $C1E2, $81E3, $4023, $01E1, $C021, $8020, $41E0 .dw $01A0, $C060, $8061, $41A1, $0063, $C1A3, $81A2, $4062, $0066, $C1A6, $81A7, $4067, $01A5, $C065, $8064, $41A4 .dw $006C, $C1AC, $81AD, $406D, $01AF, $C06F, $806E, $41AE, $01AA, $C06A, $806B, $41AB, $0069, $C1A9, $81A8, $4068 .dw $0078, $C1B8, $81B9, $4079, $01BB, $C07B, $807A, $41BA, $01BE, $C07E, $807F, $41BF, $007D, $C1BD, $81BC, $407C .dw $01B4, $C074, $8075, $41B5, $0077, $C1B7, $81B6, $4076, $0072, $C1B2, $81B3, $4073, $01B1, $C071, $8070, $41B0 .dw $0050, $C190, $8191, $4051, $0193, $C053, $8052, $4192, $0196, $C056, $8057, $4197, $0055, $C195, $8194, $4054 .dw $019C, $C05C, $805D, $419D, $005F, $C19F, $819E, $405E, $005A, $C19A, $819B, $405B, $0199, $C059, $8058, $4198 .dw $0188, $C048, $8049, $4189, $004B, $C18B, $818A, $404A, $004E, $C18E, $818F, $404F, $018D, $C04D, $804C, $418C .dw $0044, $C184, $8185, $4045, $0187, $C047, $8046, $4186, $0182, $C042, $8043, $4183, $0041, $C181, $8180, $4040
And my function calling it.
ldi YL, low(TX_BUFFER) ldi YH, high(TX_BUFFER) ; load pointer to data buffer ldi TEMP, $02 st Y+, TEMP ldi TEMP, $01 st Y+, TEMP ldi TEMP, $01 st Y+, TEMP ldi TEMP, $00 st Y+, TEMP ldi TEMP, $10 st Y+, TEMP ldi TEMP, $03 st Y+, TEMP ldi YL, low(TX_BUFFER) ldi YH, high(TX_BUFFER) ; load pointer to data buffer ldi R18, $06 ; load number of bytes in buffer rcall Calc16CRC ; calculate CRC
In my code, I've stored some values manually in RAM. The CRC result should be $8F $FB, but the result I'm getting according to the simulator is $70 $1F.
Cheers in advance - Matt