Merge pull request #128 from jieranzhi/master

added reading internal flash functions for stm32l0xx series
This commit is contained in:
Supowang1989
2020-04-07 10:09:08 +08:00
committed by GitHub
17 changed files with 1557 additions and 572 deletions

View File

@@ -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)

View File

@@ -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
*
* <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
*
* @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 <stdint.h>
#include <stdbool.h>
#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.

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

@@ -1,7 +1,7 @@
#include "lora_demo.h"
#include "stm32l0xx_hal_flash_ex2.h"
#include "RHF76.h"
#include "bsp.h"
#include <stdbool.h>
#include <Math.h>
/*
@@ -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<72><65>
* ----------------------------------------------------------------
* | 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);
}
}

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>
@@ -1123,14 +1130,14 @@
<name>$PROJ_DIR$\..\..\..\..\devices\rhf76_lora\RHF76.c</name>
</file>
</group>
<group>
<name>Drivers/CMSIS</name>
<file>
<name>$PROJ_DIR$\..\..\BSP\Src\system_stm32l0xx.c</name>
</file>
</group>
<group>
<name>Drivers/STM32L0xx_HAL_Driver</name>
<group>
<name>Drivers/CMSIS</name>
<file>
<name>$PROJ_DIR$\..\..\BSP\Src\system_stm32l0xx.c</name>
</file>
</group>
<file>
<name>$PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal.c</name>
</file>
@@ -1146,6 +1153,9 @@
<file>
<name>$PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ex.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ex2.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ramfunc.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>
@@ -1257,14 +1263,14 @@
<name>$PROJ_DIR$\..\..\..\..\devices\rhf76_lora\RHF76.c</name>
</file>
</group>
<group>
<name>Drivers/CMSIS</name>
<file>
<name>$PROJ_DIR$\..\..\BSP\Src\system_stm32l0xx.c</name>
</file>
</group>
<group>
<name>Drivers/STM32L0xx_HAL_Driver</name>
<group>
<name>Drivers/CMSIS</name>
<file>
<name>$PROJ_DIR$\..\..\BSP\Src\system_stm32l0xx.c</name>
</file>
</group>
<file>
<name>$PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal.c</name>
</file>
@@ -1280,6 +1286,9 @@
<file>
<name>$PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ex.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ex2.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ramfunc.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

@@ -1,20 +1,17 @@
#ifndef __APP_DEMO_H__
#define __APP_DEMO_H__
#include <stdbool.h>
#include "mcu_init.h"
#include "tos_at.h"
#include "string.h"
#include "cmsis_os.h"
#include "lora_module_wrapper.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
char data[32];
}ReportData_TypeDef;
void application_entry(void *arg);
#ifdef __cplusplus
}

View File

@@ -1,459 +1,477 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_AT_H_
#define _TOS_AT_H_
#include "tos_k.h"
#include "tos_at_utils.h"
#include "tos_hal.h"
#define AT_AGENT_ECHO_OK "OK"
#define AT_AGENT_ECHO_FAIL "FAIL"
#define AT_AGENT_ECHO_ERROR "ERROR"
#define AT_DATA_CHANNEL_NUM 6
#define AT_DATA_CHANNEL_FIFO_BUFFER_SIZE (2048 + 1024)
#define AT_UART_RX_FIFO_BUFFER_SIZE (2048 + 1024)
#define AT_RECV_CACHE_SIZE 2048
#define AT_CMD_BUFFER_SIZE 512
#define AT_PARSER_TASK_STACK_SIZE 2048
#define AT_PARSER_TASK_PRIO 2
typedef enum at_status_en {
AT_STATUS_OK,
AT_STATUS_ERROR,
AT_STATUS_INVALID_ARGS,
} at_status_t;
typedef struct at_cache_st {
uint8_t *buffer;
size_t buffer_size;
size_t recv_len;
} at_cache_t;
typedef enum at_parse_status_en {
AT_PARSE_STATUS_NONE,
AT_PARSE_STATUS_NEWLINE,
AT_PARSE_STATUS_EVENT,
AT_PARSE_STATUS_EXPECT,
AT_PARSE_STATUS_OVERFLOW,
} at_parse_status_t;
typedef enum at_echo_status_en {
AT_ECHO_STATUS_NONE,
AT_ECHO_STATUS_OK,
AT_ECHO_STATUS_FAIL,
AT_ECHO_STATUS_ERROR,
AT_ECHO_STATUS_EXPECT,
} at_echo_status_t;
typedef enum at_channel_status_en {
AT_CHANNEL_STATUS_NONE, /*< usually means we are try to get a channel status with invalid id */
AT_CHANNEL_STATUS_HANGING, /*< channel is not used */
AT_CHANNEL_STATUS_WORKING, /*< channel is being using */
AT_CHANNEL_STATUS_BROKEN, /*< channel is broken(module link to remote server is broken) */
} at_channel_status_t;
typedef struct at_data_channel_st {
uint8_t is_free;
k_chr_fifo_t rx_fifo;
uint8_t *rx_fifo_buffer;
k_mutex_t rx_lock;
at_channel_status_t status;
const char *remote_ip;
const char *remote_port;
} at_data_channel_t;
typedef struct at_echo_st {
char *buffer;
size_t buffer_size;
char *echo_expect;
int line_num;
at_echo_status_t status;
size_t __w_idx;
int __is_expecting;
k_sem_t __expect_notify;
} at_echo_t;
typedef void (*at_event_callback_t)(void);
typedef struct at_event_st {
const char *event_header;
at_event_callback_t event_callback;
} at_event_t;
typedef struct at_agent_st {
at_data_channel_t data_channel[AT_DATA_CHANNEL_NUM];
at_event_t *event_table;
size_t event_table_size;
at_echo_t *echo;
k_task_t parser;
at_cache_t recv_cache;
at_timer_t timer;
k_mutex_t global_lock;
char *cmd_buf;
k_mutex_t cmd_buf_lock;
hal_uart_t uart;
k_mutex_t uart_tx_lock;
k_mutex_t uart_rx_lock;
k_sem_t uart_rx_sem;
k_chr_fifo_t uart_rx_fifo;
uint8_t *uart_rx_fifo_buffer;
} at_agent_t;
#define AT_AGENT ((at_agent_t *)(&at_agent))
/**
* @brief Write data to a channel.
* Write data to a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
* @param[in] buffer data buffer to write.
* @param[in] buffer_len length of the buffer.
*
* @return errcode
* @retval -1 write failed(error).
* @retval none -1 the number of bytes written.
*/
__API__ int tos_at_channel_write(int channel_id, uint8_t *buffer, size_t buffer_len);
/**
* @brief Read data from a channel.
* Read data from a channel with a timeout.
*
* @attention None
*
* @param[in] channel_id id of the channel.
* @param[out] buffer buffer to hold the data read.
* @param[in] buffer_len length of the buffer.
* @param[in] timeout timeout.
*
* @return errcode
* @retval -1 read failed(error).
* @retval none -1 the number of bytes read.
*/
__API__ int tos_at_channel_read_timed(int channel_id, uint8_t *buffer, size_t buffer_len, uint32_t timeout);
/**
* @brief Read data from a channel.
* Read data from a channel.
*
* @attention None
*
* @param[in] channel_id id of the channel.
* @param[out] buffer buffer to hold the data read.
* @param[in] buffer_len length of the buffer.
*
* @return errcode
* @retval -1 read failed(error).
* @retval none -1 the number of bytes read.
*/
__API__ int tos_at_channel_read(int channel_id, uint8_t *buffer, size_t buffer_len);
/**
* @brief Allocate a channel.
* Allocate a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
* @param[in] ip remote ip of the channel.
* @param[in] port remote port of the channel.
*
* @return errcode
* @retval -1 allocate failed(error).
* @retval none -1 the id of the channel.
*/
__API__ int tos_at_channel_alloc_id(int channel_id, const char *ip, const char *port);
/**
* @brief Allocate a channel.
* Allocate a channel.
*
* @attention None
*
* @param[in] ip remote ip of the channel.
* @param[in] port remote port of the channel.
*
* @return errcode
* @retval -1 allocate failed(error).
* @retval none -1 the id of the channel.
*/
__API__ int tos_at_channel_alloc(const char *ip, const char *port);
/**
* @brief Free a channel.
* Free a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return errcode
* @retval -1 free failed(error).
* @retval 0 free successfully.
*/
__API__ int tos_at_channel_free(int channel_id);
/**
* @brief Set channel broken.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return errcode
* @retval -1 set failed(error).
* @retval 0 set successfully.
*/
__API__ int tos_at_channel_set_broken(int channel_id);
/**
* @brief Judge whether channel is working.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return at channel status(type of at_channel_status_t)
*/
__API__ int tos_at_channel_is_working(int channel_id);
/**
* @brief Initialize the at framework.
*
* @attention None
*
* @param[in] uart_port port number of the uart thougth which the module connect to the MCU.
* @param[in] event_table the listened event table.
* @param[in] event_table_size the size of the listened event table.
*
* @return errcode
* @retval -1 initialize failed(error).
* @retval 0 initialize successfully.
*/
__API__ int tos_at_init(hal_uart_port_t uart_port, at_event_t *event_table, size_t event_table_size);
/**
* @brief De-initialize the at framework.
*
* @attention None
*
* @return
None
*/
__API__ void tos_at_deinit(void);
/**
* @brief Create a echo struct.
*
* @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 the expected echo message.
*
* @return errcode
* @retval -1 create failed(error).
* @retval 0 create successfully.
*/
__API__ int tos_at_echo_create(at_echo_t *echo, char *buffer, size_t buffer_size, char *echo_expect);
/**
* @brief Execute an at command.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[in] timeout command wait timeout .
* @param[in] cmd at command.
*
* @return errcode
* @retval -1 execute failed(error).
* @retval 0 execute successfully.
*/
__API__ int tos_at_cmd_exec(at_echo_t *echo, uint32_t timeout, const char *cmd, ...);
/**
* @brief Execute an at command.
* Execute an at command and wait until the expected echo message received or timeout.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[in] timeout command wait timeout .
* @param[in] cmd at command.
*
* @return errcode
* @retval -1 execute failed(error).
* @retval 0 execute successfully.
*/
__API__ int tos_at_cmd_exec_until(at_echo_t *echo, uint32_t timeout, const char *cmd, ...);
/**
* @brief Send raw data througth uart.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[in] timeout command wait timeout .
* @param[in] buf data to send.
* @param[in] size size of the buf.
*
* @return errcode
* @retval -1 execute failed(error).
* @retval 0 execute successfully.
*/
__API__ int tos_at_raw_data_send(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, size_t size);
/**
* @brief Send raw data througth uart.
* Send raw data througth uart and wait until the expected echo message received or timeout.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[in] timeout command wait timeout .
* @param[in] buf data to send.
* @param[in] size size of the buf.
*
* @return errcode
* @retval -1 execute failed(error).
* @retval 0 execute successfully.
*/
__API__ int tos_at_raw_data_send_until(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, size_t size);
/**
* @brief Write byte to the at uart.
* The function called by the uart interrupt, to put the data from the uart to the at framework.
*
* @attention None
*
* @param[in] data uart received data.
*
* @return None
*/
__API__ void tos_at_uart_input_byte(uint8_t data);
/**
* @brief A global lock provided by at framework.
* The lock usually used to make a atomic function.
*
* @attention None
*
* @param None.
*
* @return errcode
* @retval -1 pend failed(error).
* @retval 0 pend successfully.
*/
__API__ int tos_at_global_lock_pend(void);
/**
* @brief A global lock provided by at framework.
* The lock usually used to make a atomic function.
*
* @attention None
*
* @param None.
*
* @return errcode
* @retval -1 post failed(error).
* @retval 0 post successfully.
*/
__API__ int tos_at_global_lock_post(void);
/**
* @brief Read data from the uart.
* Read data from the uart, usually called in listened event callback.
*
* @attention None
*
* @param[out] buffer buffer to hold the data read from the uart.
* @param[in] buffer_len length of the buffer.
*
* @return length of the data read from the uart.
*/
__API__ int tos_at_uart_read(uint8_t *buffer, size_t buffer_len);
/**
* @brief Read data from the uart.
* Read data from the uart until meet a '\n', usually called in listened event callback.
*
* @attention None
*
* @param[out] buffer buffer to hold the data read from the uart.
* @param[in] buffer_len length of the buffer.
*
* @return length of the data read from the uart.
*/
__API__ int tos_at_uart_readline(uint8_t *buffer, size_t buffer_len);
/**
* @brief Read data from the uart.
* Read data from the uart until no more incoming data, usually called in listened event callback.
*
* @attention None
*
* @param[out] buffer buffer to hold the data read from the uart.
* @param[in] buffer_len length of the buffer.
*
* @return length of the data read from the uart.
*/
__API__ int tos_at_uart_drain(uint8_t *buffer, size_t buffer_len);
/**
* @brief Get the remote ip of a channel.
* Get the remote ip of a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return remote ip of the channel.
*/
__API__ const char *tos_at_agent_channel_ip_get(int channel_id);
/**
* @brief Get the remote port of a channel.
* Get the remote port of a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return remote port of the channel.
*/
__API__ const char *tos_at_agent_channel_port_get(int channel_id);
#endif /* __AT_AGENT_H_ */
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_AT_H_
#define _TOS_AT_H_
#include "tos_k.h"
#include "tos_at_utils.h"
#include "tos_hal.h"
#define AT_AGENT_ECHO_OK "OK"
#define AT_AGENT_ECHO_FAIL "FAIL"
#define AT_AGENT_ECHO_ERROR "ERROR"
#define AT_DATA_CHANNEL_NUM 6
#define AT_DATA_CHANNEL_FIFO_BUFFER_SIZE (2048 + 1024)
#define AT_UART_RX_FIFO_BUFFER_SIZE (2048 + 1024)
#define AT_RECV_CACHE_SIZE 2048
#define AT_CMD_BUFFER_SIZE 512
#define AT_PARSER_TASK_STACK_SIZE 2048
#define AT_PARSER_TASK_PRIO 2
typedef enum at_status_en {
AT_STATUS_OK,
AT_STATUS_ERROR,
AT_STATUS_INVALID_ARGS,
} at_status_t;
typedef struct at_cache_st {
uint8_t *buffer;
size_t buffer_size;
size_t recv_len;
} at_cache_t;
typedef enum at_parse_status_en {
AT_PARSE_STATUS_NONE,
AT_PARSE_STATUS_NEWLINE,
AT_PARSE_STATUS_EVENT,
AT_PARSE_STATUS_EXPECT,
AT_PARSE_STATUS_OVERFLOW,
} at_parse_status_t;
typedef enum at_echo_status_en {
AT_ECHO_STATUS_NONE,
AT_ECHO_STATUS_OK,
AT_ECHO_STATUS_FAIL,
AT_ECHO_STATUS_ERROR,
AT_ECHO_STATUS_EXPECT,
} at_echo_status_t;
typedef enum at_channel_status_en {
AT_CHANNEL_STATUS_NONE, /*< usually means we are try to get a channel status with invalid id */
AT_CHANNEL_STATUS_HANGING, /*< channel is not used */
AT_CHANNEL_STATUS_WORKING, /*< channel is being using */
AT_CHANNEL_STATUS_BROKEN, /*< channel is broken(module link to remote server is broken) */
} at_channel_status_t;
typedef struct at_data_channel_st {
uint8_t is_free;
k_chr_fifo_t rx_fifo;
uint8_t *rx_fifo_buffer;
k_mutex_t rx_lock;
at_channel_status_t status;
const char *remote_ip;
const char *remote_port;
} at_data_channel_t;
typedef struct at_echo_st {
char *buffer;
size_t buffer_size;
char *echo_expect;
int line_num;
at_echo_status_t status;
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);
typedef struct at_event_st {
const char *event_header;
at_event_callback_t event_callback;
} at_event_t;
typedef struct at_agent_st {
at_data_channel_t data_channel[AT_DATA_CHANNEL_NUM];
at_event_t *event_table;
size_t event_table_size;
at_echo_t *echo;
k_task_t parser;
at_cache_t recv_cache;
at_timer_t timer;
k_mutex_t global_lock;
char *cmd_buf;
k_mutex_t cmd_buf_lock;
hal_uart_t uart;
k_mutex_t uart_tx_lock;
k_mutex_t uart_rx_lock;
k_sem_t uart_rx_sem;
k_chr_fifo_t uart_rx_fifo;
uint8_t *uart_rx_fifo_buffer;
} at_agent_t;
#define AT_AGENT ((at_agent_t *)(&at_agent))
/**
* @brief Write data to a channel.
* Write data to a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
* @param[in] buffer data buffer to write.
* @param[in] buffer_len length of the buffer.
*
* @return errcode
* @retval -1 write failed(error).
* @retval none -1 the number of bytes written.
*/
__API__ int tos_at_channel_write(int channel_id, uint8_t *buffer, size_t buffer_len);
/**
* @brief Read data from a channel.
* Read data from a channel with a timeout.
*
* @attention None
*
* @param[in] channel_id id of the channel.
* @param[out] buffer buffer to hold the data read.
* @param[in] buffer_len length of the buffer.
* @param[in] timeout timeout.
*
* @return errcode
* @retval -1 read failed(error).
* @retval none -1 the number of bytes read.
*/
__API__ int tos_at_channel_read_timed(int channel_id, uint8_t *buffer, size_t buffer_len, uint32_t timeout);
/**
* @brief Read data from a channel.
* Read data from a channel.
*
* @attention None
*
* @param[in] channel_id id of the channel.
* @param[out] buffer buffer to hold the data read.
* @param[in] buffer_len length of the buffer.
*
* @return errcode
* @retval -1 read failed(error).
* @retval none -1 the number of bytes read.
*/
__API__ int tos_at_channel_read(int channel_id, uint8_t *buffer, size_t buffer_len);
/**
* @brief Allocate a channel.
* Allocate a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
* @param[in] ip remote ip of the channel.
* @param[in] port remote port of the channel.
*
* @return errcode
* @retval -1 allocate failed(error).
* @retval none -1 the id of the channel.
*/
__API__ int tos_at_channel_alloc_id(int channel_id, const char *ip, const char *port);
/**
* @brief Allocate a channel.
* Allocate a channel.
*
* @attention None
*
* @param[in] ip remote ip of the channel.
* @param[in] port remote port of the channel.
*
* @return errcode
* @retval -1 allocate failed(error).
* @retval none -1 the id of the channel.
*/
__API__ int tos_at_channel_alloc(const char *ip, const char *port);
/**
* @brief Free a channel.
* Free a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return errcode
* @retval -1 free failed(error).
* @retval 0 free successfully.
*/
__API__ int tos_at_channel_free(int channel_id);
/**
* @brief Set channel broken.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return errcode
* @retval -1 set failed(error).
* @retval 0 set successfully.
*/
__API__ int tos_at_channel_set_broken(int channel_id);
/**
* @brief Judge whether channel is working.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return at channel status(type of at_channel_status_t)
*/
__API__ int tos_at_channel_is_working(int channel_id);
/**
* @brief Initialize the at framework.
*
* @attention None
*
* @param[in] uart_port port number of the uart thougth which the module connect to the MCU.
* @param[in] event_table the listened event table.
* @param[in] event_table_size the size of the listened event table.
*
* @return errcode
* @retval -1 initialize failed(error).
* @retval 0 initialize successfully.
*/
__API__ int tos_at_init(hal_uart_port_t uart_port, at_event_t *event_table, size_t event_table_size);
/**
* @brief De-initialize the at framework.
*
* @attention None
*
* @return
None
*/
__API__ void tos_at_deinit(void);
/**
* @brief Create a echo struct.
*
* @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 the expected echo message.
*
* @return errcode
* @retval -1 create failed(error).
* @retval 0 create successfully.
*/
__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.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[in] timeout command wait timeout .
* @param[in] cmd at command.
*
* @return errcode
* @retval -1 execute failed(error).
* @retval 0 execute successfully.
*/
__API__ int tos_at_cmd_exec(at_echo_t *echo, uint32_t timeout, const char *cmd, ...);
/**
* @brief Execute an at command.
* Execute an at command and wait until the expected echo message received or timeout.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[in] timeout command wait timeout .
* @param[in] cmd at command.
*
* @return errcode
* @retval -1 execute failed(error).
* @retval 0 execute successfully.
*/
__API__ int tos_at_cmd_exec_until(at_echo_t *echo, uint32_t timeout, const char *cmd, ...);
/**
* @brief Send raw data througth uart.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[in] timeout command wait timeout .
* @param[in] buf data to send.
* @param[in] size size of the buf.
*
* @return errcode
* @retval -1 execute failed(error).
* @retval 0 execute successfully.
*/
__API__ int tos_at_raw_data_send(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, size_t size);
/**
* @brief Send raw data througth uart.
* Send raw data througth uart and wait until the expected echo message received or timeout.
*
* @attention None
*
* @param[in] echo pointer to the echo struct.
* @param[in] timeout command wait timeout .
* @param[in] buf data to send.
* @param[in] size size of the buf.
*
* @return errcode
* @retval -1 execute failed(error).
* @retval 0 execute successfully.
*/
__API__ int tos_at_raw_data_send_until(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, size_t size);
/**
* @brief Write byte to the at uart.
* The function called by the uart interrupt, to put the data from the uart to the at framework.
*
* @attention None
*
* @param[in] data uart received data.
*
* @return None
*/
__API__ void tos_at_uart_input_byte(uint8_t data);
/**
* @brief A global lock provided by at framework.
* The lock usually used to make a atomic function.
*
* @attention None
*
* @param None.
*
* @return errcode
* @retval -1 pend failed(error).
* @retval 0 pend successfully.
*/
__API__ int tos_at_global_lock_pend(void);
/**
* @brief A global lock provided by at framework.
* The lock usually used to make a atomic function.
*
* @attention None
*
* @param None.
*
* @return errcode
* @retval -1 post failed(error).
* @retval 0 post successfully.
*/
__API__ int tos_at_global_lock_post(void);
/**
* @brief Read data from the uart.
* Read data from the uart, usually called in listened event callback.
*
* @attention None
*
* @param[out] buffer buffer to hold the data read from the uart.
* @param[in] buffer_len length of the buffer.
*
* @return length of the data read from the uart.
*/
__API__ int tos_at_uart_read(uint8_t *buffer, size_t buffer_len);
/**
* @brief Read data from the uart.
* Read data from the uart until meet a '\n', usually called in listened event callback.
*
* @attention None
*
* @param[out] buffer buffer to hold the data read from the uart.
* @param[in] buffer_len length of the buffer.
*
* @return length of the data read from the uart.
*/
__API__ int tos_at_uart_readline(uint8_t *buffer, size_t buffer_len);
/**
* @brief Read data from the uart.
* Read data from the uart until no more incoming data, usually called in listened event callback.
*
* @attention None
*
* @param[out] buffer buffer to hold the data read from the uart.
* @param[in] buffer_len length of the buffer.
*
* @return length of the data read from the uart.
*/
__API__ int tos_at_uart_drain(uint8_t *buffer, size_t buffer_len);
/**
* @brief Get the remote ip of a channel.
* Get the remote ip of a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return remote ip of the channel.
*/
__API__ const char *tos_at_agent_channel_ip_get(int channel_id);
/**
* @brief Get the remote port of a channel.
* Get the remote port of a channel with certain id.
*
* @attention None
*
* @param[in] channel_id id of the channel.
*
* @return remote port of the channel.
*/
__API__ const char *tos_at_agent_channel_port_get(int channel_id);
#endif /* __AT_AGENT_H_ */

