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