added fuzzy matching feature to at_echo; added set some AT+ commands for RHF76; added support for LSM6DS3;

1. in tos_at.h, added int  fuzzy_matching; field into at_echo_st struct, if this field is set to K_TRUE, then if echo message contains the string in "echo_expect" field.
2. added __API__ int tos_at_echo_fuzzy_matching_create(at_echo_t *echo, char *buffer, size_t buffer_size, char *echo_expect_contains) api to tos_at.c, which will create an at_echo_t with fuzzy_matching = K_TRUE;
3. added RHF76_ATCMD_SET_DELAY and  rhf76_set_delay to RHF76.h to allow set/query RX delay config
4. added RHF76_ATCMD_SET_DATA_RATE and rhf76_set_data_rate to RHF76.h to allow set/query date rate config
5. added rhf76_at_cmd_exe for DEBUG purpose, so that user can execute any AT+ commands they want
6. added code in lora_demo.c to demonstrate package segmentation.
This commit is contained in:
Winfred LIN
2020-04-06 23:11:48 +10:00
parent 47d6313ba1
commit b6cb7147cc
14 changed files with 1258 additions and 522 deletions

View File

@@ -17,6 +17,9 @@ void BSP_Sensor_Init(DeviceConfig_TypeDef config)
LPS22HB_Init();
LIS3MDL_Init();
LIS3MDL_Set_FullScale((LIS3MDL_FullScaleTypeDef)config.magn_fullscale);
LSM6DS3_Init();
LSM6DS3_Set_Accel_FullScale((LSM6DS3_AccelFullscaleTypeDef)config.accel_fullscale);
LSM6DS3_Set_Gyro_FullScale((LSM6DS3_GyroFullscaleTypeDef)config.gyro_fullscale);
}
void BSP_Sensor_Read(sensor_data_t *sensor_data)

View File

@@ -20,6 +20,7 @@ extern "C" {
#include "HTS221.h"
#include "LPS22HB.h"
#include "LIS3MDL.h"
#include "LSM6DS3.h"
/* Exported types ------------------------------------------------------------*/
typedef struct
@@ -27,34 +28,30 @@ typedef struct
sensor_press_t sensor_press; /* pressure sensor */
sensor_tempnhumi_t sensor_tempnhumi; /* temperature and humidity */
sensor_magn_t sensor_magn; /* magnetometer */
//--------------------------- accelerator and gyroscope -------------------//
int16_t accel_x; /* in g */
int16_t accel_y; /* in g */
int16_t accel_z; /* in g */
int16_t gyro_x; /* in degree/s */
int16_t gyro_y; /* in degree/s */
int16_t gyro_z; /* in degree/s */
sensor_motion_t sensor_motion; /* accelerometer, gyroscope */
} sensor_data_t;
// application configuration types
typedef enum{
DCT_IS_CONFIRM = 0x00U,
DCT_REPORT_PERIOD = 0x01U,
DCT_REPEAT_TIME = 0x02U,
DCT_MAGN_FULLSCALE = 0x03U,
DCT_DEFAULT = 0xFFU,
DCT_IS_CONFIRM = 0x00U,
DCT_REPORT_PERIOD = 0x01U,
DCT_REPEAT_TIME = 0x02U,
DCT_MAGN_FULLSCALE = 0x03U,
DCT_ACCEL_FULLSCALE = 0x04U,
DCT_GYRO_FULLSCALE = 0x05U,
DCT_DEFAULT = 0xFFU,
}DeviceConfigType_TypeDef;
// application configuration
typedef struct
{
uint32_t config_address;
uint16_t report_period;
uint8_t repeat_time;
LIS3MDL_FullScaleTypeDef magn_fullscale;
bool is_confirmed;
uint32_t config_address;
uint16_t report_period;
uint8_t repeat_time;
LIS3MDL_FullScaleTypeDef magn_fullscale;
LSM6DS3_AccelFullscaleTypeDef accel_fullscale;
LSM6DS3_GyroFullscaleTypeDef gyro_fullscale;
bool is_confirmed;
}DeviceConfig_TypeDef;
/* Exported constants --------------------------------------------------------*/

View File

