PDA

View Full Version : Checksum



retepsnikrep
- 23rd October 2009, 00:20
I've just started with PBP and have a checksum issue to solve.

I have a 12 byte data packet in an ARRAY which I am sending via HSEROUT.

The receiving hardware expects a checksum and it is calculated thus.

" There are basically 10 data bytes per message. Before the first is the message type (AA or 87), and after the last is the checksum. You compute it by adding the other 11 bytes, negating that (2's complement), then and'ing by 0x7f. It makes the entire message add to 0 when you and by 0x7f. "

I had a checksum working in Picaxe basic, but i'm after ideas to help convert it to PBP. My below picaxe code was for a three byte packet not twelve.



b0 = $E6 ;Calculate Checksum Routine
b1 = $40
b2 = b0 + b1 ;Add all bytes of packet together b2 = value + value + value + value etc
b2 = NOT b2 ;NOT result
b2 = b2 + 1 ;Add 1 to result
b2 = b2 AND $7F ;AND result and checksum in b2


My PBP test Code at present is very limited and just recieves data into an array and squirts it back out again. I need to modify the data in the array, calculate the new checksum and then send it on.



'-------------------------------------
' PBP BCM CODE 22/10/09 V.02 4mhz
'-------------------------------------

@ DEVICE PIC16F88,INTRC_OSC_NOCLKOUT
@ DEVICE PIC16F88,PROTECT_OFF
@ DEVICE PIC16F88,WDT_OFF
@ DEVICE PIC16F88,PWRT_ON
@ DEVICE PIC16F88,MCLR_ON
@ DEVICE PIC16F88,BOD_OFF
@ DEVICE PIC16F88,LVP_OFF
@ DEVICE PIC16F88,CPD_OFF
@ DEVICE PIC16F88,DEBUG_OFF
@ DEVICE PIC16F88,CCPMX_OFF

'DEFINE OSC 8 'Set oscilator speed to 8mHz
'OSCCON=%01111000 '8 Mhz

DEFINE OSC 4 'Set oscilator speed to 4mHz
OSCCON =%01100000 '4 Mhz

DEFINE HSER_BAUD 9600 'Set Baud rate to 9600bps
DEFINE HSER_BITS 9 'Set to 9 bit mode
DEFINE HSER_EVEN 1 'Set Even Parity
DEFINE HSER_CLROERR 1 'Clear overflow error automatically

ANSEL = 0 'ALL DIGITAL
CMCON = 7 'COMPARATORS OFF
INTCON = 0 'Disable interrupts
TRISB = %00000100 'SET PORTB RB2(RX) as input, others to OUTPUT
TRISA = %11111111 'SET PORTA AS INPUTS

DATAIN VAR BYTE[12] 'Define DATAIN as a byte array (12 Bytes)

loop: 'Start of Communications Loop
HSERIN [str DATAIN\12] 'Receive 12 bytes into array DATAIN
HSEROUT [str DATAIN\12] 'Transmit 12 bytes from array DATAIN
goto looP 'Goto Loop

END



I've done a lot of searching on the forum but i'm on such a steep learning curve with the PBP syntax my head is exploding. I would be grateful for ideas or sample code. Thanks

OK I've just tried to write some code, does this look right?



BCMDATA VAR BYTE[12] 'Define BCMDATA as a byte array (12 Bytes)
Count1 VAR BYTE 'Define Count1 as a byte variable (Used in For/Next Loops)
CheckSum VAR BYTE 'Define CheckSum as a byte variable


loop: 'Start of Communications Loop

HSERIN [str BCMDATA\12] 'Receive 12 bytes into array BCMDATA

Gosub CalcSum 'Gosub CalcSum to Calculate Checksum

HSEROUT [str BCMDATA\12] 'Transmit 12 bytes from array BCMDATA

goto looP 'Goto Loop


CalcSum: 'Calculate Packet CheckSum Routine
For Count1 = 0 to 10 'For Count1 = 0 to 10 (Start 11 byte loop)
CheckSum = CheckSum + BCMDATA[Count1] 'Add Bytes
Next Count1 'Repeat until 11 bytes added
CheckSum = NOT CheckSum 'Not CheckSum
CheckSum = CheckSum + 1 'Add 1 to CheckSum
BCMDATA[12] = CheckSum AND $7F 'AND result
Return 'Return

Melanie
- 23rd October 2009, 17:53
I haven't looked at this properly, but just giving it a quick glance, I think you need to zero the variable CHECKSUM before starting the FOR/NEXT loop.

retepsnikrep
- 24th October 2009, 04:09
Thanks I noticed that one later but have left it out so I can call my routine with the packet start byte value pre-loaded into checksum now.

So I call the routine after loading checksum with either $AA or $87 (My 12 byte packet start byte) I then run the routine on the array and store the checksum in the last byte making twelve in all.

My main program - onfigs now looks like this. The checksum is commented out at present during some other testing.




'Main Program Start

Commloop: 'Start of Communications Loop

HSERIN [WAIT($87), STR BCMDATA\11] 'Wait for packet start $87 then Receive 11 bytes into array BCMDATA


'CheckSum = $87 'Load Checksum with packet start byte value
'Gosub CalcSum 'Gosub CalcSum to Calculate Checksum

HSEROUT [$87,str BCMDATA\11] 'Transmit 12 bytes inc packet start byte $87


HSERIN [WAIT($AA), STR BCMDATA\11] 'Wait for packet start $AA then Receive 11 bytes into array BCMDATA
'CheckSum = $AA 'Load Checksum with packet start byte value
'Gosub CalcSum 'Gosub CalcSum to Calculate Checksum

HSEROUT [$AA,str BCMDATA\11] 'Transmit 12 bytes inc packet start byte $AA


'Data txd/rxd test outputs known values below to check transmission & reception

Pause 32 'Pause for 16ms
HSEROUT [$AA,$10,$00,$00,$00,$20,$40,$61,$10,$01,$00,$74] 'Transmit 12 bytes
pause 32 'Pause for 16ms
HSEROUT [$87,$40,$58,$15,$6E,$10,$01,$32,$2F,$2F,$04,$39] 'Transmit 12 bytes
pause 32 'Pause for 16ms

goto CommlooP 'Goto Loop

CalcSum: 'Calculate Packet CheckSum Routine

For Count1 = 0 to 10 'For Count1 = 0 to 10 (Start 11 byte loop)
CheckSum = CheckSum + BCMDATA[Count1] 'Add Bytes
Next Count1 'Repeat until 11 bytes added
CheckSum = NOT CheckSum 'Not CheckSum
CheckSum = CheckSum + 1 'Add 1 to CheckSum
BCMDATA[11] = CheckSum AND $7F 'AND result
Return 'Return