View File

@@ -161,9 +161,18 @@ __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;
}

View File

@@ -0,0 +1,43 @@
/**
******************************************************************************
* @file stm32l0xx_hal_flash_ex2.h
* @author jieranzhi
* @date 2020/04/02 14:59 CST
* @brief Header file of Flash EEPROM.
******************************************************************************
* @attention
*
* this file implementes FLASH read operations for stm32l0xx series(category 5
* devices), to implement a morefunctions, please refer to RM0367, which could
* be downloaded from:
* https://www.st.com/resource/en/reference_manual/dm00095744-ultra-low-power-
* stm32l0x3-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32L0xx_HAL_FLASH_EX2_H
#define __STM32L0xx_HAL_FLASH_EX2_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32l0xx_hal.h"
/* Include FLASH HAL Extended module */
#include "stm32l0xx_hal_flash_ex.h"
#include "stm32l0xx_hal_flash_ramfunc.h"
/* Exported functions --------------------------------------------------------*/
void HAL_FLASH_Prepare_Reading(uint8_t WaitState);
HAL_StatusTypeDef HAL_FLASH_ReadWord(uint32_t Address, uint32_t* Data);
HAL_StatusTypeDef HAL_FLASH_ReadHalfWord(uint32_t Address, uint16_t* Data);
#ifdef __cplusplus
}
#endif
#endif /* __STM32L0xx_HAL_FLASH_EX2_H */

