Skip to content

Instantly share code, notes, and snippets.

@atc1441
Last active September 10, 2023 21:32
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save atc1441/32c940522ba7470a56c23922341ca25a to your computer and use it in GitHub Desktop.
Save atc1441/32c940522ba7470a56c23922341ca25a to your computer and use it in GitHub Desktop.
DaFit App Update Protocol manual
Basic Manual for DaFit Fitness Tracker firmware update protocol, works for nearly any nRF52832 tracker from Company DaFit
The minimum size of update file is 0x10000(can be filled with garbage to get to size) and the maximum size is 0x2F000
the update will first get stored onto the external flash at position 0x3D1000 by the stock firmware(not by the bootloader)
the size of the update will get stored at 0x3D0000 on external flash with 4 bytes uint32_t
when bootloader gets activated it will copy the update from external flash to 0x23000 of the nRF52 internal flash.
Connect to device,
enable NOTIFY from service "0xFEEA", characteristic "0xFEE3".
write following cmd to service "0xFEEA", characteristic "0xFEE2"
Bytes
0xFE, 0xEA, 0x10, 0x09, 0x63, 0x00, 0x00, 0x00, 0x03
where
1. 2. and 3. byte = Startbytes
4. byte = length of whole CMD even when splitet into serveral NOTIFYs
5. byte = type of cmd where 0x63 = DFU_MODE
6. 7. 8. and 9. byte = Length of Update firmware in bytes. from uint32_t.
After that the device will reboot with Device Information Service("0x180A") Model Number String("0x2A24") set to "DFU=1", before it was "DFU=0"
Reconnect to device enable NOTIFY again.
From now on the notifications from "0xFEE3" will send every 4 seconds a current status of updating position.
for example:
0xFE, 0xEA, 0x10, 0x07, 0x63, 0x00,0x00
where last two bytes are current block position of update where each block = 256 bytes
Now send update bin file splitet into 256 bytes sized blocks like following CMD to service "0xFEEA", characteristic "0xFEE5"
0xFE 0x66 0x1B 0x03 0x01 0x02 0x03
where
1. byte = startbyte
2. and 3. byte = CRC check function see end of page
4. byte = length of data packet
5. 6. and 7. byte = the "Real" data, count depends on data size, when data longer than 21 byte just send next bytes without start/crc/length bytes
If packet was received succsefully the NOTIFY will increase the current block position imediatly and next block can be send.
When all is transmitted succsefully NOTIFY will send following
0xFE, 0xEA, 0x10, 0x09, 0x63, 0xFF, 0xFF, 0x66, 0x1B
where last 2 bytes are 16bit CRC of all data.
If CRC correct send following cmd to boot into bootloader:
0xFE, 0xEA, 0x10, 0x09, 0x63, 0x00, 0x00, 0x00, 0x00 to reboot into bootloader, data will be flashed to internal nRF Memory.
***************Update needs to be bigger than 100kb as far i can tell right now, can be filles with 0xFF to get the length
##### CRC FUNCTION in C ##############################################################################################################################
can be run to test on: https://www.onlinegdb.com/online_c_compiler
#include <stdio.h>
unsigned short getCRC16(unsigned char *b, int len)
{
unsigned int v5;
unsigned int v6;
unsigned int crc = 0xFEEA;
for (int u = 0; u < len; u++)
{
v5 = b[u] ^ ((crc >> 8) | (crc << 8));
v6 = (unsigned short) ((((v5 << 24 >> 28) ^ v5) << 12) ^ (v5 << 24 >> 28) ^ v5);
crc = 32 * v6 & 0x1FFF ^ v6;
}
return crc;
}
int main()
{
unsigned char dataCurrent[3] = { 0x01, 0x02, 0x03 };
unsigned int crcCalc = getCRC16(dataCurrent, 3);
printf ("CRC is: %i in hex 0x%04x", crcCalc, crcCalc); // this example gives out 26139 wich is 0x661B in hex
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment