/ Ada_BLE_RC / packetParser.cpp
packetParser.cpp
  1  // SPDX-FileCopyrightText: 2016 James DeVito for Adafruit Industries
  2  //
  3  // SPDX-License-Identifier: MIT
  4  //
  5  #include <string.h>
  6  #include <Arduino.h>
  7  #include <SPI.h>
  8  #include <SoftwareSerial.h>
  9  
 10  #include "Adafruit_BLE.h"
 11  #include "Adafruit_BluefruitLE_SPI.h"
 12  #include "Adafruit_BluefruitLE_UART.h"
 13  
 14  
 15  #define PACKET_ACC_LEN                  (15)
 16  #define PACKET_GYRO_LEN                 (15)
 17  #define PACKET_MAG_LEN                  (15)
 18  #define PACKET_QUAT_LEN                 (19)
 19  #define PACKET_BUTTON_LEN               (5)
 20  #define PACKET_COLOR_LEN                (6)
 21  #define PACKET_LOCATION_LEN             (15)
 22  
 23  //    READ_BUFSIZE            Size of the read buffer for incoming packets
 24  #define READ_BUFSIZE                    (20)
 25  
 26  
 27  /* Buffer to hold incoming characters */
 28  uint8_t packetbuffer[READ_BUFSIZE+1];
 29  
 30  /**************************************************************************/
 31  /*!
 32      @brief  Casts the four bytes at the specified address to a float
 33  */
 34  /**************************************************************************/
 35  float parsefloat(uint8_t *buffer) 
 36  {
 37    float f = ((float *)buffer)[0];
 38    return f;
 39  }
 40  
 41  /**************************************************************************/
 42  /*! 
 43      @brief  Prints a hexadecimal value in plain characters
 44      @param  data      Pointer to the byte data
 45      @param  numBytes  Data length in bytes
 46  */
 47  /**************************************************************************/
 48  void printHex(const uint8_t * data, const uint32_t numBytes)
 49  {
 50    uint32_t szPos;
 51    for (szPos=0; szPos < numBytes; szPos++) 
 52    {
 53      Serial.print(F("0x"));
 54      // Append leading 0 for small values
 55      if (data[szPos] <= 0xF)
 56      {
 57        Serial.print(F("0"));
 58        Serial.print(data[szPos] & 0xf, HEX);
 59      }
 60      else
 61      {
 62        Serial.print(data[szPos] & 0xff, HEX);
 63      }
 64      // Add a trailing space if appropriate
 65      if ((numBytes > 1) && (szPos != numBytes - 1))
 66      {
 67        Serial.print(F(" "));
 68      }
 69    }
 70    Serial.println();
 71  }
 72  
 73  /**************************************************************************/
 74  /*!
 75      @brief  Waits for incoming data and parses it
 76  */
 77  /**************************************************************************/
 78  uint8_t readPacket(Adafruit_BLE *ble, uint16_t timeout) 
 79  {
 80    uint16_t origtimeout = timeout, replyidx = 0;
 81  
 82    memset(packetbuffer, 0, READ_BUFSIZE);
 83  
 84    while (timeout--) {
 85      if (replyidx >= 20) break;
 86      if ((packetbuffer[1] == 'A') && (replyidx == PACKET_ACC_LEN))
 87        break;
 88      if ((packetbuffer[1] == 'G') && (replyidx == PACKET_GYRO_LEN))
 89        break;
 90      if ((packetbuffer[1] == 'M') && (replyidx == PACKET_MAG_LEN))
 91        break;
 92      if ((packetbuffer[1] == 'Q') && (replyidx == PACKET_QUAT_LEN))
 93        break;
 94      if ((packetbuffer[1] == 'B') && (replyidx == PACKET_BUTTON_LEN))
 95        break;
 96      if ((packetbuffer[1] == 'C') && (replyidx == PACKET_COLOR_LEN))
 97        break;
 98      if ((packetbuffer[1] == 'L') && (replyidx == PACKET_LOCATION_LEN))
 99        break;
100  
101      while (ble->available()) {
102        char c =  ble->read();
103        if (c == '!') {
104          replyidx = 0;
105        }
106        packetbuffer[replyidx] = c;
107        replyidx++;
108        timeout = origtimeout;
109      }
110      
111      if (timeout == 0) break;
112      delay(1);
113    }
114  
115    packetbuffer[replyidx] = 0;  // null term
116  
117    if (!replyidx)  // no data or timeout 
118      return 0;
119    if (packetbuffer[0] != '!')  // doesn't start with '!' packet beginning
120      return 0;
121    
122    // check checksum!
123    uint8_t xsum = 0;
124    uint8_t checksum = packetbuffer[replyidx-1];
125    
126    for (uint8_t i=0; i<replyidx-1; i++) {
127      xsum += packetbuffer[i];
128    }
129    xsum = ~xsum;
130  
131    // Throw an error message if the checksum's don't match
132    if (xsum != checksum)
133    {
134      Serial.print("Checksum mismatch in packet : ");
135      printHex(packetbuffer, replyidx+1);
136      return 0;
137    }
138    
139    // checksum passed!
140    return replyidx;
141  }
142