diff --git a/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.c b/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.c
index 57f6df9c..46840cbf 100644
--- a/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.c
+++ b/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.c
@@ -3,19 +3,23 @@
* @file bsp.c
* @author jieranzhi
* @brief provide high level interfaces to manage the sensors on the
- * application, this is a modified version of the official api
+ * application
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
-void BSP_Sensor_Init(void)
+void BSP_Sensor_Init(DeviceConfig_TypeDef config)
{
/* Initialize sensors */
HTS221_Init();
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)
diff --git a/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.h b/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.h
index c9f515ae..b9c61029 100644
--- a/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.h
+++ b/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.h
@@ -1,33 +1,9 @@
-/*
- / _____) _ | |
-( (____ _____ ____ _| |_ _____ ____| |__
- \____ \| ___ | (_ _) ___ |/ ___) _ \
- _____) ) ____| | | || |_| ____( (___| | | |
-(______/|_____)_|_|_| \__)_____)\____)_| |_|
- (C)2013 Semtech
-
-Description: contains all hardware driver
-
-License: Revised BSD License, see LICENSE.TXT file include in the project
-
-Maintainer: Miguel Luis and Gregory Cristian
-*/
/**
******************************************************************************
- * @file bsp.h
- * @author MCD Application Team
- * @brief contains all hardware driver
- ******************************************************************************
- * @attention
- *
- *
© Copyright (c) 2018 STMicroelectronics.
- * All rights reserved.
- *
- * This software component is licensed by ST under Ultimate Liberty license
- * SLA0044, the "License"; You may not use this file except in compliance with
- * the License. You may obtain a copy of the License at:
- * www.st.com/SLA0044
- *
+ * @file bsp.c
+ * @author jieranzhi
+ * @brief provide high level interfaces to manage the sensors on the
+ * application, this is a modified version of the official api
******************************************************************************
*/
@@ -40,9 +16,11 @@ extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include
+#include
#include "HTS221.h"
#include "LPS22HB.h"
#include "LIS3MDL.h"
+#include "LSM6DS3.h"
/* Exported types ------------------------------------------------------------*/
typedef struct
@@ -50,17 +28,32 @@ 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_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;
+ LSM6DS3_AccelFullscaleTypeDef accel_fullscale;
+ LSM6DS3_GyroFullscaleTypeDef gyro_fullscale;
+ bool is_confirmed;
+}DeviceConfig_TypeDef;
+
/* Exported constants --------------------------------------------------------*/
/* External variables --------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
@@ -71,7 +64,7 @@ typedef struct
* @note
* @retval None
*/
-void BSP_Sensor_Init(void);
+void BSP_Sensor_Init(DeviceConfig_TypeDef config);
/**
* @brief sensor read.
diff --git a/board/NUCLEO_STM32L073RZ/BSP/HardWare/LIS3MDL/LIS3MDL.c b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LIS3MDL/LIS3MDL.c
index adffac7b..f825b29e 100644
--- a/board/NUCLEO_STM32L073RZ/BSP/HardWare/LIS3MDL/LIS3MDL.c
+++ b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LIS3MDL/LIS3MDL.c
@@ -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;
}
diff --git a/board/NUCLEO_STM32L073RZ/BSP/HardWare/LIS3MDL/LIS3MDL.h b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LIS3MDL/LIS3MDL.h
index f61302c6..64efcd17 100644
--- a/board/NUCLEO_STM32L073RZ/BSP/HardWare/LIS3MDL/LIS3MDL.h
+++ b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LIS3MDL/LIS3MDL.h
@@ -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;
/**
diff --git a/board/NUCLEO_STM32L073RZ/BSP/HardWare/LPS22HB/LPS22HB.h b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LPS22HB/LPS22HB.h
index fbb2d265..3a997295 100644
--- a/board/NUCLEO_STM32L073RZ/BSP/HardWare/LPS22HB/LPS22HB.h
+++ b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LPS22HB/LPS22HB.h
@@ -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 -----------------------------------------------------------------*/
diff --git a/board/NUCLEO_STM32L073RZ/BSP/HardWare/LSM6DS3/LSM6DS3.c b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LSM6DS3/LSM6DS3.c
new file mode 100644
index 00000000..4070363f
--- /dev/null
+++ b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LSM6DS3/LSM6DS3.c
@@ -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
+#include
+
+// 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;
+}
\ No newline at end of file
diff --git a/board/NUCLEO_STM32L073RZ/BSP/HardWare/LSM6DS3/LSM6DS3.h b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LSM6DS3/LSM6DS3.h
new file mode 100644
index 00000000..bd842dea
--- /dev/null
+++ b/board/NUCLEO_STM32L073RZ/BSP/HardWare/LSM6DS3/LSM6DS3.h
@@ -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 ¡®1¡¯ (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
+
+/* 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_ */
diff --git a/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c b/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c
index 35583663..84c0339a 100644
--- a/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c
+++ b/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c
@@ -1,7 +1,7 @@
#include "lora_demo.h"
+#include "stm32l0xx_hal_flash_ex2.h"
#include "RHF76.h"
#include "bsp.h"
-#include
#include
/*
@@ -118,22 +118,32 @@
*/
-uint16_t report_period = 10;
-bool is_confirmed = true;
-
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 {
@@ -145,6 +155,133 @@ typedef struct device_data_wrapper_st {
dev_data_wrapper_t dev_data_wrapper;
+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 = MAGN_FULLSCALE_4;
+ config->accel_fullscale = ACCEL_FULLSCALE_4;
+ config->gyro_fullscale = GYRO_FULLSCALE_250;
+}
+
+/**
+ * @brief Write the configuration to the internal EEPROM bank 1
+ * @note a single config frame is of 32-bit(a word, 4bytes), and the config
+ * block starts with a frame whose value is 0x464E4F43U ('CONF' from
+ * low to high) and ends with a frame with a value of 0xFFFFFFFFU; a
+ * single data frame has a following structure£º
+ * ----------------------------------------------------------------
+ * | byte | 0 | 1 | 2 | 3 |
+ * ----------------------------------------------------------------
+ * | value| Device Config Type | value-L | value-H | reserve |
+ * ----------------------------------------------------------------
+ * the reserve byte could be used as an extra byte for the config
+ * value, i.e. a 24-bit value.
+ *
+ * @param config system configurations
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef write_config_to_Flash(DeviceConfig_TypeDef config)
+{
+ uint32_t frame[5] = {0};
+ frame[0] = 0x464E4F43U; // <'C'><'O'><'N'><'F'> from low to high
+ 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();
+ uint8_t retry = 10;
+
+ HAL_StatusTypeDef status = HAL_OK;
+ for(int i=0; i<5; i++)
+ {
+ status = HAL_OK;
+ do{
+ status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, config.config_address+4*i, frame[i]);
+ }while(retry--!=0 && status != HAL_OK);
+ }
+ HAL_FLASH_Lock();
+
+ return status;
+}
+
+HAL_StatusTypeDef read_config_from_Flash(DeviceConfig_TypeDef* config)
+{
+ uint32_t data = 0;
+ HAL_StatusTypeDef status = HAL_FLASH_ReadWord(config->config_address, &data);
+ if(status == HAL_OK)
+ {
+ // a valid config starts with <'C'><'O'><'N'><'F'> and ended with a word of 0xFFFFFFFF
+ if((char)(data&0xFF) == 'C'
+ &&(char)(data>>8&0xFF) == 'O'
+ &&(char)(data>>16&0xFF) == 'N'
+ &&(char)(data>>24&0xFF) == 'F')
+ {
+ int i = 0;
+ int retry = 10;
+ DeviceConfigType_TypeDef config_type = DCT_DEFAULT;
+ while(data!=0xFFFFFFFF)
+ {
+ i+=4;
+ status = HAL_FLASH_ReadWord(config->config_address+i, &data);
+ if(status != HAL_OK){
+ retry--;
+ i-=4;
+ if(retry == 0) break;
+ }else{
+ config_type = (DeviceConfigType_TypeDef)(data&0xFF);
+ switch(config_type)
+ {
+ case DCT_IS_CONFIRM:
+ {
+ config->is_confirmed = (bool)(data>>8&0xFF);
+ break;
+ }
+ case DCT_REPORT_PERIOD:
+ {
+ config->report_period = (uint16_t)(data>>8&0xFFFF);
+ break;
+ }
+ case DCT_REPEAT_TIME:
+ {
+ config->repeat_time = (uint8_t)(data>>8&0xFF);
+ break;
+ }
+ case DCT_MAGN_FULLSCALE:
+ {
+ 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;
+ }
+ }
+ }
+ }
+ }
+ }
+ return status;
+}
+
void recv_callback(uint8_t *data, uint8_t len)
{
printf("len: %d\n", len);
@@ -154,11 +291,13 @@ void recv_callback(uint8_t *data, uint8_t len)
}
if (len == 1) {
- report_period = data[0];
+ device_config.report_period = data[0];
} else if (len >= 2) {
- report_period = data[0] | (data[1] << 8);
- LIS3MDL_Set_FullScale((LIS3MDL_FullScaleTypeDef)data[2]);
- is_confirmed = (bool)data[3];
+ device_config.is_confirmed = (bool)data[3];
+ device_config.report_period = data[0] | (data[1] << 8);
+ device_config.magn_fullscale = (LIS3MDL_FullScaleTypeDef)data[2];
+ LIS3MDL_Set_FullScale(device_config.magn_fullscale);
+ write_config_to_Flash(device_config);
}
}
@@ -181,39 +320,66 @@ void print_to_screen(sensor_data_t sensor_data)
*/
void application_entry(void *arg)
{
+ // retrieve configuration from the EEPROM (if any)
+ set_config_to_default(&device_config);
+ HAL_StatusTypeDef status = read_config_from_Flash(&device_config);
+ if(status != HAL_OK)
+ {
+ printf("retrieve configuration FAILED!\r\n");
+ }
+
+ // initialization
sensor_data_t sensor_data;
-
- // initialization of sensors
- BSP_Sensor_Init();
-
+ BSP_Sensor_Init(device_config);
rhf76_lora_init(HAL_UART_PORT_1);
tos_lora_module_recvcb_register(recv_callback);
tos_lora_module_join_otaa("8cf957200000f52c", "8cf957200000f52c6d09aaaaad204a72");
+ // do the job
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 = report_period;
- // send data to the server (via gateway)
- if(is_confirmed){
- tos_lora_module_send(dev_data_wrapper.u.serialize, sizeof(dev_data_t));
- }else{
- tos_lora_module_send_unconfirmed(dev_data_wrapper.u.serialize, sizeof(dev_data_t));
- }
+ // 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);
- tos_task_delay(report_period * 1000);
+ // 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(data_frame1, sizeof(data_frame1));
+ tos_lora_module_send(data_frame2, sizeof(data_frame2));
+ }else{
+ 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);
}
}
diff --git a/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewp b/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewp
index ce06297d..1dcdb000 100644
--- a/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewp
+++ b/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewp
@@ -369,6 +369,7 @@
$PROJ_DIR$\..\..\BSP\HardWare\LPS22HB
$PROJ_DIR$\..\..\BSP\HardWare\Common
$PROJ_DIR$\..\..\BSP\HardWare\LIS3MDL
+ $PROJ_DIR$\..\..\BSP\HardWare\LSM6DS3