@@ -75,19 +75,19 @@ uint16_t LIS3MDL_Get_Sensitivity(LIS3MDL_FullScaleTypeDef fullscale)
uint16_t sensitivity = 1;
switch(fullscale)
{
case FULLSCALE_4:{
case MAGN_FULLSCALE_4:{
sensitivity = 6842;
break;
}
case FULLSCALE_8:{
case MAGN_FULLSCALE_8:{
sensitivity = 3421;
break;
}
case FULLSCALE_12:{
case MAGN_FULLSCALE_12:{
sensitivity = 2281;
break;
}
case FULLSCALE_16:{
case MAGN_FULLSCALE_16:{
sensitivity = 1711;
break;
}

View File

@@ -65,10 +65,10 @@ typedef enum
*/
typedef enum
{
FULLSCALE_4 = 0x00U,
FULLSCALE_8 = 0x01U,
FULLSCALE_12 = 0x02U,
FULLSCALE_16 = 0x03U
MAGN_FULLSCALE_4 = 0x00U,
MAGN_FULLSCALE_8 = 0x01U,
MAGN_FULLSCALE_12 = 0x02U,
MAGN_FULLSCALE_16 = 0x03U
}LIS3MDL_FullScaleTypeDef;
/**

View File

@@ -58,7 +58,7 @@ typedef enum
typedef struct
{
uint16_t sensitivity; // sensitivity per fullscale
uint32_t pressure; // X-magnetic value in LSB
uint32_t pressure; // pressure
}sensor_press_t;
/* Functions -----------------------------------------------------------------*/

View File

@@ -0,0 +1,359 @@
/**
******************************************************************************
* @file LSM6DS3.c
* @author jieranzhi
* @update 2020/03/23 19:00 CST
* @brief This file provides code for the LSM6DS3 Initialization
* and data output codes.
******************************************************************************
* @attention
*
* 1. this code is used as one of the examples in TencentOS_tiny project, it's
* just a simple implementation of the sensor functionalities, to implement
* more functions, please refer to the datasheet or the official software
* package provided by ST (STM32CubeExpansion_LRWAN_V1.3.1)
*
* 2. in this file the host MCU need to read the output persistently, which is
* not of power efficient, to achieve better power consumption performance,
* it is recommended to use FIFO.
*
******************************************************************************
*/
#include <LSM6DS3.h>
#include <i2c.h>
// initialization of LSM6DS3
void LSM6DS3_Init()
{
uint8_t cmd = 0;
// ODR: 12.5Hz, fs: 4g, BWZ: 50Hz
cmd = 0x1B;
HAL_I2C_Mem_Write(&hi2c1, LSM6DS3_ADDR_WR, LSM6DS3_CTRL1_XL, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// ODR: 12.5Hz, fs: 250dps
cmd = 0x10;
HAL_I2C_Mem_Write(&hi2c1, LSM6DS3_ADDR_WR, LSM6DS3_CTRL2_G, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// High performance: disabled to save power
cmd = 0x10;
HAL_I2C_Mem_Write(&hi2c1, LSM6DS3_ADDR_WR, LSM6DS3_CTRL6_C, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// High performance: disabled to save power
cmd = 0x80;
HAL_I2C_Mem_Write(&hi2c1, LSM6DS3_ADDR_WR, LSM6DS3_CTRL7_G, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// timestamp output: enable, pedometer algorithm: enabled
cmd = 0xC0;
HAL_I2C_Mem_Write(&hi2c1, LSM6DS3_ADDR_WR, LSM6DS3_TAP_CFG, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
}
void LSM6DS3_Set_Accel_FullScale(LSM6DS3_AccelFullscaleTypeDef fullscale)
{
uint8_t ctrl_reg1_value;
uint8_t fullscale_config = (uint8_t)fullscale;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_CTRL1_XL, I2C_MEMADD_SIZE_8BIT, &ctrl_reg1_value, 1, 0xFFFF);
fullscale_config = (ctrl_reg1_value&0xF1)|(fullscale_config&0x0E);
HAL_I2C_Mem_Write(&hi2c1, LSM6DS3_ADDR_WR, LSM6DS3_CTRL1_XL, I2C_MEMADD_SIZE_8BIT, &fullscale_config, 1, 0xFFFF);
}
void LSM6DS3_Set_Gyro_FullScale(LSM6DS3_GyroFullscaleTypeDef fullscale)
{
uint8_t ctrl_reg2_value;
uint8_t fullscale_config = (uint8_t)fullscale;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_CTRL2_G, I2C_MEMADD_SIZE_8BIT, &ctrl_reg2_value, 1, 0xFFFF);
fullscale_config = (ctrl_reg2_value&0xF1)|(fullscale_config&0x0E);
HAL_I2C_Mem_Write(&hi2c1, LSM6DS3_ADDR_WR, LSM6DS3_CTRL2_G, I2C_MEMADD_SIZE_8BIT, &fullscale_config, 1, 0xFFFF);
}
void LSM6DS3_Set_Accel_FullScale_Num(uint8_t fullscale_num)
{
LSM6DS3_AccelFullscaleTypeDef fullscale = ACCEL_FULLSCALE_2;
switch(fullscale_num)
{
case 2:
{
fullscale = ACCEL_FULLSCALE_2;
break;
}
case 16:
{
fullscale = ACCEL_FULLSCALE_16;
break;
}
case 4:
{
fullscale = ACCEL_FULLSCALE_4;
break;
}
case 8:
{
fullscale = ACCEL_FULLSCALE_8;
break;
}
default:
{
break;
}
}
LSM6DS3_Set_Accel_FullScale(fullscale);
}
void LSM6DS3_Set_Gyro_FullScale_Num(uint8_t fullscale_num)
{
LSM6DS3_GyroFullscaleTypeDef fullscale = GYRO_FULLSCALE_250;
switch(fullscale_num)
{
case 125:
{
fullscale = GYRO_FULLSCALE_125;
break;
}
case 250:
{
fullscale = GYRO_FULLSCALE_250;
break;
}
case 500:
{
fullscale = GYRO_FULLSCALE_500;
break;
}
case 1000:
{
fullscale = GYRO_FULLSCALE_1000;
break;
}
case 2000:
{
fullscale = GYRO_FULLSCALE_2000;
break;
}
default:
{
break;
}
}
LSM6DS3_Set_Gyro_FullScale(fullscale);
}
uint8_t LSM6DS3_Get_Accel_FullScale_Num(LSM6DS3_AccelFullscaleTypeDef fullscale)
{
uint8_t fullscale_num = 1;
switch(fullscale)
{
case ACCEL_FULLSCALE_2:
{
fullscale_num = 2;
break;
}
case ACCEL_FULLSCALE_16:
{
fullscale_num = 16;
break;
}
case ACCEL_FULLSCALE_4:
{
fullscale_num = 4;
break;
}
case ACCEL_FULLSCALE_8:
{
fullscale_num = 8;
break;
}
default:
{
break;
}
}
return fullscale_num;
}
uint16_t LSM6DS3_Get_Gyro_FullScale_Num(LSM6DS3_GyroFullscaleTypeDef fullscale)
{
uint16_t fullscale_num = 1;
switch(fullscale)
{
case GYRO_FULLSCALE_125:
{
fullscale_num = 125;
break;
}
case GYRO_FULLSCALE_250:
{
fullscale_num = 250;
break;
}
case GYRO_FULLSCALE_500:
{
fullscale_num = 500;
break;
}
case GYRO_FULLSCALE_1000:
{
fullscale_num = 1000;
break;
}
case GYRO_FULLSCALE_2000:
{
fullscale_num = 2000;
break;
}
default:
{
break;
}
}
return fullscale_num;
}
LSM6DS3_AccelFullscaleTypeDef LSM6DS3_Get_Accel_FullScale()
{
uint8_t fullscale;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_CTRL1_XL, I2C_MEMADD_SIZE_8BIT, &fullscale, 1, 0xFFFF);
fullscale = (fullscale<<1)>>6;
return (LSM6DS3_AccelFullscaleTypeDef)fullscale;
}
LSM6DS3_GyroFullscaleTypeDef LSM6DS3_Get_Gyro_FullScale()
{
uint8_t fullscale;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_CTRL2_G, I2C_MEMADD_SIZE_8BIT, &fullscale, 1, 0xFFFF);
fullscale = fullscale&0x02;
if(fullscale == 0x00) fullscale = fullscale&0x0C;
return (LSM6DS3_GyroFullscaleTypeDef)fullscale;
}
uint16_t LSM6DS3_Get_Accel_Sensitivity(LSM6DS3_AccelFullscaleTypeDef fullscale)
{
uint16_t sensitivity = 1;
switch(fullscale)
{
case ACCEL_FULLSCALE_2:{
sensitivity = 61;
break;
}
case ACCEL_FULLSCALE_4:{
sensitivity = 122;
break;
}
case ACCEL_FULLSCALE_8:{
sensitivity = 244;
break;
}
case ACCEL_FULLSCALE_16:{
sensitivity = 488;
break;
}
default:{
sensitivity = 1;
}
}
return sensitivity;
}
uint32_t LSM6DS3_Get_Gyro_Sensitivity(LSM6DS3_GyroFullscaleTypeDef fullscale)
{
uint32_t sensitivity = 1;
switch(fullscale)
{
case GYRO_FULLSCALE_125:{
sensitivity = 4375;
break;
}
case GYRO_FULLSCALE_250:{
sensitivity = 8750;
break;
}
case GYRO_FULLSCALE_500:{
sensitivity = 17500;
break;
}
case GYRO_FULLSCALE_1000:{
sensitivity = 35000;
break;
}
case GYRO_FULLSCALE_2000:{
sensitivity = 70000;
break;
}
default:{
sensitivity = 1;
}
}
return sensitivity;
}
uint8_t LSM6DS3_Get_Sensor_Config(sensor_motion_t* sensor_motion)
{
LSM6DS3_AccelFullscaleTypeDef accel_fullscale = LSM6DS3_Get_Accel_FullScale();
sensor_motion->accelFullscale = LSM6DS3_Get_Accel_FullScale_Num(accel_fullscale);
sensor_motion->accelSensitivity = LSM6DS3_Get_Accel_Sensitivity(accel_fullscale);
LSM6DS3_GyroFullscaleTypeDef gyro_fullscale = LSM6DS3_Get_Gyro_FullScale();
sensor_motion->gyroFullscale = LSM6DS3_Get_Gyro_FullScale_Num(gyro_fullscale);
sensor_motion->gyroSensitivity = LSM6DS3_Get_Gyro_Sensitivity(gyro_fullscale);
return 0;
}
uint8_t LSM6DS3_Get_Accel(sensor_motion_t* sensor_motion)
{
uint8_t accelx_h, accelx_l, accely_h, accely_l, accelz_h, accelz_l;
uint8_t status_dat = 0;
while((status_dat&LSM6DS3_XL_DA) != LSM6DS3_XL_DA)
{
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_STATUS_REG, I2C_MEMADD_SIZE_8BIT, &status_dat, 1, 0xFFFF);
}
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTX_H_XL, I2C_MEMADD_SIZE_8BIT, &accelx_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTX_L_XL, I2C_MEMADD_SIZE_8BIT, &accelx_l, 1, 0xFFFF);
sensor_motion->accelX = (uint16_t)accelx_h<<8|accelx_l;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTY_H_XL, I2C_MEMADD_SIZE_8BIT, &accely_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTY_L_XL, I2C_MEMADD_SIZE_8BIT, &accely_l, 1, 0xFFFF);
sensor_motion->accelY = (uint16_t)accely_h<<8|accely_l;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTZ_H_XL, I2C_MEMADD_SIZE_8BIT, &accelz_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTZ_L_XL, I2C_MEMADD_SIZE_8BIT, &accelz_l, 1, 0xFFFF);
sensor_motion->accelZ = (uint16_t)accelz_h<<8|accelz_l;
return 0;
}
uint8_t LSM6DS3_Get_Gyro(sensor_motion_t* sensor_motion)
{
uint8_t gyrox_h, gyrox_l, gyroy_h, gyroy_l, gyroz_h, gyroz_l;
uint8_t status_dat = 0;
while((status_dat&LSM6DS3_G_DA) != LSM6DS3_G_DA)
{
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_STATUS_REG, I2C_MEMADD_SIZE_8BIT, &status_dat, 1, 0xFFFF);
}
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTX_H_G, I2C_MEMADD_SIZE_8BIT, &gyrox_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTX_L_G, I2C_MEMADD_SIZE_8BIT, &gyrox_l, 1, 0xFFFF);
sensor_motion->gyroX = (uint16_t)gyrox_h<<8|gyrox_l;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTY_H_G, I2C_MEMADD_SIZE_8BIT, &gyroy_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTY_L_G, I2C_MEMADD_SIZE_8BIT, &gyroy_l, 1, 0xFFFF);
sensor_motion->gyroY = (uint16_t)gyroy_h<<8|gyroy_l;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTZ_H_G, I2C_MEMADD_SIZE_8BIT, &gyroz_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_OUTZ_L_G, I2C_MEMADD_SIZE_8BIT, &gyroz_l, 1, 0xFFFF);
sensor_motion->gyroZ = (uint16_t)gyroz_h<<8|gyroz_l;
return 0;
}
uint8_t LSM6DS3_Get_Step(sensor_motion_t* sensor_motion)
{
uint8_t step_h, step_l;
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_STEP_COUNTER_H, I2C_MEMADD_SIZE_8BIT, &step_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LSM6DS3_ADDR_RD, LSM6DS3_STEP_COUNTER_L, I2C_MEMADD_SIZE_8BIT, &step_l, 1, 0xFFFF);
sensor_motion->stepCount = (uint16_t)step_h<<8|step_l;
return 0;
}