View File

@@ -0,0 +1,89 @@
/**
******************************************************************************
* @file stm32l0xx_hal_flash_eeprom.c
* @author jieranzhi
* @date 2020/04/02 14:59 CST
* @brief implementation of Flash EEPROM operations.
******************************************************************************
* @attention
*
* this file implementes FLASH read operations for stm32l0xx series(category 5
* devices), to implement a morefunctions, please refer to RM0367, which could
* be downloaded from:
* https://www.st.com/resource/en/reference_manual/dm00095744-ultra-low-power-
* stm32l0x3-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf
******************************************************************************
*/
#include "stm32l0xx_hal_flash_ex2.h"
/**
* @brief set the correct number of wait states, and set the clock of the memory
interface
* @note The user must set the correct number of wait states (LATENCY bit in
* the FLASH_ACR register). No control is done to verify if the frequency
* or the power used is correct, with respect to the number of wait
* states. A wrong number of wait states can generate wrong read values
* (high frequency and 0 wait states) or a long time to execute a code
* (low frequency with 1 wait state).
* @param correct number of wait states
*/
void HAL_FLASH_Prepare_Reading(uint8_t WaitState)
{
__HAL_RCC_MIF_CLK_ENABLE();
__HAL_FLASH_SET_LATENCY(WaitState);
}
/**
* @brief Read word (4 bytes) from a specified address
* @note To correctly run this function, the HAL_FLASH_Prepare_Reading(...)
* function must be called before.
*
* @param Address Specifie the address to be read from.
* @param Data Specifie the data to store the
*
* @retval HAL_StatusTypeDef HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_ReadWord(uint32_t Address, uint32_t* Data)
{
HAL_StatusTypeDef status = HAL_ERROR;
/* Check the parameters */
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)||IS_FLASH_DATA_ADDRESS(Address));
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
if(status == HAL_OK)
{
*Data = *(__IO uint32_t*)Address;
}
return status;
}
/**
* @brief Read half-word (2 bytes) from a specified address
* @note To correctly run this function, the HAL_FLASH_Prepare_Reading(...)
* function must be called before.
*
* @param Address Specifie the address to be read from.
* @param Data Specifie the data to store the
*
* @retval HAL_StatusTypeDef HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_ReadHalfWord(uint32_t Address, uint16_t* Data)
{
HAL_StatusTypeDef status = HAL_ERROR;
/* Check the parameters */
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)||IS_FLASH_DATA_ADDRESS(Address));
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
if(status == HAL_OK)
{
*Data = *(__IO uint16_t*)Address;
}
return status;
}