diff --git a/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.c b/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.c index 57f6df9c..facb7837 100644 --- a/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.c +++ b/board/NUCLEO_STM32L073RZ/BSP/HardWare/Common/bsp.c @@ -3,19 +3,20 @@ * @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); } 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..6ed73014 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,6 +16,7 @@ extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include +#include #include "HTS221.h" #include "LPS22HB.h" #include "LIS3MDL.h" @@ -61,6 +38,25 @@ typedef struct } sensor_data_t; + // application configuration types + typedef enum{ + DCT_IS_CONFIRM = 0x00U, + DCT_REPORT_PERIOD = 0x01U, + DCT_REPEAT_TIME = 0x02U, + DCT_MAGN_FULLSCALE = 0x03U, + DCT_DEFAULT = 0xFFU, + }DeviceConfigType_TypeDef; + +// application configuration +typedef struct +{ + uint32_t config_address; + uint16_t report_period; + uint8_t repeat_time; + LIS3MDL_FullScaleTypeDef magn_fullscale; + bool is_confirmed; +}DeviceConfig_TypeDef; + /* Exported constants --------------------------------------------------------*/ /* External variables --------------------------------------------------------*/ /* Exported macros -----------------------------------------------------------*/ @@ -71,7 +67,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/Src/lora_demo.c b/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c index 35583663..76d00d1a 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,9 +118,6 @@ */ -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) @@ -145,6 +142,118 @@ 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 = FULLSCALE_4; +} + +/** + * @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[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; + } + default: + { + break; + } + } + } + } + } + } + return status; +} + void recv_callback(uint8_t *data, uint8_t len) { printf("len: %d\n", len); @@ -154,11 +263,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,15 +292,22 @@ 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); @@ -205,15 +323,14 @@ void application_entry(void *arg) 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; + dev_data_wrapper.u.dev_data.period = device_config.report_period; // send data to the server (via gateway) - if(is_confirmed){ + if(device_config.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)); } - - tos_task_delay(report_period * 1000); + 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..84a1b288 100644 --- a/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewp +++ b/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewp @@ -1123,14 +1123,14 @@ $PROJ_DIR$\..\..\..\..\devices\rhf76_lora\RHF76.c - - Drivers/CMSIS - - $PROJ_DIR$\..\..\BSP\Src\system_stm32l0xx.c - - Drivers/STM32L0xx_HAL_Driver + + Drivers/CMSIS + + $PROJ_DIR$\..\..\BSP\Src\system_stm32l0xx.c + + $PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal.c @@ -1146,6 +1146,9 @@ $PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ex.c + + $PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ex2.c + $PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ramfunc.c diff --git a/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewt b/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewt index 4267415e..b3317fc0 100644 --- a/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewt +++ b/board/NUCLEO_STM32L073RZ/IAR/lorawan/TencentOS_tiny.ewt @@ -1257,14 +1257,14 @@ $PROJ_DIR$\..\..\..\..\devices\rhf76_lora\RHF76.c - - Drivers/CMSIS - - $PROJ_DIR$\..\..\BSP\Src\system_stm32l0xx.c - - Drivers/STM32L0xx_HAL_Driver + + Drivers/CMSIS + + $PROJ_DIR$\..\..\BSP\Src\system_stm32l0xx.c + + $PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal.c @@ -1280,6 +1280,9 @@ $PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ex.c + + $PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ex2.c + $PROJ_DIR$\..\..\..\..\platform\vendor_bsp\st\STM32L0xx_HAL_Driver\Src\stm32l0xx_hal_flash_ramfunc.c diff --git a/examples/LoRaWAN/lora_demo.h b/examples/LoRaWAN/lora_demo.h index f6222c8e..9455bd6a 100644 --- a/examples/LoRaWAN/lora_demo.h +++ b/examples/LoRaWAN/lora_demo.h @@ -1,20 +1,17 @@ #ifndef __APP_DEMO_H__ #define __APP_DEMO_H__ +#include #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 } diff --git a/platform/vendor_bsp/st/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal_flash_ex2.h b/platform/vendor_bsp/st/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal_flash_ex2.h new file mode 100644 index 00000000..9641f2a8 --- /dev/null +++ b/platform/vendor_bsp/st/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal_flash_ex2.h @@ -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 */ \ No newline at end of file diff --git a/platform/vendor_bsp/st/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_flash_ex2.c b/platform/vendor_bsp/st/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_flash_ex2.c new file mode 100644 index 00000000..2a341d3d --- /dev/null +++ b/platform/vendor_bsp/st/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_flash_ex2.c @@ -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; +} \ No newline at end of file