View File

@@ -0,0 +1,130 @@
/**
******************************************************************************
* @file LSM6DS3.h
* @author jieranzhi (the developer)
* @update 2020/03/23 19:00 CST
* @brief This file contains basic functions prototypes and pre-definitions
* of the register addresses
******************************************************************************
* @attention
*
* 1. the temperature sensor embedded in the LSM6DS3 is intended to be embedded
* temperature compensation. Therefore, in this file we DO NOT include the
* temperature output
*
* 2. on the P-NUCLEO-LRWAN3, the SDO/SA0 pad is connected to voltage supply(
* via a resistor), LSb is <20><>1<EFBFBD><31> (address 1011101b), and the sensor uses
* connection mode 1
*
* 3. for more information, please refer to the datasheet
* (https://www.st.com/resource/en/datasheet/lsm6ds3.pdf)
*
******************************************************************************
*/
#ifndef _LSM6DS3_H_
#define _LSM6DS3_H_
#include <stm32l0xx_hal.h>
/* Registers -----------------------------------------------------------------*/
#define LSM6DS3_ADDR_WR 0xD6
#define LSM6DS3_ADDR_RD 0xD7
#define LSM6DS3_CTRL1_XL 0x10
#define LSM6DS3_CTRL2_G 0x11
#define LSM6DS3_CTRL3_C 0x12
#define LSM6DS3_CTRL4_C 0x13
#define LSM6DS3_CTRL5_C 0x14
#define LSM6DS3_CTRL6_C 0x15
#define LSM6DS3_CTRL7_G 0x16
#define LSM6DS3_CTRL8_XL 0x17
#define LSM6DS3_CTRL9_XL 0x18
#define LSM6DS3_CTRL10_C 0x19
#define LSM6DS3_STATUS_REG 0x1E
#define LSM6DS3_OUTX_L_G 0x22
#define LSM6DS3_OUTX_H_G 0x23
#define LSM6DS3_OUTY_L_G 0x24
#define LSM6DS3_OUTY_H_G 0x25
#define LSM6DS3_OUTZ_L_G 0x26
#define LSM6DS3_OUTZ_H_G 0x27
#define LSM6DS3_OUTX_L_XL 0x28
#define LSM6DS3_OUTX_H_XL 0x29
#define LSM6DS3_OUTY_L_XL 0x30
#define LSM6DS3_OUTY_H_XL 0x31
#define LSM6DS3_OUTZ_L_XL 0x32
#define LSM6DS3_OUTZ_H_XL 0x33
#define LSM6DS3_STEP_COUNTER_L 0x4B
#define LSM6DS3_STEP_COUNTER_H 0x4C
#define LSM6DS3_TAP_CFG 0x58
/* Enumeration ---------------------------------------------------------------*/
/**
* @brief STATUS structures definition
*/
typedef enum
{
LSM6DS3_T_DA = 0x04, /*!< temperature data available */
LSM6DS3_G_DA = 0x02, /*!< gyro data available */
LSM6DS3_XL_DA = 0x01, /*!< acceleration data available */
}LSM6DS3_StatusTypeDef;
typedef enum
{
ACCEL_FULLSCALE_2 = 0x00U,
ACCEL_FULLSCALE_16 = 0x04U,
ACCEL_FULLSCALE_4 = 0x08U,
ACCEL_FULLSCALE_8 = 0x0CU,
}LSM6DS3_AccelFullscaleTypeDef;
typedef enum
{
GYRO_FULLSCALE_125 = 0x02U,
GYRO_FULLSCALE_250 = 0x00U,
GYRO_FULLSCALE_500 = 0x04U,
GYRO_FULLSCALE_1000 = 0x08U,
GYRO_FULLSCALE_2000 = 0x0CU,
}LSM6DS3_GyroFullscaleTypeDef;
/**
* @brief motion sensor structures definition
*/
typedef struct
{
uint8_t accelFullscale;
uint8_t gyroFullscale;
uint16_t accelSensitivity; /*!< the sensitivity is 1000x its actual value */
uint16_t gyroSensitivity; /*!< the sensitivity is 1000x its actual value */
uint16_t gyroX;
uint16_t gyroY;
uint16_t gyroZ;
uint16_t accelX;
uint16_t accelY;
uint16_t accelZ;
uint16_t stepCount;
}sensor_motion_t;
/* Functions -----------------------------------------------------------------*/
void LSM6DS3_Init(void);
void LSM6DS3_Set_Accel_FullScale(LSM6DS3_AccelFullscaleTypeDef fullscale);
void LSM6DS3_Set_Gyro_FullScale(LSM6DS3_GyroFullscaleTypeDef fullscale);
void LSM6DS3_Set_Accel_FullScale_Num(uint8_t fullscale_num);
void LSM6DS3_Set_Gyro_FullScale_Num(uint8_t fullscale_num);
uint8_t LSM6DS3_Get_Accel_FullScale_Num(LSM6DS3_AccelFullscaleTypeDef fullscale);
uint16_t LSM6DS3_Get_Gyro_FullScale_Num(LSM6DS3_GyroFullscaleTypeDef fullscale);
LSM6DS3_AccelFullscaleTypeDef LSM6DS3_Get_Accel_FullScale(void);
LSM6DS3_GyroFullscaleTypeDef LSM6DS3_Get_Gyro_FullScale(void);
uint16_t LSM6DS3_Get_Accel_Sensitivity(LSM6DS3_AccelFullscaleTypeDef fullscale);
uint32_t LSM6DS3_Get_Gyro_Sensitivity(LSM6DS3_GyroFullscaleTypeDef fullscale);
uint8_t LSM6DS3_Get_Sensor_Config(sensor_motion_t* sensor_motion);
uint8_t LSM6DS3_Get_Accel(sensor_motion_t* sensor_motion);
uint8_t LSM6DS3_Get_Gyro(sensor_motion_t* sensor_motion);
uint8_t LSM6DS3_Get_Step(sensor_motion_t* sensor_motion);
#endif /* _LSM6DS3_H_ */

