I am trying to write a checksum function for the Bangle 2 GPS but getting a bit confused over byte orders.
What we have on Bangle 1 - is a function called writeGPScm() where you pass in the command payload and it works out the checksum.
See below.
function writeGPScmd(cmd) {
var d = [0xB5,0x62]; // sync chars
d = d.concat(cmd);
var a=0,b=0;
for (var i=2;i<d.length;i++) {
a += d[i];
b += a;
}
d.push(a&255,b&255);
Serial1.write(d);
}
// UBX-CFG-PMS - enable power management - Super-E
function UBX_CFG_PMS() {
log_debug("UBX_CFG_PMS()");
writeGPScmd([0x06,0x86, // msg class + type
8,0,//length
0x00,0x03, 0,0, 0,0, 0,0]);
}
The checksum calculation for the Bangle 2 - AT6558 is a bit different (see screenshot of spec below). @Mark_M has managed to parse a couple of CASIC commands from the GPS and collect the checksum values that the chip is sending - so these make good test cases.
This is how far I have so far.
/*
sum = (msg_id << 24) + (msg_class << 16) ++ (len_byte1 << 8) + (len_byte0)
From the CASIC Manual
The calculation of the check value can follow the following algorithm:
ckSum = (id << 24) + (class << 16) + len;
for (i = 0; i <(len / 4); i++)
{
ckSum = ckSum + payload [i];
}
*/
function casic_checksum(id, cl, len1, len0, payload) {
print("id:" + id + " cl:" + cl + " len1:" + len1 + " len0:" + len0 + " pl:" + payload);
const c1 = new Uint8Array([len0,len1,cl,id]);
const pl = new Uint8Array(payload);
let cksum = new Uint32Array(c1.buffer);
print("cksum initial=" + cksum[0].toString(16).padStart(8,'0'));
for (var i = 0; i < pl.length; i += 4) {
print("pl["+(i+0) + "]=" + pl[i]);
print("pl["+(i+1) + "]=" + pl[i+1]);
print("pl["+(i+2) + "]=" + pl[i+2]);
print("pl["+(i+3) + "]=" + pl[i+3]);
cksum[0] = cksum[0] + pl[i] + (pl[i+1] * 256) + (pl[i+2] * 256 * 256) + (pl[i+3] * 256 *256 *256);
print("cksum=" + cksum[0].toString(16).padStart(8,'0'));
}
print(cksum[0].toString(16).padStart(8,'0'));
return cksum[0];
}
/**
{
"hdr": "0xBACE",
"len": 8, "class": 6, "msgId": 0,
"payload": [ 1, 7, 192, 8, 0, 194, 1, 0 ],
"checkSum": 164218632,
"checkSum16": "0x9C9C708"
}
{
"hdr": "0xBACE",
"len": 4, "class": 5, "msgId": 1,
"payload": [ 6, 0, 0, 0 ],
"checkSum": 167773441,
"checkSum16": "0xA000501"
}
01 05 00 04 (id, class, 00, 04)
00 00 00 06 payload
-----------
01 05 00 0A - seem to calculate checksum, but send least sig byte first
(the one received first is in the low order)
*/
function test() {
let c;
// id, cl, len1, len0, payload)
print("");
c = casic_checksum(1, 5, 0, 4, [6, 0, 0, 0]);
print("test1 - expecting 0xA000501");
print(c.toString(16).padStart(8,'0'));
print("");
print("");
print("");
// id, cl, len1, len0, payload)
c = casic_checksum(0, 6, 0, 8, [1, 7, 192, 8, 0, 194, 1, 0]);
print("test2 - expecting 0x9C9C708");
print(c.toString(16).padStart(8,'0'));
}
As can be seen the output for the checksums is coming out reversed.
But this maybe because the least significant byte of the checksum is being sent first by the chip.
In the spec there is the statement:
(the one received first is in the low order)
So it could be that when we parsed the cip output we needed to take the first byte received of the checksum as byte0.
Wondering if anyone else has looked at this and can see a better way of doing it.
I tried converting the payload into Uint32Array but inside its basically still a list of bytes 0 they are not guaranteed to work the way C uint32s work in terms of overflows etc.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
Hi All,
I am trying to write a checksum function for the Bangle 2 GPS but getting a bit confused over byte orders.
What we have on Bangle 1 - is a function called writeGPScm() where you pass in the command payload and it works out the checksum.
See below.
The checksum calculation for the Bangle 2 - AT6558 is a bit different (see screenshot of spec below).
@Mark_M has managed to parse a couple of CASIC commands from the GPS and collect the checksum values that the chip is sending - so these make good test cases.
This is how far I have so far.
And the output of the tests are:
As can be seen the output for the checksums is coming out reversed.
But this maybe because the least significant byte of the checksum is being sent first by the chip.
In the spec there is the statement:
(the one received first is in the low order)
So it could be that when we parsed the cip output we needed to take the first byte received of the checksum as byte0.
Wondering if anyone else has looked at this and can see a better way of doing it.
I tried converting the payload into Uint32Array but inside its basically still a list of bytes 0 they are not guaranteed to work the way C uint32s work in terms of overflows etc.
1 Attachment