added lorawan example in IAR, and added support for LIS3MDL and LPS22HB sensors

1. modified the HTS221: removed magic numbers, added a sensor_tempnhumi_t struct to accommodate temperature and humidity data
2. added .h and .c files for LIS3MDL magnetic sensor
3. added .h and .c files for LPS22HB pressure sensor
3. added IAR (EWARM) project for lorawan example
4. added bsp.c and bsp.h to manager the sensors
This commit is contained in:
Winfred LIN
2020-03-31 17:48:27 +11:00
parent a3078ac232
commit da5884920a
19 changed files with 8101 additions and 1494 deletions

View File

@@ -0,0 +1,35 @@
/**
******************************************************************************
* @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
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
void BSP_Sensor_Init(void)
{
/* Initialize sensors */
HTS221_Init();
LPS22HB_Init();
LIS3MDL_Init();
}
void BSP_Sensor_Read(sensor_data_t *sensor_data)
{
sensor_tempnhumi_t tempnhumi_sensor;
sensor_press_t press_sensor;
sensor_magn_t magn_sensor;
HTS221_Get_TemperatureAndHumidity(&tempnhumi_sensor);
LPS22HB_Get_Press(&press_sensor);
LIS3MDL_Get_Magn(&magn_sensor);
sensor_data->sensor_press = press_sensor;
sensor_data->sensor_tempnhumi = tempnhumi_sensor;
sensor_data->sensor_magn = magn_sensor;
}

View File

