If your concern is size and speed, why not use it as is with he addition of _ before CRC variable (_CRC)?
I think it will work just fine.
Ioannis
If your concern is size and speed, why not use it as is with he addition of _ before CRC variable (_CRC)?
I think it will work just fine.
Ioannis
Hi Ioannis:
Since the Dattalo method wasn't mentioned in the thread, I simply wanted to pass it along, hoping it might be useful or helpful to PBP users. I'm afraid I don't know how you would implement it in PBP.
While I've tried all of the methods discussed in this thread in the past, now days in my C programs I use bit level cumulative CRC built into my low level 1-Wire read/write bit driver. Total cost for doing it this way is 8 words of program memory, 1 byte of RAM, and 0 cycles processing overhead since the CRC code executes during a portion of the delay required to fill out the 60 usec read slot timing.
Cheerful regards, Mike
Hmm, yes I see what you mean. In Basic this does not seem an easy job to do.
I will try it and see if it works.
Ioannis
My main concern is how to save the W register and then restore it.
I tried
MOVW _wsave
but did not compile.
Ioannis
The command would be: movwf
Here is a quick attempt at converting the asm to PBP. Note that this is not the most efficeint/elegant conversion, but it should be a bit clearer was to what's happening.
Code:crc VAR BYTE i_w VAR BYTE goto start crc_8: crc = i_w ^ crc ;xorwf crc,f i_w = 0 ;clrw IF crc.0 = 1 THEN ;btfsc crc,0 i_w = i_w ^ $5E ;xorlw 0x5e END IF IF crc.1 = 1 THEN ;btfsc crc,0 i_w = i_w ^ $BC ;xorlw 0xbc END IF IF crc.2 = 1 THEN ;btfsc crc,0 i_w = i_w ^ $61 ;xorlw 0x61 END IF IF crc.3 = 1 THEN ;btfsc crc,0 i_w = i_w ^ $C2 ;xorlw 0xc2 END IF IF crc.4 = 1 THEN ;btfsc crc,0 i_w = i_w ^ $9D ;xorlw 0x9d END IF IF crc.5 = 1 THEN ;btfsc crc,0 i_w = i_w ^ $23 ;xorlw 0x23 END IF IF crc.6 = 1 THEN ;btfsc crc,0 i_w = i_w ^ $46 ;xorlw 0x46 END IF IF crc.7 = 1 THEN ;btfsc crc,0 i_w = i_w ^ $8C ;xorlw 0x8c END IF crc = i_w ;movwf crc RETURN start: crc = 0 ;clrf crc i_w = 1 ;movlw 1 GOSUB crc_8 ;call crc_8 crc = 0 ;clrf crc i_w = 2 ;movlw 2 GOSUB crc_8 ;call crc_8 crc = 0 ;clrf crc i_w = 4 ;movlw 4 GOSUB crc_8 ;call crc_8 crc = 0 ;clrf crc i_w = 8 ;movlw 8 GOSUB crc_8 ;call crc_8 crc = 0 ;clrf crc i_w = $10 ;movlw 0x10 GOSUB crc_8 ;call crc_8 crc = 0 ;clrf crc i_w = $20 ;movlw 0x20 GOSUB crc_8 ;call crc_8 crc = 0 ;clrf crc i_w = $40 ;movlw 0x40 GOSUB crc_8 ;call crc_8 crc = 0 ;clrf crc i_w = $80 ;movlw 0x80 GOSUB crc_8 ;call crc_8 END
This is a translation for another basic compiler:
Function crc_dattalo(crc As Byte, crc_data As Byte) As Byte
Some additional info and comparison between three different approaches: http://www.ccsinfo.com/forum/viewtop...015&highlight=Code:'dattalo's CRC-8 Function '(328_Tcy / 41.0_us) Dim i As Byte i = crc_data Xor crc i = i And 0xff crc = 0 If i.0 = 1 Then crc = crc Xor 0x5e Endif If i.1 = 1 Then crc = crc Xor 0xbc Endif If i.2 = 1 Then crc = crc Xor 0x61 Endif If i.3 = 1 Then crc = crc Xor 0xc2 Endif If i.4 = 1 Then crc = crc Xor 0x9d Endif If i.5 = 1 Then crc = crc Xor 0x23 Endif If i.6 = 1 Then crc = crc Xor 0x46 Endif If i.7 = 1 Then crc = crc Xor 0x8c Endif crc_dattalo = crc End Function
Last edited by languer; - 24th May 2012 at 06:15.
Even though I'm not a PBP developer, I've always enjoyed exchanging ideas and experiences with members here. That said, I wonder if anyone is interested in my zero overhead CRC8 method, even if it isn't a PBP example?
In my zero overhead CRC8 method I use a portion of the 60-usec read/write 'slot' time to implement CRC8 at the bit level within the OneWire read bit routine. Here's the tail end of a read bit routine from code for an enhanced mid-range 16F device;
Using CRC in my DS18x20 programs is simply a matter of clearing the 'crc' variable before reading the 9 byte DS18x20 'scratchpad' or an 8 byte ROMID and verifying that the 'crc' variable equals zero afterwards. You must read all 9 'scratchpad' bytes to have a valid 'crc'. Just ignore or throw away the bytes you don't need.Code:; ; bit level cumulative CRC (data bit in Carry at entry & exit) ; clrf WREG ; |00 rlf WREG,W ; save C in wreg (0x00 or 0x01) |00 xorwf crc,F ; xor b0 bits, result in 'crc' |00 rrf crc,F ; is xor result 0 (Carry = 0)? |00 skpnc ; yes, skip, else |00 iorlw 0x18 ; w = x8+x5+x4+1 poly and bit 0 |00 rrf WREG,W ; restore C, wreg = 0x8C or 0x00 |00 xorwf crc,F ; apply the polynomial or not |00 ; ; remainder of 60-usec read/write 'slot' ; DelayCy(46*usecs-14) ; 46-usecs minus 14 cycles |00 banksel owtris ; bank 1 |01 bsf owtris,owpin ; output hi-z '1' @ 61-usecs |01 banksel 0 ; bank 0 |00 bsf INTCON,GIE ; interrupts on |00 return ; Carry = data bit |00
I admit I have no idea if this method could be implemented in PBP with its intrinsic OneWire commands but I suspect you gurus will find a way to use it if you think the method is worthwhile.
Have fun. Cheerful regards, Mike (K8LH)
Last edited by Mike, K8LH; - 8th May 2018 at 18:20.
Bookmarks