400 lines
12 KiB
C
400 lines
12 KiB
C
/*!
|
|
* @file CayenneLpp.c
|
|
*
|
|
* @brief Implements the Cayenne Low Power Protocol
|
|
*
|
|
* \copyright Revised BSD License, see section \ref LICENSE.
|
|
*
|
|
* \code
|
|
* ______ _
|
|
* / _____) _ | |
|
|
* ( (____ _____ ____ _| |_ _____ ____| |__
|
|
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
|
* _____) ) ____| | | || |_| ____( (___| | | |
|
|
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
|
* (C)2013-2018 Semtech
|
|
*
|
|
* \endcode
|
|
*
|
|
* \author Miguel Luis ( Semtech )
|
|
*/
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "stm32_mem.h"
|
|
#include "CayenneLpp.h"
|
|
/* USER CODE BEGIN Includes */
|
|
|
|
/* USER CODE END Includes */
|
|
|
|
/* External variables ---------------------------------------------------------*/
|
|
/* USER CODE BEGIN EV */
|
|
|
|
/* USER CODE END EV */
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* USER CODE BEGIN PTD */
|
|
|
|
/* USER CODE END PTD */
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
#define CAYENNE_LPP_MAXBUFFER_SIZE 242
|
|
#define LPP_DIGITAL_INPUT 0 /* 1 byte */
|
|
#define LPP_DIGITAL_OUTPUT 1 /* 1 byte */
|
|
#define LPP_ANALOG_INPUT 2 /* 2 bytes, 0.01 signed */
|
|
#define LPP_ANALOG_OUTPUT 3 /* 2 bytes, 0.01 signed */
|
|
#define LPP_LUMINOSITY 101 /* 2 bytes, 1 lux unsigned */
|
|
#define LPP_PRESENCE 102 /* 1 byte, 1 */
|
|
#define LPP_TEMPERATURE 103 /* 2 bytes, 0.1 Celsius degrees signed */
|
|
#define LPP_RELATIVE_HUMIDITY 104 /* 1 byte, 0.5% unsigned */
|
|
#define LPP_ACCELEROMETER 113 /* 2 bytes per axis, 0.001G */
|
|
#define LPP_BAROMETRIC_PRESSURE 115 /* 2 bytes 0.1 hPa Unsigned */
|
|
#define LPP_GYROMETER 134 /* 2 bytes per axis, 0.01 degrees/s */
|
|
#define LPP_GPS 136 /* 3 byte lon/lat 0.0001 degrees, 3 bytes alt 0.01m */
|
|
|
|
/* Data ID + Data Type + Data Size */
|
|
#define LPP_DIGITAL_INPUT_SIZE 3
|
|
#define LPP_DIGITAL_OUTPUT_SIZE 3
|
|
#define LPP_ANALOG_INPUT_SIZE 4
|
|
#define LPP_ANALOG_OUTPUT_SIZE 4
|
|
#define LPP_LUMINOSITY_SIZE 4
|
|
#define LPP_PRESENCE_SIZE 3
|
|
#define LPP_TEMPERATURE_SIZE 4
|
|
#define LPP_RELATIVE_HUMIDITY_SIZE 3
|
|
#define LPP_ACCELEROMETER_SIZE 8
|
|
#define LPP_BAROMETRIC_PRESSURE_SIZE 4
|
|
#define LPP_GYROMETER_SIZE 8
|
|
#define LPP_GPS_SIZE 11
|
|
|
|
/* USER CODE BEGIN PD */
|
|
|
|
/* USER CODE END PD */
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* USER CODE BEGIN PM */
|
|
|
|
/* USER CODE END PM */
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
static uint8_t CayenneLppBuffer[CAYENNE_LPP_MAXBUFFER_SIZE];
|
|
static uint8_t CayenneLppCursor = 0;
|
|
/* USER CODE BEGIN PV */
|
|
|
|
/* USER CODE END PV */
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN PFP */
|
|
|
|
/* USER CODE END PFP */
|
|
|
|
/* Exported functions --------------------------------------------------------*/
|
|
void CayenneLppInit(void)
|
|
{
|
|
CayenneLppCursor = 0;
|
|
/* USER CODE BEGIN CayenneLppCursor */
|
|
|
|
/* USER CODE END CayenneLppCursor */
|
|
}
|
|
|
|
void CayenneLppReset(void)
|
|
{
|
|
CayenneLppCursor = 0;
|
|
/* USER CODE BEGIN CayenneLppReset */
|
|
|
|
/* USER CODE END CayenneLppReset */
|
|
}
|
|
|
|
uint8_t CayenneLppGetSize(void)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppGetSize */
|
|
|
|
/* USER CODE END CayenneLppGetSize */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t *CayenneLppGetBuffer(void)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppGetBuffer */
|
|
|
|
/* USER CODE END CayenneLppGetBuffer */
|
|
return CayenneLppBuffer;
|
|
}
|
|
|
|
uint8_t CayenneLppCopy(uint8_t *dst)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppCopy_1 */
|
|
|
|
/* USER CODE END CayenneLppCopy_1 */
|
|
UTIL_MEM_cpy_8(dst, CayenneLppBuffer, CayenneLppCursor);
|
|
/* USER CODE BEGIN CayenneLppCopy_2 */
|
|
|
|
/* USER CODE END CayenneLppCopy_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddDigitalInput(uint8_t channel, uint8_t value)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddDigitalInput_1 */
|
|
|
|
/* USER CODE END CayenneLppAddDigitalInput_1 */
|
|
if ((CayenneLppCursor + LPP_DIGITAL_INPUT_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_DIGITAL_INPUT;
|
|
CayenneLppBuffer[CayenneLppCursor++] = value;
|
|
/* USER CODE BEGIN CayenneLppAddDigitalInput_2 */
|
|
|
|
/* USER CODE END CayenneLppAddDigitalInput_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddDigitalOutput(uint8_t channel, uint8_t value)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddDigitalOutput_1 */
|
|
|
|
/* USER CODE END CayenneLppAddDigitalOutput_1 */
|
|
if ((CayenneLppCursor + LPP_DIGITAL_OUTPUT_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_DIGITAL_OUTPUT;
|
|
CayenneLppBuffer[CayenneLppCursor++] = value;
|
|
/* USER CODE BEGIN CayenneLppAddDigitalOutput_2 */
|
|
|
|
/* USER CODE END CayenneLppAddDigitalOutput_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddAnalogInput(uint8_t channel, float value)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddAnalogInput_1 */
|
|
|
|
/* USER CODE END CayenneLppAddAnalogInput_1 */
|
|
if ((CayenneLppCursor + LPP_ANALOG_INPUT_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int16_t val = (int16_t)(value * 100);
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_ANALOG_INPUT;
|
|
CayenneLppBuffer[CayenneLppCursor++] = val >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = val;
|
|
/* USER CODE BEGIN CayenneLppAddAnalogInput_2 */
|
|
|
|
/* USER CODE END CayenneLppAddAnalogInput_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddAnalogOutput(uint8_t channel, float value)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddAnalogOutput_1 */
|
|
|
|
/* USER CODE END CayenneLppAddAnalogOutput_1 */
|
|
if ((CayenneLppCursor + LPP_ANALOG_OUTPUT_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
int16_t val = (int16_t)(value * 100);
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_ANALOG_OUTPUT;
|
|
CayenneLppBuffer[CayenneLppCursor++] = val >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = val;
|
|
/* USER CODE BEGIN CayenneLppAddAnalogOutput_2 */
|
|
|
|
/* USER CODE END CayenneLppAddAnalogOutput_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddLuminosity(uint8_t channel, uint16_t lux)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddLuminosity_1 */
|
|
|
|
/* USER CODE END CayenneLppAddLuminosity_1 */
|
|
if ((CayenneLppCursor + LPP_LUMINOSITY_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_LUMINOSITY;
|
|
CayenneLppBuffer[CayenneLppCursor++] = lux >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = lux;
|
|
/* USER CODE BEGIN CayenneLppAddLuminosity_2 */
|
|
|
|
/* USER CODE END CayenneLppAddLuminosity_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddPresence(uint8_t channel, uint8_t value)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddPresence_1 */
|
|
|
|
/* USER CODE END CayenneLppAddPresence_1 */
|
|
if ((CayenneLppCursor + LPP_PRESENCE_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_PRESENCE;
|
|
CayenneLppBuffer[CayenneLppCursor++] = value;
|
|
/* USER CODE BEGIN CayenneLppAddPresence_2 */
|
|
|
|
/* USER CODE END CayenneLppAddPresence_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddTemperature(uint8_t channel, float celsius)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddTemperature_1 */
|
|
|
|
/* USER CODE END CayenneLppAddTemperature_1 */
|
|
if ((CayenneLppCursor + LPP_TEMPERATURE_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
int16_t val = (int16_t)(celsius * 10);
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_TEMPERATURE;
|
|
CayenneLppBuffer[CayenneLppCursor++] = val >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = val;
|
|
/* USER CODE BEGIN CayenneLppAddTemperature_2 */
|
|
|
|
/* USER CODE END CayenneLppAddTemperature_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddRelativeHumidity(uint8_t channel, float rh)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddRelativeHumidity_1 */
|
|
|
|
/* USER CODE END CayenneLppAddRelativeHumidity_1 */
|
|
if ((CayenneLppCursor + LPP_RELATIVE_HUMIDITY_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_RELATIVE_HUMIDITY;
|
|
CayenneLppBuffer[CayenneLppCursor++] = (uint8_t)(rh * 2);
|
|
/* USER CODE BEGIN CayenneLppAddRelativeHumidity_2 */
|
|
|
|
/* USER CODE END CayenneLppAddRelativeHumidity_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddAccelerometer(uint8_t channel, float x, float y, float z)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddAccelerometer_1 */
|
|
|
|
/* USER CODE END CayenneLppAddAccelerometer_1 */
|
|
if ((CayenneLppCursor + LPP_ACCELEROMETER_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
int16_t vx = (int16_t)(x * 1000);
|
|
int16_t vy = (int16_t)(y * 1000);
|
|
int16_t vz = (int16_t)(z * 1000);
|
|
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_ACCELEROMETER;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vx >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vx;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vy >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vy;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vz >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vz;
|
|
/* USER CODE BEGIN CayenneLppAddAccelerometer_2 */
|
|
|
|
/* USER CODE END CayenneLppAddAccelerometer_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddBarometricPressure(uint8_t channel, float hpa)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddBarometricPressure_1 */
|
|
|
|
/* USER CODE END CayenneLppAddBarometricPressure_1 */
|
|
if ((CayenneLppCursor + LPP_BAROMETRIC_PRESSURE_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
int16_t val = (int16_t)(hpa * 10);
|
|
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_BAROMETRIC_PRESSURE;
|
|
CayenneLppBuffer[CayenneLppCursor++] = val >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = val;
|
|
/* USER CODE BEGIN CayenneLppAddBarometricPressure_2 */
|
|
|
|
/* USER CODE END CayenneLppAddBarometricPressure_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddGyrometer(uint8_t channel, float x, float y, float z)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddGyrometer_1 */
|
|
|
|
/* USER CODE END CayenneLppAddGyrometer_1 */
|
|
if ((CayenneLppCursor + LPP_GYROMETER_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
int16_t vx = (int16_t)(x * 100);
|
|
int16_t vy = (int16_t)(y * 100);
|
|
int16_t vz = (int16_t)(z * 100);
|
|
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_GYROMETER;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vx >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vx;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vy >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vy;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vz >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = vz;
|
|
/* USER CODE BEGIN CayenneLppAddGyrometer_2 */
|
|
|
|
/* USER CODE END CayenneLppAddGyrometer_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
uint8_t CayenneLppAddGps(uint8_t channel, float latitude, float longitude, float meters)
|
|
{
|
|
/* USER CODE BEGIN CayenneLppAddGps_1 */
|
|
|
|
/* USER CODE END CayenneLppAddGps_1 */
|
|
if ((CayenneLppCursor + LPP_GPS_SIZE) > CAYENNE_LPP_MAXBUFFER_SIZE)
|
|
{
|
|
return 0;
|
|
}
|
|
int32_t lat = (int32_t)(latitude * 10000);
|
|
int32_t lon = (int32_t)(longitude * 10000);
|
|
int32_t alt = (int32_t)(meters * 100);
|
|
|
|
CayenneLppBuffer[CayenneLppCursor++] = channel;
|
|
CayenneLppBuffer[CayenneLppCursor++] = LPP_GPS;
|
|
|
|
CayenneLppBuffer[CayenneLppCursor++] = lat >> 16;
|
|
CayenneLppBuffer[CayenneLppCursor++] = lat >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = lat;
|
|
CayenneLppBuffer[CayenneLppCursor++] = lon >> 16;
|
|
CayenneLppBuffer[CayenneLppCursor++] = lon >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = lon;
|
|
CayenneLppBuffer[CayenneLppCursor++] = alt >> 16;
|
|
CayenneLppBuffer[CayenneLppCursor++] = alt >> 8;
|
|
CayenneLppBuffer[CayenneLppCursor++] = alt;
|
|
/* USER CODE BEGIN CayenneLppAddGps_2 */
|
|
|
|
/* USER CODE END CayenneLppAddGps_2 */
|
|
return CayenneLppCursor;
|
|
}
|
|
|
|
/* USER CODE BEGIN EF */
|
|
|
|
/* USER CODE END EF */
|
|
|
|
/* Private Functions Definition -----------------------------------------------*/
|
|
/* USER CODE BEGIN PrFD */
|
|
|
|
/* USER CODE END PrFD */
|