;---------------------------------------------------------------------- ; PIC CRC16 Implementation with Restricted Table Size ; ; Digital Nemesis Pty Ltd ; www.digitalnemesis.com ; ;---------------------------------------------------------------------- list p=12c508a ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _MCLRE_OFF & _IntRC_OSC ;---------------------------------------------------------------------- ; Program Variables ; Note that we start at RAM location 0x07 ;---------------------------------------------------------------------- CBLOCK 0x07 CRC16_High ; The CRC Register CRC16_Low Index ; Temp registers used during CRC update, can Temp ; be reused when not calling CRC_Update Count CRC16_MessageByte ENDC ;---------------------------------------------------------------------- ; Startup Code ORG 0x000 ; coding begins here MOVWF OSCCAL ; update register with factory cal value ; Skip to the main code GOTO BeginProgram ;---------------------------------------------------------------------- ; CRC16 Lookup Table. This is actually the Low and High lookup tables ; conconated together to save a few words of ROM space. ; ; To access the Low table, Enter with 0 <= W <= 15 ; To access the High table, Enter with 16 <= W <= 31 ; ; This can easily be achieved by setting or clearing bit 4. CRC16_Lookup: ANDLW 1FH ADDWF PCL, F RETLW 000H ; LOW Byte Data RETLW 021H RETLW 042H RETLW 063H RETLW 084H RETLW 0A5H RETLW 0C6H RETLW 0E7H RETLW 008H RETLW 029H RETLW 04AH RETLW 06BH RETLW 08CH RETLW 0ADH RETLW 0CEH RETLW 0EFH RETLW 000H ; HIGH Byte DATA RETLW 010H RETLW 020H RETLW 030H RETLW 040H RETLW 050H RETLW 060H RETLW 070H RETLW 081H RETLW 091H RETLW 0A1H RETLW 0B1H RETLW 0C1H RETLW 0D1H RETLW 0E1H RETLW 0F1H ;---------------------------------------------------------------------- ; CRC_Init Subroutine CRC_Init: MOVLW 0FFH MOVWF CRC16_High MOVWF CRC16_Low RETLW 0 ;---------------------------------------------------------------------- ; CRC_Update Subroutine CRC_Update: ; Save the Message Byte in the W register MOVWF CRC16_MessageByte ; We need to perform two iterations each processing 4 bits from the ; CRC16_MessageByte register. MSB first. MOVLW 2 MOVWF Count CRC16_UpdateLoop: ; Extract the top four bits from the CRC register and store them in ; the Index register SWAPF CRC16_High, W ANDLW 00FH MOVWF Index ; Index = CRC16_High >> 4 ; Get the top 4 bits from the message byte and XOR it with the ; bits extracted from the CRC register to generate the lookup index. ; Note that on the second iteration the nibbles in the message byte ; will have been swaped again so we are actually getting the low ; nibble of the message byte SWAPF CRC16_MessageByte, W ANDLW 00FH XORWF Index, F ; Index = Index ^ (CRC16_MessageByte >> 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 ; Do the table lookups and XOR into the CRC Registers MOVF Index, W CALL CRC16_Lookup XORWF CRC16_Low, F ; CRC16_Low = CRC16_Low ^ CRC16_LookupLow[t] BSF Index, 4 ; Access High Table MOVF Index, W CALL CRC16_Lookup XORWF CRC16_High, F ; CRC16_High = CRC16_High ^ CRC16_LookupHigh[t] ; Swap the nibbles in the message byte so that next iteration we do the ; low nibble SWAPF CRC16_MessageByte, F ; Check if we need to iterate again DECFSZ Count, F GOTO CRC16_UpdateLoop RETLW 0 ; return Finished ;---------------------------------------------------------------------- ; Beginnig of Main Program ;---------------------------------------------------------------------- BeginProgram: ; Initialise the CRC registers CALL CRC_Init ; Test Vector: "123456789" ; Result: 0x29B1 MOVLW '1' CALL CRC_Update MOVLW '2' CALL CRC_Update MOVLW '3' CALL CRC_Update MOVLW '4' CALL CRC_Update MOVLW '5' CALL CRC_Update MOVLW '6' CALL CRC_Update MOVLW '7' CALL CRC_Update MOVLW '8' CALL CRC_Update MOVLW '9' CALL CRC_Update Forever: GOTO Forever END