@@ -0,0 +1,89 @@
/*
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(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
*
* <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
* All rights reserved.</center></h2>
*
* 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
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BSP_H__
#define __BSP_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include "HTS221.h"
#include "LPS22HB.h"
#include "LIS3MDL.h"
/* Exported types ------------------------------------------------------------*/
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_data_t;
/* Exported constants --------------------------------------------------------*/
/* External variables --------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/**
* @brief initialises the sensor
*
* @note
* @retval None
*/
void BSP_Sensor_Init(void);
/**
* @brief sensor read.
*
* @note none
* @retval sensor_data
*/
void BSP_Sensor_Read(sensor_data_t *sensor_data);
#ifdef __cplusplus
}
#endif
#endif /* __BSP_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -2,7 +2,8 @@
* @breif HTS221<32><31><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
* @author Mculover666(www.mculover666.cn)
* @date 2019-12-27
* @version 1.0.0
* @modified by jieranzhi 2020/03/23
* @version 1.0.1
********************************************/
#include <HTS221.h>
@@ -15,7 +16,7 @@ void HTS221_Init()
//<2F><><EFBFBD>÷ֱ<C3B7><D6B1><EFBFBD>
cmd = 0x3F;
HAL_I2C_Mem_Write(&hi2c1, HTS221_ADDR_WR, 0x10, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
HAL_I2C_Mem_Write(&hi2c1, HTS221_ADDR_WR, HTS221_AV_CONF, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
//<2F><><EFBFBD>õ<EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cmd = 0x84;
@@ -57,11 +58,11 @@ uint8_t HTS221_Get_Temperature(int16_t* temperature)
int32_t tmp32;
/*1. <20><>ȡT0_degC_x8 <20><> T1_degC_x8 У<><D0A3>ֵ */
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x32, I2C_MEMADD_SIZE_8BIT, &T0_degC_x8, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x33, I2C_MEMADD_SIZE_8BIT, &T1_degC_x8, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_T0_degC_x8, I2C_MEMADD_SIZE_8BIT, &T0_degC_x8, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_T1_degC_x8, I2C_MEMADD_SIZE_8BIT, &T1_degC_x8, 1, 0xFFFF);
/*2. <20><>ȡT1_degC <20><> T0_degC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ*/
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x35, I2C_MEMADD_SIZE_8BIT, &tmp, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_T1_T0_msb, I2C_MEMADD_SIZE_8BIT, &tmp, 1, 0xFFFF);
// <20><><EFBFBD><EFBFBD>T0_degC and T1_degC ֵ */
T0_degC_x8_u16 = (((uint16_t)(tmp & 0x03)) << 8) | ((uint16_t)T0_degC_x8);
@@ -70,10 +71,10 @@ uint8_t HTS221_Get_Temperature(int16_t* temperature)
T1_degC = T1_degC_x8_u16>>3;
/*3. <20><>ȡ T0_OUT <20><> T1_OUT ֵ */
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x3C, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x3D, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x3E, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x3F, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_T0_OUT_L, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_T0_OUT_H, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_T1_OUT_L, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_T1_OUT_H, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
T0_out = (((uint16_t)buffer[1])<<8) | (uint16_t)buffer[0];
T1_out = (((uint16_t)buffer[3])<<8) | (uint16_t)buffer[2];
@@ -90,8 +91,8 @@ uint8_t HTS221_Get_Temperature(int16_t* temperature)
T_out = (((uint16_t)buffer[1])<<8) | (uint16_t)buffer[0];
/* 5. ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>㵱ǰ<E3B5B1><C7B0>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>ֵ */
tmp32 = ((int32_t)(T_out - T0_out)) * ((int32_t)(T1_degC - T0_degC)*10);
*temperature = tmp32 /(T1_out - T0_out) + T0_degC*10;
tmp32 = ((int32_t)(T_out - T0_out)) * ((int32_t)(T1_degC - T0_degC));
*temperature = tmp32*10 /(T1_out - T0_out) + T0_degC*10;
return 0;
}
@@ -108,24 +109,24 @@ uint8_t HTS221_Get_Humidity(int16_t* humidity)
/* 1. <20><>ȡH0_rH and H1_rH У<><D0A3>ֵ */
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x30, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x31, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_H0_rH_x2, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_H1_rH_x2, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
H0_rh = buffer[0] >> 1;
H1_rh = buffer[1] >> 1;
/*2. <20><>ȡ H0_T0_OUT У<><D0A3>ֵ */
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x36, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x37, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_H0_T0_OUT_L, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_H0_T0_OUT_H, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
H0_T0_out = (((uint16_t)buffer[1])<<8) | (uint16_t)buffer[0];
/*3. <20><>ȡ H1_T0_OUT У<><D0A3>ֵ */
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x3A, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, 0x3B, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_H1_T0_OUT_L, I2C_MEMADD_SIZE_8BIT, &buffer[0], 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_H1_T0_OUT_H, I2C_MEMADD_SIZE_8BIT, &buffer[1], 1, 0xFFFF);
H1_T0_out = (((uint16_t)buffer[1])<<8) | (uint16_t)buffer[0];
/*4. <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD>ȡת<C8A1><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
HTS221_Start();
while(status_dat != 0x03)
while(status_dat != (HTS221_T_DA|HTS221_H_DA))
{
HAL_I2C_Mem_Read(&hi2c1, HTS221_ADDR_RD, HTS221_STATUS_REG, I2C_MEMADD_SIZE_8BIT, &status_dat, 1, 0xFFFF);
}
@@ -145,3 +146,20 @@ uint8_t HTS221_Get_Humidity(int16_t* humidity)
return 0;
}
/* <20><>ȡHT221<32><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sensor<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
uint8_t HTS221_Get_TemperatureAndHumidity(sensor_tempnhumi_t* tempnhumi_sensor)
{
int16_t temperature;
int16_t humidity;
HTS221_Get_Temperature(&temperature);
HTS221_Get_Humidity(&humidity);
tempnhumi_sensor->temp_sensitivity = 64;
tempnhumi_sensor->temperature = temperature;
tempnhumi_sensor->humi_sensitivity = 256;
tempnhumi_sensor->humidity = humidity;
return 0;
}

View File

@@ -10,6 +10,7 @@
#define HTS221_CTRL_REG2 0x21
#define HTS221_CTRL_REG3 0x22
#define HTS221_AV_CONF 0x10
#define HTS221_STATUS_REG 0x27
#define HTS221_HUMIDITY_OUT_L 0x28
@@ -17,9 +18,45 @@
#define HTS221_TEMP_OUT_L 0x2A
#define HTS221_TEMP_OUT_H 0x2B
void HTS221_Init(void);
#define HTS221_H0_rH_x2 0x30
#define HTS221_H1_rH_x2 0x31
#define HTS221_H0_T0_OUT_L 0x36
#define HTS221_H0_T0_OUT_H 0x37
#define HTS221_H1_T0_OUT_L 0x3A
#define HTS221_H1_T0_OUT_H 0x3B
#define HTS221_T0_degC_x8 0x32
#define HTS221_T1_degC_x8 0x33
#define HTS221_T1_T0_msb 0x35
#define HTS221_T0_OUT_L 0x3C
#define HTS221_T0_OUT_H 0x3D
#define HTS221_T1_OUT_L 0x3E
#define HTS221_T1_OUT_H 0x3F
/**
* @brief temperature & humidity sensor structures definition
* added by jieranzhi, 2020/03/29
*/
typedef struct
{
uint8_t temp_sensitivity;
int16_t temperature;
uint16_t humi_sensitivity;
int16_t humidity;
}sensor_tempnhumi_t;
/**
* @brief STATUS structures definition
*/
typedef enum
{
HTS221_T_DA = 0x01U, /*!< temperature data available */
HTS221_H_DA = 0x02U, /*!< humidity data available */
}HTS221_StatusTypeDef;
void HTS221_Init(void);
uint8_t HTS221_Get_Temperature(int16_t* temperature);
uint8_t HTS221_Get_Humidity(int16_t* humidity);
uint8_t HTS221_Get_TemperatureAndHumidity(sensor_tempnhumi_t* tempnhumi_sensor);
#endif /* _HTS221_H_ */