View File

@@ -119,18 +119,31 @@
*/
typedef struct device_data_st {
uint8_t magn_fullscale; // fullscale of magnetometer(RW)
uint8_t temp_sensitivity; // temperature sensitivity (R)
uint16_t humi_sensitivity; // humidity sensitivity (R)
uint16_t press_sensitivity; // pressure sensitivity (R)
uint16_t magn_sensitivity; // magnetic sensitivity (R)
int16_t temperature; // temperature (R)
int16_t humidity; // humidity (R)
int16_t magn_x; // X-magnetic value in LSB (R)
int16_t magn_y; // Y-magnetic value in LSB (R)
int16_t magn_z; // Z-magnetic value in LSB (R)
uint16_t period; // report period (R)
uint32_t pressure; // pressure (R)
// -- data set 1
uint8_t magn_fullscale; // fullscale of magnetometer (RW)
uint8_t temp_sensitivity; // temperature sensitivity (R)
uint16_t humi_sensitivity; // humidity sensitivity (R)
uint16_t press_sensitivity; // pressure sensitivity (R)
uint16_t magn_sensitivity; // magnetic sensitivity (R)
int16_t temperature; // temperature (R)
int16_t humidity; // humidity (R)
int16_t magn_x; // X-magnetic value in LSB (R)
int16_t magn_y; // Y-magnetic value in LSB (R)
int16_t magn_z; // Z-magnetic value in LSB (R)
uint16_t period; // report period (R)
uint32_t pressure; // pressure (R)
// --- data set 2
uint16_t accel_fullscale; // fullscale of accelerometer(RW)
uint16_t gyro_fullscale; // fullscale of magnetometer (RW)
int16_t accel_x; // X-accel value in LSB (R)
int16_t accel_y; // Y-accel value in LSB (R)
int16_t accel_z; // Z-accel value in LSB (R)
int16_t gyro_x; // X-gyro value in LSB (R)
int16_t gyro_y; // Y-gyro value in LSB (R)
int16_t gyro_z; // Z-gyro value in LSB (R)
uint32_t accel_sensitivity; // accel sensitivity (R)
uint32_t gyro_sensitivity; // gyro sensitivity (R)
} __PACKED__ dev_data_t;
typedef struct device_data_wrapper_st {
@@ -146,10 +159,12 @@ DeviceConfig_TypeDef device_config;
void set_config_to_default(DeviceConfig_TypeDef* config)
{
config->config_address = 0x08080000U;
config->is_confirmed = true;
config->report_period = 10;
config->magn_fullscale = FULLSCALE_4;
config->config_address = 0x08080000U;
config->is_confirmed = true;
config->report_period = 10;
config->magn_fullscale = MAGN_FULLSCALE_4;
config->accel_fullscale = ACCEL_FULLSCALE_4;
config->gyro_fullscale = GYRO_FULLSCALE_250;
}
/**
@@ -177,6 +192,9 @@ HAL_StatusTypeDef write_config_to_Flash(DeviceConfig_TypeDef config)
frame[1] = (uint32_t)config.is_confirmed<<8 | (uint32_t)DCT_IS_CONFIRM;
frame[2] = (uint32_t)config.report_period<<8 | (uint32_t)DCT_REPORT_PERIOD;
frame[3] = (uint32_t)config.repeat_time<<8 | (uint32_t)DCT_REPEAT_TIME;
frame[3] = (uint32_t)config.magn_fullscale<<8 | (uint32_t)DCT_MAGN_FULLSCALE;
frame[3] = (uint32_t)config.accel_fullscale<<8 | (uint32_t)DCT_ACCEL_FULLSCALE;
frame[3] = (uint32_t)config.gyro_fullscale<<8 | (uint32_t)DCT_GYRO_FULLSCALE;
frame[4] = 0xFFFFFFFFU;
HAL_FLASH_Unlock();
@@ -242,6 +260,16 @@ HAL_StatusTypeDef read_config_from_Flash(DeviceConfig_TypeDef* config)
config->magn_fullscale = (LIS3MDL_FullScaleTypeDef)(data>>8&0xFF);
break;
}
case DCT_ACCEL_FULLSCALE:
{
config->accel_fullscale = (LSM6DS3_AccelFullscaleTypeDef)(data>>8&0xFF);
break;
}
case DCT_GYRO_FULLSCALE:
{
config->gyro_fullscale = (LSM6DS3_GyroFullscaleTypeDef)(data>>8&0xFF);
break;
}
default:
{
break;
@@ -311,24 +339,45 @@ void application_entry(void *arg)
while (1) {
BSP_Sensor_Read(&sensor_data);
print_to_screen(sensor_data);
// generate data frame
dev_data_wrapper.u.dev_data.magn_fullscale = (uint8_t)(sensor_data.sensor_magn.fullscale);
dev_data_wrapper.u.dev_data.temp_sensitivity = (uint8_t)(sensor_data.sensor_tempnhumi.temp_sensitivity);
dev_data_wrapper.u.dev_data.humi_sensitivity = (uint16_t)(sensor_data.sensor_tempnhumi.humi_sensitivity);
dev_data_wrapper.u.dev_data.press_sensitivity = (uint16_t)(sensor_data.sensor_press.sensitivity);
dev_data_wrapper.u.dev_data.magn_sensitivity = (uint16_t)(sensor_data.sensor_magn.sensitivity);
dev_data_wrapper.u.dev_data.temperature = (int16_t)(sensor_data.sensor_tempnhumi.temperature);
dev_data_wrapper.u.dev_data.humidity = (int16_t)(sensor_data.sensor_tempnhumi.humidity);
dev_data_wrapper.u.dev_data.magn_x = (int16_t)(sensor_data.sensor_magn.magn_x);
dev_data_wrapper.u.dev_data.magn_y = (int16_t)(sensor_data.sensor_magn.magn_y);
dev_data_wrapper.u.dev_data.magn_z = (int16_t)(sensor_data.sensor_magn.magn_z);
dev_data_wrapper.u.dev_data.pressure = (uint32_t)(sensor_data.sensor_press.pressure);
dev_data_wrapper.u.dev_data.period = device_config.report_period;
// generate data frame for data set 1
dev_data_wrapper.u.dev_data.magn_fullscale = (uint8_t)(sensor_data.sensor_magn.fullscale);
dev_data_wrapper.u.dev_data.temp_sensitivity = (uint8_t)(sensor_data.sensor_tempnhumi.temp_sensitivity);
dev_data_wrapper.u.dev_data.humi_sensitivity = (uint16_t)(sensor_data.sensor_tempnhumi.humi_sensitivity);
dev_data_wrapper.u.dev_data.press_sensitivity = (uint16_t)(sensor_data.sensor_press.sensitivity);
dev_data_wrapper.u.dev_data.magn_sensitivity = (uint16_t)(sensor_data.sensor_magn.sensitivity);
dev_data_wrapper.u.dev_data.temperature = (int16_t)(sensor_data.sensor_tempnhumi.temperature);
dev_data_wrapper.u.dev_data.humidity = (int16_t)(sensor_data.sensor_tempnhumi.humidity);
dev_data_wrapper.u.dev_data.magn_x = (int16_t)(sensor_data.sensor_magn.magn_x);
dev_data_wrapper.u.dev_data.magn_y = (int16_t)(sensor_data.sensor_magn.magn_y);
dev_data_wrapper.u.dev_data.magn_z = (int16_t)(sensor_data.sensor_magn.magn_z);
dev_data_wrapper.u.dev_data.period = device_config.report_period;
dev_data_wrapper.u.dev_data.pressure = (uint32_t)(sensor_data.sensor_press.pressure);
// generate data frame for data set 2
dev_data_wrapper.u.dev_data.accel_fullscale = (uint16_t)(sensor_data.sensor_motion.accelFullscale);
dev_data_wrapper.u.dev_data.gyro_fullscale = (uint16_t)(sensor_data.sensor_motion.gyroFullscale);
dev_data_wrapper.u.dev_data.accel_sensitivity = (uint32_t)(sensor_data.sensor_motion.accelSensitivity);
dev_data_wrapper.u.dev_data.gyro_sensitivity = (uint32_t)(sensor_data.sensor_motion.gyroSensitivity);
dev_data_wrapper.u.dev_data.accel_x = (int16_t)(sensor_data.sensor_motion.accelX);
dev_data_wrapper.u.dev_data.accel_y = (int16_t)(sensor_data.sensor_motion.accelY);
dev_data_wrapper.u.dev_data.accel_z = (int16_t)(sensor_data.sensor_motion.accelZ);
dev_data_wrapper.u.dev_data.gyro_x = (int16_t)(sensor_data.sensor_motion.gyroX);
dev_data_wrapper.u.dev_data.gyro_y = (int16_t)(sensor_data.sensor_motion.gyroY);
dev_data_wrapper.u.dev_data.gyro_z = (int16_t)(sensor_data.sensor_motion.gyroZ);
// package segmentation
uint8_t data_frame1[25]={0}; // idx = 0
uint8_t data_frame2[25]={1}; // idx = 1
memcpy(data_frame1+1, dev_data_wrapper.u.serialize, sizeof(uint8_t)*24);
memcpy(data_frame2+1, dev_data_wrapper.u.serialize+24, sizeof(uint8_t)*24);
// send data to the server (via gateway)
if(device_config.is_confirmed){
tos_lora_module_send(dev_data_wrapper.u.serialize, sizeof(dev_data_t));
tos_lora_module_send(data_frame1, sizeof(data_frame1));
tos_lora_module_send(data_frame2, sizeof(data_frame2));
}else{
tos_lora_module_send_unconfirmed(dev_data_wrapper.u.serialize, sizeof(dev_data_t));
tos_lora_module_send_unconfirmed(data_frame1, sizeof(data_frame1));
tos_lora_module_send_unconfirmed(data_frame2, sizeof(data_frame2));
}
tos_task_delay(device_config.report_period * 1000);
}

View File

@@ -369,6 +369,7 @@
<state>$PROJ_DIR$\..\..\BSP\HardWare\LPS22HB</state>
<state>$PROJ_DIR$\..\..\BSP\HardWare\Common</state>
<state>$PROJ_DIR$\..\..\BSP\HardWare\LIS3MDL</state>
<state>$PROJ_DIR$\..\..\BSP\HardWare\LSM6DS3</state>
</option>
<option>
<name>CCStdIncCheck</name>
@@ -1079,6 +1080,12 @@
<name>$PROJ_DIR$\..\..\BSP\HardWare\LPS22HB\LPS22HB.c</name>
</file>
</group>
<group>
<name>LSM6DS3</name>
<file>
<name>$PROJ_DIR$\..\..\BSP\HardWare\LSM6DS3\LSM6DS3.c</name>
</file>
</group>
<file>
<name>$PROJ_DIR$\..\..\BSP\HardWare\Common\bsp.c</name>
</file>

View File

@@ -1213,6 +1213,12 @@
<name>$PROJ_DIR$\..\..\BSP\HardWare\LPS22HB\LPS22HB.c</name>
</file>
</group>
<group>
<name>LSM6DS3</name>
<file>
<name>$PROJ_DIR$\..\..\BSP\HardWare\LSM6DS3\LSM6DS3.c</name>
</file>
</group>
<file>
<name>$PROJ_DIR$\..\..\BSP\HardWare\Common\bsp.c</name>
</file>

View File

@@ -154,7 +154,7 @@ static int rhf76_set_chanel(void)
return -1;
}
static int rhf76_set_repeat(uint8_t num)
int rhf76_set_repeat(uint8_t num)
{
int try = 0;
at_echo_t echo;
@@ -174,6 +174,56 @@ static int rhf76_set_repeat(uint8_t num)
return -1;
}
int rhf76_set_data_rate(uint8_t num)
{
if(num>15) return -1; // num should between [0, 15]
int try = 0;
at_echo_t echo;
char cmd[14] = {0};
char expect[10] = {'\0'};
snprintf(cmd, sizeof(cmd), RHF76_ATCMD_SET_DATA_RATE, num);
snprintf(expect, sizeof(expect), " DR%d", num);
tos_at_echo_fuzzy_matching_create(&echo, NULL, 0, expect);
while (try++ < 10) {
tos_at_cmd_exec(&echo, 3000, cmd);
if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) {
return 0;
}
}
return -1;
}
int rhf76_set_delay(char *param)
{
int try = 0;
at_echo_t echo;
char cmd[20] = {0};
char expect[20] = {'\0'};
snprintf(cmd, sizeof(cmd), RHF76_ATCMD_SET_DELAY, param);
snprintf(expect, sizeof(expect), "+DELAY %s", param);
tos_at_echo_create(&echo, NULL, 0, expect);
while (try++ < 10) {
tos_at_cmd_exec(&echo, 3000, cmd);
if(strstr(param,"?")!=NULL) return 0;
if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) {
return 0;
}
}
return -1;
}
int rhf76_at_cmd_exe(char *cmd)
{
at_echo_t echo;
tos_at_echo_create(&echo, NULL, 0, NULL);
tos_at_cmd_exec(&echo, 8000, cmd);
return 0;
}
static int rhf76_set_adr_off(void)
{
int try = 0;
@@ -329,10 +379,34 @@ static int rhf76_init(void)
printf("rhf76 set repeat times for unconfirmed message FAILED\n");
return -1;
}
at_delay_ms(2000);
printf("Init RHF76 LoRa done\n");
/*----------------------------------------------------*/
/*--- the following code is only used for debuging ---*/
/*----------------------------------------------------*/
/*<-- query/set UART Timeout (~TX timeout) -->*/
// rhf76_at_cmd_exe("AT+UART=TIMEOUT, 300\r\n");
// rhf76_at_cmd_exe("AT+UART=TIMEOUT\r\n");
/*<-- query current band config -->*/
// rhf76_at_cmd_exe("AT+DR=SCHEME\r\n");
// rhf76_at_cmd_exe("AT+LW=CDR\r\n");
/*<-- query current data rate and the corresponding max payload size -->*/
rhf76_set_data_rate(0);
// rhf76_at_cmd_exe("at+dr=0\r\n");
// rhf76_at_cmd_exe("AT+DR\r\n");
// rhf76_at_cmd_exe("AT+LW=LEN\r\n");
/*<-- query RX1\RX2\JRX1\JRX2 delay config -->*/
// rhf76_set_delay("?");
/*<-- query RF config -->*/
// rhf76_at_cmd_exe("AT+MODE=TEST\r\n");
// rhf76_at_cmd_exe("AT+TEST=?\r\n");
return 0;
}
@@ -454,7 +528,6 @@ static int rhf76_send(const void *buf, size_t len)
static int rhf76_send_unconfirmed(const void *buf, size_t len)
{
char *str_buf = NULL;
at_echo_t echo;

View File

@@ -69,9 +69,11 @@ typedef enum lora_key_type {
#define RHF76_ATCMD_FMT_SEND_MSGHEX "AT+MSGHEX=\"%s\"\r\n"
#define RHF76_ATCMD_SET_REPT "AT+REPT=%d\r\n"
#define RHF76_ATCMD_SET_DELAY "AT+DELAY=%s\r\n"
#define RHF76_ATCMD_SET_BAND_CN470 "AT+DR=CN470\r\n"
#define RHF76_ATCMD_REPLY_BAND_CN470 "+DR: CN470"
#define RHF76_ATCMD_SET_DATA_RATE "AT+DR=%d\r\n"
#define RHF76_ATCMD_SET_CHANNEL "at+ch=num,80-87\r\n"
#define RHF76_ATCMD_SET_ADR_OFF "at+adr=off\r\n"
@@ -84,5 +86,66 @@ typedef enum lora_key_type {
int rhf76_lora_init(hal_uart_port_t uart_port);
/**
* @brief set the delay for RX1,RX2,JRX1,JRX2 OR query current delay config
* @note Examples:
* to set the delay(ms):
* rhf76_set_delay("RX1,2000");
*
* to query current delay config:
* rhf76_set_delay("?");
*
* @param params operation string
*
* @retval int Status
*/
int rhf76_set_delay(char *param);
/**
* @brief set repeat times when sending unconfirmed message
* @note it is equal to sending
* AT+REPT=2
* +REPT: 2
*
* @param num repeat times
*
* @retval int Status
*/
int rhf76_set_repeat(uint8_t num);
/**
* @brief set date rate, which would affect the maximum payload size
* @note this function is for DEBUG purpose only, it allows user to execute
* AT+ commands by passing the AT+ command to the function as an arg-
* ument.
* For example,users can query the RF configuration by following code:
*
* rhf76_at_cmd_exe("AT+MODE=TEST\r\n");
* rhf76_at_cmd_exe("AT+TEST=?\r\n");
*
* @param num data rate
*
* @retval int Status
*/
int rhf76_set_data_rate(uint8_t num);
/**
* @brief execute AT+ commands
* @note this function is for DEBUG purpose only, it allows user to execute
* AT+ commands by passing the AT+ command to the function as an arg-
* ument.
* For example,users can query the RF configuration by following code:
*
* rhf76_at_cmd_exe("AT+MODE=TEST\r\n");
* rhf76_at_cmd_exe("AT+TEST=?\r\n");
*
* @param cmd AT+ commands
*
* @retval int Status
*/
int rhf76_at_cmd_exe(char *cmd);
#endif /* __RHF76_H__ */

View File

@@ -93,6 +93,7 @@ typedef struct at_echo_st {
size_t __w_idx;
int __is_expecting;
k_sem_t __expect_notify;
int fuzzy_matching;
} at_echo_t;
typedef void (*at_event_callback_t)(void);
@@ -268,7 +269,8 @@ __API__ int tos_at_init(hal_uart_port_t uart_port, at_event_t *event_table, size
*
* @attention None
*
* @return
* @return
None
*/
__API__ void tos_at_deinit(void);
@@ -288,6 +290,22 @@ __API__ void tos_at_deinit(void);
*/
__API__ int tos_at_echo_create(at_echo_t *echo, char *buffer, size_t buffer_size, char *echo_expect);
/**
* @brief Create a echo struct with fuzzy matching for expected echo.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[out] buffer buffer to hold the received message from the module.
* @param[in] buffer_size size of the buffer.
* @param[in] echo_expect_contains if the echo message contains echo_expect_contains, it is a matching.
*
* @return errcode
* @retval -1 create failed(error).
* @retval 0 create successfully.
*/
__API__ int tos_at_echo_fuzzy_matching_create(at_echo_t *echo, char *buffer, size_t buffer_size, char *echo_expect_contains);
/**
* @brief Execute an at command.
*

View File

@@ -161,10 +161,19 @@ __STATIC__ int at_is_echo_expect(void)
return 0;
}
if(at_echo->fuzzy_matching){
if(strstr(recv_buffer, expect)!=NULL){
return 0;
}
return -1;
}
if (strncmp(expect, recv_buffer, expect_len) == 0) {
return 1;
}
return 0;
}
@@ -337,6 +346,28 @@ __API__ int tos_at_echo_create(at_echo_t *echo, char *buffer, size_t buffer_size
echo->status = AT_ECHO_STATUS_NONE;
echo->__w_idx = 0;
echo->__is_expecting = K_FALSE;
echo->fuzzy_matching = K_FALSE;
return 0;
}
__API__ int tos_at_echo_fuzzy_matching_create(at_echo_t *echo, char *buffer, size_t buffer_size, char *echo_expect_contains)
{
if (!echo) {
return -1;
}
if (buffer) {
memset(buffer, 0, buffer_size);
}
echo->buffer = buffer;
echo->buffer_size = buffer_size;
echo->echo_expect = echo_expect_contains;
echo->line_num = 0;
echo->status = AT_ECHO_STATUS_NONE;
echo->__w_idx = 0;
echo->__is_expecting = K_FALSE;
echo->fuzzy_matching = K_TRUE;
return 0;
}