TableOfContents

Protocol

  • The protocol is based on individual serial data frames that are organized as shown in the following table.

Start-Byte

Address Byte

ID-Byte

n Data-Bytes coded

CRC-Byte1

CRC-Byte2

Stop-Byte

'#'

'a'+ Addr

'V','D' etc

"modified-base64"

variable

variable

'\r'

Commands

  • The Commands based on the dataframes above are listed [:en/SerialCommands:here]

Include(en/SerialCommands)

Slave Adresses

  • Since Navi 0.12h FC 0.71f Mag 0.19 there are constant SlaveAdresses:

Slave-Address

Part

1

FC

2

NC

3

MK3MAG

Data Format

  • Have a look into the Functions Decode64 and SendOutData in uart.c of the FC Firmware to see how the Data is encoded and decoded:

       1 void SendOutData(unsigned char cmd,unsigned char addr, unsigned char *snd, unsigned char len)
       2 {
       3  unsigned int pt = 0;
       4  unsigned char a,b,c;
       5  unsigned char ptr = 0;
       6  SendeBuffer[pt++] = '#';               // Start-Byte
       7  SendeBuffer[pt++] = 'a' + addr;        // Adress
       8  SendeBuffer[pt++] = cmd;               // Command
       9  while(len)
      10   {
      11    if(len) { a = snd[ptr++]; len--;} else a = 0;
      12    if(len) { b = snd[ptr++]; len--;} else b = 0;
      13    if(len) { c = snd[ptr++]; len--;} else c = 0;
      14    SendeBuffer[pt++] = '=' + (a >> 2);
      15    SendeBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
      16    SendeBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
      17    SendeBuffer[pt++] = '=' + ( c & 0x3f);
      18   }
      19  AddCRC(pt);
      20 }
      21 void Decode64(unsigned char *ptrOut, unsigned char len, unsigned char ptrIn,unsigned char max)
      22 {
      23  unsigned char a,b,c,d;
      24  unsigned char ptr = 0;
      25  unsigned char x,y,z;
      26  while(len)
      27   {
      28    a = RxdBuffer[ptrIn++] - '=';
      29    b = RxdBuffer[ptrIn++] - '=';
      30    c = RxdBuffer[ptrIn++] - '=';
      31    d = RxdBuffer[ptrIn++] - '=';
      32    if(ptrIn > max - 2) break;     // dont process more data than recieved
      33    x = (a << 2) | (b >> 4);
      34    y = ((b & 0x0f) << 4) | (c >> 2);
      35    z = ((c & 0x03) << 6) | d;
      36    if(len--) ptrOut[ptr++] = x; else break;
      37    if(len--) ptrOut[ptr++] = y; else break;
      38    if(len--) ptrOut[ptr++] = z; else break;
      39   }
      40 }
    
    • /!\ ToDo: describe data-format

Checksum

  •    1 unsigned int tmpCRC = 0;
       2 for(int i = 0; i <  DataBufferLength;i++)
       3  {
       4   tmpCRC += DataBuffer[i];
       5  }
       6 tmpCRC %= 4096;
       7 CRC1 = '=' + tmpCRC / 64;
       8 CRC2 = '=' + tmpCRC % 64;
    
  • /!\ ToDo: describe checksum calculation verbaly

Implementations

  • Sometimes its a lot more easy to look at code rather than reather than to look at Specifications/Documentation:
  • uart.c in the Flight-Ctrl Firmware ( C )
  • MKCommunicator.java from ["DUBwise"] ( Java / J2ME )
  • mktool.cpp @ ["QMKGroundStation"] ( C++ )
  • GroundStation ( LabView )

  • VibrationTest ["en/VibrationTest"] (Python)

Links