View File

@@ -0,0 +1,136 @@
/**
******************************************************************************
* @file LIS3MDL.c
* @author jieranzhi
* @update 2020/03/23 19:00 CST
* @brief This file provides code for the LIS3MDL 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 will to read the output persistently, which is
* NOT of power efficient.
*
******************************************************************************
*/
#include <LIS3MDL.h>
#include <i2c.h>
// initialization of LIS3MDL
void LIS3MDL_Init()
{
uint8_t cmd = 0;
// enable temperature sensor(temperature compensation);X and Y axes operative
// mode(Medium-performance); Output data rate(10Hz); disable high data rate
// disable Self-test
cmd = 0xB0;
HAL_I2C_Mem_Write(&hi2c1, LIS3MDL_ADDR_WR, LIS3MDL_CTRL_REG1, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// Full-scale:+/-4gauss; Reboot memory(normal)
cmd = 0x00;
HAL_I2C_Mem_Write(&hi2c1, LIS3MDL_ADDR_WR, LIS3MDL_CTRL_REG2, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// disable lowpower mode; Operating mode (continuous mode)
cmd = 0x00;
HAL_I2C_Mem_Write(&hi2c1, LIS3MDL_ADDR_WR, LIS3MDL_CTRL_REG3, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// Z-axis operative mode (Medium-performance)
cmd = 0x04;
HAL_I2C_Mem_Write(&hi2c1, LIS3MDL_ADDR_WR, LIS3MDL_CTRL_REG4, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// disable FAST READ; data block update(continuous)
cmd = 0x40;
HAL_I2C_Mem_Write(&hi2c1, LIS3MDL_ADDR_WR, LIS3MDL_CTRL_REG5, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
}
// get fullscale configuration
LIS3MDL_FullScaleTypeDef LIS3MDL_Get_FullScale()
{
uint8_t fullscale;
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_CTRL_REG2, I2C_MEMADD_SIZE_8BIT, &fullscale, 1, 0xFFFF);
fullscale = (fullscale<<1)>>6;
return (LIS3MDL_FullScaleTypeDef)fullscale;
}
// set fullscale of the sensor
void LIS3MDL_Set_FullScale(LIS3MDL_FullScaleTypeDef fullscale)
{
uint8_t ctrl_reg2_value;
uint8_t fullscale_config = (uint8_t)fullscale;
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_CTRL_REG2, I2C_MEMADD_SIZE_8BIT, &ctrl_reg2_value, 1, 0xFFFF);
fullscale_config = (ctrl_reg2_value&0x9F)|(fullscale_config<<5);
HAL_I2C_Mem_Write(&hi2c1, LIS3MDL_ADDR_WR, LIS3MDL_CTRL_REG2, I2C_MEMADD_SIZE_8BIT, &fullscale_config, 1, 0xFFFF);
}
// calculate the sensitivity per fullscale
uint16_t LIS3MDL_Get_Sensitivity(LIS3MDL_FullScaleTypeDef fullscale)
{
uint16_t sensitivity = 1;
switch(fullscale)
{
case FULLSCALE_4:{
sensitivity = 6842;
break;
}
case FULLSCALE_8:{
sensitivity = 3421;
break;
}
case FULLSCALE_12:{
sensitivity = 2281;
break;
}
case FULLSCALE_16:{
sensitivity = 1711;
break;
}
default:{
sensitivity = 1;
}
}
return sensitivity;
}
// start a new acquisition by enabling the one-shot bit in the LIS3MDL_CTRL_REG2
// and read the magnetic field from the sensor
uint8_t LIS3MDL_Get_Magn(sensor_magn_t* magn_sensor)
{
uint8_t status_dat = 0;
uint8_t magn_x_out_l = 0;
uint8_t magn_x_out_h = 0;
uint8_t magn_y_out_l = 0;
uint8_t magn_y_out_h = 0;
uint8_t magn_z_out_l = 0;
uint8_t magn_z_out_h = 0;
// get fullscale and sensitivity
LIS3MDL_FullScaleTypeDef fullscale = LIS3MDL_Get_FullScale();
magn_sensor->fullscale = (uint8_t)fullscale;
magn_sensor->sensitivity = LIS3MDL_Get_Sensitivity(fullscale);
// wait until the data is ready
while((status_dat&LIS3MDL_ZYXDA) != LIS3MDL_ZYXDA)
{
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_STATUS_REG, I2C_MEMADD_SIZE_8BIT, &status_dat, 1, 0xFFFF);
}
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_X_OUT_L, I2C_MEMADD_SIZE_8BIT, &magn_x_out_l, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_X_OUT_H, I2C_MEMADD_SIZE_8BIT, &magn_x_out_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_Y_OUT_L, I2C_MEMADD_SIZE_8BIT, &magn_y_out_l, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_Y_OUT_H, I2C_MEMADD_SIZE_8BIT, &magn_y_out_h, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_Z_OUT_L, I2C_MEMADD_SIZE_8BIT, &magn_z_out_l, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LIS3MDL_ADDR_RD, LIS3MDL_Z_OUT_H, I2C_MEMADD_SIZE_8BIT, &magn_z_out_h, 1, 0xFFFF);
magn_sensor->magn_x = (uint16_t)magn_x_out_h<<8|magn_x_out_l;
magn_sensor->magn_y = (uint16_t)magn_y_out_h<<8|magn_y_out_l;
magn_sensor->magn_z = (uint16_t)magn_z_out_h<<8|magn_z_out_l;
return 0;
}

View File

@@ -0,0 +1,93 @@
/**
******************************************************************************
* @file LIS3MDL.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 LIS3MDL 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)
*
* 3. for more information, please refer to the datasheet
* (https://www.st.com/resource/en/datasheet/lis3mdl.pdf)
*
******************************************************************************
*/
#ifndef _LIS3MDL_H_
#define _LIS3MDL_H_
#include <stm32l0xx_hal.h>
/* Registers -----------------------------------------------------------------*/
#define LIS3MDL_ADDR_WR 0x3C
#define LIS3MDL_ADDR_RD 0x3D
#define LIS3MDL_CTRL_REG1 0x20
#define LIS3MDL_CTRL_REG2 0x21
#define LIS3MDL_CTRL_REG3 0x22
#define LIS3MDL_CTRL_REG4 0x23
#define LIS3MDL_CTRL_REG5 0x24
#define LIS3MDL_STATUS_REG 0x27
#define LIS3MDL_X_OUT_L 0x28
#define LIS3MDL_X_OUT_H 0x29
#define LIS3MDL_Y_OUT_L 0x2A
#define LIS3MDL_Y_OUT_H 0x2B
#define LIS3MDL_Z_OUT_L 0x2C
#define LIS3MDL_Z_OUT_H 0x2D
/* Enumeration ---------------------------------------------------------------*/
/**
* @brief STATUS structures definition
*/
typedef enum
{
LIS3MDL_ZYXOR = 0x80U, /*!< XYZ-axis data overrun */
LIS3MDL_ZOR = 0x40U, /*!< Z-axis data overrun */
LIS3MDL_YOR = 0x20U, /*!< Y-axis data overrun */
LIS3MDL_XOR = 0x10U, /*!< X-axis data overrun */
LIS3MDL_ZYXDA = 0x08U, /*!< XYZ-axis data available */
LIS3MDL_ZDA = 0x04U, /*!< Z-axis data available */
LIS3MDL_YDA = 0x02U, /*!< Y-axis data available */
LIS3MDL_XDA = 0x01U, /*!< X-axis data available */
}LIS3MDL_StatusTypeDef;
/**
* @brief STATUS structures definition
*/
typedef enum
{
FULLSCALE_4 = 0x00U,
FULLSCALE_8 = 0x01U,
FULLSCALE_12 = 0x02U,
FULLSCALE_16 = 0x03U
}LIS3MDL_FullScaleTypeDef;
/**
* @brief magnetic sensor structures definition
*/
typedef struct
{
uint8_t fullscale; // fullscale of magnetometer
uint16_t sensitivity; // sensitivity per fullscale
uint16_t magn_x; // X-magnetic value in LSB
uint16_t magn_y; // Y-magnetic value in LSB
uint16_t magn_z; // Z-magnetic value in LSB
}sensor_magn_t;
/* Functions -----------------------------------------------------------------*/
void LIS3MDL_Init(void);
void LIS3MDL_Set_FullScale(LIS3MDL_FullScaleTypeDef fullscale);
LIS3MDL_FullScaleTypeDef LIS3MDL_Get_FullScale(void);
uint16_t LIS3MDL_Get_Sensitivity(LIS3MDL_FullScaleTypeDef fullscale);
uint8_t LIS3MDL_Get_Magn(sensor_magn_t* magn_sensor);
#endif /* _LIS3MDL_H_ */

View File

@@ -0,0 +1,79 @@
/**
******************************************************************************
* @file LPS22HB.c
* @author jieranzhi
* @update 2020/03/23 19:00 CST
* @brief This file provides code for the LPS22HB 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 <LPS22HB.h>
#include <i2c.h>
// initialization of LPS22HB
void LPS22HB_Init()
{
uint8_t cmd = 0;
// reset the Low-power mode configuration
cmd = 0x00;
HAL_I2C_Mem_Write(&hi2c1, LPS22HB_ADDR_WR, LPS22HB_RES_CONF_REG, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// setup data rate(power down, 000); disable lowpass filter (we use one-shot in this case); Block data update(continuous)
cmd = 0x00;
HAL_I2C_Mem_Write(&hi2c1, LPS22HB_ADDR_WR, LPS22HB_CTRL_REG1, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// reboot mode(normal); disable FIFO; enable IF_ADD_INC; enable I2C; software reset mode(normal); one-shot mode(idle)
cmd = 0x10;
HAL_I2C_Mem_Write(&hi2c1, LPS22HB_ADDR_WR, LPS22HB_CTRL_REG2, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
// interupt control: set to default value (0x00)
cmd = 0x00;
HAL_I2C_Mem_Write(&hi2c1, LPS22HB_ADDR_WR, LPS22HB_CTRL_REG3, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
}
// enable one-shot to start a new acquisition (conversion)
static void LPS22HB_Start()
{
uint8_t cmd = 0;
HAL_I2C_Mem_Read(&hi2c1, LPS22HB_ADDR_RD, LPS22HB_CTRL_REG2, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
cmd |= 0x01;
HAL_I2C_Mem_Write(&hi2c1, LPS22HB_ADDR_WR, LPS22HB_CTRL_REG2, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0xFFFF);
}
// start a new acquisition by enabling the one-shot bit in the LPS22HB_CTRL_REG2
// and read the pressure from the sensor
uint8_t LPS22HB_Get_Press(sensor_press_t* press_sensor)
{
uint8_t status_dat = 0;
uint8_t pressure_out_l = 0;
uint8_t pressure_out_h = 0;
uint8_t pressure_out_xl = 0;
press_sensor->sensitivity = 4096;
LPS22HB_Start();
while((status_dat&LPS22HB_P_DA) != LPS22HB_P_DA)
{
HAL_I2C_Mem_Read(&hi2c1, LPS22HB_ADDR_RD, LPS22HB_STATUS_REG, I2C_MEMADD_SIZE_8BIT, &status_dat, 1, 0xFFFF);
}
HAL_I2C_Mem_Read(&hi2c1, LPS22HB_ADDR_RD, LPS22HB_PRESS_OUT_XL, I2C_MEMADD_SIZE_8BIT, &pressure_out_xl, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LPS22HB_ADDR_RD, LPS22HB_PRESS_OUT_L, I2C_MEMADD_SIZE_8BIT, &pressure_out_l, 1, 0xFFFF);
HAL_I2C_Mem_Read(&hi2c1, LPS22HB_ADDR_RD, LPS22HB_PRESS_OUT_H, I2C_MEMADD_SIZE_8BIT, &pressure_out_h, 1, 0xFFFF);
press_sensor->pressure = (((uint32_t)pressure_out_h<<16) | ((uint16_t)pressure_out_l<<8) | pressure_out_xl);
return 0;
}

View File

@@ -0,0 +1,68 @@
/**
******************************************************************************
* @file LPS22HB.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 LPS22HB 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)
*
* 3. for more information, please refer to the datasheet
* (https://www.st.com/resource/en/datasheet/dm00140895.pdf)
*
******************************************************************************
*/
#ifndef _LPS22HB_H_
#define _LPS22HB_H_
#include <stm32l0xx_hal.h>
/* Registers -----------------------------------------------------------------*/
#define LPS22HB_ADDR_WR 0xBA
#define LPS22HB_ADDR_RD 0xBB
#define LPS22HB_CTRL_REG1 0x10
#define LPS22HB_CTRL_REG2 0x11
#define LPS22HB_CTRL_REG3 0x12
#define LPS22HB_RES_CONF_REG 0x1A
#define LPS22HB_STATUS_REG 0x27
#define LPS22HB_PRESS_OUT_XL 0x28
#define LPS22HB_PRESS_OUT_L 0x29
#define LPS22HB_PRESS_OUT_H 0x2A
/* Enumeration ---------------------------------------------------------------*/
/**
* @brief STATUS structures definition
*/
typedef enum
{
LPS22HB_T_OR = 0x20, /*!< temperature overrun */
LPS22HB_P_OR = 0x10, /*!< pressure overrun */
LPS22HB_T_DA = 0x02, /*!< new temperature data available */
LPS22HB_P_DA = 0x01, /*!< new pressure data available */
}LPS22HB_StatusTypeDef;
/**
* @brief pressure sensor structures definition
*/
typedef struct
{
uint16_t sensitivity; // sensitivity per fullscale
uint32_t pressure; // X-magnetic value in LSB
}sensor_press_t;
/* Functions -----------------------------------------------------------------*/
void LPS22HB_Init(void);
uint8_t LPS22HB_Get_Press(sensor_press_t* press_sensor);
#endif /* _LPS22HB_H_ */