From 169400eda9091086ae91b544ebe943fcdb0a1077 Mon Sep 17 00:00:00 2001 From: sundp Date: Sun, 18 Feb 2024 17:04:10 +0800 Subject: [PATCH] restart after lunar new year --- .cproject | 468 +-- Core/Inc/acc_hal_integration.h | 32 +- Core/Inc/acc_integration.h | 118 +- Core/Inc/acc_integration_log.h | 108 +- Core/Inc/sts_lamp_bar.h | 216 +- Core/Inc/tim.h | 102 +- Core/Src/acc_hal_integration_a111.c | 450 +-- ..._hal_integration_stm32cube_sparkfun_a111.c | 450 +-- Core/Src/acc_integration_log.c | 108 +- Core/Src/acc_integration_stm32.c | 90 +- Core/Src/sts_lamp_bar.c | 1248 +++---- Core/Src/yunhorn_sts_distance_rss.c | 320 +- Core/Src/yunhorn_sts_presence_rss.c | 1346 ++++---- .../yunhorn_sts_presence_rss_bring_up_test.c | 416 +-- Core/Src/yunhorn_sts_presence_sensor.c | 924 +++--- .../rss/include/acc_base_configuration.h | 456 +-- .../rss/include/acc_definitions_a111.h | 152 +- .../rss/include/acc_definitions_common.h | 90 +- .../rss/include/acc_detector_distance.h | 1662 +++++----- .../rss/include/acc_detector_presence.h | 1164 +++---- .../rss/include/acc_hal_definitions.h | 624 ++-- STM32CubeIDE/rss/include/acc_rss.h | 296 +- .../rss/include/acc_rss_assembly_test.h | 454 +-- .../rss/include/acc_rss_diagnostics.h | 82 +- STM32CubeIDE/rss/include/acc_service.h | 858 ++--- .../rss/include/acc_service_envelope.h | 478 +-- STM32CubeIDE/rss/include/acc_service_iq.h | 576 ++-- .../rss/include/acc_service_power_bins.h | 452 +-- STM32CubeIDE/rss/include/acc_service_sparse.h | 588 ++-- STM32CubeIDE/rss/include/acc_version.h | 28 +- as923_1_jp.js | 208 +- decoder.js | 242 +- mcu/STM32WLE5CCUX_FLASH.ld_ | 372 +-- mcu_2_55jc.sh | 20 +- mcu_2_e5cc.sh | 18 +- mlx90640/MLX90640_API.c | 2912 ++++++++--------- rss/include/acc_base_configuration.h | 456 +-- rss/include/acc_definitions_a111.h | 152 +- rss/include/acc_definitions_common.h | 90 +- rss/include/acc_detector_distance.h | 1662 +++++----- rss/include/acc_detector_presence.h | 1164 +++---- rss/include/acc_hal_definitions.h | 624 ++-- rss/include/acc_rss.h | 296 +- rss/include/acc_rss_assembly_test.h | 454 +-- rss/include/acc_rss_diagnostics.h | 82 +- rss/include/acc_service.h | 858 ++--- rss/include/acc_service_envelope.h | 478 +-- rss/include/acc_service_iq.h | 576 ++-- rss/include/acc_service_power_bins.h | 452 +-- rss/include/acc_service_sparse.h | 588 ++-- rss/include/acc_version.h | 28 +- 51 files changed, 13044 insertions(+), 13044 deletions(-) diff --git a/.cproject b/.cproject index d29d3f4..284d00a 100644 --- a/.cproject +++ b/.cproject @@ -1,235 +1,235 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Core/Inc/acc_hal_integration.h b/Core/Inc/acc_hal_integration.h index adaf372..7e10302 100644 --- a/Core/Inc/acc_hal_integration.h +++ b/Core/Inc/acc_hal_integration.h @@ -1,16 +1,16 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_HAL_INTEGRATION_H_ -#define ACC_HAL_INTEGRATION_H_ - -#include "acc_definitions_common.h" -#include "acc_hal_definitions.h" - -/** - * @brief Get hal implementation reference - */ -const acc_hal_t *acc_hal_integration_get_implementation(void); -bool hal_test_spi_read_chipid(uint8_t chipid[2]); - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_HAL_INTEGRATION_H_ +#define ACC_HAL_INTEGRATION_H_ + +#include "acc_definitions_common.h" +#include "acc_hal_definitions.h" + +/** + * @brief Get hal implementation reference + */ +const acc_hal_t *acc_hal_integration_get_implementation(void); +bool hal_test_spi_read_chipid(uint8_t chipid[2]); + +#endif diff --git a/Core/Inc/acc_integration.h b/Core/Inc/acc_integration.h index fb1b8fc..60ac485 100644 --- a/Core/Inc/acc_integration.h +++ b/Core/Inc/acc_integration.h @@ -1,59 +1,59 @@ -// Copyright (c) Acconeer AB, 2019-2022 -// All rights reserved - -#ifndef ACC_INTEGRATION_H_ -#define ACC_INTEGRATION_H_ - -#include -#include -#include - - -typedef void (*acc_integration_uart_read_func_t)(uint8_t data, uint32_t status); - - -/** - * @brief Sleep for a specified number of microseconds - * - * @param time_usec Time in microseconds to sleep - */ -void acc_integration_sleep_us(uint32_t time_usec); - - -/** - * @brief Sleep for a specified number of milliseconds - * - * @param time_msec Time in milliseconds to sleep - */ -void acc_integration_sleep_ms(uint32_t time_msec); - - -/** - * @brief Allocate dynamic memory - * - * @param[in] size The bytesize of the reuested memory block - * @return Returns either NULL or a unique pointer to a memory block - */ -void *acc_integration_mem_alloc(size_t size); - - -/** - * @brief Free dynamic memory - * - * @param[in] ptr A pointer to the memory space to be freed - */ -void acc_integration_mem_free(void *ptr); - - -/** - * @brief Get current time - * - * It is important that this value wraps correctly and uses all bits. I.e. it should count - * upwards to 2^32 - 1 and then 0 again. - * - * @returns Current time as milliseconds - */ -uint32_t acc_integration_get_time(void); - - -#endif +// Copyright (c) Acconeer AB, 2019-2022 +// All rights reserved + +#ifndef ACC_INTEGRATION_H_ +#define ACC_INTEGRATION_H_ + +#include +#include +#include + + +typedef void (*acc_integration_uart_read_func_t)(uint8_t data, uint32_t status); + + +/** + * @brief Sleep for a specified number of microseconds + * + * @param time_usec Time in microseconds to sleep + */ +void acc_integration_sleep_us(uint32_t time_usec); + + +/** + * @brief Sleep for a specified number of milliseconds + * + * @param time_msec Time in milliseconds to sleep + */ +void acc_integration_sleep_ms(uint32_t time_msec); + + +/** + * @brief Allocate dynamic memory + * + * @param[in] size The bytesize of the reuested memory block + * @return Returns either NULL or a unique pointer to a memory block + */ +void *acc_integration_mem_alloc(size_t size); + + +/** + * @brief Free dynamic memory + * + * @param[in] ptr A pointer to the memory space to be freed + */ +void acc_integration_mem_free(void *ptr); + + +/** + * @brief Get current time + * + * It is important that this value wraps correctly and uses all bits. I.e. it should count + * upwards to 2^32 - 1 and then 0 again. + * + * @returns Current time as milliseconds + */ +uint32_t acc_integration_get_time(void); + + +#endif diff --git a/Core/Inc/acc_integration_log.h b/Core/Inc/acc_integration_log.h index 22a4802..6886a75 100644 --- a/Core/Inc/acc_integration_log.h +++ b/Core/Inc/acc_integration_log.h @@ -1,54 +1,54 @@ -// Copyright (c) Acconeer AB, 2016-2021 -// All rights reserved - -#ifndef ACC_INTEGRATION_LOG_H_ -#define ACC_INTEGRATION_LOG_H_ - -#include "acc_definitions_common.h" -#include "acc_integration.h" - -#ifdef ACC_LOG_RSS_H_ -#error "acc_integration_log.h and acc_log_rss.h cannot coexist" -#endif - -#define ACC_LOG(level, ...) acc_integration_log(level, MODULE, __VA_ARGS__) - -#define ACC_LOG_ERROR(...) ACC_LOG(ACC_LOG_LEVEL_ERROR, __VA_ARGS__) -#define ACC_LOG_WARNING(...) ACC_LOG(ACC_LOG_LEVEL_WARNING, __VA_ARGS__) -#define ACC_LOG_INFO(...) ACC_LOG(ACC_LOG_LEVEL_INFO, __VA_ARGS__) -#define ACC_LOG_VERBOSE(...) ACC_LOG(ACC_LOG_LEVEL_VERBOSE, __VA_ARGS__) -#define ACC_LOG_DEBUG(...) ACC_LOG(ACC_LOG_LEVEL_DEBUG, __VA_ARGS__) - -#define ACC_LOG_SIGN(a) (((a) < 0.0f) ? (-1.0f) : (1.0f)) -#define ACC_LOG_FLOAT_INT(a) ((unsigned long int)((a) + 0.0000005f)) -#define ACC_LOG_FLOAT_DEC(a) (unsigned long int)((1000000.0f * (((a) + 0.0000005f) - ((unsigned int)((a) + 0.0000005f))))) - -#define ACC_LOG_FLOAT_TO_INTEGER(a) (((a) < 0.0f) ? "-" : ""), ACC_LOG_FLOAT_INT((a) * ACC_LOG_SIGN(a)), ACC_LOG_FLOAT_DEC((a) * ACC_LOG_SIGN(a)) - -/** - * @brief Specifier for printing float type using integers. - */ -#define PRIfloat "s%lu.%06lu" - - -#if defined(__GNUC__) -#define PRINTF_ATTRIBUTE_CHECK(a, b) __attribute__((format(printf, a, b))) -#else -#define PRINTF_ATTRIBUTE_CHECK(a, b) -#endif - - -/** - * @brief Log function - * - * This log function can be used as a complement to for example printf. - * It adds useful information to the log such as time and log level - * - * @param[in] level The severity level for the log - * @param[in] module The name of the SW module from where the log is called - * @param[in] format The information to be logged, same format as for printf - */ -void acc_integration_log(acc_log_level_t level, const char *module, const char *format, ...) PRINTF_ATTRIBUTE_CHECK(3, 4); - - -#endif +// Copyright (c) Acconeer AB, 2016-2021 +// All rights reserved + +#ifndef ACC_INTEGRATION_LOG_H_ +#define ACC_INTEGRATION_LOG_H_ + +#include "acc_definitions_common.h" +#include "acc_integration.h" + +#ifdef ACC_LOG_RSS_H_ +#error "acc_integration_log.h and acc_log_rss.h cannot coexist" +#endif + +#define ACC_LOG(level, ...) acc_integration_log(level, MODULE, __VA_ARGS__) + +#define ACC_LOG_ERROR(...) ACC_LOG(ACC_LOG_LEVEL_ERROR, __VA_ARGS__) +#define ACC_LOG_WARNING(...) ACC_LOG(ACC_LOG_LEVEL_WARNING, __VA_ARGS__) +#define ACC_LOG_INFO(...) ACC_LOG(ACC_LOG_LEVEL_INFO, __VA_ARGS__) +#define ACC_LOG_VERBOSE(...) ACC_LOG(ACC_LOG_LEVEL_VERBOSE, __VA_ARGS__) +#define ACC_LOG_DEBUG(...) ACC_LOG(ACC_LOG_LEVEL_DEBUG, __VA_ARGS__) + +#define ACC_LOG_SIGN(a) (((a) < 0.0f) ? (-1.0f) : (1.0f)) +#define ACC_LOG_FLOAT_INT(a) ((unsigned long int)((a) + 0.0000005f)) +#define ACC_LOG_FLOAT_DEC(a) (unsigned long int)((1000000.0f * (((a) + 0.0000005f) - ((unsigned int)((a) + 0.0000005f))))) + +#define ACC_LOG_FLOAT_TO_INTEGER(a) (((a) < 0.0f) ? "-" : ""), ACC_LOG_FLOAT_INT((a) * ACC_LOG_SIGN(a)), ACC_LOG_FLOAT_DEC((a) * ACC_LOG_SIGN(a)) + +/** + * @brief Specifier for printing float type using integers. + */ +#define PRIfloat "s%lu.%06lu" + + +#if defined(__GNUC__) +#define PRINTF_ATTRIBUTE_CHECK(a, b) __attribute__((format(printf, a, b))) +#else +#define PRINTF_ATTRIBUTE_CHECK(a, b) +#endif + + +/** + * @brief Log function + * + * This log function can be used as a complement to for example printf. + * It adds useful information to the log such as time and log level + * + * @param[in] level The severity level for the log + * @param[in] module The name of the SW module from where the log is called + * @param[in] format The information to be logged, same format as for printf + */ +void acc_integration_log(acc_log_level_t level, const char *module, const char *format, ...) PRINTF_ATTRIBUTE_CHECK(3, 4); + + +#endif diff --git a/Core/Inc/sts_lamp_bar.h b/Core/Inc/sts_lamp_bar.h index 7911d83..5a02d78 100644 --- a/Core/Inc/sts_lamp_bar.h +++ b/Core/Inc/sts_lamp_bar.h @@ -1,108 +1,108 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : sts_lamp_bar.h - * @brief : Header for sts_lamp_bar.c file. - * This file contains the common defines of the application. - ****************************************************************************** - * @attention - * - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STS_LAMP_BAR_H -#define __STS_LAMP_BAR_H - -#ifdef __cplusplus -extern "C" { -#endif - - -#include "main.h" - -#define DEFAULT_SATURATION 50 // 0 - 100 S:Saturation, 0~100 -#define DEFAULT_BRIGHTNESS 50 // 0 - 100 V:Value of lightness, 0~100 - -#define STS_Status_Door_Close (0) //Normal Close NC:Open -#define STS_Status_Door_Open (1) //Normal Close NC:Close - -enum sts_lamp_color { - STS_DARK = 0, //灭:0 - STS_GREEN, //绿:1 0 1 0 - STS_RED, //红:2 1 0 0 - STS_BLUE, //蓝:3 0 0 1 - STS_YELLOW, //黄:4 1 1 0 - STS_PINK, //紫:5 1 0 1 - STS_CYAN, //青:6 0 1 1 - STS_WHITE, //白:7 1 1 1 - STS_RED_BLUE //红蓝闪烁:8 -}; - -enum sts_oo_work_mode { - STS_NETWORK_MODE = 0, // 0 NETWORK MODE - STS_WIRED_MODE, // 1 WIRED MODE === WATER LEAKAGE, SOAP CAPACITY SENSOR MODE - STS_REEDSWITCH_MODE, // 2 REED SWITCH ONLY - STS_RSS_MODE, // 3 RSS ONLY - STS_DUAL_MODE, // 4 RSS + REED SWITCH IN ONE UNIT - STS_REMOTE_REED_RSS_MODE, // 5 REMOTE REED SWITCH + RSS MODE 2023-05-04 - STS_DUAL_RSS_MODE, // 6 RSS_1 + RSS_2 IN TWO UNITS - STS_TOF_RSS_MODE, // 7 TOF + RSS MODE - STS_TOF_DISTANCE_MODE, // 8 TOF DISTANCE - STS_TOF_PRESENCE_MODE, // 9 TOF PRESENCE OCCUPANCY - STS_TOF_IN_OUT_MODE, // A TOF IN OUT COUNT - STS_FALL_DETECTION_MODE, // B DUAL_MODE + FALL DETECTION - - STS_OTHER_MODE // ? OTHER MODE -}; - -#define STS_Reed_Hall_State HAL_GPIO_ReadPin(BUT1_GPIO_Port, BUT1_Pin) - -//void STS_Lamp_Bar_All(uint8_t lamp_color, uint8_t luminance_level); -void STS_Lamp_Bar_Set_Color(uint8_t red, uint8_t green, uint8_t blue ); -void STS_Lamp_Bar_Set_RGB(uint8_t red, uint8_t green, uint8_t blue); - -void STS_Lamp_Bar_Init(void); -void STS_Lamp_Bar_Full_Color_Gradient(void); -void STS_WS2812B_Refresh(void); -void STS_WS2812B_Set_RGB(uint8_t R, uint8_t G, uint8_t B, uint8_t idx); -void STS_Reed_Hall_Working(void); -void STS_Lamp_Bar_Self_Test_Simple(void); -void STS_Lamp_Bar_Self_Test(void); -void STS_Lamp_Bar_Set_Dark(void); -void sts_rgb_unit_test(void); -void STS_Reed_Hall_Presence_Detection(void); - -void STS_RSS_Smart_Presence_Detection(void); -void STS_RSS_Smart_Presence(void); - -void STS_Combined_Status_Processing(void); - -// Before Join LoRa-WAN Network -void STS_Lamp_Bar_Scoller(uint8_t color, uint8_t luminance_level); -// Occupancy Status, Set Color to STS_RED -// Vacant Status, Set Color to STS_GREEN -void STS_Lamp_Bar_Set_STS_RGB_Color(uint8_t sts_lamp_color, uint8_t luminance_level); -void STS_Lamp_Bar_Refresh(void); - -void STS_YunhornSTSEventP1_Process(void); -void STS_YunhornSTSEventP2_Process(void); -void STS_YunhornSTSEventP3_Process(void); -void STS_YunhornSTSEventP4_Process(void); -void STS_YunhornSTSEventP5_Process(void); -void STS_YunhornSTSEventP6_Process(void); -void STS_YunhornSTSEventP7_Process(void); -void STS_YunhornSTSEventP8_Process(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _STS_LAMP_BAR_H */ - +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : sts_lamp_bar.h + * @brief : Header for sts_lamp_bar.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STS_LAMP_BAR_H +#define __STS_LAMP_BAR_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "main.h" + +#define DEFAULT_SATURATION 50 // 0 - 100 S:Saturation, 0~100 +#define DEFAULT_BRIGHTNESS 50 // 0 - 100 V:Value of lightness, 0~100 + +#define STS_Status_Door_Close (0) //Normal Close NC:Open +#define STS_Status_Door_Open (1) //Normal Close NC:Close + +enum sts_lamp_color { + STS_DARK = 0, //灭:0 + STS_GREEN, //绿:1 0 1 0 + STS_RED, //红:2 1 0 0 + STS_BLUE, //蓝:3 0 0 1 + STS_YELLOW, //黄:4 1 1 0 + STS_PINK, //紫:5 1 0 1 + STS_CYAN, //青:6 0 1 1 + STS_WHITE, //白:7 1 1 1 + STS_RED_BLUE //红蓝闪烁:8 +}; + +enum sts_oo_work_mode { + STS_NETWORK_MODE = 0, // 0 NETWORK MODE + STS_WIRED_MODE, // 1 WIRED MODE === WATER LEAKAGE, SOAP CAPACITY SENSOR MODE + STS_REEDSWITCH_MODE, // 2 REED SWITCH ONLY + STS_RSS_MODE, // 3 RSS ONLY + STS_DUAL_MODE, // 4 RSS + REED SWITCH IN ONE UNIT + STS_REMOTE_REED_RSS_MODE, // 5 REMOTE REED SWITCH + RSS MODE 2023-05-04 + STS_DUAL_RSS_MODE, // 6 RSS_1 + RSS_2 IN TWO UNITS + STS_TOF_RSS_MODE, // 7 TOF + RSS MODE + STS_TOF_DISTANCE_MODE, // 8 TOF DISTANCE + STS_TOF_PRESENCE_MODE, // 9 TOF PRESENCE OCCUPANCY + STS_TOF_IN_OUT_MODE, // A TOF IN OUT COUNT + STS_FALL_DETECTION_MODE, // B DUAL_MODE + FALL DETECTION + + STS_OTHER_MODE // ? OTHER MODE +}; + +#define STS_Reed_Hall_State HAL_GPIO_ReadPin(BUT1_GPIO_Port, BUT1_Pin) + +//void STS_Lamp_Bar_All(uint8_t lamp_color, uint8_t luminance_level); +void STS_Lamp_Bar_Set_Color(uint8_t red, uint8_t green, uint8_t blue ); +void STS_Lamp_Bar_Set_RGB(uint8_t red, uint8_t green, uint8_t blue); + +void STS_Lamp_Bar_Init(void); +void STS_Lamp_Bar_Full_Color_Gradient(void); +void STS_WS2812B_Refresh(void); +void STS_WS2812B_Set_RGB(uint8_t R, uint8_t G, uint8_t B, uint8_t idx); +void STS_Reed_Hall_Working(void); +void STS_Lamp_Bar_Self_Test_Simple(void); +void STS_Lamp_Bar_Self_Test(void); +void STS_Lamp_Bar_Set_Dark(void); +void sts_rgb_unit_test(void); +void STS_Reed_Hall_Presence_Detection(void); + +void STS_RSS_Smart_Presence_Detection(void); +void STS_RSS_Smart_Presence(void); + +void STS_Combined_Status_Processing(void); + +// Before Join LoRa-WAN Network +void STS_Lamp_Bar_Scoller(uint8_t color, uint8_t luminance_level); +// Occupancy Status, Set Color to STS_RED +// Vacant Status, Set Color to STS_GREEN +void STS_Lamp_Bar_Set_STS_RGB_Color(uint8_t sts_lamp_color, uint8_t luminance_level); +void STS_Lamp_Bar_Refresh(void); + +void STS_YunhornSTSEventP1_Process(void); +void STS_YunhornSTSEventP2_Process(void); +void STS_YunhornSTSEventP3_Process(void); +void STS_YunhornSTSEventP4_Process(void); +void STS_YunhornSTSEventP5_Process(void); +void STS_YunhornSTSEventP6_Process(void); +void STS_YunhornSTSEventP7_Process(void); +void STS_YunhornSTSEventP8_Process(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _STS_LAMP_BAR_H */ + diff --git a/Core/Inc/tim.h b/Core/Inc/tim.h index efd1057..24a3c78 100644 --- a/Core/Inc/tim.h +++ b/Core/Inc/tim.h @@ -1,51 +1,51 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file tim.h - * @brief This file contains all the function prototypes for - * the tim.c file - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __TIM_H__ -#define __TIM_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN Private defines */ -extern TIM_HandleTypeDef htim1; -/* USER CODE END Private defines */ - - -/* USER CODE BEGIN Prototypes */ -void MX_TIM1_Init(void); -void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __TIM_H__ */ - +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for + * the tim.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TIM_H__ +#define __TIM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ +extern TIM_HandleTypeDef htim1; +/* USER CODE END Private defines */ + + +/* USER CODE BEGIN Prototypes */ +void MX_TIM1_Init(void); +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIM_H__ */ + diff --git a/Core/Src/acc_hal_integration_a111.c b/Core/Src/acc_hal_integration_a111.c index 38dd51e..7362b38 100644 --- a/Core/Src/acc_hal_integration_a111.c +++ b/Core/Src/acc_hal_integration_a111.c @@ -1,225 +1,225 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved -// This file is subject to the terms and conditions defined in the file -// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part -// of this source code package. - -#include -#include -#include -#include -#include - -#include "main.h" -#include "sys_app.h" - -#include "acc_definitions_common.h" -#include "acc_hal_definitions.h" -#include "acc_hal_integration.h" -#include "acc_integration.h" -#include "acc_integration_log.h" - -#include "acc_version.h" -#include "acc_rss.h" - -enum transfer_state { - TRANSFER_COMPLETE = (int) 0, - TRANSFER_ERROR, - TRANSFER_READY -}; - -/* spi handle */ -extern SPI_HandleTypeDef A111_SPI_HANDLE; - -/** - * @brief The number of sensors available on the board - */ -#define SENSOR_COUNT 1 - -/** - * @brief Size of SPI transfer buffer - */ -#ifndef A111_SPI_MAX_TRANSFER_SIZE -#define A111_SPI_MAX_TRANSFER_SIZE 65535 //4096 //65535 -#endif - -/** - * @brief The reference frequency used by this board - * - * This assumes 26 MHz on the Sparkfun A111 Board - */ -//#define ACC_BOARD_REF_FREQ 26000000 -#define ACC_BOARD_REF_FREQ 24000000 - -static inline void disable_interrupts(void) -{ - __disable_irq(); -} - - -static inline void enable_interrupts(void) -{ - __enable_irq(); - __ISB(); -} - -#ifdef A111_USE_SPI_DMA -static volatile bool spi_transfer_complete; - -void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) -{ - (void)hspi; - spi_transfer_complete = true; -} -#endif - - -//---------------------------------------- -// Implementation of RSS HAL handlers -//---------------------------------------- - - -static void acc_hal_integration_sensor_transfer(acc_sensor_id_t sensor_id, uint8_t *buffer, size_t buffer_size) -{ - (void)sensor_id; // Ignore parameter sensor_id - - const uint32_t SPI_TRANSMIT_RECEIVE_TIMEOUT = 5000; - - HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_RESET); - -#ifdef A111_USE_SPI_DMA - spi_transfer_complete = false; - HAL_StatusTypeDef status = HAL_SPI_TransmitReceive_DMA(&A111_SPI_HANDLE, buffer, buffer, buffer_size); - - if (status != HAL_OK) - { - return; - } - - uint32_t start = HAL_GetTick(); - - while (!spi_transfer_complete && (HAL_GetTick() - start) < SPI_TRANSMIT_RECEIVE_TIMEOUT) - { - // Turn off interrupts - disable_interrupts(); - // Check once more so that the interrupt have not occurred - if (!spi_transfer_complete) - { - __WFI(); - } - - // Enable interrupt again, the ISR will execute directly after this - enable_interrupts(); - } -#else - HAL_SPI_TransmitReceive(&A111_SPI_HANDLE, buffer, buffer, buffer_size, SPI_TRANSMIT_RECEIVE_TIMEOUT); -#endif - - HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_SET); -} - - -static void acc_hal_integration_sensor_power_on(acc_sensor_id_t sensor_id) -{ - (void)sensor_id; // Ignore parameter sensor_id - HAL_GPIO_WritePin(A111_ENABLE_GPIO_Port, A111_ENABLE_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_SET); - - // Wait 2 ms to make sure that the sensor crystal have time to stabilize - HAL_Delay(2); -} - - -static void acc_hal_integration_sensor_power_off(acc_sensor_id_t sensor_id) -{ - (void)sensor_id; // Ignore parameter sensor_id - - HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_RESET); - HAL_GPIO_WritePin(A111_ENABLE_GPIO_Port, A111_ENABLE_Pin, GPIO_PIN_RESET); - - // Wait after power off to leave the sensor in a known state - // in case the application intends to enable the sensor directly - HAL_Delay(2); -} - - -static bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms) -{ - (void)sensor_id; // Ignore parameter sensor_id - - const uint32_t wait_begin_ms = HAL_GetTick(); - while ((HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) != GPIO_PIN_SET) && - (HAL_GetTick() - wait_begin_ms < timeout_ms)) - { - // Wait for the GPIO interrupt - disable_interrupts(); - // Check again so that IRQ did not occur - if (HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) != GPIO_PIN_SET) - { - __WFI(); - } - - // Enable interrupts again to allow pending interrupt to be handled - enable_interrupts(); - } - - return HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) == GPIO_PIN_SET; -} - - -static float acc_hal_integration_get_reference_frequency(void) -{ - return ACC_BOARD_REF_FREQ; -} - - -static const acc_hal_t hal = -{ - .properties.sensor_count = SENSOR_COUNT, - .properties.max_spi_transfer_size = A111_SPI_MAX_TRANSFER_SIZE, - - .sensor_device.power_on = acc_hal_integration_sensor_power_on, - .sensor_device.power_off = acc_hal_integration_sensor_power_off, - .sensor_device.wait_for_interrupt = acc_hal_integration_wait_for_sensor_interrupt, - .sensor_device.transfer = acc_hal_integration_sensor_transfer, - .sensor_device.get_reference_frequency = acc_hal_integration_get_reference_frequency, - - .os.mem_alloc = malloc, - .os.mem_free = free, - .os.gettime = acc_integration_get_time, - - .log.log_level = ACC_LOG_LEVEL_INFO, - .log.log = acc_integration_log, - - .optimization.transfer16 = NULL, -}; - - -const acc_hal_t *acc_hal_integration_get_implementation(void) -{ - return &hal; -} - - -bool hal_test_spi_read_chipid(uint8_t chipid[2]) -{ - const uint32_t sensor = 1; - uint8_t buffer[6] = {0x30,0x0,0x0,0x0,0x0,0x0}; - const acc_hal_t *hal = acc_hal_integration_get_implementation(); - hal->sensor_device.power_on(sensor); - hal->sensor_device.transfer(sensor,buffer,sizeof(buffer)); - hal->sensor_device.power_off(sensor); - if (buffer[4] == 0x11 && buffer[5] == 0x12) { - chipid[0] = buffer[4]; - chipid[1] = buffer[5]; - return true; - } - else - { - chipid[0] = 0x0; - chipid[1] = 0x0; - return false; - } - -} - +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved +// This file is subject to the terms and conditions defined in the file +// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part +// of this source code package. + +#include +#include +#include +#include +#include + +#include "main.h" +#include "sys_app.h" + +#include "acc_definitions_common.h" +#include "acc_hal_definitions.h" +#include "acc_hal_integration.h" +#include "acc_integration.h" +#include "acc_integration_log.h" + +#include "acc_version.h" +#include "acc_rss.h" + +enum transfer_state { + TRANSFER_COMPLETE = (int) 0, + TRANSFER_ERROR, + TRANSFER_READY +}; + +/* spi handle */ +extern SPI_HandleTypeDef A111_SPI_HANDLE; + +/** + * @brief The number of sensors available on the board + */ +#define SENSOR_COUNT 1 + +/** + * @brief Size of SPI transfer buffer + */ +#ifndef A111_SPI_MAX_TRANSFER_SIZE +#define A111_SPI_MAX_TRANSFER_SIZE 65535 //4096 //65535 +#endif + +/** + * @brief The reference frequency used by this board + * + * This assumes 26 MHz on the Sparkfun A111 Board + */ +//#define ACC_BOARD_REF_FREQ 26000000 +#define ACC_BOARD_REF_FREQ 24000000 + +static inline void disable_interrupts(void) +{ + __disable_irq(); +} + + +static inline void enable_interrupts(void) +{ + __enable_irq(); + __ISB(); +} + +#ifdef A111_USE_SPI_DMA +static volatile bool spi_transfer_complete; + +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) +{ + (void)hspi; + spi_transfer_complete = true; +} +#endif + + +//---------------------------------------- +// Implementation of RSS HAL handlers +//---------------------------------------- + + +static void acc_hal_integration_sensor_transfer(acc_sensor_id_t sensor_id, uint8_t *buffer, size_t buffer_size) +{ + (void)sensor_id; // Ignore parameter sensor_id + + const uint32_t SPI_TRANSMIT_RECEIVE_TIMEOUT = 5000; + + HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_RESET); + +#ifdef A111_USE_SPI_DMA + spi_transfer_complete = false; + HAL_StatusTypeDef status = HAL_SPI_TransmitReceive_DMA(&A111_SPI_HANDLE, buffer, buffer, buffer_size); + + if (status != HAL_OK) + { + return; + } + + uint32_t start = HAL_GetTick(); + + while (!spi_transfer_complete && (HAL_GetTick() - start) < SPI_TRANSMIT_RECEIVE_TIMEOUT) + { + // Turn off interrupts + disable_interrupts(); + // Check once more so that the interrupt have not occurred + if (!spi_transfer_complete) + { + __WFI(); + } + + // Enable interrupt again, the ISR will execute directly after this + enable_interrupts(); + } +#else + HAL_SPI_TransmitReceive(&A111_SPI_HANDLE, buffer, buffer, buffer_size, SPI_TRANSMIT_RECEIVE_TIMEOUT); +#endif + + HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_SET); +} + + +static void acc_hal_integration_sensor_power_on(acc_sensor_id_t sensor_id) +{ + (void)sensor_id; // Ignore parameter sensor_id + HAL_GPIO_WritePin(A111_ENABLE_GPIO_Port, A111_ENABLE_Pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_SET); + + // Wait 2 ms to make sure that the sensor crystal have time to stabilize + HAL_Delay(2); +} + + +static void acc_hal_integration_sensor_power_off(acc_sensor_id_t sensor_id) +{ + (void)sensor_id; // Ignore parameter sensor_id + + HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(A111_ENABLE_GPIO_Port, A111_ENABLE_Pin, GPIO_PIN_RESET); + + // Wait after power off to leave the sensor in a known state + // in case the application intends to enable the sensor directly + HAL_Delay(2); +} + + +static bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms) +{ + (void)sensor_id; // Ignore parameter sensor_id + + const uint32_t wait_begin_ms = HAL_GetTick(); + while ((HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) != GPIO_PIN_SET) && + (HAL_GetTick() - wait_begin_ms < timeout_ms)) + { + // Wait for the GPIO interrupt + disable_interrupts(); + // Check again so that IRQ did not occur + if (HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) != GPIO_PIN_SET) + { + __WFI(); + } + + // Enable interrupts again to allow pending interrupt to be handled + enable_interrupts(); + } + + return HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) == GPIO_PIN_SET; +} + + +static float acc_hal_integration_get_reference_frequency(void) +{ + return ACC_BOARD_REF_FREQ; +} + + +static const acc_hal_t hal = +{ + .properties.sensor_count = SENSOR_COUNT, + .properties.max_spi_transfer_size = A111_SPI_MAX_TRANSFER_SIZE, + + .sensor_device.power_on = acc_hal_integration_sensor_power_on, + .sensor_device.power_off = acc_hal_integration_sensor_power_off, + .sensor_device.wait_for_interrupt = acc_hal_integration_wait_for_sensor_interrupt, + .sensor_device.transfer = acc_hal_integration_sensor_transfer, + .sensor_device.get_reference_frequency = acc_hal_integration_get_reference_frequency, + + .os.mem_alloc = malloc, + .os.mem_free = free, + .os.gettime = acc_integration_get_time, + + .log.log_level = ACC_LOG_LEVEL_INFO, + .log.log = acc_integration_log, + + .optimization.transfer16 = NULL, +}; + + +const acc_hal_t *acc_hal_integration_get_implementation(void) +{ + return &hal; +} + + +bool hal_test_spi_read_chipid(uint8_t chipid[2]) +{ + const uint32_t sensor = 1; + uint8_t buffer[6] = {0x30,0x0,0x0,0x0,0x0,0x0}; + const acc_hal_t *hal = acc_hal_integration_get_implementation(); + hal->sensor_device.power_on(sensor); + hal->sensor_device.transfer(sensor,buffer,sizeof(buffer)); + hal->sensor_device.power_off(sensor); + if (buffer[4] == 0x11 && buffer[5] == 0x12) { + chipid[0] = buffer[4]; + chipid[1] = buffer[5]; + return true; + } + else + { + chipid[0] = 0x0; + chipid[1] = 0x0; + return false; + } + +} + diff --git a/Core/Src/acc_hal_integration_stm32cube_sparkfun_a111.c b/Core/Src/acc_hal_integration_stm32cube_sparkfun_a111.c index 38dd51e..7362b38 100644 --- a/Core/Src/acc_hal_integration_stm32cube_sparkfun_a111.c +++ b/Core/Src/acc_hal_integration_stm32cube_sparkfun_a111.c @@ -1,225 +1,225 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved -// This file is subject to the terms and conditions defined in the file -// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part -// of this source code package. - -#include -#include -#include -#include -#include - -#include "main.h" -#include "sys_app.h" - -#include "acc_definitions_common.h" -#include "acc_hal_definitions.h" -#include "acc_hal_integration.h" -#include "acc_integration.h" -#include "acc_integration_log.h" - -#include "acc_version.h" -#include "acc_rss.h" - -enum transfer_state { - TRANSFER_COMPLETE = (int) 0, - TRANSFER_ERROR, - TRANSFER_READY -}; - -/* spi handle */ -extern SPI_HandleTypeDef A111_SPI_HANDLE; - -/** - * @brief The number of sensors available on the board - */ -#define SENSOR_COUNT 1 - -/** - * @brief Size of SPI transfer buffer - */ -#ifndef A111_SPI_MAX_TRANSFER_SIZE -#define A111_SPI_MAX_TRANSFER_SIZE 65535 //4096 //65535 -#endif - -/** - * @brief The reference frequency used by this board - * - * This assumes 26 MHz on the Sparkfun A111 Board - */ -//#define ACC_BOARD_REF_FREQ 26000000 -#define ACC_BOARD_REF_FREQ 24000000 - -static inline void disable_interrupts(void) -{ - __disable_irq(); -} - - -static inline void enable_interrupts(void) -{ - __enable_irq(); - __ISB(); -} - -#ifdef A111_USE_SPI_DMA -static volatile bool spi_transfer_complete; - -void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) -{ - (void)hspi; - spi_transfer_complete = true; -} -#endif - - -//---------------------------------------- -// Implementation of RSS HAL handlers -//---------------------------------------- - - -static void acc_hal_integration_sensor_transfer(acc_sensor_id_t sensor_id, uint8_t *buffer, size_t buffer_size) -{ - (void)sensor_id; // Ignore parameter sensor_id - - const uint32_t SPI_TRANSMIT_RECEIVE_TIMEOUT = 5000; - - HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_RESET); - -#ifdef A111_USE_SPI_DMA - spi_transfer_complete = false; - HAL_StatusTypeDef status = HAL_SPI_TransmitReceive_DMA(&A111_SPI_HANDLE, buffer, buffer, buffer_size); - - if (status != HAL_OK) - { - return; - } - - uint32_t start = HAL_GetTick(); - - while (!spi_transfer_complete && (HAL_GetTick() - start) < SPI_TRANSMIT_RECEIVE_TIMEOUT) - { - // Turn off interrupts - disable_interrupts(); - // Check once more so that the interrupt have not occurred - if (!spi_transfer_complete) - { - __WFI(); - } - - // Enable interrupt again, the ISR will execute directly after this - enable_interrupts(); - } -#else - HAL_SPI_TransmitReceive(&A111_SPI_HANDLE, buffer, buffer, buffer_size, SPI_TRANSMIT_RECEIVE_TIMEOUT); -#endif - - HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_SET); -} - - -static void acc_hal_integration_sensor_power_on(acc_sensor_id_t sensor_id) -{ - (void)sensor_id; // Ignore parameter sensor_id - HAL_GPIO_WritePin(A111_ENABLE_GPIO_Port, A111_ENABLE_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_SET); - - // Wait 2 ms to make sure that the sensor crystal have time to stabilize - HAL_Delay(2); -} - - -static void acc_hal_integration_sensor_power_off(acc_sensor_id_t sensor_id) -{ - (void)sensor_id; // Ignore parameter sensor_id - - HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_RESET); - HAL_GPIO_WritePin(A111_ENABLE_GPIO_Port, A111_ENABLE_Pin, GPIO_PIN_RESET); - - // Wait after power off to leave the sensor in a known state - // in case the application intends to enable the sensor directly - HAL_Delay(2); -} - - -static bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms) -{ - (void)sensor_id; // Ignore parameter sensor_id - - const uint32_t wait_begin_ms = HAL_GetTick(); - while ((HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) != GPIO_PIN_SET) && - (HAL_GetTick() - wait_begin_ms < timeout_ms)) - { - // Wait for the GPIO interrupt - disable_interrupts(); - // Check again so that IRQ did not occur - if (HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) != GPIO_PIN_SET) - { - __WFI(); - } - - // Enable interrupts again to allow pending interrupt to be handled - enable_interrupts(); - } - - return HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) == GPIO_PIN_SET; -} - - -static float acc_hal_integration_get_reference_frequency(void) -{ - return ACC_BOARD_REF_FREQ; -} - - -static const acc_hal_t hal = -{ - .properties.sensor_count = SENSOR_COUNT, - .properties.max_spi_transfer_size = A111_SPI_MAX_TRANSFER_SIZE, - - .sensor_device.power_on = acc_hal_integration_sensor_power_on, - .sensor_device.power_off = acc_hal_integration_sensor_power_off, - .sensor_device.wait_for_interrupt = acc_hal_integration_wait_for_sensor_interrupt, - .sensor_device.transfer = acc_hal_integration_sensor_transfer, - .sensor_device.get_reference_frequency = acc_hal_integration_get_reference_frequency, - - .os.mem_alloc = malloc, - .os.mem_free = free, - .os.gettime = acc_integration_get_time, - - .log.log_level = ACC_LOG_LEVEL_INFO, - .log.log = acc_integration_log, - - .optimization.transfer16 = NULL, -}; - - -const acc_hal_t *acc_hal_integration_get_implementation(void) -{ - return &hal; -} - - -bool hal_test_spi_read_chipid(uint8_t chipid[2]) -{ - const uint32_t sensor = 1; - uint8_t buffer[6] = {0x30,0x0,0x0,0x0,0x0,0x0}; - const acc_hal_t *hal = acc_hal_integration_get_implementation(); - hal->sensor_device.power_on(sensor); - hal->sensor_device.transfer(sensor,buffer,sizeof(buffer)); - hal->sensor_device.power_off(sensor); - if (buffer[4] == 0x11 && buffer[5] == 0x12) { - chipid[0] = buffer[4]; - chipid[1] = buffer[5]; - return true; - } - else - { - chipid[0] = 0x0; - chipid[1] = 0x0; - return false; - } - -} - +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved +// This file is subject to the terms and conditions defined in the file +// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part +// of this source code package. + +#include +#include +#include +#include +#include + +#include "main.h" +#include "sys_app.h" + +#include "acc_definitions_common.h" +#include "acc_hal_definitions.h" +#include "acc_hal_integration.h" +#include "acc_integration.h" +#include "acc_integration_log.h" + +#include "acc_version.h" +#include "acc_rss.h" + +enum transfer_state { + TRANSFER_COMPLETE = (int) 0, + TRANSFER_ERROR, + TRANSFER_READY +}; + +/* spi handle */ +extern SPI_HandleTypeDef A111_SPI_HANDLE; + +/** + * @brief The number of sensors available on the board + */ +#define SENSOR_COUNT 1 + +/** + * @brief Size of SPI transfer buffer + */ +#ifndef A111_SPI_MAX_TRANSFER_SIZE +#define A111_SPI_MAX_TRANSFER_SIZE 65535 //4096 //65535 +#endif + +/** + * @brief The reference frequency used by this board + * + * This assumes 26 MHz on the Sparkfun A111 Board + */ +//#define ACC_BOARD_REF_FREQ 26000000 +#define ACC_BOARD_REF_FREQ 24000000 + +static inline void disable_interrupts(void) +{ + __disable_irq(); +} + + +static inline void enable_interrupts(void) +{ + __enable_irq(); + __ISB(); +} + +#ifdef A111_USE_SPI_DMA +static volatile bool spi_transfer_complete; + +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) +{ + (void)hspi; + spi_transfer_complete = true; +} +#endif + + +//---------------------------------------- +// Implementation of RSS HAL handlers +//---------------------------------------- + + +static void acc_hal_integration_sensor_transfer(acc_sensor_id_t sensor_id, uint8_t *buffer, size_t buffer_size) +{ + (void)sensor_id; // Ignore parameter sensor_id + + const uint32_t SPI_TRANSMIT_RECEIVE_TIMEOUT = 5000; + + HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_RESET); + +#ifdef A111_USE_SPI_DMA + spi_transfer_complete = false; + HAL_StatusTypeDef status = HAL_SPI_TransmitReceive_DMA(&A111_SPI_HANDLE, buffer, buffer, buffer_size); + + if (status != HAL_OK) + { + return; + } + + uint32_t start = HAL_GetTick(); + + while (!spi_transfer_complete && (HAL_GetTick() - start) < SPI_TRANSMIT_RECEIVE_TIMEOUT) + { + // Turn off interrupts + disable_interrupts(); + // Check once more so that the interrupt have not occurred + if (!spi_transfer_complete) + { + __WFI(); + } + + // Enable interrupt again, the ISR will execute directly after this + enable_interrupts(); + } +#else + HAL_SPI_TransmitReceive(&A111_SPI_HANDLE, buffer, buffer, buffer_size, SPI_TRANSMIT_RECEIVE_TIMEOUT); +#endif + + HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_SET); +} + + +static void acc_hal_integration_sensor_power_on(acc_sensor_id_t sensor_id) +{ + (void)sensor_id; // Ignore parameter sensor_id + HAL_GPIO_WritePin(A111_ENABLE_GPIO_Port, A111_ENABLE_Pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_SET); + + // Wait 2 ms to make sure that the sensor crystal have time to stabilize + HAL_Delay(2); +} + + +static void acc_hal_integration_sensor_power_off(acc_sensor_id_t sensor_id) +{ + (void)sensor_id; // Ignore parameter sensor_id + + HAL_GPIO_WritePin(A111_CS_N_GPIO_Port, A111_CS_N_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(A111_ENABLE_GPIO_Port, A111_ENABLE_Pin, GPIO_PIN_RESET); + + // Wait after power off to leave the sensor in a known state + // in case the application intends to enable the sensor directly + HAL_Delay(2); +} + + +static bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms) +{ + (void)sensor_id; // Ignore parameter sensor_id + + const uint32_t wait_begin_ms = HAL_GetTick(); + while ((HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) != GPIO_PIN_SET) && + (HAL_GetTick() - wait_begin_ms < timeout_ms)) + { + // Wait for the GPIO interrupt + disable_interrupts(); + // Check again so that IRQ did not occur + if (HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) != GPIO_PIN_SET) + { + __WFI(); + } + + // Enable interrupts again to allow pending interrupt to be handled + enable_interrupts(); + } + + return HAL_GPIO_ReadPin(A111_SENSOR_INTERRUPT_GPIO_Port, A111_SENSOR_INTERRUPT_Pin) == GPIO_PIN_SET; +} + + +static float acc_hal_integration_get_reference_frequency(void) +{ + return ACC_BOARD_REF_FREQ; +} + + +static const acc_hal_t hal = +{ + .properties.sensor_count = SENSOR_COUNT, + .properties.max_spi_transfer_size = A111_SPI_MAX_TRANSFER_SIZE, + + .sensor_device.power_on = acc_hal_integration_sensor_power_on, + .sensor_device.power_off = acc_hal_integration_sensor_power_off, + .sensor_device.wait_for_interrupt = acc_hal_integration_wait_for_sensor_interrupt, + .sensor_device.transfer = acc_hal_integration_sensor_transfer, + .sensor_device.get_reference_frequency = acc_hal_integration_get_reference_frequency, + + .os.mem_alloc = malloc, + .os.mem_free = free, + .os.gettime = acc_integration_get_time, + + .log.log_level = ACC_LOG_LEVEL_INFO, + .log.log = acc_integration_log, + + .optimization.transfer16 = NULL, +}; + + +const acc_hal_t *acc_hal_integration_get_implementation(void) +{ + return &hal; +} + + +bool hal_test_spi_read_chipid(uint8_t chipid[2]) +{ + const uint32_t sensor = 1; + uint8_t buffer[6] = {0x30,0x0,0x0,0x0,0x0,0x0}; + const acc_hal_t *hal = acc_hal_integration_get_implementation(); + hal->sensor_device.power_on(sensor); + hal->sensor_device.transfer(sensor,buffer,sizeof(buffer)); + hal->sensor_device.power_off(sensor); + if (buffer[4] == 0x11 && buffer[5] == 0x12) { + chipid[0] = buffer[4]; + chipid[1] = buffer[5]; + return true; + } + else + { + chipid[0] = 0x0; + chipid[1] = 0x0; + return false; + } + +} + diff --git a/Core/Src/acc_integration_log.c b/Core/Src/acc_integration_log.c index 7b77b7b..8f98521 100644 --- a/Core/Src/acc_integration_log.c +++ b/Core/Src/acc_integration_log.c @@ -1,54 +1,54 @@ -// Copyright (c) Acconeer AB, 2019-2022 -// All rights reserved -// This file is subject to the terms and conditions defined in the file -// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part -// of this source code package. - -#include -#include -#include -#include - -#include "acc_definitions_common.h" -#include "acc_integration.h" -#include "acc_integration_log.h" - -#define LOG_BUFFER_MAX_SIZE 150 - -#define LOG_FORMAT "%02u:%02u:%02u.%03u (%c) (%s) %s\n" - - -void acc_integration_log(acc_log_level_t level, const char *module, const char *format, ...) -{ - char log_buffer[LOG_BUFFER_MAX_SIZE]; - va_list ap; - - va_start(ap, format); - - int ret = vsnprintf(log_buffer, LOG_BUFFER_MAX_SIZE, format, ap); - - if (ret >= LOG_BUFFER_MAX_SIZE) - { - log_buffer[LOG_BUFFER_MAX_SIZE - 4] = '.'; - log_buffer[LOG_BUFFER_MAX_SIZE - 3] = '.'; - log_buffer[LOG_BUFFER_MAX_SIZE - 2] = '.'; - log_buffer[LOG_BUFFER_MAX_SIZE - 1] = 0; - } - - uint32_t time_ms = acc_integration_get_time(); - char level_ch; - - unsigned int timestamp = time_ms; - unsigned int hours = timestamp / 1000 / 60 / 60; - unsigned int minutes = timestamp / 1000 / 60 % 60; - unsigned int seconds = timestamp / 1000 % 60; - unsigned int milliseconds = timestamp % 1000; - - level_ch = (level <= ACC_LOG_LEVEL_DEBUG) ? "EWIVD"[level] : '?'; - - printf(LOG_FORMAT, hours, minutes, seconds, milliseconds, level_ch, module, log_buffer); - - fflush(stdout); - - va_end(ap); -} +// Copyright (c) Acconeer AB, 2019-2022 +// All rights reserved +// This file is subject to the terms and conditions defined in the file +// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part +// of this source code package. + +#include +#include +#include +#include + +#include "acc_definitions_common.h" +#include "acc_integration.h" +#include "acc_integration_log.h" + +#define LOG_BUFFER_MAX_SIZE 150 + +#define LOG_FORMAT "%02u:%02u:%02u.%03u (%c) (%s) %s\n" + + +void acc_integration_log(acc_log_level_t level, const char *module, const char *format, ...) +{ + char log_buffer[LOG_BUFFER_MAX_SIZE]; + va_list ap; + + va_start(ap, format); + + int ret = vsnprintf(log_buffer, LOG_BUFFER_MAX_SIZE, format, ap); + + if (ret >= LOG_BUFFER_MAX_SIZE) + { + log_buffer[LOG_BUFFER_MAX_SIZE - 4] = '.'; + log_buffer[LOG_BUFFER_MAX_SIZE - 3] = '.'; + log_buffer[LOG_BUFFER_MAX_SIZE - 2] = '.'; + log_buffer[LOG_BUFFER_MAX_SIZE - 1] = 0; + } + + uint32_t time_ms = acc_integration_get_time(); + char level_ch; + + unsigned int timestamp = time_ms; + unsigned int hours = timestamp / 1000 / 60 / 60; + unsigned int minutes = timestamp / 1000 / 60 % 60; + unsigned int seconds = timestamp / 1000 % 60; + unsigned int milliseconds = timestamp % 1000; + + level_ch = (level <= ACC_LOG_LEVEL_DEBUG) ? "EWIVD"[level] : '?'; + + printf(LOG_FORMAT, hours, minutes, seconds, milliseconds, level_ch, module, log_buffer); + + fflush(stdout); + + va_end(ap); +} diff --git a/Core/Src/acc_integration_stm32.c b/Core/Src/acc_integration_stm32.c index ca11e3c..027ccc6 100644 --- a/Core/Src/acc_integration_stm32.c +++ b/Core/Src/acc_integration_stm32.c @@ -1,45 +1,45 @@ -// Copyright (c) Acconeer AB, 2019-2022 -// All rights reserved -// This file is subject to the terms and conditions defined in the file -// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part -// of this source code package. - -#include -#include -#include - -#include "main.h" - -#include "acc_integration.h" - - -void acc_integration_sleep_ms(uint32_t time_msec) -{ - HAL_Delay(time_msec); -} - - -void acc_integration_sleep_us(uint32_t time_usec) -{ - uint32_t time_msec = (time_usec / 1000) + 1; - - HAL_Delay(time_msec); -} - - -uint32_t acc_integration_get_time(void) -{ - return HAL_GetTick(); -} - - -void *acc_integration_mem_alloc(size_t size) -{ - return malloc(size); -} - - -void acc_integration_mem_free(void *ptr) -{ - free(ptr); -} +// Copyright (c) Acconeer AB, 2019-2022 +// All rights reserved +// This file is subject to the terms and conditions defined in the file +// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part +// of this source code package. + +#include +#include +#include + +#include "main.h" + +#include "acc_integration.h" + + +void acc_integration_sleep_ms(uint32_t time_msec) +{ + HAL_Delay(time_msec); +} + + +void acc_integration_sleep_us(uint32_t time_usec) +{ + uint32_t time_msec = (time_usec / 1000) + 1; + + HAL_Delay(time_msec); +} + + +uint32_t acc_integration_get_time(void) +{ + return HAL_GetTick(); +} + + +void *acc_integration_mem_alloc(size_t size) +{ + return malloc(size); +} + + +void acc_integration_mem_free(void *ptr) +{ + free(ptr); +} diff --git a/Core/Src/sts_lamp_bar.c b/Core/Src/sts_lamp_bar.c index d17a762..1d97a00 100644 --- a/Core/Src/sts_lamp_bar.c +++ b/Core/Src/sts_lamp_bar.c @@ -1,624 +1,624 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file yunhorn_sts_lamp_bar.c * - * @author Yunhorn (r) Technology Limited Application Team * - * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 Yunhorn Technology Limited. - * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ -#include "main.h" -#include "dma.h" -#include "tim.h" -#include "string.h" -#include "sys_app.h" -#include "stm32_systime.h" -#include "sts_lamp_bar.h" - -#include "yunhorn_sts_sensors.h" - -#define ONE_PULSE (36) -#define ZERO_PULSE (20) - -#define LED_DATA_LEN (24) -#define WS2812B_DATA_LEN (LED_DATA_LEN * (STS_LAMP_BAR_LED_NUM+4)) -#define DEFAULT_LUMINANCE_LEVEL (20) -#define RESET_PULSE (10) //(80) TO FIX DARK_COLOR AND SM2 - - -typedef struct ws2812b_e { - uint16_t head[3]; - uint16_t GRB[24*STS_LAMP_BAR_LED_NUM]; - uint16_t tail; -} WS2812B_FrameTypeDef; - -volatile WS2812B_FrameTypeDef rgb_buf = { - .head[0] = 0, - .head[1] = 0, - .head[2] = 0, - .tail = 0 -}; - -uint8_t color_rgb[8][3] = { //STS_COLOR R G B MAPPING TABLE - {0,0,0},{0,1,0},{1,0,0},{0,0,1},{1,1,0},{1,0,1},{0,1,1},{1,1,1} -}; -volatile uint8_t sts_service_mask; -volatile uint8_t sts_work_mode = STS_DUAL_MODE; -volatile uint8_t sts_reed_hall_ext_int = 0; -volatile uint8_t sts_status_color = STS_DARK; -volatile uint8_t sts_lamp_bar_color = STS_GREEN; //puColor -volatile uint8_t sts_cloud_netcolor = STS_GREEN; //netColor -volatile uint8_t sts_occupancy_status; -volatile uint8_t sts_reed_hall_changed_flag = 1; -volatile uint8_t sts_reed_hall_result =0; -volatile uint8_t sts_tof_result_changed_flag = 0; -volatile uint8_t sts_water_leakage_result=0; -volatile uint8_t sts_water_leakage_changed_flag=0; - -volatile uint8_t sts_rss_result_changed_flag = 0; -volatile uint8_t sts_rss_result = STS_RESULT_NO_MOTION; -volatile uint8_t sts_rss_2nd_result = STS_RESULT_NO_MOTION; //2nd RSS sensor status -volatile uint8_t sts_tof_result = STS_RESULT_NO_MOTION; -volatile uint8_t last_sts_rss_result; -volatile uint8_t last_sts_reed_hall_result = 2; //Initial state, not 0, not 1 -volatile uint8_t last_lamp_bar_color; -extern volatile uint8_t sts_presence_fall_detection; -extern volatile float sts_presence_rss_distance; -extern volatile uint8_t sensor_data_ready; -extern SysTime_t mems_event_time; -extern volatile uint32_t event_start_time, event_stop_time; -uint8_t luminance_level = DEFAULT_LUMINANCE_LEVEL; - - -void STS_YunhornSTSEventP1_Process(void) -{ - STS_Lamp_Bar_Refresh(); - if ((sts_work_mode == STS_WIRED_MODE) || (sts_work_mode == STS_REEDSWITCH_MODE) || (sts_work_mode == STS_DUAL_MODE)) - { - STS_Reed_Hall_Presence_Detection(); - - if (sts_reed_hall_result == last_sts_reed_hall_result) { - sts_reed_hall_changed_flag = 0; - } else { - sts_reed_hall_changed_flag = 1; - STS_Combined_Status_Processing(); - } - - last_sts_reed_hall_result = sts_reed_hall_result; - } - -} - -void STS_YunhornSTSEventP2_Process(void) -{ - STS_Lamp_Bar_Refresh(); - if ((sts_work_mode >= STS_RSS_MODE) && (sts_work_mode <= STS_TOF_RSS_MODE)) - { - STS_RSS_Smart_Presence_Detection(); - STS_Reed_Hall_Presence_Detection(); - - if (sts_rss_result == last_sts_rss_result) { - sts_rss_result_changed_flag =0; - } else { - sts_rss_result_changed_flag =1; - last_sts_rss_result = sts_rss_result; - } - - if (sts_reed_hall_result == last_sts_reed_hall_result) - { - sts_reed_hall_changed_flag = 0; - - } else - { - sts_reed_hall_changed_flag = 1; - } - if (sts_service_mask > 0 ) { - sts_rss_result_changed_flag =0; - sts_reed_hall_changed_flag = 0; - } - - STS_Combined_Status_Processing(); - - last_sts_rss_result = sts_rss_result; - last_sts_reed_hall_result = sts_reed_hall_result; - } - -} - -void STS_Reed_Hall_Presence_Detection(void) -{ -// HAL_Delay(50); // BOUNCING ELIMIATION - - if (STS_Reed_Hall_State == STS_Status_Door_Open) - { - sts_reed_hall_result = STS_Status_Door_Open; - - } else if (STS_Reed_Hall_State == STS_Status_Door_Close) - { - sts_reed_hall_result = STS_Status_Door_Close; - - } - - //sts_reed_hall_result = ((STS_Reed_Hall_State)&STS_Status_Door_Open); - -// HAL_Delay(20); // BOUNCING ELIMIATION - - sts_reed_hall_changed_flag = 0; - - sts_reed_hall_ext_int = 0; - -} - -void STS_RSS_Smart_Presence_Detection(void) -{ - STS_Lamp_Bar_Refresh(); - - //sts_presence_rss_presence_detection(); - - sts_presence_rss_fall_rise_detection(); - -// if (sts_presence_fall_detection) { -// STS_YunhornSTSFallDetection(); -// } - -} - -/* - * STS P3 process, Lamp Bar Scoller - */ -void STS_YunhornSTSEventP3_Process(void) -{ - STS_Lamp_Bar_Refresh(); - if (STS_Reed_Hall_State == STS_Status_Door_Open) - { - sts_lamp_bar_color =STS_GREEN; - } - else - { - sts_lamp_bar_color =STS_RED; - } - STS_Lamp_Bar_Scoller(sts_lamp_bar_color, luminance_level); -} - -/* - * STS SOAP Level detection Process, STS_CAP_Sensor_Detection Process - * STS_CAP_SWITCH(ON) Boost Voltage to 5V, then hold for 1000 ms - * HAL_Delay(1000) (ms) - * STS_CAP_Read_Data() Read STS_CAP_DATA state - * STS_CAP_SWITCH(OFF) Switch Off Boosted Voltage - */ -void STS_YunhornSTSEventP4_Process(void) -{ - - APP_LOG(TS_OFF, VLEVEL_L, "\r\n P4 Testing Process\r\n"); - -} - -/* - * STS P5 Process, Detection ToF distance (VL53L0X) - * - */ - -void STS_YunhornSTSEventP5_Process(void) -{ - APP_LOG(TS_OFF, VLEVEL_L, "\r\n P5 Testing Process\r\n"); -} - -/* - * STS P6 Process, Detection ToF IN-OUT PEOPLE COUNT (VL53L3X) - * - */ - -void STS_YunhornSTSEventP6_Process(void) -{ - APP_LOG(TS_OFF, VLEVEL_L, "\r\n P6 Testing Process\r\n"); -} - - -/* - * STS P7 Process, Detection IAQ Sensors - * air quality and odor level sensors - */ - -void STS_YunhornSTSEventP7_Process(void) -{ - APP_LOG(TS_OFF, VLEVEL_L, "\r\n P7 Testing Process\r\n"); -} - - -/* - * STS P8 Process, Detection xxx Sensors - * xxx sensors - */ - -void STS_YunhornSTSEventP8_Process(void) -{ - APP_LOG(TS_OFF, VLEVEL_L, "\r\n P8 Testing Process\r\n"); -} - - -void STS_Lamp_Bar_Set_Dark(void) -{ - for (uint8_t i=0; i< STS_LAMP_BAR_LED_NUM; i++) - { - STS_WS2812B_Set_RGB(0x00,0x00,0x00,i); - } - //STS_WS2812B_Refresh(); -} - -void STS_WS2812B_Refresh(void) -{ - HAL_TIM_PWM_Start_DMA(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL, (uint32_t *)&rgb_buf, (RESET_PULSE+WS2812B_DATA_LEN+1)); - - //HAL_TIM_PWM_Start_IT(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL); -} - -void STS_Lamp_Bar_Init(void) -{ - if (sts_service_mask == STS_SERVICE_MASK_L0) - { - STS_Lamp_Bar_Set_STS_RGB_Color(STS_GREEN, luminance_level); - //STS_WS2812B_Refresh(); - HAL_Delay(200); - STS_Lamp_Bar_Set_STS_RGB_Color(STS_RED, luminance_level); - //STS_WS2812B_Refresh(); - HAL_Delay(200); - STS_Lamp_Bar_Set_STS_RGB_Color(STS_BLUE, luminance_level); - //STS_WS2812B_Refresh(); - HAL_Delay(200); - } -} - -//marquee scoller -void STS_Lamp_Bar_Scoller(uint8_t color, uint8_t luminance_level) -{ - STS_Lamp_Bar_Set_Dark(); - - for(uint8_t i = 0; i<(STS_LAMP_BAR_LED_NUM+1); i++) - { - //if (sts_service_mask < STS_SERVICE_MASK_L1) - // STS_WS2812B_Refresh(); - HAL_Delay(60); - if (i < STS_LAMP_BAR_LED_NUM) { - STS_WS2812B_Set_RGB(color_rgb[color][0]*luminance_level,color_rgb[color][1]*luminance_level, color_rgb[color][2]*luminance_level, i); - } - } - HAL_Delay(10); - - //if (sts_service_mask == STS_SERVICE_MASK_L0) { - // STS_WS2812B_Refresh(); - //} - -} - - -void STS_WS2812B_Set_RGB(uint8_t R, uint8_t G, uint8_t B, uint8_t idx) -{ - if (idx < STS_LAMP_BAR_LED_NUM) - { - for (uint8_t j = 0; j < 8; j ++) - { - rgb_buf.GRB[idx*24+j] = (G&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; - rgb_buf.GRB[idx*24+8+j] = (R&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; - rgb_buf.GRB[idx*24+16+j] = (B&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; - } - } - // CHANGED AT 2023-05-10 - if (sts_service_mask == STS_SERVICE_MASK_L0) { - STS_WS2812B_Refresh(); - } -} - -void STS_Lamp_Bar_Set_RGB_Color(uint8_t red, uint8_t green, uint8_t blue ) -{ - HAL_Delay(1); - for(uint8_t i = 0; i < STS_LAMP_BAR_LED_NUM; i++) - { - for (uint8_t j = 0; j < 8; j ++) - { - rgb_buf.GRB[i*24+j] = (green&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; - rgb_buf.GRB[i*24+8+j] = (red&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; - rgb_buf.GRB[i*24+16+j] = (blue&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; - } - } - if (sts_service_mask == STS_SERVICE_MASK_L0) { - STS_WS2812B_Refresh(); - } - -} - - -void STS_Lamp_Bar_Refresh(void) -{ - STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); -} -void STS_Lamp_Bar_Set_STS_RGB_Color(uint8_t sts_lamp_color, uint8_t luminance_level) -{ - uint8_t lum = luminance_level; - - STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, 0x0); - switch (sts_lamp_color) - { - case STS_DARK: - STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, 0x0); - break; - case STS_GREEN: - STS_Lamp_Bar_Set_RGB_Color(0x0, lum, 0x0); - break; - case STS_RED: - STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, 0x0); - break; - case STS_BLUE: - STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, lum); - break; - case STS_YELLOW: - STS_Lamp_Bar_Set_RGB_Color(lum, lum, 0x0); - break; - case STS_PINK: - STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, lum); - break; - case STS_CYAN: - STS_Lamp_Bar_Set_RGB_Color(0x0, lum, lum); - break; - case STS_WHITE: - STS_Lamp_Bar_Set_RGB_Color(lum, lum, lum); - break; - case STS_RED_BLUE: - STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, 0x0); - HAL_Delay(300); - STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, lum); - HAL_Delay(300); - break; - } -} - -void STS_Reed_Hall_Working(void) -{ - -} -void STS_Combined_Status_Processing(void) -{ - mems_event_time = SysTimeGetMcuTime(); - - if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close) || (sts_tof_result == STS_RESULT_PRESENCE)) - { - - if (event_start_time == 0) { - - event_start_time = mems_event_time.Seconds; - event_stop_time = 0; - - APP_LOG(TS_OFF, VLEVEL_L, "\r\n Event Started at %6u Seconds \r\n", event_start_time); - } - - - } else if ((sts_rss_result != STS_RESULT_MOTION) || (sts_reed_hall_result != STS_Status_Door_Close) || (sts_tof_result != STS_RESULT_PRESENCE)) - { - if (event_stop_time ==0) - { - event_stop_time = mems_event_time.Seconds; - - event_start_time = 0; - - APP_LOG(TS_OFF, VLEVEL_L, "\r\n Event Stop at %6u Seconds \r\n", event_stop_time); - } - } - - switch (sts_work_mode) - { - case STS_NETWORK_MODE: - sts_status_color = sts_cloud_netcolor; - break; - case STS_WIRED_MODE: // NO LAMP BAR FOR THOSE WATER LEAKAGE SENSOR OR SOAP CAPACITY SENSORS - sts_status_color = STS_DARK; - sts_water_leakage_result = (sts_reed_hall_result == STS_Status_Door_Open )?STS_RESULT_WATER_LEAKAGE_YES:STS_RESULT_WATER_LEAKAGE_NO; - sts_water_leakage_changed_flag = 1; - break; - case STS_REEDSWITCH_MODE: - - sts_status_color = (sts_reed_hall_result == STS_Status_Door_Open )? STS_GREEN: STS_RED; - - break; - case STS_RSS_MODE: - if (sts_rss_result == STS_RESULT_NO_MOTION){ - sts_status_color = STS_GREEN; - } else if ((sts_rss_result == STS_RESULT_MOTION)) - { - sts_status_color = STS_RED; - } - break; - case STS_DUAL_MODE: - if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_result == STS_Status_Door_Open )) - { - sts_status_color = STS_GREEN; - - } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close )) - { - sts_status_color = STS_RED; - } - break; - case STS_REMOTE_REED_RSS_MODE: - if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_result == STS_Status_Door_Open )) - { - sts_status_color = STS_GREEN; - - } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close )) - { - sts_status_color = STS_RED; - } - break; - case STS_DUAL_RSS_MODE: - if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_rss_2nd_result == STS_RESULT_NO_MOTION)) - { - sts_status_color = STS_GREEN; - } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_rss_2nd_result == STS_RESULT_MOTION)) - { - sts_status_color = STS_RED; - } - - break; - case STS_TOF_RSS_MODE: - if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_tof_result == STS_RESULT_NO_PRESENCE)){ - sts_status_color = STS_GREEN; - - } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_tof_result == STS_RESULT_PRESENCE)) - { - sts_status_color = STS_RED; - } - - break; -// TO-DO LIST *********************************************************** - case STS_TOF_DISTANCE_MODE: - if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { - sts_status_color = STS_GREEN; - } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { - sts_status_color = STS_RED; - } - break; - case STS_TOF_PRESENCE_MODE: - if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { - sts_status_color = STS_GREEN; - } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { - sts_status_color = STS_RED; - } - break; - case STS_TOF_IN_OUT_MODE: - if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { - sts_status_color = STS_GREEN; - } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { - sts_status_color = STS_RED; - } - break; -// TO-DO LIST *********************************************************** - default: - break; - } - - - if (sts_status_color == STS_RED_BLUE) - { - STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); - } - if ((sts_work_mode == STS_WIRED_MODE) || (sts_service_mask > STS_SERVICE_MASK_L0)) - { - sts_status_color = STS_DARK; - sts_lamp_bar_color = STS_DARK; - last_lamp_bar_color = STS_DARK; - STS_Lamp_Bar_Set_Dark(); - } - else - { - - //if ((last_lamp_bar_color != sts_status_color)) - { - sts_lamp_bar_color = ((sts_service_mask == STS_SERVICE_MASK_L0)? sts_status_color:STS_DARK); - - STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); - - if ((sts_service_mask == STS_SERVICE_MASK_L0) || (sts_lamp_bar_color == STS_DARK)) - { - // STS_WS2812B_Refresh(); - } - - last_lamp_bar_color = sts_lamp_bar_color; - } - } - - if ((sts_rss_result_changed_flag)|| (sts_reed_hall_changed_flag) || (sts_tof_result_changed_flag) || (sts_water_leakage_changed_flag)) - { - sensor_data_ready = 1; - STS_PRESENCE_SENSOR_Prepare_Send_Data(); - sts_rss_result_changed_flag =0; - sts_reed_hall_changed_flag =0; - sts_tof_result_changed_flag =0; - sts_water_leakage_changed_flag=0; - } -} - -void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) -{ - __HAL_TIM_SetCompare(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL,0); - HAL_TIM_PWM_Stop_DMA(&STS_LAMP_BAR_HTIM,STS_LAMP_BAR_TIM_CHANNEL); - -} - -void STS_Lamp_Bar_Self_Test_Simple(void) -{ - uint8_t color=0, luminance_level=10; - APP_LOG(TS_OFF, VLEVEL_M, "\r\n [#1] RGB Space Lumianance Level Testing Start\r\n"); - for (color=STS_GREEN; color <= STS_RED_BLUE; color++) - { - luminance_level = 10; - do { - STS_Lamp_Bar_Set_STS_RGB_Color(color, luminance_level); - HAL_Delay(10); - luminance_level += 20; - } while (luminance_level < 99); - //STS_Lamp_Bar_Set_Dark(); - } - APP_LOG(TS_OFF, VLEVEL_M, "\r\n [#1] RGB Space Lumianance Level Testing Finished\r\n"); -} -void STS_Lamp_Bar_Self_Test(void) -{ - uint8_t color=0, luminance_level=10; - - APP_LOG(TS_OFF, VLEVEL_M, "\r\n YunHorn STS Indicative Lamp Self Test\r\n"); - - STS_Lamp_Bar_Self_Test_Simple(); - - APP_LOG(TS_OFF, VLEVEL_H, "\r\n [#2] Scoller Testing\r\n"); - for (color = STS_GREEN; color <= STS_RED_BLUE; color++) - { - STS_Lamp_Bar_Scoller(color, luminance_level); - } - STS_Lamp_Bar_Set_Dark(); - - APP_LOG(TS_OFF, VLEVEL_M, "\r\n [##] YunHorn STS Indicative Lamp Self Test Finished\r\n"); - if ((sts_work_mode == STS_WIRED_MODE) ) - { - STS_Lamp_Bar_Set_Dark(); - } else - { - STS_Lamp_Bar_Set_STS_RGB_Color(STS_GREEN, luminance_level); - } - - -} -void sts_rgb_unit_test(void) -{ - - APP_LOG(TS_OFF, VLEVEL_L, "\r\n STS Lamp Bar Init...\r\n"); - - STS_Lamp_Bar_Set_Dark(); - - STS_Lamp_Bar_Full_Color_Gradient(); - - STS_Lamp_Bar_Self_Test(); - - do { - for (uint8_t i=0; i<9; i++) - { - APP_LOG(TS_OFF, VLEVEL_L, "\r\n STS Lamp Bar color = %d...\r\n", i); - - STS_Lamp_Bar_Set_STS_RGB_Color(i, luminance_level); - STS_Combined_Status_Processing(); - HAL_Delay(6000); - STS_Lamp_Bar_Set_Dark(); - } - } while(1); - - - -} - +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file yunhorn_sts_lamp_bar.c * + * @author Yunhorn (r) Technology Limited Application Team * + * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 Yunhorn Technology Limited. + * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +#include "main.h" +#include "dma.h" +#include "tim.h" +#include "string.h" +#include "sys_app.h" +#include "stm32_systime.h" +#include "sts_lamp_bar.h" + +#include "yunhorn_sts_sensors.h" + +#define ONE_PULSE (36) +#define ZERO_PULSE (20) + +#define LED_DATA_LEN (24) +#define WS2812B_DATA_LEN (LED_DATA_LEN * (STS_LAMP_BAR_LED_NUM+4)) +#define DEFAULT_LUMINANCE_LEVEL (20) +#define RESET_PULSE (10) //(80) TO FIX DARK_COLOR AND SM2 + + +typedef struct ws2812b_e { + uint16_t head[3]; + uint16_t GRB[24*STS_LAMP_BAR_LED_NUM]; + uint16_t tail; +} WS2812B_FrameTypeDef; + +volatile WS2812B_FrameTypeDef rgb_buf = { + .head[0] = 0, + .head[1] = 0, + .head[2] = 0, + .tail = 0 +}; + +uint8_t color_rgb[8][3] = { //STS_COLOR R G B MAPPING TABLE + {0,0,0},{0,1,0},{1,0,0},{0,0,1},{1,1,0},{1,0,1},{0,1,1},{1,1,1} +}; +volatile uint8_t sts_service_mask; +volatile uint8_t sts_work_mode = STS_DUAL_MODE; +volatile uint8_t sts_reed_hall_ext_int = 0; +volatile uint8_t sts_status_color = STS_DARK; +volatile uint8_t sts_lamp_bar_color = STS_GREEN; //puColor +volatile uint8_t sts_cloud_netcolor = STS_GREEN; //netColor +volatile uint8_t sts_occupancy_status; +volatile uint8_t sts_reed_hall_changed_flag = 1; +volatile uint8_t sts_reed_hall_result =0; +volatile uint8_t sts_tof_result_changed_flag = 0; +volatile uint8_t sts_water_leakage_result=0; +volatile uint8_t sts_water_leakage_changed_flag=0; + +volatile uint8_t sts_rss_result_changed_flag = 0; +volatile uint8_t sts_rss_result = STS_RESULT_NO_MOTION; +volatile uint8_t sts_rss_2nd_result = STS_RESULT_NO_MOTION; //2nd RSS sensor status +volatile uint8_t sts_tof_result = STS_RESULT_NO_MOTION; +volatile uint8_t last_sts_rss_result; +volatile uint8_t last_sts_reed_hall_result = 2; //Initial state, not 0, not 1 +volatile uint8_t last_lamp_bar_color; +extern volatile uint8_t sts_presence_fall_detection; +extern volatile float sts_presence_rss_distance; +extern volatile uint8_t sensor_data_ready; +extern SysTime_t mems_event_time; +extern volatile uint32_t event_start_time, event_stop_time; +uint8_t luminance_level = DEFAULT_LUMINANCE_LEVEL; + + +void STS_YunhornSTSEventP1_Process(void) +{ + STS_Lamp_Bar_Refresh(); + if ((sts_work_mode == STS_WIRED_MODE) || (sts_work_mode == STS_REEDSWITCH_MODE) || (sts_work_mode == STS_DUAL_MODE)) + { + STS_Reed_Hall_Presence_Detection(); + + if (sts_reed_hall_result == last_sts_reed_hall_result) { + sts_reed_hall_changed_flag = 0; + } else { + sts_reed_hall_changed_flag = 1; + STS_Combined_Status_Processing(); + } + + last_sts_reed_hall_result = sts_reed_hall_result; + } + +} + +void STS_YunhornSTSEventP2_Process(void) +{ + STS_Lamp_Bar_Refresh(); + if ((sts_work_mode >= STS_RSS_MODE) && (sts_work_mode <= STS_TOF_RSS_MODE)) + { + STS_RSS_Smart_Presence_Detection(); + STS_Reed_Hall_Presence_Detection(); + + if (sts_rss_result == last_sts_rss_result) { + sts_rss_result_changed_flag =0; + } else { + sts_rss_result_changed_flag =1; + last_sts_rss_result = sts_rss_result; + } + + if (sts_reed_hall_result == last_sts_reed_hall_result) + { + sts_reed_hall_changed_flag = 0; + + } else + { + sts_reed_hall_changed_flag = 1; + } + if (sts_service_mask > 0 ) { + sts_rss_result_changed_flag =0; + sts_reed_hall_changed_flag = 0; + } + + STS_Combined_Status_Processing(); + + last_sts_rss_result = sts_rss_result; + last_sts_reed_hall_result = sts_reed_hall_result; + } + +} + +void STS_Reed_Hall_Presence_Detection(void) +{ +// HAL_Delay(50); // BOUNCING ELIMIATION + + if (STS_Reed_Hall_State == STS_Status_Door_Open) + { + sts_reed_hall_result = STS_Status_Door_Open; + + } else if (STS_Reed_Hall_State == STS_Status_Door_Close) + { + sts_reed_hall_result = STS_Status_Door_Close; + + } + + //sts_reed_hall_result = ((STS_Reed_Hall_State)&STS_Status_Door_Open); + +// HAL_Delay(20); // BOUNCING ELIMIATION + + sts_reed_hall_changed_flag = 0; + + sts_reed_hall_ext_int = 0; + +} + +void STS_RSS_Smart_Presence_Detection(void) +{ + STS_Lamp_Bar_Refresh(); + + //sts_presence_rss_presence_detection(); + + sts_presence_rss_fall_rise_detection(); + +// if (sts_presence_fall_detection) { +// STS_YunhornSTSFallDetection(); +// } + +} + +/* + * STS P3 process, Lamp Bar Scoller + */ +void STS_YunhornSTSEventP3_Process(void) +{ + STS_Lamp_Bar_Refresh(); + if (STS_Reed_Hall_State == STS_Status_Door_Open) + { + sts_lamp_bar_color =STS_GREEN; + } + else + { + sts_lamp_bar_color =STS_RED; + } + STS_Lamp_Bar_Scoller(sts_lamp_bar_color, luminance_level); +} + +/* + * STS SOAP Level detection Process, STS_CAP_Sensor_Detection Process + * STS_CAP_SWITCH(ON) Boost Voltage to 5V, then hold for 1000 ms + * HAL_Delay(1000) (ms) + * STS_CAP_Read_Data() Read STS_CAP_DATA state + * STS_CAP_SWITCH(OFF) Switch Off Boosted Voltage + */ +void STS_YunhornSTSEventP4_Process(void) +{ + + APP_LOG(TS_OFF, VLEVEL_L, "\r\n P4 Testing Process\r\n"); + +} + +/* + * STS P5 Process, Detection ToF distance (VL53L0X) + * + */ + +void STS_YunhornSTSEventP5_Process(void) +{ + APP_LOG(TS_OFF, VLEVEL_L, "\r\n P5 Testing Process\r\n"); +} + +/* + * STS P6 Process, Detection ToF IN-OUT PEOPLE COUNT (VL53L3X) + * + */ + +void STS_YunhornSTSEventP6_Process(void) +{ + APP_LOG(TS_OFF, VLEVEL_L, "\r\n P6 Testing Process\r\n"); +} + + +/* + * STS P7 Process, Detection IAQ Sensors + * air quality and odor level sensors + */ + +void STS_YunhornSTSEventP7_Process(void) +{ + APP_LOG(TS_OFF, VLEVEL_L, "\r\n P7 Testing Process\r\n"); +} + + +/* + * STS P8 Process, Detection xxx Sensors + * xxx sensors + */ + +void STS_YunhornSTSEventP8_Process(void) +{ + APP_LOG(TS_OFF, VLEVEL_L, "\r\n P8 Testing Process\r\n"); +} + + +void STS_Lamp_Bar_Set_Dark(void) +{ + for (uint8_t i=0; i< STS_LAMP_BAR_LED_NUM; i++) + { + STS_WS2812B_Set_RGB(0x00,0x00,0x00,i); + } + //STS_WS2812B_Refresh(); +} + +void STS_WS2812B_Refresh(void) +{ + HAL_TIM_PWM_Start_DMA(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL, (uint32_t *)&rgb_buf, (RESET_PULSE+WS2812B_DATA_LEN+1)); + + //HAL_TIM_PWM_Start_IT(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL); +} + +void STS_Lamp_Bar_Init(void) +{ + if (sts_service_mask == STS_SERVICE_MASK_L0) + { + STS_Lamp_Bar_Set_STS_RGB_Color(STS_GREEN, luminance_level); + //STS_WS2812B_Refresh(); + HAL_Delay(200); + STS_Lamp_Bar_Set_STS_RGB_Color(STS_RED, luminance_level); + //STS_WS2812B_Refresh(); + HAL_Delay(200); + STS_Lamp_Bar_Set_STS_RGB_Color(STS_BLUE, luminance_level); + //STS_WS2812B_Refresh(); + HAL_Delay(200); + } +} + +//marquee scoller +void STS_Lamp_Bar_Scoller(uint8_t color, uint8_t luminance_level) +{ + STS_Lamp_Bar_Set_Dark(); + + for(uint8_t i = 0; i<(STS_LAMP_BAR_LED_NUM+1); i++) + { + //if (sts_service_mask < STS_SERVICE_MASK_L1) + // STS_WS2812B_Refresh(); + HAL_Delay(60); + if (i < STS_LAMP_BAR_LED_NUM) { + STS_WS2812B_Set_RGB(color_rgb[color][0]*luminance_level,color_rgb[color][1]*luminance_level, color_rgb[color][2]*luminance_level, i); + } + } + HAL_Delay(10); + + //if (sts_service_mask == STS_SERVICE_MASK_L0) { + // STS_WS2812B_Refresh(); + //} + +} + + +void STS_WS2812B_Set_RGB(uint8_t R, uint8_t G, uint8_t B, uint8_t idx) +{ + if (idx < STS_LAMP_BAR_LED_NUM) + { + for (uint8_t j = 0; j < 8; j ++) + { + rgb_buf.GRB[idx*24+j] = (G&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; + rgb_buf.GRB[idx*24+8+j] = (R&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; + rgb_buf.GRB[idx*24+16+j] = (B&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; + } + } + // CHANGED AT 2023-05-10 + if (sts_service_mask == STS_SERVICE_MASK_L0) { + STS_WS2812B_Refresh(); + } +} + +void STS_Lamp_Bar_Set_RGB_Color(uint8_t red, uint8_t green, uint8_t blue ) +{ + HAL_Delay(1); + for(uint8_t i = 0; i < STS_LAMP_BAR_LED_NUM; i++) + { + for (uint8_t j = 0; j < 8; j ++) + { + rgb_buf.GRB[i*24+j] = (green&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; + rgb_buf.GRB[i*24+8+j] = (red&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; + rgb_buf.GRB[i*24+16+j] = (blue&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; + } + } + if (sts_service_mask == STS_SERVICE_MASK_L0) { + STS_WS2812B_Refresh(); + } + +} + + +void STS_Lamp_Bar_Refresh(void) +{ + STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); +} +void STS_Lamp_Bar_Set_STS_RGB_Color(uint8_t sts_lamp_color, uint8_t luminance_level) +{ + uint8_t lum = luminance_level; + + STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, 0x0); + switch (sts_lamp_color) + { + case STS_DARK: + STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, 0x0); + break; + case STS_GREEN: + STS_Lamp_Bar_Set_RGB_Color(0x0, lum, 0x0); + break; + case STS_RED: + STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, 0x0); + break; + case STS_BLUE: + STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, lum); + break; + case STS_YELLOW: + STS_Lamp_Bar_Set_RGB_Color(lum, lum, 0x0); + break; + case STS_PINK: + STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, lum); + break; + case STS_CYAN: + STS_Lamp_Bar_Set_RGB_Color(0x0, lum, lum); + break; + case STS_WHITE: + STS_Lamp_Bar_Set_RGB_Color(lum, lum, lum); + break; + case STS_RED_BLUE: + STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, 0x0); + HAL_Delay(300); + STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, lum); + HAL_Delay(300); + break; + } +} + +void STS_Reed_Hall_Working(void) +{ + +} +void STS_Combined_Status_Processing(void) +{ + mems_event_time = SysTimeGetMcuTime(); + + if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close) || (sts_tof_result == STS_RESULT_PRESENCE)) + { + + if (event_start_time == 0) { + + event_start_time = mems_event_time.Seconds; + event_stop_time = 0; + + APP_LOG(TS_OFF, VLEVEL_L, "\r\n Event Started at %6u Seconds \r\n", event_start_time); + } + + + } else if ((sts_rss_result != STS_RESULT_MOTION) || (sts_reed_hall_result != STS_Status_Door_Close) || (sts_tof_result != STS_RESULT_PRESENCE)) + { + if (event_stop_time ==0) + { + event_stop_time = mems_event_time.Seconds; + + event_start_time = 0; + + APP_LOG(TS_OFF, VLEVEL_L, "\r\n Event Stop at %6u Seconds \r\n", event_stop_time); + } + } + + switch (sts_work_mode) + { + case STS_NETWORK_MODE: + sts_status_color = sts_cloud_netcolor; + break; + case STS_WIRED_MODE: // NO LAMP BAR FOR THOSE WATER LEAKAGE SENSOR OR SOAP CAPACITY SENSORS + sts_status_color = STS_DARK; + sts_water_leakage_result = (sts_reed_hall_result == STS_Status_Door_Open )?STS_RESULT_WATER_LEAKAGE_YES:STS_RESULT_WATER_LEAKAGE_NO; + sts_water_leakage_changed_flag = 1; + break; + case STS_REEDSWITCH_MODE: + + sts_status_color = (sts_reed_hall_result == STS_Status_Door_Open )? STS_GREEN: STS_RED; + + break; + case STS_RSS_MODE: + if (sts_rss_result == STS_RESULT_NO_MOTION){ + sts_status_color = STS_GREEN; + } else if ((sts_rss_result == STS_RESULT_MOTION)) + { + sts_status_color = STS_RED; + } + break; + case STS_DUAL_MODE: + if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_result == STS_Status_Door_Open )) + { + sts_status_color = STS_GREEN; + + } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close )) + { + sts_status_color = STS_RED; + } + break; + case STS_REMOTE_REED_RSS_MODE: + if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_result == STS_Status_Door_Open )) + { + sts_status_color = STS_GREEN; + + } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close )) + { + sts_status_color = STS_RED; + } + break; + case STS_DUAL_RSS_MODE: + if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_rss_2nd_result == STS_RESULT_NO_MOTION)) + { + sts_status_color = STS_GREEN; + } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_rss_2nd_result == STS_RESULT_MOTION)) + { + sts_status_color = STS_RED; + } + + break; + case STS_TOF_RSS_MODE: + if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_tof_result == STS_RESULT_NO_PRESENCE)){ + sts_status_color = STS_GREEN; + + } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_tof_result == STS_RESULT_PRESENCE)) + { + sts_status_color = STS_RED; + } + + break; +// TO-DO LIST *********************************************************** + case STS_TOF_DISTANCE_MODE: + if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { + sts_status_color = STS_GREEN; + } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { + sts_status_color = STS_RED; + } + break; + case STS_TOF_PRESENCE_MODE: + if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { + sts_status_color = STS_GREEN; + } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { + sts_status_color = STS_RED; + } + break; + case STS_TOF_IN_OUT_MODE: + if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { + sts_status_color = STS_GREEN; + } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { + sts_status_color = STS_RED; + } + break; +// TO-DO LIST *********************************************************** + default: + break; + } + + + if (sts_status_color == STS_RED_BLUE) + { + STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); + } + if ((sts_work_mode == STS_WIRED_MODE) || (sts_service_mask > STS_SERVICE_MASK_L0)) + { + sts_status_color = STS_DARK; + sts_lamp_bar_color = STS_DARK; + last_lamp_bar_color = STS_DARK; + STS_Lamp_Bar_Set_Dark(); + } + else + { + + //if ((last_lamp_bar_color != sts_status_color)) + { + sts_lamp_bar_color = ((sts_service_mask == STS_SERVICE_MASK_L0)? sts_status_color:STS_DARK); + + STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); + + if ((sts_service_mask == STS_SERVICE_MASK_L0) || (sts_lamp_bar_color == STS_DARK)) + { + // STS_WS2812B_Refresh(); + } + + last_lamp_bar_color = sts_lamp_bar_color; + } + } + + if ((sts_rss_result_changed_flag)|| (sts_reed_hall_changed_flag) || (sts_tof_result_changed_flag) || (sts_water_leakage_changed_flag)) + { + sensor_data_ready = 1; + STS_PRESENCE_SENSOR_Prepare_Send_Data(); + sts_rss_result_changed_flag =0; + sts_reed_hall_changed_flag =0; + sts_tof_result_changed_flag =0; + sts_water_leakage_changed_flag=0; + } +} + +void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) +{ + __HAL_TIM_SetCompare(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL,0); + HAL_TIM_PWM_Stop_DMA(&STS_LAMP_BAR_HTIM,STS_LAMP_BAR_TIM_CHANNEL); + +} + +void STS_Lamp_Bar_Self_Test_Simple(void) +{ + uint8_t color=0, luminance_level=10; + APP_LOG(TS_OFF, VLEVEL_M, "\r\n [#1] RGB Space Lumianance Level Testing Start\r\n"); + for (color=STS_GREEN; color <= STS_RED_BLUE; color++) + { + luminance_level = 10; + do { + STS_Lamp_Bar_Set_STS_RGB_Color(color, luminance_level); + HAL_Delay(10); + luminance_level += 20; + } while (luminance_level < 99); + //STS_Lamp_Bar_Set_Dark(); + } + APP_LOG(TS_OFF, VLEVEL_M, "\r\n [#1] RGB Space Lumianance Level Testing Finished\r\n"); +} +void STS_Lamp_Bar_Self_Test(void) +{ + uint8_t color=0, luminance_level=10; + + APP_LOG(TS_OFF, VLEVEL_M, "\r\n YunHorn STS Indicative Lamp Self Test\r\n"); + + STS_Lamp_Bar_Self_Test_Simple(); + + APP_LOG(TS_OFF, VLEVEL_H, "\r\n [#2] Scoller Testing\r\n"); + for (color = STS_GREEN; color <= STS_RED_BLUE; color++) + { + STS_Lamp_Bar_Scoller(color, luminance_level); + } + STS_Lamp_Bar_Set_Dark(); + + APP_LOG(TS_OFF, VLEVEL_M, "\r\n [##] YunHorn STS Indicative Lamp Self Test Finished\r\n"); + if ((sts_work_mode == STS_WIRED_MODE) ) + { + STS_Lamp_Bar_Set_Dark(); + } else + { + STS_Lamp_Bar_Set_STS_RGB_Color(STS_GREEN, luminance_level); + } + + +} +void sts_rgb_unit_test(void) +{ + + APP_LOG(TS_OFF, VLEVEL_L, "\r\n STS Lamp Bar Init...\r\n"); + + STS_Lamp_Bar_Set_Dark(); + + STS_Lamp_Bar_Full_Color_Gradient(); + + STS_Lamp_Bar_Self_Test(); + + do { + for (uint8_t i=0; i<9; i++) + { + APP_LOG(TS_OFF, VLEVEL_L, "\r\n STS Lamp Bar color = %d...\r\n", i); + + STS_Lamp_Bar_Set_STS_RGB_Color(i, luminance_level); + STS_Combined_Status_Processing(); + HAL_Delay(6000); + STS_Lamp_Bar_Set_Dark(); + } + } while(1); + + + +} + diff --git a/Core/Src/yunhorn_sts_distance_rss.c b/Core/Src/yunhorn_sts_distance_rss.c index ed30a62..b508650 100644 --- a/Core/Src/yunhorn_sts_distance_rss.c +++ b/Core/Src/yunhorn_sts_distance_rss.c @@ -1,160 +1,160 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file yunhorn_sts_distance_rss.c * - * @author Yunhorn (r) Technology Limited Application Team * - * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 Yunhorn Technology Limited. - * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include -#include - -/* USER CODE BEGIN Includes */ -#include -#include "acc_detector_distance.h" -#include "acc_hal_definitions.h" -#include "acc_hal_integration.h" -#include "acc_rss.h" -#include "acc_version.h" -#include "sys_app.h" -#include "yunhorn_sts_prd_conf.h" -#include "yunhorn_sts_sensors.h" - -#define STS_DISTANCE_START_M (0.8f) -#define STS_DISTANCE_LENGTH_M (1.4f) -#define STS_DISTANCE_PROFILE ACC_SERVICE_PROFILE_2 -#define STS_DISTANCE_HWAAS (63) - -//volatile distance_measure_cfg_t distance_cfg={1.5, 2.0, 1, 63, 2, 10, 0.5, 1.3, 0.2}; -volatile distance_measure_cfg_t distance_cfg={1.5, 2.0, 2, 63, 2, 10, 0.5, 1.3, 0.2}; -extern float sts_distance_rss_distance; - -static void sts_distance_rss_update_configuration(acc_detector_distance_configuration_t distance_configuration); - - -static void print_distances(acc_detector_distance_result_t *result, uint16_t reflection_count); - - -int sts_distance_rss_detector_distance(void); - -int sts_distance_rss_detector_distance(void) -{ - const acc_hal_t *hal = acc_hal_integration_get_implementation(); - - if (!acc_rss_activate(hal)) - { - APP_LOG(TS_OFF, VLEVEL_M, "Failed to activate RSS\n"); - return EXIT_FAILURE; - } - - acc_rss_override_sensor_id_check_at_creation(true); - - acc_detector_distance_configuration_t distance_configuration = acc_detector_distance_configuration_create(); - - if (distance_configuration == NULL) - { - APP_LOG(TS_OFF, VLEVEL_M, "acc_detector_distance_configuration_create() failed\n"); - acc_rss_deactivate(); - return EXIT_FAILURE; - } - - sts_distance_rss_update_configuration(distance_configuration); - acc_detector_distance_handle_t distance_handle = acc_detector_distance_create(distance_configuration); - - if (distance_handle == NULL) - { - APP_LOG(TS_OFF, VLEVEL_M, "acc_detector_distance_create() failed\n"); - acc_detector_distance_configuration_destroy(&distance_configuration); - acc_rss_deactivate(); - return EXIT_FAILURE; - } - - acc_detector_distance_configuration_destroy(&distance_configuration); - - if (!acc_detector_distance_activate(distance_handle)) - { - APP_LOG(TS_OFF, VLEVEL_M, "acc_detector_distance_activate() failed\n"); - acc_detector_distance_destroy(&distance_handle); - acc_rss_deactivate(); - return EXIT_FAILURE; - } - - bool success = true; - const int iterations = 2; //5; - uint16_t number_of_peaks = 10; - acc_detector_distance_result_t result[number_of_peaks]; - acc_detector_distance_result_info_t result_info; - sts_distance_rss_distance = 0.0; - - for (int i = 0; i < iterations; i++) - { - success = acc_detector_distance_get_next(distance_handle, result, number_of_peaks, &result_info); - - if (!success) - { - APP_LOG(TS_OFF, VLEVEL_M, "acc_detector_distance_get_next() failed\n"); - break; - } - sts_distance_rss_distance += result->distance_m; - print_distances(result, result_info.number_of_peaks); - } - - sts_distance_rss_distance = 1000.0f*sts_distance_rss_distance/iterations; - - bool deactivated = acc_detector_distance_deactivate(distance_handle); - - acc_detector_distance_destroy(&distance_handle); - - acc_rss_deactivate(); - - if (deactivated && success) - { - APP_LOG(TS_OFF, VLEVEL_H, "Application finished OK\n"); - return EXIT_SUCCESS; - } - - return EXIT_FAILURE; -} - -static void sts_distance_rss_update_configuration(acc_detector_distance_configuration_t distance_configuration) -{ - acc_detector_distance_configuration_requested_start_set(distance_configuration, distance_cfg.start_m); - acc_detector_distance_configuration_requested_length_set(distance_configuration, distance_cfg.length_m); - acc_detector_distance_configuration_service_profile_set(distance_configuration, distance_cfg.acc_profile); - acc_detector_distance_configuration_hw_accelerated_average_samples_set(distance_configuration, distance_cfg.hwaas); - - acc_detector_distance_configuration_threshold_sensitivity_set(distance_configuration, distance_cfg.threshold); - acc_detector_distance_configuration_sweep_averaging_set(distance_configuration,distance_cfg.sweep_average); - acc_detector_distance_configuration_receiver_gain_set(distance_configuration,distance_cfg.gain); - acc_detector_distance_configuration_downsampling_factor_set(distance_configuration, distance_cfg.downsampling); - - acc_detector_distance_configuration_threshold_type_set(distance_configuration, ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_CFAR); - acc_detector_distance_configuration_record_background_sweeps_set(distance_configuration, 16); - -} - - -static void print_distances(acc_detector_distance_result_t *result, uint16_t reflection_count) -{ - APP_LOG(TS_OFF, VLEVEL_M, "Found %u peaks:\n", (unsigned int)reflection_count); - - for (uint16_t i = 0; i < reflection_count; i++) - { - APP_LOG(TS_OFF, VLEVEL_M, "Amplitude %u at %u mm\n", (unsigned int)result[i].amplitude, - (unsigned int)(result[i].distance_m * 1000)); - } -} +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file yunhorn_sts_distance_rss.c * + * @author Yunhorn (r) Technology Limited Application Team * + * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 Yunhorn Technology Limited. + * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include + +/* USER CODE BEGIN Includes */ +#include +#include "acc_detector_distance.h" +#include "acc_hal_definitions.h" +#include "acc_hal_integration.h" +#include "acc_rss.h" +#include "acc_version.h" +#include "sys_app.h" +#include "yunhorn_sts_prd_conf.h" +#include "yunhorn_sts_sensors.h" + +#define STS_DISTANCE_START_M (0.8f) +#define STS_DISTANCE_LENGTH_M (1.4f) +#define STS_DISTANCE_PROFILE ACC_SERVICE_PROFILE_2 +#define STS_DISTANCE_HWAAS (63) + +//volatile distance_measure_cfg_t distance_cfg={1.5, 2.0, 1, 63, 2, 10, 0.5, 1.3, 0.2}; +volatile distance_measure_cfg_t distance_cfg={1.5, 2.0, 2, 63, 2, 10, 0.5, 1.3, 0.2}; +extern float sts_distance_rss_distance; + +static void sts_distance_rss_update_configuration(acc_detector_distance_configuration_t distance_configuration); + + +static void print_distances(acc_detector_distance_result_t *result, uint16_t reflection_count); + + +int sts_distance_rss_detector_distance(void); + +int sts_distance_rss_detector_distance(void) +{ + const acc_hal_t *hal = acc_hal_integration_get_implementation(); + + if (!acc_rss_activate(hal)) + { + APP_LOG(TS_OFF, VLEVEL_M, "Failed to activate RSS\n"); + return EXIT_FAILURE; + } + + acc_rss_override_sensor_id_check_at_creation(true); + + acc_detector_distance_configuration_t distance_configuration = acc_detector_distance_configuration_create(); + + if (distance_configuration == NULL) + { + APP_LOG(TS_OFF, VLEVEL_M, "acc_detector_distance_configuration_create() failed\n"); + acc_rss_deactivate(); + return EXIT_FAILURE; + } + + sts_distance_rss_update_configuration(distance_configuration); + acc_detector_distance_handle_t distance_handle = acc_detector_distance_create(distance_configuration); + + if (distance_handle == NULL) + { + APP_LOG(TS_OFF, VLEVEL_M, "acc_detector_distance_create() failed\n"); + acc_detector_distance_configuration_destroy(&distance_configuration); + acc_rss_deactivate(); + return EXIT_FAILURE; + } + + acc_detector_distance_configuration_destroy(&distance_configuration); + + if (!acc_detector_distance_activate(distance_handle)) + { + APP_LOG(TS_OFF, VLEVEL_M, "acc_detector_distance_activate() failed\n"); + acc_detector_distance_destroy(&distance_handle); + acc_rss_deactivate(); + return EXIT_FAILURE; + } + + bool success = true; + const int iterations = 2; //5; + uint16_t number_of_peaks = 10; + acc_detector_distance_result_t result[number_of_peaks]; + acc_detector_distance_result_info_t result_info; + sts_distance_rss_distance = 0.0; + + for (int i = 0; i < iterations; i++) + { + success = acc_detector_distance_get_next(distance_handle, result, number_of_peaks, &result_info); + + if (!success) + { + APP_LOG(TS_OFF, VLEVEL_M, "acc_detector_distance_get_next() failed\n"); + break; + } + sts_distance_rss_distance += result->distance_m; + print_distances(result, result_info.number_of_peaks); + } + + sts_distance_rss_distance = 1000.0f*sts_distance_rss_distance/iterations; + + bool deactivated = acc_detector_distance_deactivate(distance_handle); + + acc_detector_distance_destroy(&distance_handle); + + acc_rss_deactivate(); + + if (deactivated && success) + { + APP_LOG(TS_OFF, VLEVEL_H, "Application finished OK\n"); + return EXIT_SUCCESS; + } + + return EXIT_FAILURE; +} + +static void sts_distance_rss_update_configuration(acc_detector_distance_configuration_t distance_configuration) +{ + acc_detector_distance_configuration_requested_start_set(distance_configuration, distance_cfg.start_m); + acc_detector_distance_configuration_requested_length_set(distance_configuration, distance_cfg.length_m); + acc_detector_distance_configuration_service_profile_set(distance_configuration, distance_cfg.acc_profile); + acc_detector_distance_configuration_hw_accelerated_average_samples_set(distance_configuration, distance_cfg.hwaas); + + acc_detector_distance_configuration_threshold_sensitivity_set(distance_configuration, distance_cfg.threshold); + acc_detector_distance_configuration_sweep_averaging_set(distance_configuration,distance_cfg.sweep_average); + acc_detector_distance_configuration_receiver_gain_set(distance_configuration,distance_cfg.gain); + acc_detector_distance_configuration_downsampling_factor_set(distance_configuration, distance_cfg.downsampling); + + acc_detector_distance_configuration_threshold_type_set(distance_configuration, ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_CFAR); + acc_detector_distance_configuration_record_background_sweeps_set(distance_configuration, 16); + +} + + +static void print_distances(acc_detector_distance_result_t *result, uint16_t reflection_count) +{ + APP_LOG(TS_OFF, VLEVEL_M, "Found %u peaks:\n", (unsigned int)reflection_count); + + for (uint16_t i = 0; i < reflection_count; i++) + { + APP_LOG(TS_OFF, VLEVEL_M, "Amplitude %u at %u mm\n", (unsigned int)result[i].amplitude, + (unsigned int)(result[i].distance_m * 1000)); + } +} diff --git a/Core/Src/yunhorn_sts_presence_rss.c b/Core/Src/yunhorn_sts_presence_rss.c index 7b6057f..cff8238 100644 --- a/Core/Src/yunhorn_sts_presence_rss.c +++ b/Core/Src/yunhorn_sts_presence_rss.c @@ -1,673 +1,673 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file yunhorn_sts_presence_rss.c * - * @author Yunhorn (r) Technology Limited Application Team * - * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 Yunhorn Technology Limited. - * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include -#include -#include "math.h" - -/* USER CODE BEGIN Includes */ -#include "acc_definitions_common.h" -#include "acc_detector_presence.h" -#include "acc_hal_definitions.h" -#include "acc_hal_integration.h" -#include "acc_integration.h" -#include "acc_rss.h" -#include "acc_version.h" -#include "sys_app.h" -#include "yunhorn_sts_prd_conf.h" -#include "yunhorn_sts_sensors.h" -/* -#define DEFAULT_START_M (0.2f) -#define DEFAULT_LENGTH_M (1.4f) -#define DEFAULT_POWER_SAVE_MODE ACC_POWER_SAVE_MODE_SLEEP -*/ -#define DEFAULT_UPDATE_RATE (10) -#define DEFAULT_DETECTION_THRESHOLD (2.0f) -#define DEFAULT_NBR_REMOVED_PC_2 (0) - -#define DEFAULT_PROFILE ACC_SERVICE_PROFILE_4 //ACC_SERVICE_PROFILE_4 -#define DEFAULT_UPDATE_RATE (10) -#define DEFAULT_POWER_SAVE_MODE ACC_POWER_SAVE_MODE_ACTIVE -#define DEFAULT_SENSOR_ID (1) - -#define DEFAULT_START_M (0.8f) //(0.80f) //default 0.2 unit(meter) [1] -#define DEFAULT_LENGTH_M (2.5f) // (2.0f)) //default 1.0 unit(meter) [2] -#define DEFAULT_ZONE_LENGTH (0.4f) //default 0.4 unit(meter) -#define DEFAULT_UPDATE_RATE_WAKEUP (2.0f) //default 80 unit(hz) -#define DEFAULT_UPDATE_RATE_TRACKING (10.0f) //default 80 unit(hz) [7] - -#define DEFAULT_UPDATE_RATE_PRESENCE (65.0F) //(65.0f) //default 80 unit(hz) -//#define DEFAULT_UPDATE_RATE_PRESENCE (80.0F) //(65.0f) //default 80 unit(hz) - -#define DEFAULT_HWAAS (63) //default 10 unit(hz) -#define DEFAULT_THRESHOLD (1.5f) //default 1.5 level float [3] - -//acc_detector_presence_configuration_filter_parameters_t -#define DEFAULT_INTER_FRAME_DEVIATION_TIME_CONST (0.5f) //default 0.5 unit(seconds) [6] -#define DEFAULT_INTER_FRAME_FAST_CUTOFF (10.0f) //default 20.0 unit(hz) [8] -#define DEFAULT_INTER_FRAME_SLOW_CUTOFF (0.01f) //(0.01f) 0.2 hz unit(hz) [9] -#define DEFAULT_INTRA_FRAME_TIME_CONST (0) //default 0.0 unit(seconds) -#define DEFAULT_INTRA_FRAME_WEIGHT (0) //default 0.6 - -#define DEFAULT_OUTPUT_TIME_CONST (0.5f) //default 0.5 unit(seconds) [5] -//#define DEFAULT_OUTPUT_TIME_CONST (0.4f) //default 0.5 unit(seconds) [5] - -#define DEFAULT_NBR_REMOVED_PC (0) //default 0 int [10] - -#define DEFAULT_DOWNSAMPLING_FACTOR (2) //default 1 -#define DEFAULT_RECEIVER_GAIN (0.40f) //default 0.9 gain mdB [4] -//#define DEFAULT_RECEIVER_GAIN (0.65f) //default 0.9 gain mdB [4] - -#define DEFAULT_MOTION_DATASET_LEN (128) //MOTION DATASET/PATTERN COLLECTION -#define DEFAULT_MOTION_FEATURE_LEN (10) //MOTION FEATURE IDENDIFIED - - -extern volatile uint8_t sts_fall_detection_acc_threshold, sts_fall_detection_depth_threshold, sts_occupancy_overtime_threshold; -extern volatile uint8_t sts_rss_result, sts_rss_config_updated_flag; -extern volatile float sts_distance_rss_distance; -volatile float sts_presence_rss_distance, sts_presence_rss_score; -volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config; -//static void update_configuration(acc_detector_presence_configuration_t presence_configuration); -static void print_result(acc_detector_presence_result_t result); -volatile uint16_t motion_count, motion_feature_count; -static acc_detector_presence_result_t sts_motion_dataset[DEFAULT_MOTION_DATASET_LEN]; -static STS_PRESENCE_Motion_Featuer_t sts_motion_feature[DEFAULT_MOTION_FEATURE_LEN]; -volatile uint8_t sts_fall_rising_detected_result = STS_PRESENCE_NONE; -volatile uint8_t last_sts_fall_rising_detected_result= STS_PRESENCE_NONE; -volatile float last_average_presence_distance; -volatile uint16_t sts_fall_rising_pattern_factor1=0, sts_fall_rising_pattern_factor2=0; -volatile uint16_t sts_roc_acc_standard_variance=0; -extern volatile uint8_t sts_presence_fall_detection; -/* USER CODE END Includes */ - -/* External variables ---------------------------------------------------------*/ -/* USER CODE BEGIN EV */ - -/* USER CODE END EV */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN PTD */ - -/* USER CODE END PTD */ - -/* Private define ------------------------------------------------------------*/ - -/* USER CODE BEGIN PD */ - -/* USER CODE END PD */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN PM */ - -/* USER CODE END PM */ - -/* Private variables ---------------------------------------------------------*/ - -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ -#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111)) - -#endif - -/* USER CODE END PFP */ - -/* Exported functions --------------------------------------------------------*/ - -void STS_PRESENCE_RSS_update_default_configuration(acc_detector_presence_configuration_t presence_configuration) -{ - acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); - - acc_detector_presence_configuration_service_profile_set(presence_configuration, DEFAULT_PROFILE); - - acc_detector_presence_configuration_update_rate_set(presence_configuration, DEFAULT_UPDATE_RATE); - acc_detector_presence_configuration_detection_threshold_set(presence_configuration, DEFAULT_DETECTION_THRESHOLD); - acc_detector_presence_configuration_start_set(presence_configuration, DEFAULT_START_M); - acc_detector_presence_configuration_length_set(presence_configuration, DEFAULT_LENGTH_M); - acc_detector_presence_configuration_power_save_mode_set(presence_configuration, DEFAULT_POWER_SAVE_MODE); - acc_detector_presence_configuration_nbr_removed_pc_set(presence_configuration, DEFAULT_NBR_REMOVED_PC); - -} - -/** - * @brief Set default values in presence configuration - * - * @param[in] presence_configuration The presence configuration to set default values in - */ -static void set_default_configuration(acc_detector_presence_configuration_t presence_configuration) -{ - acc_detector_presence_configuration_service_profile_set(presence_configuration, DEFAULT_PROFILE); - - acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); - acc_detector_presence_configuration_update_rate_set(presence_configuration, DEFAULT_UPDATE_RATE_PRESENCE); - acc_detector_presence_configuration_detection_threshold_set(presence_configuration, DEFAULT_THRESHOLD); - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - //acc_service_sparse_configuration_sweeps_per_frame_set(sparse_configuration, sweeps_per_frame); - - acc_detector_presence_configuration_start_set(presence_configuration, DEFAULT_START_M); - acc_detector_presence_configuration_length_set(presence_configuration, DEFAULT_LENGTH_M); - acc_detector_presence_configuration_downsampling_factor_set(presence_configuration, DEFAULT_DOWNSAMPLING_FACTOR); - acc_detector_presence_configuration_receiver_gain_set(presence_configuration, DEFAULT_RECEIVER_GAIN); - - acc_detector_presence_configuration_filter_parameters_t filter = acc_detector_presence_configuration_filter_parameters_get( - presence_configuration); - filter.inter_frame_deviation_time_const = DEFAULT_INTER_FRAME_DEVIATION_TIME_CONST; - -// will be disabled if this value > 1/2 of update rate, default update rate 65, so must < 30 -// - filter.inter_frame_fast_cutoff = DEFAULT_INTER_FRAME_FAST_CUTOFF; - - filter.inter_frame_slow_cutoff = DEFAULT_INTER_FRAME_SLOW_CUTOFF; - -// no effect if intra-frame-weight set to 0 - filter.intra_frame_time_const = DEFAULT_INTRA_FRAME_TIME_CONST; -// for slow movement, people sit still, rest in sofa, seat, closestool, etc. -// set the intra_frame_weight to 0.0 - filter.intra_frame_weight = DEFAULT_INTRA_FRAME_WEIGHT; - - - filter.output_time_const = DEFAULT_OUTPUT_TIME_CONST; //0.0f; - acc_detector_presence_configuration_filter_parameters_set(presence_configuration, &filter); - acc_detector_presence_configuration_nbr_removed_pc_set(presence_configuration, DEFAULT_NBR_REMOVED_PC); - acc_detector_presence_configuration_power_save_mode_set(presence_configuration, ACC_POWER_SAVE_MODE_ACTIVE); -} - -/** - * @brief Set default values in fall_rise detection configuration - * - * @param[in] fall_rise_configuration The fall rise configuration to set default values in - */ -static void set_default_fall_rise_configuration(acc_detector_presence_configuration_t presence_configuration) -{ - acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); - - acc_detector_presence_configuration_service_profile_set(presence_configuration, DEFAULT_PROFILE); - - acc_detector_presence_configuration_update_rate_set(presence_configuration, DEFAULT_UPDATE_RATE_PRESENCE); - acc_detector_presence_configuration_detection_threshold_set(presence_configuration, DEFAULT_THRESHOLD); - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - //acc_service_sparse_configuration_sweeps_per_frame_set(sparse_configuration, sweeps_per_frame); - - acc_detector_presence_configuration_start_set(presence_configuration, DEFAULT_START_M); - acc_detector_presence_configuration_length_set(presence_configuration, DEFAULT_LENGTH_M); - acc_detector_presence_configuration_downsampling_factor_set(presence_configuration, DEFAULT_DOWNSAMPLING_FACTOR); - acc_detector_presence_configuration_receiver_gain_set(presence_configuration, DEFAULT_RECEIVER_GAIN); - - acc_detector_presence_configuration_filter_parameters_t filter = acc_detector_presence_configuration_filter_parameters_get( - presence_configuration); -// if intra-frame-weight set to 1.0, then the following inter-frame parameters have no effect - filter.inter_frame_deviation_time_const = DEFAULT_INTER_FRAME_DEVIATION_TIME_CONST; - filter.inter_frame_fast_cutoff = 10.0f; //DEFAULT_INTER_FRAME_FAST_CUTOFF; - filter.inter_frame_slow_cutoff = 0.5f; //DEFAULT_INTER_FRAME_SLOW_CUTOFF; - -// For fast movement, decrease the time constant -// filter.intra_frame_time_const = DEFAULT_INTRA_FRAME_TIME_CONST; - filter.intra_frame_time_const = 0.2f; - -// filter.intra_frame_weight = DEFAULT_INTRA_FRAME_WEIGHT; -// FOR fast movement tracking set intra-frame-weight to 1.0 - filter.intra_frame_weight = 1.0f; - -// if detection toggles too often, increase the following, if too sluggish, decrease it instead - filter.output_time_const = DEFAULT_OUTPUT_TIME_CONST; //0.0f; - acc_detector_presence_configuration_filter_parameters_set(presence_configuration, &filter); - acc_detector_presence_configuration_nbr_removed_pc_set(presence_configuration, DEFAULT_NBR_REMOVED_PC); - acc_detector_presence_configuration_power_save_mode_set(presence_configuration, ACC_POWER_SAVE_MODE_ACTIVE); -} - - -static void sts_rss_set_current_configuration_full(acc_detector_presence_configuration_t presence_configuration) -{ - acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); - -// acc_service_profile_t presence_profile = sts_presence_rss_config.default_profile; -// acc_detector_presence_configuration_service_profile_set(presence_configuration, presence_profile); - - acc_detector_presence_configuration_update_rate_set(presence_configuration, sts_presence_rss_config.default_update_rate_presence); //DEFAULT_UPDATE_RATE_2); - acc_detector_presence_configuration_detection_threshold_set(presence_configuration, sts_presence_rss_config.default_threshold);//DEFAULT_DETECTION_THRESHOLD_2); - - acc_detector_presence_configuration_start_set(presence_configuration, sts_presence_rss_config.default_start_m); - acc_detector_presence_configuration_length_set(presence_configuration, sts_presence_rss_config.default_length_m); //DEFAULT_LENGTH_M_2); - - acc_detector_presence_configuration_downsampling_factor_set(presence_configuration, sts_presence_rss_config.default_downsampling_factor); - acc_detector_presence_configuration_receiver_gain_set(presence_configuration, sts_presence_rss_config.default_receiver_gain); - - acc_detector_presence_configuration_filter_parameters_t filter = acc_detector_presence_configuration_filter_parameters_get( - presence_configuration); - filter.inter_frame_deviation_time_const = sts_presence_rss_config.default_inter_frame_deviation_time_const; - filter.inter_frame_fast_cutoff = sts_presence_rss_config.default_inter_frame_fast_cutoff; - filter.inter_frame_slow_cutoff = sts_presence_rss_config.default_inter_frame_slow_cutoff; - filter.intra_frame_time_const = sts_presence_rss_config.default_intra_frame_time_const; - filter.intra_frame_weight = sts_presence_rss_config.default_intra_frame_weight; - filter.output_time_const = sts_presence_rss_config.default_output_time_const; //0.0f; - acc_detector_presence_configuration_filter_parameters_set(presence_configuration, &filter); - - acc_detector_presence_configuration_nbr_removed_pc_set(presence_configuration, sts_presence_rss_config.default_nbr_removed_pc); - acc_detector_presence_configuration_hw_accelerated_average_samples_set(presence_configuration, sts_presence_rss_config.default_hwaas); - -} - -static void sts_rss_set_current_configuration_simple(acc_detector_presence_configuration_t presence_configuration) -{ - acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); - acc_detector_presence_configuration_update_rate_set(presence_configuration, DEFAULT_UPDATE_RATE_PRESENCE); - - acc_detector_presence_configuration_start_set(presence_configuration, sts_presence_rss_config.default_start_m); - acc_detector_presence_configuration_length_set(presence_configuration, sts_presence_rss_config.default_length_m); //DEFAULT_LENGTH_M_2); - acc_detector_presence_configuration_detection_threshold_set(presence_configuration, sts_presence_rss_config.default_threshold);//DEFAULT_DETECTION_THRESHOLD_2); - acc_detector_presence_configuration_receiver_gain_set(presence_configuration, sts_presence_rss_config.default_receiver_gain); - -} - - -static void print_result(acc_detector_presence_result_t result) -{ - if (result.presence_detected) - { - uint32_t detected_zone = (uint32_t)((float)(result.presence_distance - DEFAULT_START_M) / (float)DEFAULT_ZONE_LENGTH); - - APP_LOG(TS_OFF, VLEVEL_H,"Motion in zone: %u, distance: %d, score: %d\n", (unsigned int)detected_zone, - (int)(result.presence_distance * 1000.0f), - (int)(result.presence_score * 1000.0f)); - } - else - { - APP_LOG(TS_OFF, VLEVEL_H,"No motion, score: %d\n", (int)(result.presence_score * 1000.0f)); - } -} - - -int sts_presence_rss_fall_rise_detection(void) -{ - const acc_hal_t *hal = acc_hal_integration_get_implementation(); - - if (!acc_rss_activate(hal)) - { - APP_LOG(TS_OFF, VLEVEL_H,"Failed to activate RSS\n"); - return EXIT_FAILURE; - } - - acc_rss_override_sensor_id_check_at_creation(true); - - acc_detector_presence_configuration_t presence_configuration = acc_detector_presence_configuration_create(); - if (presence_configuration == NULL) - { - APP_LOG(TS_OFF, VLEVEL_H,"Failed to create configuration\n"); - acc_rss_deactivate(); - return EXIT_FAILURE; - } - - switch (sts_rss_config_updated_flag) - { - case STS_RSS_CONFIG_DEFAULT: - set_default_configuration(presence_configuration); - break; - case STS_RSS_CONFIG_SIMPLE: - sts_rss_set_current_configuration_simple(presence_configuration); - APP_LOG(TS_OFF, VLEVEL_L,"\r\n##### YUNHORN STS *** Simple *** cfg applied\n"); - - break; - case STS_RSS_CONFIG_FULL: - sts_rss_set_current_configuration_full(presence_configuration); - APP_LOG(TS_OFF, VLEVEL_L,"\r\n######### YUNHORN STS *** FULL *** cfg applied\n"); - break; - default: - break; - } - sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT; //update finished, set to 0 - - acc_detector_presence_handle_t handle = acc_detector_presence_create(presence_configuration); - if (handle == NULL) - { - APP_LOG(TS_OFF, VLEVEL_H,"Failed to create detector\n"); - acc_detector_presence_configuration_destroy(&presence_configuration); - acc_detector_presence_destroy(&handle); - acc_rss_deactivate(); - return EXIT_FAILURE; - } - -// ******** First Half detection of fall down and rise up - if (!acc_detector_presence_activate(handle)) - { - APP_LOG(TS_OFF, VLEVEL_H, "Failed to activate detector \n"); - return false; - } - - bool success = true; - const int iterations = (DEFAULT_UPDATE_RATE_PRESENCE+1); - acc_detector_presence_result_t result; - uint8_t average_result = 0; - float average_distance =0.0f; - float average_score =0.0f; - for (int i = 0; i < (iterations/2); i++) - { - success = acc_detector_presence_get_next(handle, &result); - if (!success) - { - APP_LOG(TS_OFF, VLEVEL_H,"acc_detector_presence_get_next() failed\n"); - break; - } - - print_result(result); - //if (!result.data_saturated) - { - if (result.presence_detected) - { - average_result++; - average_distance += result.presence_distance; - average_score += result.presence_score; - } - - if (sts_presence_fall_detection == 1) - { - sts_motion_dataset[motion_count].presence_distance = result.presence_distance; - sts_motion_dataset[motion_count].presence_score = result.presence_score; - - if (motion_count ++ == DEFAULT_MOTION_DATASET_LEN) - { - STS_YunhornCheckStandardDeviation(); - motion_count = 0; - } - } - } - - acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); // DEFAULT_UPDATE_RATE); - } - - acc_detector_presence_deactivate(handle); - APP_LOG(TS_OFF, VLEVEL_H,"First Half Presence Detection, Motion Count = %u \r\n", (int)motion_count); - -// ******** Second Half detection of fall down and rise up - - set_default_fall_rise_configuration(presence_configuration); - - if (!acc_detector_presence_reconfigure(&handle, presence_configuration)) - { - APP_LOG(TS_OFF, VLEVEL_M,"Failed to reconfigure detector\n"); - acc_detector_presence_configuration_destroy(&presence_configuration); - acc_detector_presence_destroy(&handle); - acc_rss_deactivate(); - return EXIT_FAILURE; - } - - - if (!acc_detector_presence_activate(handle)) - { - APP_LOG(TS_OFF, VLEVEL_H, "Failed to activate detector \n"); - return false; - } - acc_detector_presence_configuration_destroy(&presence_configuration); - - for (int i = 0; i < (iterations/2); i++) - { - success = acc_detector_presence_get_next(handle, &result); - if (!success) - { - APP_LOG(TS_OFF, VLEVEL_H,"acc_detector_presence_get_next() failed\n"); - break; - } - - print_result(result); - //if (!result.data_saturated) - { - if (result.presence_detected) - { - average_result++; - average_distance += result.presence_distance; - average_score += result.presence_score; - } - - if (sts_presence_fall_detection == 1) - { - sts_motion_dataset[motion_count].presence_distance = result.presence_distance; - sts_motion_dataset[motion_count].presence_score = result.presence_score; - - if (motion_count ++ == DEFAULT_MOTION_DATASET_LEN) - { - STS_YunhornCheckStandardDeviation(); - motion_count = 0; - } - } - } - - acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); // DEFAULT_UPDATE_RATE); - } - - APP_LOG(TS_OFF, VLEVEL_H,"Second Half, Fall Rise Detection, Motion Count = %u \r\n", (int)motion_count); - - sts_rss_result = (average_result > 3)? 1: 0; - average_distance = (1000.0f*average_distance)/average_result; // in meters - average_score = (1000.0f*average_score)/average_result; - sts_presence_rss_distance = average_distance; - sts_presence_rss_score = average_score; - if (average_score !=0) //if (sts_rss_result) - { - APP_LOG(TS_OFF, VLEVEL_H,"\r\n######## Motion: %u Distance=%u mm, Score=%u Average_result=%u out of %u \r\n", - (uint8_t)sts_rss_result,(int) average_distance, (int)(average_score), (int)average_result, (int)iterations); - } - - - bool deactivated = acc_detector_presence_deactivate(handle); - - acc_detector_presence_destroy(&handle); - - acc_rss_deactivate(); - - if (deactivated && success) - { - //APP_LOG(TS_OFF, VLEVEL_M,"Application finished OK\n"); - return EXIT_SUCCESS; - } - - return EXIT_FAILURE; - -} - -void STS_YunhornCheckStandardDeviation(void) -{ - uint16_t i,j; - float sum_presence_distance = 0, sum_presence_score=0; - float average_presence_distance = 0, average_presence_score=0; - float variance_presence_distance = 0, variance_presence_score=0; - float standard_variance_presence_distance = 0, standard_variance_presence_score=0; - - float roc_distance[DEFAULT_MOTION_DATASET_LEN]={0}, sum_roc_distance=0, average_roc_distance=0, variance_roc_distance=0, standard_variance_roc_distance=0; - float roc_acc[DEFAULT_MOTION_DATASET_LEN]={0}, sum_roc_acc=0.0f, average_roc_acc=0.0f, variance_roc_acc=0.0f, standard_variance_roc_acc=0.0f;; - //act as speed of change at given time slot acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); - - //SUM - for(i= 0; i< DEFAULT_MOTION_DATASET_LEN; i++) - { - sum_presence_distance += (float)sts_motion_dataset[i].presence_distance; - sum_presence_score += (float)sts_motion_dataset[i].presence_score; - } - // AVERAGE - average_presence_distance = ((float)sum_presence_distance/(float)DEFAULT_MOTION_DATASET_LEN); - average_presence_score = ((float)sum_presence_score/(float)DEFAULT_MOTION_DATASET_LEN); - - // VARIANCE - for (j = 0; j < DEFAULT_MOTION_DATASET_LEN; j++) - { - variance_presence_distance += (float)pow(sts_motion_dataset[j].presence_distance - average_presence_distance,2); - variance_presence_score += (float)pow(sts_motion_dataset[j].presence_score - average_presence_score,2); - } - variance_presence_distance /= (float)DEFAULT_MOTION_DATASET_LEN; - variance_presence_score /= (float)DEFAULT_MOTION_DATASET_LEN; - - //STANDARD VARIANCE - standard_variance_presence_distance = (float)pow(variance_presence_distance,0.5); - standard_variance_presence_score = (float)pow(variance_presence_score,0.5); - - - // ROC distance - // SUM - for(i= 0; i< (DEFAULT_MOTION_DATASET_LEN-1); i++) - { - roc_distance[i] = (float)(labs(sts_motion_dataset[i+1].presence_distance - sts_motion_dataset[i].presence_distance)); - sum_roc_distance += ((float)roc_distance[i]); - } - - average_roc_distance = (float)sum_roc_distance/(float)(DEFAULT_MOTION_DATASET_LEN-1); - - for (j = 0; j < (DEFAULT_MOTION_DATASET_LEN-1); j++) - { - variance_roc_distance += (float)(pow((float)roc_distance[j] - (float)average_roc_distance,2.0f)); - } - - variance_roc_distance /= (float)(DEFAULT_MOTION_DATASET_LEN-1); - - standard_variance_roc_distance = (float)pow((float)variance_roc_distance,0.5f); - - - // ROC Acceleration - - for(i= 0; i< (DEFAULT_MOTION_DATASET_LEN-2); i++) - { - roc_acc[i] = (float)(labs((float)roc_distance[i+1] - (float)roc_distance[i])); - sum_roc_acc += ((float)roc_acc[i]); - } - - average_roc_acc = (float)sum_roc_acc/(float)(DEFAULT_MOTION_DATASET_LEN-2); - - for (j = 0; j < (DEFAULT_MOTION_DATASET_LEN-2); j++) - { - variance_roc_acc += (float)pow((float)((float)roc_acc[j] - (float)average_roc_acc),2.0f); - } - - variance_roc_acc /= (float)(DEFAULT_MOTION_DATASET_LEN-2); - - standard_variance_roc_acc = (float)pow((float)variance_roc_acc,0.5f); - - //Normallize to m/s --- * DEFAULT_MOTION_DATASET_LEN for One single second - - average_roc_distance *= (float)DEFAULT_MOTION_DATASET_LEN; - variance_roc_distance *= (float)DEFAULT_MOTION_DATASET_LEN; - standard_variance_roc_distance *= (float)DEFAULT_MOTION_DATASET_LEN; - - average_roc_acc *= (float)DEFAULT_MOTION_DATASET_LEN; - variance_roc_acc *= (float)DEFAULT_MOTION_DATASET_LEN; - standard_variance_roc_acc *= (float)DEFAULT_MOTION_DATASET_LEN; - - // print result - - APP_LOG(TS_OFF, VLEVEL_H, "\r\n-------------Distance Average =%6u; Variance = %6u ; Standard =%6u \r\n", - (int)(average_presence_distance*1000.0f), (int)(variance_presence_distance*1000.0f), (int)(standard_variance_presence_distance*1000.0f)); - - APP_LOG(TS_OFF, VLEVEL_H, "-------------Motion Average =%6u; Variance = %6u ; Standard =%6u \r\n", - (int)(average_presence_score*1000.0f), (int)(variance_presence_score*1000.0f), (int)(standard_variance_presence_score*1000.0f)); - - APP_LOG(TS_OFF, VLEVEL_H, "-------------ROC Dist Average =%6u; Variance = %6u ; Standard =%6u \r\n", - (int)(average_roc_distance), (int)(variance_roc_distance), (int)(standard_variance_roc_distance)); - - APP_LOG(TS_OFF, VLEVEL_H, "-------------ROC ACC Average =%6u; Variance = %6u ; Standard =%6u \r\n", - (int)(average_roc_acc), (int)(variance_roc_acc), (int)(standard_variance_roc_acc)); - - sts_fall_rising_pattern_factor1 = (int)(standard_variance_roc_distance); - sts_fall_rising_pattern_factor2 = (int)(fabs(average_presence_distance - fmax(0,last_average_presence_distance))*100.0f); // in cm - APP_LOG(TS_OFF, VLEVEL_H,"Avg-Dist =%6u, Last_AVG-Dist =%6u \r\n", (int)(average_presence_distance*1000.0f), (int)(last_average_presence_distance*1000.0f)); - - APP_LOG(TS_OFF, VLEVEL_H, "Threshold 1: \r\nAcc = %6u \r\nMeasure 1 = %6u ---- \r\n", - (int)(sts_fall_detection_acc_threshold), (int)(sts_fall_rising_pattern_factor1)); - - APP_LOG(TS_OFF, VLEVEL_H, "Threshold 2: \r\nDis = %6u cm \r\nMeasure 2 = %6u cm ---- \r\n", - (int)(sts_fall_detection_depth_threshold), (int)(sts_fall_rising_pattern_factor2)); - - - if ( sts_fall_rising_pattern_factor1 > (uint16_t)sts_fall_detection_acc_threshold) - { - - // if ((average_presence_distance > (sts_motion_feature[motion_feature_count].p_dist_avg + sts_motion_feature[motion_feature_count].p_dist_v))) - // if ((average_presence_distance > (sts_motion_feature[motion_feature_count].p_dist_avg + sts_motion_feature[motion_feature_count].p_dist_v))) - // if ((average_presence_distance > (last_average_presence_distance + sts_fall_detection_depth_threshold*0.1))) - if ((sts_fall_rising_pattern_factor2 > sts_fall_detection_depth_threshold ) && (average_presence_distance > DEFAULT_START_M)) - { - sts_fall_rising_detected_result = STS_PRESENCE_FALL; - last_sts_fall_rising_detected_result = sts_fall_rising_detected_result; - } - - motion_feature_count ++; - if (motion_feature_count == DEFAULT_MOTION_FEATURE_LEN) motion_feature_count = 0; - - sts_motion_feature[motion_feature_count].p_dist_avg = average_presence_distance; - sts_motion_feature[motion_feature_count].p_dist_v = variance_presence_distance; - sts_motion_feature[motion_feature_count].p_dist_standard = standard_variance_presence_distance; - sts_motion_feature[motion_feature_count].m_score_avg = standard_variance_presence_score; - sts_motion_feature[motion_feature_count].roc_avg = average_roc_distance; - sts_motion_feature[motion_feature_count].roc_standard = standard_variance_roc_distance; - - sts_motion_feature[motion_feature_count].fall_rising = sts_fall_rising_detected_result; - sts_roc_acc_standard_variance = (uint8_t) standard_variance_roc_acc; - - - if ( sts_fall_rising_detected_result == STS_PRESENCE_FALL ) - { - APP_LOG(TS_OFF, VLEVEL_L, "\r\n\n\n >>>>>>>>>>>>>>>>> Suspecious Object FALL DOWN detected \r\n"); - } - //if (average_presence_distance > DEFAULT_START_M) - { - // last_average_presence_distance = average_presence_distance; - } - - } else if ((last_sts_fall_rising_detected_result == STS_PRESENCE_FALL)) - { - if ((average_presence_distance < (sts_motion_feature[motion_feature_count].p_dist_avg + sts_motion_feature[motion_feature_count].p_dist_standard))) - { - - sts_fall_rising_detected_result = STS_PRESENCE_RISING; - - if ( sts_fall_rising_detected_result == STS_PRESENCE_RISING ) - { - APP_LOG(TS_OFF, VLEVEL_L, "\r\n\n\n >>>>>>>>>>>>>>>>> Suspecious Object RISING UP detected \r\n"); - - } - - last_sts_fall_rising_detected_result = sts_fall_rising_detected_result; - } else if ((average_presence_distance + sts_motion_feature[motion_feature_count].p_dist_standard) > last_average_presence_distance) - { - sts_fall_rising_detected_result = STS_PRESENCE_LAYDOWN; - } else { - sts_fall_rising_detected_result = STS_PRESENCE_NONE; - } - } - - last_average_presence_distance = average_presence_distance; - - if (sts_fall_rising_detected_result != STS_PRESENCE_NONE) - { - STS_FallDetection_LampBarProcess(); - } - -} - - - -/* USER CODE BEGIN EF */ - -/* USER CODE END EF */ - -/* Private Functions Definition -----------------------------------------------*/ -/* USER CODE BEGIN PrFD */ - -/* USER CODE END PrFD */ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file yunhorn_sts_presence_rss.c * + * @author Yunhorn (r) Technology Limited Application Team * + * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 Yunhorn Technology Limited. + * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "math.h" + +/* USER CODE BEGIN Includes */ +#include "acc_definitions_common.h" +#include "acc_detector_presence.h" +#include "acc_hal_definitions.h" +#include "acc_hal_integration.h" +#include "acc_integration.h" +#include "acc_rss.h" +#include "acc_version.h" +#include "sys_app.h" +#include "yunhorn_sts_prd_conf.h" +#include "yunhorn_sts_sensors.h" +/* +#define DEFAULT_START_M (0.2f) +#define DEFAULT_LENGTH_M (1.4f) +#define DEFAULT_POWER_SAVE_MODE ACC_POWER_SAVE_MODE_SLEEP +*/ +#define DEFAULT_UPDATE_RATE (10) +#define DEFAULT_DETECTION_THRESHOLD (2.0f) +#define DEFAULT_NBR_REMOVED_PC_2 (0) + +#define DEFAULT_PROFILE ACC_SERVICE_PROFILE_4 //ACC_SERVICE_PROFILE_4 +#define DEFAULT_UPDATE_RATE (10) +#define DEFAULT_POWER_SAVE_MODE ACC_POWER_SAVE_MODE_ACTIVE +#define DEFAULT_SENSOR_ID (1) + +#define DEFAULT_START_M (0.8f) //(0.80f) //default 0.2 unit(meter) [1] +#define DEFAULT_LENGTH_M (2.5f) // (2.0f)) //default 1.0 unit(meter) [2] +#define DEFAULT_ZONE_LENGTH (0.4f) //default 0.4 unit(meter) +#define DEFAULT_UPDATE_RATE_WAKEUP (2.0f) //default 80 unit(hz) +#define DEFAULT_UPDATE_RATE_TRACKING (10.0f) //default 80 unit(hz) [7] + +#define DEFAULT_UPDATE_RATE_PRESENCE (65.0F) //(65.0f) //default 80 unit(hz) +//#define DEFAULT_UPDATE_RATE_PRESENCE (80.0F) //(65.0f) //default 80 unit(hz) + +#define DEFAULT_HWAAS (63) //default 10 unit(hz) +#define DEFAULT_THRESHOLD (1.5f) //default 1.5 level float [3] + +//acc_detector_presence_configuration_filter_parameters_t +#define DEFAULT_INTER_FRAME_DEVIATION_TIME_CONST (0.5f) //default 0.5 unit(seconds) [6] +#define DEFAULT_INTER_FRAME_FAST_CUTOFF (10.0f) //default 20.0 unit(hz) [8] +#define DEFAULT_INTER_FRAME_SLOW_CUTOFF (0.01f) //(0.01f) 0.2 hz unit(hz) [9] +#define DEFAULT_INTRA_FRAME_TIME_CONST (0) //default 0.0 unit(seconds) +#define DEFAULT_INTRA_FRAME_WEIGHT (0) //default 0.6 + +#define DEFAULT_OUTPUT_TIME_CONST (0.5f) //default 0.5 unit(seconds) [5] +//#define DEFAULT_OUTPUT_TIME_CONST (0.4f) //default 0.5 unit(seconds) [5] + +#define DEFAULT_NBR_REMOVED_PC (0) //default 0 int [10] + +#define DEFAULT_DOWNSAMPLING_FACTOR (2) //default 1 +#define DEFAULT_RECEIVER_GAIN (0.40f) //default 0.9 gain mdB [4] +//#define DEFAULT_RECEIVER_GAIN (0.65f) //default 0.9 gain mdB [4] + +#define DEFAULT_MOTION_DATASET_LEN (128) //MOTION DATASET/PATTERN COLLECTION +#define DEFAULT_MOTION_FEATURE_LEN (10) //MOTION FEATURE IDENDIFIED + + +extern volatile uint8_t sts_fall_detection_acc_threshold, sts_fall_detection_depth_threshold, sts_occupancy_overtime_threshold; +extern volatile uint8_t sts_rss_result, sts_rss_config_updated_flag; +extern volatile float sts_distance_rss_distance; +volatile float sts_presence_rss_distance, sts_presence_rss_score; +volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config; +//static void update_configuration(acc_detector_presence_configuration_t presence_configuration); +static void print_result(acc_detector_presence_result_t result); +volatile uint16_t motion_count, motion_feature_count; +static acc_detector_presence_result_t sts_motion_dataset[DEFAULT_MOTION_DATASET_LEN]; +static STS_PRESENCE_Motion_Featuer_t sts_motion_feature[DEFAULT_MOTION_FEATURE_LEN]; +volatile uint8_t sts_fall_rising_detected_result = STS_PRESENCE_NONE; +volatile uint8_t last_sts_fall_rising_detected_result= STS_PRESENCE_NONE; +volatile float last_average_presence_distance; +volatile uint16_t sts_fall_rising_pattern_factor1=0, sts_fall_rising_pattern_factor2=0; +volatile uint16_t sts_roc_acc_standard_variance=0; +extern volatile uint8_t sts_presence_fall_detection; +/* USER CODE END Includes */ + +/* External variables ---------------------------------------------------------*/ +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ + +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ +#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111)) + +#endif + +/* USER CODE END PFP */ + +/* Exported functions --------------------------------------------------------*/ + +void STS_PRESENCE_RSS_update_default_configuration(acc_detector_presence_configuration_t presence_configuration) +{ + acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); + + acc_detector_presence_configuration_service_profile_set(presence_configuration, DEFAULT_PROFILE); + + acc_detector_presence_configuration_update_rate_set(presence_configuration, DEFAULT_UPDATE_RATE); + acc_detector_presence_configuration_detection_threshold_set(presence_configuration, DEFAULT_DETECTION_THRESHOLD); + acc_detector_presence_configuration_start_set(presence_configuration, DEFAULT_START_M); + acc_detector_presence_configuration_length_set(presence_configuration, DEFAULT_LENGTH_M); + acc_detector_presence_configuration_power_save_mode_set(presence_configuration, DEFAULT_POWER_SAVE_MODE); + acc_detector_presence_configuration_nbr_removed_pc_set(presence_configuration, DEFAULT_NBR_REMOVED_PC); + +} + +/** + * @brief Set default values in presence configuration + * + * @param[in] presence_configuration The presence configuration to set default values in + */ +static void set_default_configuration(acc_detector_presence_configuration_t presence_configuration) +{ + acc_detector_presence_configuration_service_profile_set(presence_configuration, DEFAULT_PROFILE); + + acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); + acc_detector_presence_configuration_update_rate_set(presence_configuration, DEFAULT_UPDATE_RATE_PRESENCE); + acc_detector_presence_configuration_detection_threshold_set(presence_configuration, DEFAULT_THRESHOLD); + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //acc_service_sparse_configuration_sweeps_per_frame_set(sparse_configuration, sweeps_per_frame); + + acc_detector_presence_configuration_start_set(presence_configuration, DEFAULT_START_M); + acc_detector_presence_configuration_length_set(presence_configuration, DEFAULT_LENGTH_M); + acc_detector_presence_configuration_downsampling_factor_set(presence_configuration, DEFAULT_DOWNSAMPLING_FACTOR); + acc_detector_presence_configuration_receiver_gain_set(presence_configuration, DEFAULT_RECEIVER_GAIN); + + acc_detector_presence_configuration_filter_parameters_t filter = acc_detector_presence_configuration_filter_parameters_get( + presence_configuration); + filter.inter_frame_deviation_time_const = DEFAULT_INTER_FRAME_DEVIATION_TIME_CONST; + +// will be disabled if this value > 1/2 of update rate, default update rate 65, so must < 30 +// + filter.inter_frame_fast_cutoff = DEFAULT_INTER_FRAME_FAST_CUTOFF; + + filter.inter_frame_slow_cutoff = DEFAULT_INTER_FRAME_SLOW_CUTOFF; + +// no effect if intra-frame-weight set to 0 + filter.intra_frame_time_const = DEFAULT_INTRA_FRAME_TIME_CONST; +// for slow movement, people sit still, rest in sofa, seat, closestool, etc. +// set the intra_frame_weight to 0.0 + filter.intra_frame_weight = DEFAULT_INTRA_FRAME_WEIGHT; + + + filter.output_time_const = DEFAULT_OUTPUT_TIME_CONST; //0.0f; + acc_detector_presence_configuration_filter_parameters_set(presence_configuration, &filter); + acc_detector_presence_configuration_nbr_removed_pc_set(presence_configuration, DEFAULT_NBR_REMOVED_PC); + acc_detector_presence_configuration_power_save_mode_set(presence_configuration, ACC_POWER_SAVE_MODE_ACTIVE); +} + +/** + * @brief Set default values in fall_rise detection configuration + * + * @param[in] fall_rise_configuration The fall rise configuration to set default values in + */ +static void set_default_fall_rise_configuration(acc_detector_presence_configuration_t presence_configuration) +{ + acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); + + acc_detector_presence_configuration_service_profile_set(presence_configuration, DEFAULT_PROFILE); + + acc_detector_presence_configuration_update_rate_set(presence_configuration, DEFAULT_UPDATE_RATE_PRESENCE); + acc_detector_presence_configuration_detection_threshold_set(presence_configuration, DEFAULT_THRESHOLD); + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //acc_service_sparse_configuration_sweeps_per_frame_set(sparse_configuration, sweeps_per_frame); + + acc_detector_presence_configuration_start_set(presence_configuration, DEFAULT_START_M); + acc_detector_presence_configuration_length_set(presence_configuration, DEFAULT_LENGTH_M); + acc_detector_presence_configuration_downsampling_factor_set(presence_configuration, DEFAULT_DOWNSAMPLING_FACTOR); + acc_detector_presence_configuration_receiver_gain_set(presence_configuration, DEFAULT_RECEIVER_GAIN); + + acc_detector_presence_configuration_filter_parameters_t filter = acc_detector_presence_configuration_filter_parameters_get( + presence_configuration); +// if intra-frame-weight set to 1.0, then the following inter-frame parameters have no effect + filter.inter_frame_deviation_time_const = DEFAULT_INTER_FRAME_DEVIATION_TIME_CONST; + filter.inter_frame_fast_cutoff = 10.0f; //DEFAULT_INTER_FRAME_FAST_CUTOFF; + filter.inter_frame_slow_cutoff = 0.5f; //DEFAULT_INTER_FRAME_SLOW_CUTOFF; + +// For fast movement, decrease the time constant +// filter.intra_frame_time_const = DEFAULT_INTRA_FRAME_TIME_CONST; + filter.intra_frame_time_const = 0.2f; + +// filter.intra_frame_weight = DEFAULT_INTRA_FRAME_WEIGHT; +// FOR fast movement tracking set intra-frame-weight to 1.0 + filter.intra_frame_weight = 1.0f; + +// if detection toggles too often, increase the following, if too sluggish, decrease it instead + filter.output_time_const = DEFAULT_OUTPUT_TIME_CONST; //0.0f; + acc_detector_presence_configuration_filter_parameters_set(presence_configuration, &filter); + acc_detector_presence_configuration_nbr_removed_pc_set(presence_configuration, DEFAULT_NBR_REMOVED_PC); + acc_detector_presence_configuration_power_save_mode_set(presence_configuration, ACC_POWER_SAVE_MODE_ACTIVE); +} + + +static void sts_rss_set_current_configuration_full(acc_detector_presence_configuration_t presence_configuration) +{ + acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); + +// acc_service_profile_t presence_profile = sts_presence_rss_config.default_profile; +// acc_detector_presence_configuration_service_profile_set(presence_configuration, presence_profile); + + acc_detector_presence_configuration_update_rate_set(presence_configuration, sts_presence_rss_config.default_update_rate_presence); //DEFAULT_UPDATE_RATE_2); + acc_detector_presence_configuration_detection_threshold_set(presence_configuration, sts_presence_rss_config.default_threshold);//DEFAULT_DETECTION_THRESHOLD_2); + + acc_detector_presence_configuration_start_set(presence_configuration, sts_presence_rss_config.default_start_m); + acc_detector_presence_configuration_length_set(presence_configuration, sts_presence_rss_config.default_length_m); //DEFAULT_LENGTH_M_2); + + acc_detector_presence_configuration_downsampling_factor_set(presence_configuration, sts_presence_rss_config.default_downsampling_factor); + acc_detector_presence_configuration_receiver_gain_set(presence_configuration, sts_presence_rss_config.default_receiver_gain); + + acc_detector_presence_configuration_filter_parameters_t filter = acc_detector_presence_configuration_filter_parameters_get( + presence_configuration); + filter.inter_frame_deviation_time_const = sts_presence_rss_config.default_inter_frame_deviation_time_const; + filter.inter_frame_fast_cutoff = sts_presence_rss_config.default_inter_frame_fast_cutoff; + filter.inter_frame_slow_cutoff = sts_presence_rss_config.default_inter_frame_slow_cutoff; + filter.intra_frame_time_const = sts_presence_rss_config.default_intra_frame_time_const; + filter.intra_frame_weight = sts_presence_rss_config.default_intra_frame_weight; + filter.output_time_const = sts_presence_rss_config.default_output_time_const; //0.0f; + acc_detector_presence_configuration_filter_parameters_set(presence_configuration, &filter); + + acc_detector_presence_configuration_nbr_removed_pc_set(presence_configuration, sts_presence_rss_config.default_nbr_removed_pc); + acc_detector_presence_configuration_hw_accelerated_average_samples_set(presence_configuration, sts_presence_rss_config.default_hwaas); + +} + +static void sts_rss_set_current_configuration_simple(acc_detector_presence_configuration_t presence_configuration) +{ + acc_detector_presence_configuration_sensor_set(presence_configuration, DEFAULT_SENSOR_ID); + acc_detector_presence_configuration_update_rate_set(presence_configuration, DEFAULT_UPDATE_RATE_PRESENCE); + + acc_detector_presence_configuration_start_set(presence_configuration, sts_presence_rss_config.default_start_m); + acc_detector_presence_configuration_length_set(presence_configuration, sts_presence_rss_config.default_length_m); //DEFAULT_LENGTH_M_2); + acc_detector_presence_configuration_detection_threshold_set(presence_configuration, sts_presence_rss_config.default_threshold);//DEFAULT_DETECTION_THRESHOLD_2); + acc_detector_presence_configuration_receiver_gain_set(presence_configuration, sts_presence_rss_config.default_receiver_gain); + +} + + +static void print_result(acc_detector_presence_result_t result) +{ + if (result.presence_detected) + { + uint32_t detected_zone = (uint32_t)((float)(result.presence_distance - DEFAULT_START_M) / (float)DEFAULT_ZONE_LENGTH); + + APP_LOG(TS_OFF, VLEVEL_H,"Motion in zone: %u, distance: %d, score: %d\n", (unsigned int)detected_zone, + (int)(result.presence_distance * 1000.0f), + (int)(result.presence_score * 1000.0f)); + } + else + { + APP_LOG(TS_OFF, VLEVEL_H,"No motion, score: %d\n", (int)(result.presence_score * 1000.0f)); + } +} + + +int sts_presence_rss_fall_rise_detection(void) +{ + const acc_hal_t *hal = acc_hal_integration_get_implementation(); + + if (!acc_rss_activate(hal)) + { + APP_LOG(TS_OFF, VLEVEL_H,"Failed to activate RSS\n"); + return EXIT_FAILURE; + } + + acc_rss_override_sensor_id_check_at_creation(true); + + acc_detector_presence_configuration_t presence_configuration = acc_detector_presence_configuration_create(); + if (presence_configuration == NULL) + { + APP_LOG(TS_OFF, VLEVEL_H,"Failed to create configuration\n"); + acc_rss_deactivate(); + return EXIT_FAILURE; + } + + switch (sts_rss_config_updated_flag) + { + case STS_RSS_CONFIG_DEFAULT: + set_default_configuration(presence_configuration); + break; + case STS_RSS_CONFIG_SIMPLE: + sts_rss_set_current_configuration_simple(presence_configuration); + APP_LOG(TS_OFF, VLEVEL_L,"\r\n##### YUNHORN STS *** Simple *** cfg applied\n"); + + break; + case STS_RSS_CONFIG_FULL: + sts_rss_set_current_configuration_full(presence_configuration); + APP_LOG(TS_OFF, VLEVEL_L,"\r\n######### YUNHORN STS *** FULL *** cfg applied\n"); + break; + default: + break; + } + sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT; //update finished, set to 0 + + acc_detector_presence_handle_t handle = acc_detector_presence_create(presence_configuration); + if (handle == NULL) + { + APP_LOG(TS_OFF, VLEVEL_H,"Failed to create detector\n"); + acc_detector_presence_configuration_destroy(&presence_configuration); + acc_detector_presence_destroy(&handle); + acc_rss_deactivate(); + return EXIT_FAILURE; + } + +// ******** First Half detection of fall down and rise up + if (!acc_detector_presence_activate(handle)) + { + APP_LOG(TS_OFF, VLEVEL_H, "Failed to activate detector \n"); + return false; + } + + bool success = true; + const int iterations = (DEFAULT_UPDATE_RATE_PRESENCE+1); + acc_detector_presence_result_t result; + uint8_t average_result = 0; + float average_distance =0.0f; + float average_score =0.0f; + for (int i = 0; i < (iterations/2); i++) + { + success = acc_detector_presence_get_next(handle, &result); + if (!success) + { + APP_LOG(TS_OFF, VLEVEL_H,"acc_detector_presence_get_next() failed\n"); + break; + } + + print_result(result); + //if (!result.data_saturated) + { + if (result.presence_detected) + { + average_result++; + average_distance += result.presence_distance; + average_score += result.presence_score; + } + + if (sts_presence_fall_detection == 1) + { + sts_motion_dataset[motion_count].presence_distance = result.presence_distance; + sts_motion_dataset[motion_count].presence_score = result.presence_score; + + if (motion_count ++ == DEFAULT_MOTION_DATASET_LEN) + { + STS_YunhornCheckStandardDeviation(); + motion_count = 0; + } + } + } + + acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); // DEFAULT_UPDATE_RATE); + } + + acc_detector_presence_deactivate(handle); + APP_LOG(TS_OFF, VLEVEL_H,"First Half Presence Detection, Motion Count = %u \r\n", (int)motion_count); + +// ******** Second Half detection of fall down and rise up + + set_default_fall_rise_configuration(presence_configuration); + + if (!acc_detector_presence_reconfigure(&handle, presence_configuration)) + { + APP_LOG(TS_OFF, VLEVEL_M,"Failed to reconfigure detector\n"); + acc_detector_presence_configuration_destroy(&presence_configuration); + acc_detector_presence_destroy(&handle); + acc_rss_deactivate(); + return EXIT_FAILURE; + } + + + if (!acc_detector_presence_activate(handle)) + { + APP_LOG(TS_OFF, VLEVEL_H, "Failed to activate detector \n"); + return false; + } + acc_detector_presence_configuration_destroy(&presence_configuration); + + for (int i = 0; i < (iterations/2); i++) + { + success = acc_detector_presence_get_next(handle, &result); + if (!success) + { + APP_LOG(TS_OFF, VLEVEL_H,"acc_detector_presence_get_next() failed\n"); + break; + } + + print_result(result); + //if (!result.data_saturated) + { + if (result.presence_detected) + { + average_result++; + average_distance += result.presence_distance; + average_score += result.presence_score; + } + + if (sts_presence_fall_detection == 1) + { + sts_motion_dataset[motion_count].presence_distance = result.presence_distance; + sts_motion_dataset[motion_count].presence_score = result.presence_score; + + if (motion_count ++ == DEFAULT_MOTION_DATASET_LEN) + { + STS_YunhornCheckStandardDeviation(); + motion_count = 0; + } + } + } + + acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); // DEFAULT_UPDATE_RATE); + } + + APP_LOG(TS_OFF, VLEVEL_H,"Second Half, Fall Rise Detection, Motion Count = %u \r\n", (int)motion_count); + + sts_rss_result = (average_result > 3)? 1: 0; + average_distance = (1000.0f*average_distance)/average_result; // in meters + average_score = (1000.0f*average_score)/average_result; + sts_presence_rss_distance = average_distance; + sts_presence_rss_score = average_score; + if (average_score !=0) //if (sts_rss_result) + { + APP_LOG(TS_OFF, VLEVEL_H,"\r\n######## Motion: %u Distance=%u mm, Score=%u Average_result=%u out of %u \r\n", + (uint8_t)sts_rss_result,(int) average_distance, (int)(average_score), (int)average_result, (int)iterations); + } + + + bool deactivated = acc_detector_presence_deactivate(handle); + + acc_detector_presence_destroy(&handle); + + acc_rss_deactivate(); + + if (deactivated && success) + { + //APP_LOG(TS_OFF, VLEVEL_M,"Application finished OK\n"); + return EXIT_SUCCESS; + } + + return EXIT_FAILURE; + +} + +void STS_YunhornCheckStandardDeviation(void) +{ + uint16_t i,j; + float sum_presence_distance = 0, sum_presence_score=0; + float average_presence_distance = 0, average_presence_score=0; + float variance_presence_distance = 0, variance_presence_score=0; + float standard_variance_presence_distance = 0, standard_variance_presence_score=0; + + float roc_distance[DEFAULT_MOTION_DATASET_LEN]={0}, sum_roc_distance=0, average_roc_distance=0, variance_roc_distance=0, standard_variance_roc_distance=0; + float roc_acc[DEFAULT_MOTION_DATASET_LEN]={0}, sum_roc_acc=0.0f, average_roc_acc=0.0f, variance_roc_acc=0.0f, standard_variance_roc_acc=0.0f;; + //act as speed of change at given time slot acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); + + //SUM + for(i= 0; i< DEFAULT_MOTION_DATASET_LEN; i++) + { + sum_presence_distance += (float)sts_motion_dataset[i].presence_distance; + sum_presence_score += (float)sts_motion_dataset[i].presence_score; + } + // AVERAGE + average_presence_distance = ((float)sum_presence_distance/(float)DEFAULT_MOTION_DATASET_LEN); + average_presence_score = ((float)sum_presence_score/(float)DEFAULT_MOTION_DATASET_LEN); + + // VARIANCE + for (j = 0; j < DEFAULT_MOTION_DATASET_LEN; j++) + { + variance_presence_distance += (float)pow(sts_motion_dataset[j].presence_distance - average_presence_distance,2); + variance_presence_score += (float)pow(sts_motion_dataset[j].presence_score - average_presence_score,2); + } + variance_presence_distance /= (float)DEFAULT_MOTION_DATASET_LEN; + variance_presence_score /= (float)DEFAULT_MOTION_DATASET_LEN; + + //STANDARD VARIANCE + standard_variance_presence_distance = (float)pow(variance_presence_distance,0.5); + standard_variance_presence_score = (float)pow(variance_presence_score,0.5); + + + // ROC distance + // SUM + for(i= 0; i< (DEFAULT_MOTION_DATASET_LEN-1); i++) + { + roc_distance[i] = (float)(labs(sts_motion_dataset[i+1].presence_distance - sts_motion_dataset[i].presence_distance)); + sum_roc_distance += ((float)roc_distance[i]); + } + + average_roc_distance = (float)sum_roc_distance/(float)(DEFAULT_MOTION_DATASET_LEN-1); + + for (j = 0; j < (DEFAULT_MOTION_DATASET_LEN-1); j++) + { + variance_roc_distance += (float)(pow((float)roc_distance[j] - (float)average_roc_distance,2.0f)); + } + + variance_roc_distance /= (float)(DEFAULT_MOTION_DATASET_LEN-1); + + standard_variance_roc_distance = (float)pow((float)variance_roc_distance,0.5f); + + + // ROC Acceleration + + for(i= 0; i< (DEFAULT_MOTION_DATASET_LEN-2); i++) + { + roc_acc[i] = (float)(labs((float)roc_distance[i+1] - (float)roc_distance[i])); + sum_roc_acc += ((float)roc_acc[i]); + } + + average_roc_acc = (float)sum_roc_acc/(float)(DEFAULT_MOTION_DATASET_LEN-2); + + for (j = 0; j < (DEFAULT_MOTION_DATASET_LEN-2); j++) + { + variance_roc_acc += (float)pow((float)((float)roc_acc[j] - (float)average_roc_acc),2.0f); + } + + variance_roc_acc /= (float)(DEFAULT_MOTION_DATASET_LEN-2); + + standard_variance_roc_acc = (float)pow((float)variance_roc_acc,0.5f); + + //Normallize to m/s --- * DEFAULT_MOTION_DATASET_LEN for One single second + + average_roc_distance *= (float)DEFAULT_MOTION_DATASET_LEN; + variance_roc_distance *= (float)DEFAULT_MOTION_DATASET_LEN; + standard_variance_roc_distance *= (float)DEFAULT_MOTION_DATASET_LEN; + + average_roc_acc *= (float)DEFAULT_MOTION_DATASET_LEN; + variance_roc_acc *= (float)DEFAULT_MOTION_DATASET_LEN; + standard_variance_roc_acc *= (float)DEFAULT_MOTION_DATASET_LEN; + + // print result + + APP_LOG(TS_OFF, VLEVEL_H, "\r\n-------------Distance Average =%6u; Variance = %6u ; Standard =%6u \r\n", + (int)(average_presence_distance*1000.0f), (int)(variance_presence_distance*1000.0f), (int)(standard_variance_presence_distance*1000.0f)); + + APP_LOG(TS_OFF, VLEVEL_H, "-------------Motion Average =%6u; Variance = %6u ; Standard =%6u \r\n", + (int)(average_presence_score*1000.0f), (int)(variance_presence_score*1000.0f), (int)(standard_variance_presence_score*1000.0f)); + + APP_LOG(TS_OFF, VLEVEL_H, "-------------ROC Dist Average =%6u; Variance = %6u ; Standard =%6u \r\n", + (int)(average_roc_distance), (int)(variance_roc_distance), (int)(standard_variance_roc_distance)); + + APP_LOG(TS_OFF, VLEVEL_H, "-------------ROC ACC Average =%6u; Variance = %6u ; Standard =%6u \r\n", + (int)(average_roc_acc), (int)(variance_roc_acc), (int)(standard_variance_roc_acc)); + + sts_fall_rising_pattern_factor1 = (int)(standard_variance_roc_distance); + sts_fall_rising_pattern_factor2 = (int)(fabs(average_presence_distance - fmax(0,last_average_presence_distance))*100.0f); // in cm + APP_LOG(TS_OFF, VLEVEL_H,"Avg-Dist =%6u, Last_AVG-Dist =%6u \r\n", (int)(average_presence_distance*1000.0f), (int)(last_average_presence_distance*1000.0f)); + + APP_LOG(TS_OFF, VLEVEL_H, "Threshold 1: \r\nAcc = %6u \r\nMeasure 1 = %6u ---- \r\n", + (int)(sts_fall_detection_acc_threshold), (int)(sts_fall_rising_pattern_factor1)); + + APP_LOG(TS_OFF, VLEVEL_H, "Threshold 2: \r\nDis = %6u cm \r\nMeasure 2 = %6u cm ---- \r\n", + (int)(sts_fall_detection_depth_threshold), (int)(sts_fall_rising_pattern_factor2)); + + + if ( sts_fall_rising_pattern_factor1 > (uint16_t)sts_fall_detection_acc_threshold) + { + + // if ((average_presence_distance > (sts_motion_feature[motion_feature_count].p_dist_avg + sts_motion_feature[motion_feature_count].p_dist_v))) + // if ((average_presence_distance > (sts_motion_feature[motion_feature_count].p_dist_avg + sts_motion_feature[motion_feature_count].p_dist_v))) + // if ((average_presence_distance > (last_average_presence_distance + sts_fall_detection_depth_threshold*0.1))) + if ((sts_fall_rising_pattern_factor2 > sts_fall_detection_depth_threshold ) && (average_presence_distance > DEFAULT_START_M)) + { + sts_fall_rising_detected_result = STS_PRESENCE_FALL; + last_sts_fall_rising_detected_result = sts_fall_rising_detected_result; + } + + motion_feature_count ++; + if (motion_feature_count == DEFAULT_MOTION_FEATURE_LEN) motion_feature_count = 0; + + sts_motion_feature[motion_feature_count].p_dist_avg = average_presence_distance; + sts_motion_feature[motion_feature_count].p_dist_v = variance_presence_distance; + sts_motion_feature[motion_feature_count].p_dist_standard = standard_variance_presence_distance; + sts_motion_feature[motion_feature_count].m_score_avg = standard_variance_presence_score; + sts_motion_feature[motion_feature_count].roc_avg = average_roc_distance; + sts_motion_feature[motion_feature_count].roc_standard = standard_variance_roc_distance; + + sts_motion_feature[motion_feature_count].fall_rising = sts_fall_rising_detected_result; + sts_roc_acc_standard_variance = (uint8_t) standard_variance_roc_acc; + + + if ( sts_fall_rising_detected_result == STS_PRESENCE_FALL ) + { + APP_LOG(TS_OFF, VLEVEL_L, "\r\n\n\n >>>>>>>>>>>>>>>>> Suspecious Object FALL DOWN detected \r\n"); + } + //if (average_presence_distance > DEFAULT_START_M) + { + // last_average_presence_distance = average_presence_distance; + } + + } else if ((last_sts_fall_rising_detected_result == STS_PRESENCE_FALL)) + { + if ((average_presence_distance < (sts_motion_feature[motion_feature_count].p_dist_avg + sts_motion_feature[motion_feature_count].p_dist_standard))) + { + + sts_fall_rising_detected_result = STS_PRESENCE_RISING; + + if ( sts_fall_rising_detected_result == STS_PRESENCE_RISING ) + { + APP_LOG(TS_OFF, VLEVEL_L, "\r\n\n\n >>>>>>>>>>>>>>>>> Suspecious Object RISING UP detected \r\n"); + + } + + last_sts_fall_rising_detected_result = sts_fall_rising_detected_result; + } else if ((average_presence_distance + sts_motion_feature[motion_feature_count].p_dist_standard) > last_average_presence_distance) + { + sts_fall_rising_detected_result = STS_PRESENCE_LAYDOWN; + } else { + sts_fall_rising_detected_result = STS_PRESENCE_NONE; + } + } + + last_average_presence_distance = average_presence_distance; + + if (sts_fall_rising_detected_result != STS_PRESENCE_NONE) + { + STS_FallDetection_LampBarProcess(); + } + +} + + + +/* USER CODE BEGIN EF */ + +/* USER CODE END EF */ + +/* Private Functions Definition -----------------------------------------------*/ +/* USER CODE BEGIN PrFD */ + +/* USER CODE END PrFD */ diff --git a/Core/Src/yunhorn_sts_presence_rss_bring_up_test.c b/Core/Src/yunhorn_sts_presence_rss_bring_up_test.c index 173282c..505e8d4 100644 --- a/Core/Src/yunhorn_sts_presence_rss_bring_up_test.c +++ b/Core/Src/yunhorn_sts_presence_rss_bring_up_test.c @@ -1,208 +1,208 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file yunhorn_sts_presence_rss_bring_up_test.c * - * @author Yunhorn (r) Technology Limited Application Team * - * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 Yunhorn Technology Limited. - * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include -#include -#include -#include - -#include "acc_hal_definitions.h" -#include "acc_hal_integration.h" -#include "acc_rss.h" -#include "acc_rss_assembly_test.h" -#include "acc_version.h" -#include "sys_app.h" - - - -#define DEFAULT_SENSOR_ID 1 - -static bool run_test(acc_rss_assembly_test_configuration_t configuration); - -int sts_presence_rss_bring_up_test(uint8_t *rss_self_test_result); - -int sts_presence_rss_bring_up_test(uint8_t *rss_self_test_result) -{ - uint8_t t=0; - uint8_t test_result[12]={0x0}; - - APP_LOG(TS_OFF, VLEVEL_H,"-- 0 -- Acconeer software version %s\n", acc_version_get()); - - const acc_hal_t *hal = acc_hal_integration_get_implementation(); - - test_result[t++] = (uint8_t) acc_rss_activate(hal); //(1) - - acc_rss_assembly_test_configuration_t configuration = acc_rss_assembly_test_configuration_create(); - - test_result[t++] = (uint8_t)((configuration != NULL)? 1:0); //(2) - - acc_rss_assembly_test_configuration_sensor_set(configuration, DEFAULT_SENSOR_ID); - - // Disable all tests (they are enabled by default) - acc_rss_assembly_test_configuration_all_tests_disable(configuration); - - // Enable and run: Read Test - acc_rss_assembly_test_configuration_communication_read_test_enable(configuration); - - - if (!run_test(configuration)) - { - test_result[t++] = 0; //(3) - acc_rss_assembly_test_configuration_destroy(&configuration); - acc_rss_deactivate(); - //return EXIT_FAILURE; - } else { - test_result[t++] = 1; - } - - acc_rss_assembly_test_configuration_communication_read_test_disable(configuration); - - // Enable and run: Write Read Test - acc_rss_assembly_test_configuration_communication_write_read_test_enable(configuration); - if (!run_test(configuration)) - { - test_result[t++] = 0; //(4) - acc_rss_assembly_test_configuration_destroy(&configuration); - acc_rss_deactivate(); - //return EXIT_FAILURE; - } else { - test_result[t++] = 1; - } - - acc_rss_assembly_test_configuration_communication_write_read_test_disable(configuration); - - // Enable and run: Interrupt Test - acc_rss_assembly_test_configuration_communication_interrupt_test_enable(configuration); - if (!run_test(configuration)) - { - test_result[t++] = 0; //(5) - acc_rss_assembly_test_configuration_destroy(&configuration); - acc_rss_deactivate(); - //return EXIT_FAILURE; - } else { - - test_result[t++] = 1; - } - - acc_rss_assembly_test_configuration_communication_interrupt_test_disable(configuration); - - // Enable and run: Hibernate Test - acc_rss_assembly_test_configuration_communication_hibernate_test_enable(configuration); - if (!run_test(configuration)) - { - test_result[t++] = 0; //(6) - acc_rss_assembly_test_configuration_destroy(&configuration); - acc_rss_deactivate(); - //return EXIT_FAILURE; - } else { - - test_result[t++] = 1; - } - - acc_rss_assembly_test_configuration_communication_hibernate_test_disable(configuration); - - // Enable and run: Supply Test - acc_rss_assembly_test_configuration_supply_test_enable(configuration); - if (!run_test(configuration)) - { - test_result[t++] = 0; //(7) - acc_rss_assembly_test_configuration_destroy(&configuration); - acc_rss_deactivate(); - //return EXIT_FAILURE; - } else { - - test_result[t++] = 1; - } - - acc_rss_assembly_test_configuration_supply_test_disable(configuration); - - // Enable and run: Clock Test - acc_rss_assembly_test_configuration_clock_test_enable(configuration); - if (!run_test(configuration)) - { - test_result[t++] = 0; // (8) - acc_rss_assembly_test_configuration_destroy(&configuration); - acc_rss_deactivate(); - //return EXIT_FAILURE; - } else { - - test_result[t++] = 1; - } - - acc_rss_assembly_test_configuration_clock_test_disable(configuration); - - // Enable and run: Power cycle test - acc_rss_assembly_test_configuration_power_cycle_test_enable(configuration); - if (!run_test(configuration)) - { - test_result[t++] = 0; //(9) - acc_rss_assembly_test_configuration_destroy(&configuration); - acc_rss_deactivate(); - //return EXIT_FAILURE; - } else { - - test_result[t++] = 1; - } - - - acc_rss_assembly_test_configuration_power_cycle_test_disable(configuration); - - APP_LOG(TS_OFF, VLEVEL_H,"-- 10 -- Bring up test: All tests passed\n"); - test_result[t++] = 1; //(10) - - memcpy(rss_self_test_result, test_result, t); - APP_LOG(TS_OFF, VLEVEL_H,"--Bring up test result #=%d \r\n", t); - acc_rss_assembly_test_configuration_destroy(&configuration); - acc_rss_deactivate(); - - return EXIT_SUCCESS; -} - - -static bool run_test(acc_rss_assembly_test_configuration_t configuration) -{ - acc_rss_assembly_test_result_t test_results[ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS]; - uint16_t nr_of_test_results = ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS; - bool all_passed = true; - - if (!acc_rss_assembly_test(configuration, test_results, &nr_of_test_results)) - { - APP_LOG(TS_OFF, VLEVEL_H,"Bring up test: Failed to complete\n"); - return false; - } else { - APP_LOG(TS_OFF, VLEVEL_H,"Bring up test: SUCCESS to complete\n"); - - } - - for (uint16_t i = 0; i < nr_of_test_results; i++) - { - const bool passed = test_results[i].test_passed; - APP_LOG(TS_OFF, VLEVEL_H,"Name: %s, result: %s\n", test_results[i].test_name, passed ? "Pass" : "Fail"); - - if (!passed) - { - all_passed = false; - } - } - - return all_passed; -} +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file yunhorn_sts_presence_rss_bring_up_test.c * + * @author Yunhorn (r) Technology Limited Application Team * + * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 Yunhorn Technology Limited. + * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include + +#include "acc_hal_definitions.h" +#include "acc_hal_integration.h" +#include "acc_rss.h" +#include "acc_rss_assembly_test.h" +#include "acc_version.h" +#include "sys_app.h" + + + +#define DEFAULT_SENSOR_ID 1 + +static bool run_test(acc_rss_assembly_test_configuration_t configuration); + +int sts_presence_rss_bring_up_test(uint8_t *rss_self_test_result); + +int sts_presence_rss_bring_up_test(uint8_t *rss_self_test_result) +{ + uint8_t t=0; + uint8_t test_result[12]={0x0}; + + APP_LOG(TS_OFF, VLEVEL_H,"-- 0 -- Acconeer software version %s\n", acc_version_get()); + + const acc_hal_t *hal = acc_hal_integration_get_implementation(); + + test_result[t++] = (uint8_t) acc_rss_activate(hal); //(1) + + acc_rss_assembly_test_configuration_t configuration = acc_rss_assembly_test_configuration_create(); + + test_result[t++] = (uint8_t)((configuration != NULL)? 1:0); //(2) + + acc_rss_assembly_test_configuration_sensor_set(configuration, DEFAULT_SENSOR_ID); + + // Disable all tests (they are enabled by default) + acc_rss_assembly_test_configuration_all_tests_disable(configuration); + + // Enable and run: Read Test + acc_rss_assembly_test_configuration_communication_read_test_enable(configuration); + + + if (!run_test(configuration)) + { + test_result[t++] = 0; //(3) + acc_rss_assembly_test_configuration_destroy(&configuration); + acc_rss_deactivate(); + //return EXIT_FAILURE; + } else { + test_result[t++] = 1; + } + + acc_rss_assembly_test_configuration_communication_read_test_disable(configuration); + + // Enable and run: Write Read Test + acc_rss_assembly_test_configuration_communication_write_read_test_enable(configuration); + if (!run_test(configuration)) + { + test_result[t++] = 0; //(4) + acc_rss_assembly_test_configuration_destroy(&configuration); + acc_rss_deactivate(); + //return EXIT_FAILURE; + } else { + test_result[t++] = 1; + } + + acc_rss_assembly_test_configuration_communication_write_read_test_disable(configuration); + + // Enable and run: Interrupt Test + acc_rss_assembly_test_configuration_communication_interrupt_test_enable(configuration); + if (!run_test(configuration)) + { + test_result[t++] = 0; //(5) + acc_rss_assembly_test_configuration_destroy(&configuration); + acc_rss_deactivate(); + //return EXIT_FAILURE; + } else { + + test_result[t++] = 1; + } + + acc_rss_assembly_test_configuration_communication_interrupt_test_disable(configuration); + + // Enable and run: Hibernate Test + acc_rss_assembly_test_configuration_communication_hibernate_test_enable(configuration); + if (!run_test(configuration)) + { + test_result[t++] = 0; //(6) + acc_rss_assembly_test_configuration_destroy(&configuration); + acc_rss_deactivate(); + //return EXIT_FAILURE; + } else { + + test_result[t++] = 1; + } + + acc_rss_assembly_test_configuration_communication_hibernate_test_disable(configuration); + + // Enable and run: Supply Test + acc_rss_assembly_test_configuration_supply_test_enable(configuration); + if (!run_test(configuration)) + { + test_result[t++] = 0; //(7) + acc_rss_assembly_test_configuration_destroy(&configuration); + acc_rss_deactivate(); + //return EXIT_FAILURE; + } else { + + test_result[t++] = 1; + } + + acc_rss_assembly_test_configuration_supply_test_disable(configuration); + + // Enable and run: Clock Test + acc_rss_assembly_test_configuration_clock_test_enable(configuration); + if (!run_test(configuration)) + { + test_result[t++] = 0; // (8) + acc_rss_assembly_test_configuration_destroy(&configuration); + acc_rss_deactivate(); + //return EXIT_FAILURE; + } else { + + test_result[t++] = 1; + } + + acc_rss_assembly_test_configuration_clock_test_disable(configuration); + + // Enable and run: Power cycle test + acc_rss_assembly_test_configuration_power_cycle_test_enable(configuration); + if (!run_test(configuration)) + { + test_result[t++] = 0; //(9) + acc_rss_assembly_test_configuration_destroy(&configuration); + acc_rss_deactivate(); + //return EXIT_FAILURE; + } else { + + test_result[t++] = 1; + } + + + acc_rss_assembly_test_configuration_power_cycle_test_disable(configuration); + + APP_LOG(TS_OFF, VLEVEL_H,"-- 10 -- Bring up test: All tests passed\n"); + test_result[t++] = 1; //(10) + + memcpy(rss_self_test_result, test_result, t); + APP_LOG(TS_OFF, VLEVEL_H,"--Bring up test result #=%d \r\n", t); + acc_rss_assembly_test_configuration_destroy(&configuration); + acc_rss_deactivate(); + + return EXIT_SUCCESS; +} + + +static bool run_test(acc_rss_assembly_test_configuration_t configuration) +{ + acc_rss_assembly_test_result_t test_results[ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS]; + uint16_t nr_of_test_results = ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS; + bool all_passed = true; + + if (!acc_rss_assembly_test(configuration, test_results, &nr_of_test_results)) + { + APP_LOG(TS_OFF, VLEVEL_H,"Bring up test: Failed to complete\n"); + return false; + } else { + APP_LOG(TS_OFF, VLEVEL_H,"Bring up test: SUCCESS to complete\n"); + + } + + for (uint16_t i = 0; i < nr_of_test_results; i++) + { + const bool passed = test_results[i].test_passed; + APP_LOG(TS_OFF, VLEVEL_H,"Name: %s, result: %s\n", test_results[i].test_name, passed ? "Pass" : "Fail"); + + if (!passed) + { + all_passed = false; + } + } + + return all_passed; +} diff --git a/Core/Src/yunhorn_sts_presence_sensor.c b/Core/Src/yunhorn_sts_presence_sensor.c index afc6b9c..cf4eb07 100644 --- a/Core/Src/yunhorn_sts_presence_sensor.c +++ b/Core/Src/yunhorn_sts_presence_sensor.c @@ -1,462 +1,462 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file yunhorn_sts_presence_sensor.c * - * @author Yunhorn (r) Technology Limited Application Team * - * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 Yunhorn Technology Limited. - * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "stdint.h" -#include "platform.h" -#include "sys_conf.h" -#include "sys_app.h" -#include "stdio.h" -#include "stm32_systime.h" -#include "adc_if.h" -#include "gpio.h" -#include "LmHandler.h" -#include "lora_app.h" -#include "yunhorn_sts_prd_conf.h" -#include "yunhorn_sts_sensors.h" -#include "sts_cmox_hmac_sha.h" -/* USER CODE BEGIN Includes */ -#if (defined(USE_ACCONEER_A111)) - -extern volatile uint8_t sts_ac_code[20]; -volatile STS_OO_SensorStatusDataTypeDef sts_o6_sensorData; -volatile STS_PRESENCE_SENSOR_Event_Status_t sts_o6_event_status; -volatile float sts_distance_rss_distance; -extern volatile float sts_presence_rss_distance, sts_presence_rss_score; -volatile uint8_t sts_rss_config_updated_flag = 0; -extern volatile uint8_t sensor_data_ready; -extern volatile uint8_t mems_int1_detected, link_wakeup, link_sleep; -extern volatile uint32_t event_start_time, event_stop_time; -extern volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config; -extern volatile sts_cfg_nvm_t sts_cfg_nvm; -extern volatile uint8_t sts_fall_detection_acc_threshold, sts_fall_detection_depth_threshold, sts_occupancy_overtime_threshold; -extern volatile uint8_t sts_reed_hall_result, sts_rss_result, sts_rss_2nd_result,sts_tof_result, sts_status_color, sts_lamp_bar_color, sts_work_mode, sts_service_mask; -extern volatile distance_measure_cfg_t distance_cfg; -extern uint8_t sts_fall_rising_detected_result; -extern volatile uint16_t sts_fall_rising_pattern_factor1; -extern volatile uint16_t sts_roc_acc_standard_variance; -extern uint8_t luminance_level; -SysTime_t mems_event_time; - -#endif - -/* USER CODE END Includes */ - -/* External variables ---------------------------------------------------------*/ -/* USER CODE BEGIN EV */ - -/* USER CODE END EV */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN PTD */ - -/* USER CODE END PTD */ - -/* Private define ------------------------------------------------------------*/ - -/* USER CODE BEGIN PD */ - -/* USER CODE END PD */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN PM */ - -/* USER CODE END PM */ - -/* Private variables ---------------------------------------------------------*/ - -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ -#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111)) - -#endif - -/* USER CODE END PFP */ - -/* Exported functions --------------------------------------------------------*/ - -void STS_FallDetection_LampBarProcess(void) -{ - uint8_t buf[32]={0x0}; - uint8_t i=0; - switch (sts_fall_rising_detected_result) - { - case STS_PRESENCE_LAYDOWN: - - break; - case STS_PRESENCE_FALL: - sts_lamp_bar_color = STS_BLUE; //STS_RED_BLUE; - sts_status_color = STS_BLUE; //STS_RED_BLUE; - sts_rss_result = STS_RESULT_MOTION; - STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); - - buf[i++] = (uint8_t)sts_lamp_bar_color; - buf[i++] = (uint8_t)sts_work_mode; - buf[i++] = (uint8_t)sts_fall_rising_detected_result; - - buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1/10 + 0x30)&0xFF; - buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1%10 + 0x30)&0xFF; - buf[i++] = (uint8_t)(sts_roc_acc_standard_variance/10 + 0x30)&0xFF; - buf[i++] = (uint8_t)(sts_roc_acc_standard_variance%10 + 0x30)&0xFF; - break; - - case STS_PRESENCE_RISING: - sts_lamp_bar_color = STS_RED; // normal occupancy status - sts_status_color = STS_RED; // normal occupancy status - sts_rss_result = STS_RESULT_MOTION; - STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); - buf[i++] = (uint8_t)sts_lamp_bar_color; - buf[i++] = (uint8_t)sts_work_mode; - buf[i++] = (uint8_t)sts_fall_rising_detected_result; - - // TESTING ONLY TO BE REMOVED - buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1/10 + 0x30)&0xFF; - buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1%10 + 0x30)&0xFF; - buf[i++] = (uint8_t)(sts_roc_acc_standard_variance/10 + 0x30)&0xFF; - buf[i++] = (uint8_t)(sts_roc_acc_standard_variance%10 + 0x30)&0xFF; - break; - - default: - break; - } - - APP_LOG(TS_OFF, VLEVEL_L, "\r\n <<<<<<<<<<<<<< Fall Rise state=%d, send buf size = %d \r\n", - sts_fall_rising_detected_result, i ) - - STS_SENSOR_Upload_Message((LORAWAN_USER_APP_PORT+2), i, (char*)buf); - - sts_fall_rising_detected_result = STS_PRESENCE_NONE; - -} - -void STS_YunhornSTSFallDetection(void) -{ - //APP_LOG(TS_OFF, VLEVEL_M, "\r\n YUNHORN STS FALL DETECTION \r\n"); - - //STS_YunhornCheckStandardDeviation(); - -} - -void STS_PRESENCE_SENSOR_NVM_CFG(void) -{ - sts_presence_rss_config.default_start_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f); - sts_presence_rss_config.default_length_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f); - sts_presence_rss_config.default_threshold = (float)((float)sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f); - sts_presence_rss_config.default_receiver_gain = (float)((float)sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f); - - sts_presence_rss_config.default_zone_length_m = DEFAULT_ZONE_LENGTH; - sts_presence_rss_config.default_profile = (float)(sts_cfg_nvm.p[RSS_CFG_PROFILE]); - sts_presence_rss_config.default_update_rate_tracking = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_TRACKING]); - sts_presence_rss_config.default_update_rate_presence = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_PRESENCE]); - sts_presence_rss_config.default_hwaas = (float)(sts_cfg_nvm.p[RSS_CFG_HWAAS]); - - sts_presence_rss_config.default_nbr_removed_pc = (float)(sts_cfg_nvm.p[RSS_CFG_NBR_REMOVED_PC]); - -//filter parameter - sts_presence_rss_config.default_inter_frame_deviation_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_DEVIATION]*0.1f); - sts_presence_rss_config.default_inter_frame_fast_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_FAST_CUTOFF]); - sts_presence_rss_config.default_inter_frame_slow_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_SLOW_CUTOFF]*0.01f); - sts_presence_rss_config.default_intra_frame_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_TIME]); - sts_presence_rss_config.default_intra_frame_weight = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_WEIGHT]*0.1f); - sts_presence_rss_config.default_output_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_OUTPUT_TIME]*0.1f); -//filter parameter - - sts_presence_rss_config.default_downsampling_factor = (float)(sts_cfg_nvm.p[RSS_CFG_DOWNSAMPLING_FACTOR]); - sts_presence_rss_config.default_power_save_mode = (float)(sts_cfg_nvm.p[RSS_CFG_POWER_MODE]); - - sts_rss_config_updated_flag = STS_RSS_CONFIG_FULL; //set to 2 for FULL config effect in next detection -} - -void STS_PRESENCE_SENSOR_NVM_CFG_SIMPLE(void) -{ - sts_presence_rss_config.default_start_m = (float)(sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f); - sts_presence_rss_config.default_length_m = (float)(sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f); - sts_presence_rss_config.default_threshold = (float)(sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f); - sts_presence_rss_config.default_receiver_gain = (float)(sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f); - - sts_rss_config_updated_flag = STS_RSS_CONFIG_SIMPLE; //set to 1 for simple config effect in next detection -} - -void STS_PRESENCE_SENSOR_Init_Send_Data(void) -{ - sts_o6_sensorData.lamp_bar_color = STS_GREEN; - sts_o6_sensorData.workmode = STS_DUAL_MODE; - - sts_o6_sensorData.state_sensor1_on_off = 0x0; - sts_o6_sensorData.state_sensor2_on_off = 0x0; - sts_o6_sensorData.state_sensor3_on_off = 0x0; - sts_o6_sensorData.state_sensor4_on_off = 0x0; - sts_o6_sensorData.rss_presence_distance = 0x0; - sts_o6_sensorData.rss_presence_score = 0x0; - sts_o6_sensorData.fall_state = STS_PRESENCE_NONE; - sts_o6_sensorData.fall_speed = 0x0; - sts_o6_sensorData.fall_gravity = 0x0; - sts_o6_sensorData.event_start_time = 0x0; - sts_o6_sensorData.event_stop_time = 0x0; - sts_o6_sensorData.overtime = 0x0; - - sts_o6_sensorData.battery_Pct = 99; // 99% as init value - sts_o6_sensorData.dutycycletimelevel = 1; - sensor_data_ready = 0; -} -void STS_PRESENCE_SENSOR_Prepare_Send_Data(void) -{ - sts_o6_sensorData.lamp_bar_color = sts_lamp_bar_color; - sts_o6_sensorData.workmode = sts_work_mode; - sts_o6_sensorData.state_sensor1_on_off = ((STS_Reed_Hall_State == STS_Status_Door_Open)? 0U:1U); - sts_o6_sensorData.state_sensor2_on_off = sts_rss_result; - sts_o6_sensorData.state_sensor3_on_off = sts_tof_result; - sts_o6_sensorData.state_sensor4_on_off = sts_rss_2nd_result; - if (sts_rss_result == STS_RESULT_MOTION) - { - sts_o6_sensorData.rss_presence_distance = (uint16_t)(sts_presence_rss_distance)&0xFFFF; - sts_o6_sensorData.rss_presence_score = (uint16_t)(sts_presence_rss_score)&0xFFFF; - } else { - sts_o6_sensorData.rss_presence_distance = 0x0; - sts_o6_sensorData.rss_presence_score = 0x0; - } - sts_o6_sensorData.fall_state = sts_fall_rising_detected_result; - if (sts_fall_rising_detected_result != STS_PRESENCE_NONE) - { - sts_o6_sensorData.fall_speed = (uint8_t)sts_fall_rising_pattern_factor1; - sts_o6_sensorData.fall_gravity = (uint8_t)sts_roc_acc_standard_variance; - } - - sts_o6_sensorData.overtime = (event_stop_time - event_start_time)> (sts_occupancy_overtime_threshold*60)? 1:0; - sts_o6_sensorData.event_start_time = event_start_time; - sts_o6_sensorData.event_stop_time = event_stop_time; -} - -void STS_PRESENCE_SENSOR_Read(STS_OO_SensorStatusDataTypeDef *o6_data) -{ - o6_data->lamp_bar_color = (uint8_t)sts_o6_sensorData.lamp_bar_color; - o6_data->workmode = (uint8_t)sts_o6_sensorData.workmode; - - o6_data->state_sensor1_on_off = (uint8_t)sts_o6_sensorData.state_sensor1_on_off; - o6_data->state_sensor2_on_off = (uint8_t)sts_o6_sensorData.state_sensor2_on_off; - o6_data->state_sensor3_on_off = (uint8_t)sts_o6_sensorData.state_sensor3_on_off; - o6_data->state_sensor4_on_off = (uint8_t)sts_o6_sensorData.state_sensor4_on_off; - o6_data->rss_presence_distance = (uint16_t)sts_o6_sensorData.rss_presence_distance; - o6_data->rss_presence_score = (uint16_t)sts_o6_sensorData.rss_presence_score; - o6_data->event_start_time = (uint32_t)sts_o6_sensorData.event_start_time; - o6_data->event_stop_time = (uint32_t)sts_o6_sensorData.event_stop_time; - o6_data->overtime = (uint8_t)sts_o6_sensorData.overtime; - - o6_data->battery_Pct = (uint8_t)sts_o6_sensorData.battery_Pct; - o6_data->dutycycletimelevel = (uint8_t)sts_o6_sensorData.dutycycletimelevel; - -} - -void STS_PRESENCE_SENSOR_GetValue(void) -{ - -} - -void STS_PRESENCE_SENSOR_WakeUp_Process_Sampling(void) -{ - if ((sensor_data_ready ==0)) { - STS_PRESENCE_SENSOR_GetValue(); - } -} - -void STS_PRESENCE_SENSOR_After_Wake_Up() -{ - -} - -/** - * @brief Initializes the motion sensors - * @param Instance Motion sensor instance - * @param Functions Motion sensor functions. Could be : - * - MOTION_ACCELERO for instance - * @retval BSP status - */ -void STS_PRESENCE_SENSOR_Init(void) -{ - APP_LOG(TS_ON, VLEVEL_M, "##### YunHorn SmarToilets(r) Presence Sensor Started\r\n"); - - sts_o6_sensorData.workmode = (uint8_t)STS_DUAL_MODE; - sts_o6_sensorData.lamp_bar_color = (uint8_t)STS_GREEN; - sts_o6_sensorData.battery_Pct = 99; - sts_o6_sensorData.dutycycletimelevel = 1; - sts_o6_sensorData.event_start_time = 0; - sts_o6_sensorData.event_stop_time = 0; - - STS_SENSOR_Power_ON(0); - STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init(); - STS_PRESENCE_SENSOR_TOF_Init(); - STS_PRESENCE_SENSOR_RSS_Init(); - - mems_int1_detected=0; -} - -void STS_PRESENCE_SENSOR_TOF_Init(void) -{ - APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS TOF Initializing \r\n"); - -} -void STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init(void) -{ - - APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) REED SWITCH HALL ELEMENT Initializing \r\n"); - -} -void STS_PRESENCE_SENSOR_RSS_Init(void) -{ - APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS RSS Initializing \r\n"); - - STS_SENSOR_Power_ON(0); - - STS_PRESENCE_SENSOR_NVM_CFG(); - - sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT; - - mems_int1_detected=0; - -} - -void STS_MOTION_SENSOR_ACT_INACT_DURATION_Init() -{ - -} - -void STS_PRESENCE_SENSOR_Get_Event_Status(STS_PRESENCE_SENSOR_Event_Status_t *Status) -{ - uint8_t int_source=0; - SysTime_t mems_event_time; - //int_source = ADXL345_GetRegisterValue(ADXL345_REG_INT_SOURCE); - - if (int_source & 0x10) { - mems_event_time = SysTimeGetMcuTime(); - Status->WakeUpStatus = 1U; - event_start_time = mems_event_time.Seconds; - } - else { - Status->WakeUpStatus =0U; - } - - if (int_source & 0x08) { - mems_event_time = SysTimeGetMcuTime(); - Status->SleepStatus = 1U; - event_stop_time = mems_event_time.Seconds; - } - else { - Status->SleepStatus = 0U; - - } - - -} - - -void STS_PRESENCE_SENSOR_Distance_Measure_Process(void) -{ - uint8_t exit_status = EXIT_SUCCESS, i=0; - - APP_LOG(TS_OFF, VLEVEL_H, "\r\n ****start_m=%u length_m=%u profile=%u hwaas=%u \r\n", - (unsigned int)(distance_cfg.start_m*1000),(unsigned int)(distance_cfg.length_m*1000), - (unsigned int)(distance_cfg.acc_profile),(unsigned int)(distance_cfg.hwaas)); - do - { - exit_status = sts_distance_rss_detector_distance(); - HAL_Delay(100); - i++; - } while ((exit_status == EXIT_FAILURE) && (i < 1)); - -} - -void STS_PRESENCE_SENSOR_Function_Test_Process(uint8_t *self_test_result, uint8_t count) -{ - uint8_t bring_up_result[20]; - STS_SENSOR_Power_ON(0); - HAL_Init(); - MX_GPIO_Init(); - HAL_Delay(150); //wait for sensor ready - - for (uint8_t i=0;i < count; i++) //while(1) - { - STS_Lamp_Bar_Self_Test_Simple(); - - sts_presence_rss_bring_up_test(bring_up_result); - - HAL_Delay(5000); - - STS_PRESENCE_SENSOR_Distance_Measure_Process(); - - } - - memcpy(self_test_result,bring_up_result, 10); - mems_int1_detected=0; -} - - -void STS_PRESENCE_SENSOR_Enable_Wake_Up_Detection() -{ - -} - -void STS_PRESENCE_SENSOR_Disable_Wake_Up_Detection(void) -{ - -} - -uint8_t STS_SENSOR_MEMS_Get_ID(uint8_t *devID) -{ - uint8_t scanned_id[2] = {0x0,0x0}; - -#ifdef USE_ACCONEER_A111 - if (hal_test_spi_read_chipid(scanned_id)) - { - devID[0] = scanned_id[0]; - devID[1] = scanned_id[1]; - return true; - } - else - { - return false; - } -#endif - -} -/* -uint16_t STS_RSS_A111_GetDeviceIDValue(void) -{ - uint16_t devid=0; - if (STS_SENSOR_MEMS_Get_ID(&devid)) - { - return (uint16_t)devid; - } else return 0; -} -*/ - - -/* USER CODE BEGIN EF */ - -/* USER CODE END EF */ - -/* Private Functions Definition -----------------------------------------------*/ -/* USER CODE BEGIN PrFD */ - -/* USER CODE END PrFD */ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file yunhorn_sts_presence_sensor.c * + * @author Yunhorn (r) Technology Limited Application Team * + * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 Yunhorn Technology Limited. + * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stdint.h" +#include "platform.h" +#include "sys_conf.h" +#include "sys_app.h" +#include "stdio.h" +#include "stm32_systime.h" +#include "adc_if.h" +#include "gpio.h" +#include "LmHandler.h" +#include "lora_app.h" +#include "yunhorn_sts_prd_conf.h" +#include "yunhorn_sts_sensors.h" +#include "sts_cmox_hmac_sha.h" +/* USER CODE BEGIN Includes */ +#if (defined(USE_ACCONEER_A111)) + +extern volatile uint8_t sts_ac_code[20]; +volatile STS_OO_SensorStatusDataTypeDef sts_o6_sensorData; +volatile STS_PRESENCE_SENSOR_Event_Status_t sts_o6_event_status; +volatile float sts_distance_rss_distance; +extern volatile float sts_presence_rss_distance, sts_presence_rss_score; +volatile uint8_t sts_rss_config_updated_flag = 0; +extern volatile uint8_t sensor_data_ready; +extern volatile uint8_t mems_int1_detected, link_wakeup, link_sleep; +extern volatile uint32_t event_start_time, event_stop_time; +extern volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config; +extern volatile sts_cfg_nvm_t sts_cfg_nvm; +extern volatile uint8_t sts_fall_detection_acc_threshold, sts_fall_detection_depth_threshold, sts_occupancy_overtime_threshold; +extern volatile uint8_t sts_reed_hall_result, sts_rss_result, sts_rss_2nd_result,sts_tof_result, sts_status_color, sts_lamp_bar_color, sts_work_mode, sts_service_mask; +extern volatile distance_measure_cfg_t distance_cfg; +extern uint8_t sts_fall_rising_detected_result; +extern volatile uint16_t sts_fall_rising_pattern_factor1; +extern volatile uint16_t sts_roc_acc_standard_variance; +extern uint8_t luminance_level; +SysTime_t mems_event_time; + +#endif + +/* USER CODE END Includes */ + +/* External variables ---------------------------------------------------------*/ +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ + +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ +#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111)) + +#endif + +/* USER CODE END PFP */ + +/* Exported functions --------------------------------------------------------*/ + +void STS_FallDetection_LampBarProcess(void) +{ + uint8_t buf[32]={0x0}; + uint8_t i=0; + switch (sts_fall_rising_detected_result) + { + case STS_PRESENCE_LAYDOWN: + + break; + case STS_PRESENCE_FALL: + sts_lamp_bar_color = STS_BLUE; //STS_RED_BLUE; + sts_status_color = STS_BLUE; //STS_RED_BLUE; + sts_rss_result = STS_RESULT_MOTION; + STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); + + buf[i++] = (uint8_t)sts_lamp_bar_color; + buf[i++] = (uint8_t)sts_work_mode; + buf[i++] = (uint8_t)sts_fall_rising_detected_result; + + buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1/10 + 0x30)&0xFF; + buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1%10 + 0x30)&0xFF; + buf[i++] = (uint8_t)(sts_roc_acc_standard_variance/10 + 0x30)&0xFF; + buf[i++] = (uint8_t)(sts_roc_acc_standard_variance%10 + 0x30)&0xFF; + break; + + case STS_PRESENCE_RISING: + sts_lamp_bar_color = STS_RED; // normal occupancy status + sts_status_color = STS_RED; // normal occupancy status + sts_rss_result = STS_RESULT_MOTION; + STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); + buf[i++] = (uint8_t)sts_lamp_bar_color; + buf[i++] = (uint8_t)sts_work_mode; + buf[i++] = (uint8_t)sts_fall_rising_detected_result; + + // TESTING ONLY TO BE REMOVED + buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1/10 + 0x30)&0xFF; + buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1%10 + 0x30)&0xFF; + buf[i++] = (uint8_t)(sts_roc_acc_standard_variance/10 + 0x30)&0xFF; + buf[i++] = (uint8_t)(sts_roc_acc_standard_variance%10 + 0x30)&0xFF; + break; + + default: + break; + } + + APP_LOG(TS_OFF, VLEVEL_L, "\r\n <<<<<<<<<<<<<< Fall Rise state=%d, send buf size = %d \r\n", + sts_fall_rising_detected_result, i ) + + STS_SENSOR_Upload_Message((LORAWAN_USER_APP_PORT+2), i, (char*)buf); + + sts_fall_rising_detected_result = STS_PRESENCE_NONE; + +} + +void STS_YunhornSTSFallDetection(void) +{ + //APP_LOG(TS_OFF, VLEVEL_M, "\r\n YUNHORN STS FALL DETECTION \r\n"); + + //STS_YunhornCheckStandardDeviation(); + +} + +void STS_PRESENCE_SENSOR_NVM_CFG(void) +{ + sts_presence_rss_config.default_start_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f); + sts_presence_rss_config.default_length_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f); + sts_presence_rss_config.default_threshold = (float)((float)sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f); + sts_presence_rss_config.default_receiver_gain = (float)((float)sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f); + + sts_presence_rss_config.default_zone_length_m = DEFAULT_ZONE_LENGTH; + sts_presence_rss_config.default_profile = (float)(sts_cfg_nvm.p[RSS_CFG_PROFILE]); + sts_presence_rss_config.default_update_rate_tracking = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_TRACKING]); + sts_presence_rss_config.default_update_rate_presence = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_PRESENCE]); + sts_presence_rss_config.default_hwaas = (float)(sts_cfg_nvm.p[RSS_CFG_HWAAS]); + + sts_presence_rss_config.default_nbr_removed_pc = (float)(sts_cfg_nvm.p[RSS_CFG_NBR_REMOVED_PC]); + +//filter parameter + sts_presence_rss_config.default_inter_frame_deviation_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_DEVIATION]*0.1f); + sts_presence_rss_config.default_inter_frame_fast_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_FAST_CUTOFF]); + sts_presence_rss_config.default_inter_frame_slow_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_SLOW_CUTOFF]*0.01f); + sts_presence_rss_config.default_intra_frame_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_TIME]); + sts_presence_rss_config.default_intra_frame_weight = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_WEIGHT]*0.1f); + sts_presence_rss_config.default_output_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_OUTPUT_TIME]*0.1f); +//filter parameter + + sts_presence_rss_config.default_downsampling_factor = (float)(sts_cfg_nvm.p[RSS_CFG_DOWNSAMPLING_FACTOR]); + sts_presence_rss_config.default_power_save_mode = (float)(sts_cfg_nvm.p[RSS_CFG_POWER_MODE]); + + sts_rss_config_updated_flag = STS_RSS_CONFIG_FULL; //set to 2 for FULL config effect in next detection +} + +void STS_PRESENCE_SENSOR_NVM_CFG_SIMPLE(void) +{ + sts_presence_rss_config.default_start_m = (float)(sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f); + sts_presence_rss_config.default_length_m = (float)(sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f); + sts_presence_rss_config.default_threshold = (float)(sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f); + sts_presence_rss_config.default_receiver_gain = (float)(sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f); + + sts_rss_config_updated_flag = STS_RSS_CONFIG_SIMPLE; //set to 1 for simple config effect in next detection +} + +void STS_PRESENCE_SENSOR_Init_Send_Data(void) +{ + sts_o6_sensorData.lamp_bar_color = STS_GREEN; + sts_o6_sensorData.workmode = STS_DUAL_MODE; + + sts_o6_sensorData.state_sensor1_on_off = 0x0; + sts_o6_sensorData.state_sensor2_on_off = 0x0; + sts_o6_sensorData.state_sensor3_on_off = 0x0; + sts_o6_sensorData.state_sensor4_on_off = 0x0; + sts_o6_sensorData.rss_presence_distance = 0x0; + sts_o6_sensorData.rss_presence_score = 0x0; + sts_o6_sensorData.fall_state = STS_PRESENCE_NONE; + sts_o6_sensorData.fall_speed = 0x0; + sts_o6_sensorData.fall_gravity = 0x0; + sts_o6_sensorData.event_start_time = 0x0; + sts_o6_sensorData.event_stop_time = 0x0; + sts_o6_sensorData.overtime = 0x0; + + sts_o6_sensorData.battery_Pct = 99; // 99% as init value + sts_o6_sensorData.dutycycletimelevel = 1; + sensor_data_ready = 0; +} +void STS_PRESENCE_SENSOR_Prepare_Send_Data(void) +{ + sts_o6_sensorData.lamp_bar_color = sts_lamp_bar_color; + sts_o6_sensorData.workmode = sts_work_mode; + sts_o6_sensorData.state_sensor1_on_off = ((STS_Reed_Hall_State == STS_Status_Door_Open)? 0U:1U); + sts_o6_sensorData.state_sensor2_on_off = sts_rss_result; + sts_o6_sensorData.state_sensor3_on_off = sts_tof_result; + sts_o6_sensorData.state_sensor4_on_off = sts_rss_2nd_result; + if (sts_rss_result == STS_RESULT_MOTION) + { + sts_o6_sensorData.rss_presence_distance = (uint16_t)(sts_presence_rss_distance)&0xFFFF; + sts_o6_sensorData.rss_presence_score = (uint16_t)(sts_presence_rss_score)&0xFFFF; + } else { + sts_o6_sensorData.rss_presence_distance = 0x0; + sts_o6_sensorData.rss_presence_score = 0x0; + } + sts_o6_sensorData.fall_state = sts_fall_rising_detected_result; + if (sts_fall_rising_detected_result != STS_PRESENCE_NONE) + { + sts_o6_sensorData.fall_speed = (uint8_t)sts_fall_rising_pattern_factor1; + sts_o6_sensorData.fall_gravity = (uint8_t)sts_roc_acc_standard_variance; + } + + sts_o6_sensorData.overtime = (event_stop_time - event_start_time)> (sts_occupancy_overtime_threshold*60)? 1:0; + sts_o6_sensorData.event_start_time = event_start_time; + sts_o6_sensorData.event_stop_time = event_stop_time; +} + +void STS_PRESENCE_SENSOR_Read(STS_OO_SensorStatusDataTypeDef *o6_data) +{ + o6_data->lamp_bar_color = (uint8_t)sts_o6_sensorData.lamp_bar_color; + o6_data->workmode = (uint8_t)sts_o6_sensorData.workmode; + + o6_data->state_sensor1_on_off = (uint8_t)sts_o6_sensorData.state_sensor1_on_off; + o6_data->state_sensor2_on_off = (uint8_t)sts_o6_sensorData.state_sensor2_on_off; + o6_data->state_sensor3_on_off = (uint8_t)sts_o6_sensorData.state_sensor3_on_off; + o6_data->state_sensor4_on_off = (uint8_t)sts_o6_sensorData.state_sensor4_on_off; + o6_data->rss_presence_distance = (uint16_t)sts_o6_sensorData.rss_presence_distance; + o6_data->rss_presence_score = (uint16_t)sts_o6_sensorData.rss_presence_score; + o6_data->event_start_time = (uint32_t)sts_o6_sensorData.event_start_time; + o6_data->event_stop_time = (uint32_t)sts_o6_sensorData.event_stop_time; + o6_data->overtime = (uint8_t)sts_o6_sensorData.overtime; + + o6_data->battery_Pct = (uint8_t)sts_o6_sensorData.battery_Pct; + o6_data->dutycycletimelevel = (uint8_t)sts_o6_sensorData.dutycycletimelevel; + +} + +void STS_PRESENCE_SENSOR_GetValue(void) +{ + +} + +void STS_PRESENCE_SENSOR_WakeUp_Process_Sampling(void) +{ + if ((sensor_data_ready ==0)) { + STS_PRESENCE_SENSOR_GetValue(); + } +} + +void STS_PRESENCE_SENSOR_After_Wake_Up() +{ + +} + +/** + * @brief Initializes the motion sensors + * @param Instance Motion sensor instance + * @param Functions Motion sensor functions. Could be : + * - MOTION_ACCELERO for instance + * @retval BSP status + */ +void STS_PRESENCE_SENSOR_Init(void) +{ + APP_LOG(TS_ON, VLEVEL_M, "##### YunHorn SmarToilets(r) Presence Sensor Started\r\n"); + + sts_o6_sensorData.workmode = (uint8_t)STS_DUAL_MODE; + sts_o6_sensorData.lamp_bar_color = (uint8_t)STS_GREEN; + sts_o6_sensorData.battery_Pct = 99; + sts_o6_sensorData.dutycycletimelevel = 1; + sts_o6_sensorData.event_start_time = 0; + sts_o6_sensorData.event_stop_time = 0; + + STS_SENSOR_Power_ON(0); + STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init(); + STS_PRESENCE_SENSOR_TOF_Init(); + STS_PRESENCE_SENSOR_RSS_Init(); + + mems_int1_detected=0; +} + +void STS_PRESENCE_SENSOR_TOF_Init(void) +{ + APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS TOF Initializing \r\n"); + +} +void STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init(void) +{ + + APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) REED SWITCH HALL ELEMENT Initializing \r\n"); + +} +void STS_PRESENCE_SENSOR_RSS_Init(void) +{ + APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS RSS Initializing \r\n"); + + STS_SENSOR_Power_ON(0); + + STS_PRESENCE_SENSOR_NVM_CFG(); + + sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT; + + mems_int1_detected=0; + +} + +void STS_MOTION_SENSOR_ACT_INACT_DURATION_Init() +{ + +} + +void STS_PRESENCE_SENSOR_Get_Event_Status(STS_PRESENCE_SENSOR_Event_Status_t *Status) +{ + uint8_t int_source=0; + SysTime_t mems_event_time; + //int_source = ADXL345_GetRegisterValue(ADXL345_REG_INT_SOURCE); + + if (int_source & 0x10) { + mems_event_time = SysTimeGetMcuTime(); + Status->WakeUpStatus = 1U; + event_start_time = mems_event_time.Seconds; + } + else { + Status->WakeUpStatus =0U; + } + + if (int_source & 0x08) { + mems_event_time = SysTimeGetMcuTime(); + Status->SleepStatus = 1U; + event_stop_time = mems_event_time.Seconds; + } + else { + Status->SleepStatus = 0U; + + } + + +} + + +void STS_PRESENCE_SENSOR_Distance_Measure_Process(void) +{ + uint8_t exit_status = EXIT_SUCCESS, i=0; + + APP_LOG(TS_OFF, VLEVEL_H, "\r\n ****start_m=%u length_m=%u profile=%u hwaas=%u \r\n", + (unsigned int)(distance_cfg.start_m*1000),(unsigned int)(distance_cfg.length_m*1000), + (unsigned int)(distance_cfg.acc_profile),(unsigned int)(distance_cfg.hwaas)); + do + { + exit_status = sts_distance_rss_detector_distance(); + HAL_Delay(100); + i++; + } while ((exit_status == EXIT_FAILURE) && (i < 1)); + +} + +void STS_PRESENCE_SENSOR_Function_Test_Process(uint8_t *self_test_result, uint8_t count) +{ + uint8_t bring_up_result[20]; + STS_SENSOR_Power_ON(0); + HAL_Init(); + MX_GPIO_Init(); + HAL_Delay(150); //wait for sensor ready + + for (uint8_t i=0;i < count; i++) //while(1) + { + STS_Lamp_Bar_Self_Test_Simple(); + + sts_presence_rss_bring_up_test(bring_up_result); + + HAL_Delay(5000); + + STS_PRESENCE_SENSOR_Distance_Measure_Process(); + + } + + memcpy(self_test_result,bring_up_result, 10); + mems_int1_detected=0; +} + + +void STS_PRESENCE_SENSOR_Enable_Wake_Up_Detection() +{ + +} + +void STS_PRESENCE_SENSOR_Disable_Wake_Up_Detection(void) +{ + +} + +uint8_t STS_SENSOR_MEMS_Get_ID(uint8_t *devID) +{ + uint8_t scanned_id[2] = {0x0,0x0}; + +#ifdef USE_ACCONEER_A111 + if (hal_test_spi_read_chipid(scanned_id)) + { + devID[0] = scanned_id[0]; + devID[1] = scanned_id[1]; + return true; + } + else + { + return false; + } +#endif + +} +/* +uint16_t STS_RSS_A111_GetDeviceIDValue(void) +{ + uint16_t devid=0; + if (STS_SENSOR_MEMS_Get_ID(&devid)) + { + return (uint16_t)devid; + } else return 0; +} +*/ + + +/* USER CODE BEGIN EF */ + +/* USER CODE END EF */ + +/* Private Functions Definition -----------------------------------------------*/ +/* USER CODE BEGIN PrFD */ + +/* USER CODE END PrFD */ diff --git a/STM32CubeIDE/rss/include/acc_base_configuration.h b/STM32CubeIDE/rss/include/acc_base_configuration.h index cdfb712..14209e9 100644 --- a/STM32CubeIDE/rss/include/acc_base_configuration.h +++ b/STM32CubeIDE/rss/include/acc_base_configuration.h @@ -1,228 +1,228 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_BASE_CONFIGURATION_H_ -#define ACC_BASE_CONFIGURATION_H_ - -#include -#include - -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" - - -/** - * @defgroup Base Service Base Configuration - * - * @brief Service base configuration API description - * - * @{ - */ - - -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_OFF ACC_POWER_SAVE_MODE_OFF -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_SLEEP ACC_POWER_SAVE_MODE_SLEEP -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_READY ACC_POWER_SAVE_MODE_READY -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_ACTIVE ACC_POWER_SAVE_MODE_ACTIVE -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_HIBERNATE ACC_POWER_SAVE_MODE_HIBERNATE - - -/** - * @brief Power save mode data type, see @ref acc_power_save_mode_enum_t - */ -typedef acc_power_save_mode_t acc_base_configuration_power_save_mode_t; - - -/** - * @brief Service base configuration container - */ -struct acc_base_configuration; - -typedef struct acc_base_configuration *acc_base_configuration_t; - - -/** - * @brief Get the sensor ID for the sensor to be configured - * - * @param[in] configuration The base configuration to get the sensor id from - * @return Sensor Id - */ -acc_sensor_id_t acc_base_configuration_sensor_get(acc_base_configuration_t configuration); - - -/** - * @brief Set the sensor ID for the sensor to be configured - * - * @param[in] configuration The base configuration to set the sensor id in - * @param[in] sensor_id The sensor id to set - */ -void acc_base_configuration_sensor_set(acc_base_configuration_t configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get the requested start of the sweep - * - * @param[in] configuration The base configuration to get the requested start from - * @return Requested start - */ -float acc_base_configuration_requested_start_get(acc_base_configuration_t configuration); - - -/** - * @brief Set the requested start of the sweep - * - * @param[in] configuration The base configuration to set the requested start in - * @param[in] start_m The requested start in meters - */ -void acc_base_configuration_requested_start_set(acc_base_configuration_t configuration, float start_m); - - -/** - * @brief Get the requested length of the sweep - * - * @param[in] configuration The base configuration to get the requested length from - * @return Requested length - */ -float acc_base_configuration_requested_length_get(acc_base_configuration_t configuration); - - -/** - * @brief Set the requested length of the sweep - * - * @param[in] configuration The base configuration to set the requested length in - * @param[in] length_m The requested length in meters - */ -void acc_base_configuration_requested_length_set(acc_base_configuration_t configuration, float length_m); - - -/** - * @brief Set the service repetition mode to on demand - * - * In on demand mode, the sensor produces data when requested by the application. - * The application is also responsible for the timing between updates. - * - * This mode must be used if the configured length requires stitching in the service. - * - * @param[in] configuration The base configuration to set on demand mode in - */ -void acc_base_configuration_repetition_mode_on_demand_set(acc_base_configuration_t configuration); - - -/** - * @brief Set the service repetition mode to streaming mode - * - * The sensor produces data according to the configured update rate using sensor - * hardware timing which is very accurate. - * - * @param[in] configuration The base configuration to set streaming mode in - * @param[in] update_rate The output data rate from the service in hertz - */ -void acc_base_configuration_repetition_mode_streaming_set(acc_base_configuration_t configuration, float update_rate); - - -/** - * @brief Get power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data frame aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] configuration The base configuration to get power save mode for - * @return Power save mode - */ -acc_power_save_mode_t acc_base_configuration_power_save_mode_get(acc_base_configuration_t configuration); - - -/** - * @brief Set power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data frame aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] configuration The base configuration to set power save mode in - * @param[in] power_save_mode The power save mode to use - */ -void acc_base_configuration_power_save_mode_set(acc_base_configuration_t configuration, - acc_power_save_mode_t power_save_mode); - - -/** - * @brief Get receiver gain setting - * - * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] configuration The base configuration to get receiver gain setting for - * @return Receiver gain setting - */ -float acc_base_configuration_receiver_gain_get(acc_base_configuration_t configuration); - - -/** - * @brief Set receiver gain setting - * - * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] configuration The base configuration to set receiver gain setting in - * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 - */ -void acc_base_configuration_receiver_gain_set(acc_base_configuration_t configuration, float gain); - - -/** - * @brief Get TX disable mode - * - * Will be true if TX is disabled, false otherwise. - * - * @param[in] configuration The base configuration to set TX disable mode in - * @return TX disable mode - */ -bool acc_base_configuration_tx_disable_get(acc_base_configuration_t configuration); - - -/** - * @brief Set TX disable mode - * - * If set to true, TX disable mode is enabled. This will disable the radio transmitter. - * To measure RX noise floor, it is recommended to also switch off internal - * noise level normalization (see each service if applicable). - * - * @param[in] configuration The base configuration to set TX disable mode in - * @param[in] tx_disable TX disable mode, true or false - */ -void acc_base_configuration_tx_disable_set(acc_base_configuration_t configuration, bool tx_disable); - - -/** - * @brief Get the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The base configuration to get hardware accelerated average samples from - * @return Hardware accelerated average samples - */ -uint8_t acc_base_configuration_hw_accelerated_average_samples_get(acc_base_configuration_t configuration); - - -/** - * @brief Set the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The base configuration to set hardware accelerated average samples in - * @param[in] samples Hardware accelerated average samples - */ -void acc_base_configuration_hw_accelerated_average_samples_set(acc_base_configuration_t configuration, uint8_t samples); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_BASE_CONFIGURATION_H_ +#define ACC_BASE_CONFIGURATION_H_ + +#include +#include + +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" + + +/** + * @defgroup Base Service Base Configuration + * + * @brief Service base configuration API description + * + * @{ + */ + + +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_OFF ACC_POWER_SAVE_MODE_OFF +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_SLEEP ACC_POWER_SAVE_MODE_SLEEP +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_READY ACC_POWER_SAVE_MODE_READY +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_ACTIVE ACC_POWER_SAVE_MODE_ACTIVE +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_HIBERNATE ACC_POWER_SAVE_MODE_HIBERNATE + + +/** + * @brief Power save mode data type, see @ref acc_power_save_mode_enum_t + */ +typedef acc_power_save_mode_t acc_base_configuration_power_save_mode_t; + + +/** + * @brief Service base configuration container + */ +struct acc_base_configuration; + +typedef struct acc_base_configuration *acc_base_configuration_t; + + +/** + * @brief Get the sensor ID for the sensor to be configured + * + * @param[in] configuration The base configuration to get the sensor id from + * @return Sensor Id + */ +acc_sensor_id_t acc_base_configuration_sensor_get(acc_base_configuration_t configuration); + + +/** + * @brief Set the sensor ID for the sensor to be configured + * + * @param[in] configuration The base configuration to set the sensor id in + * @param[in] sensor_id The sensor id to set + */ +void acc_base_configuration_sensor_set(acc_base_configuration_t configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get the requested start of the sweep + * + * @param[in] configuration The base configuration to get the requested start from + * @return Requested start + */ +float acc_base_configuration_requested_start_get(acc_base_configuration_t configuration); + + +/** + * @brief Set the requested start of the sweep + * + * @param[in] configuration The base configuration to set the requested start in + * @param[in] start_m The requested start in meters + */ +void acc_base_configuration_requested_start_set(acc_base_configuration_t configuration, float start_m); + + +/** + * @brief Get the requested length of the sweep + * + * @param[in] configuration The base configuration to get the requested length from + * @return Requested length + */ +float acc_base_configuration_requested_length_get(acc_base_configuration_t configuration); + + +/** + * @brief Set the requested length of the sweep + * + * @param[in] configuration The base configuration to set the requested length in + * @param[in] length_m The requested length in meters + */ +void acc_base_configuration_requested_length_set(acc_base_configuration_t configuration, float length_m); + + +/** + * @brief Set the service repetition mode to on demand + * + * In on demand mode, the sensor produces data when requested by the application. + * The application is also responsible for the timing between updates. + * + * This mode must be used if the configured length requires stitching in the service. + * + * @param[in] configuration The base configuration to set on demand mode in + */ +void acc_base_configuration_repetition_mode_on_demand_set(acc_base_configuration_t configuration); + + +/** + * @brief Set the service repetition mode to streaming mode + * + * The sensor produces data according to the configured update rate using sensor + * hardware timing which is very accurate. + * + * @param[in] configuration The base configuration to set streaming mode in + * @param[in] update_rate The output data rate from the service in hertz + */ +void acc_base_configuration_repetition_mode_streaming_set(acc_base_configuration_t configuration, float update_rate); + + +/** + * @brief Get power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data frame aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] configuration The base configuration to get power save mode for + * @return Power save mode + */ +acc_power_save_mode_t acc_base_configuration_power_save_mode_get(acc_base_configuration_t configuration); + + +/** + * @brief Set power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data frame aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] configuration The base configuration to set power save mode in + * @param[in] power_save_mode The power save mode to use + */ +void acc_base_configuration_power_save_mode_set(acc_base_configuration_t configuration, + acc_power_save_mode_t power_save_mode); + + +/** + * @brief Get receiver gain setting + * + * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] configuration The base configuration to get receiver gain setting for + * @return Receiver gain setting + */ +float acc_base_configuration_receiver_gain_get(acc_base_configuration_t configuration); + + +/** + * @brief Set receiver gain setting + * + * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] configuration The base configuration to set receiver gain setting in + * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 + */ +void acc_base_configuration_receiver_gain_set(acc_base_configuration_t configuration, float gain); + + +/** + * @brief Get TX disable mode + * + * Will be true if TX is disabled, false otherwise. + * + * @param[in] configuration The base configuration to set TX disable mode in + * @return TX disable mode + */ +bool acc_base_configuration_tx_disable_get(acc_base_configuration_t configuration); + + +/** + * @brief Set TX disable mode + * + * If set to true, TX disable mode is enabled. This will disable the radio transmitter. + * To measure RX noise floor, it is recommended to also switch off internal + * noise level normalization (see each service if applicable). + * + * @param[in] configuration The base configuration to set TX disable mode in + * @param[in] tx_disable TX disable mode, true or false + */ +void acc_base_configuration_tx_disable_set(acc_base_configuration_t configuration, bool tx_disable); + + +/** + * @brief Get the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The base configuration to get hardware accelerated average samples from + * @return Hardware accelerated average samples + */ +uint8_t acc_base_configuration_hw_accelerated_average_samples_get(acc_base_configuration_t configuration); + + +/** + * @brief Set the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The base configuration to set hardware accelerated average samples in + * @param[in] samples Hardware accelerated average samples + */ +void acc_base_configuration_hw_accelerated_average_samples_set(acc_base_configuration_t configuration, uint8_t samples); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_definitions_a111.h b/STM32CubeIDE/rss/include/acc_definitions_a111.h index d775490..289301f 100644 --- a/STM32CubeIDE/rss/include/acc_definitions_a111.h +++ b/STM32CubeIDE/rss/include/acc_definitions_a111.h @@ -1,76 +1,76 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_DEFINITIONS_A111_H_ -#define ACC_DEFINITIONS_A111_H_ - -#include - - -/** - * @brief Power save mode - * - * Each power save mode corresponds to how much of the sensor hardware is shutdown - * between data frame aquisition. Mode 'OFF' means that the whole sensor is shutdown. - * Mode 'ACTIVE' means that the sensor is in its active state all the time. - * Mode 'HIBERNATE' means that the sensor is still powered but the internal oscillator is - * turned off and the application needs to clock the sensor by toggling a GPIO a pre-defined - * number of times to enter and exit this mode. Mode 'HIBERNATE' is currently only supported - * by the Sparse service - * - * For each power save mode there will be a limit in the achievable update rate. Mode 'OFF' - * can achieve the lowest power consumption but also has the lowest update rate limit - */ -typedef enum -{ - ACC_POWER_SAVE_MODE_OFF, - ACC_POWER_SAVE_MODE_SLEEP, - ACC_POWER_SAVE_MODE_READY, - ACC_POWER_SAVE_MODE_ACTIVE, - ACC_POWER_SAVE_MODE_HIBERNATE, -} acc_power_save_mode_enum_t; -typedef uint32_t acc_power_save_mode_t; - - -/** - * @brief Service profile - * - * Each profile consists of a number of settings for the sensor that configures - * the RX and TX paths. Profile 1 maximizes on the depth resolution and - * profile 5 maximizes on radar loop gain with a sliding scale in between. - */ -typedef enum -{ - ACC_SERVICE_PROFILE_1 = 1, - ACC_SERVICE_PROFILE_2, - ACC_SERVICE_PROFILE_3, - ACC_SERVICE_PROFILE_4, - ACC_SERVICE_PROFILE_5, -} acc_service_profile_t; - - -/** - * @brief Maximum Unambiguous Range - */ -typedef enum -{ - /** Maximum unambiguous range 11.5 m, maximum measurable distance 7.0 m, pulse repetition frequency 13.0 MHz */ - ACC_SERVICE_MUR_6 = 6, - /** Maximum unambiguous range 17.3 m, maximum measurable distance 12.7 m , pulse repetition frequency 8.7 MHz */ - ACC_SERVICE_MUR_9 = 9, - - /** Default maximum unambiguous range */ - ACC_SERVICE_MUR_DEFAULT = ACC_SERVICE_MUR_6, -} acc_service_mur_t; - - -/** - * Type used when retrieving and setting a sensor calibration context - */ -typedef struct -{ - uint8_t data[64]; -} acc_calibration_context_t; - - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_DEFINITIONS_A111_H_ +#define ACC_DEFINITIONS_A111_H_ + +#include + + +/** + * @brief Power save mode + * + * Each power save mode corresponds to how much of the sensor hardware is shutdown + * between data frame aquisition. Mode 'OFF' means that the whole sensor is shutdown. + * Mode 'ACTIVE' means that the sensor is in its active state all the time. + * Mode 'HIBERNATE' means that the sensor is still powered but the internal oscillator is + * turned off and the application needs to clock the sensor by toggling a GPIO a pre-defined + * number of times to enter and exit this mode. Mode 'HIBERNATE' is currently only supported + * by the Sparse service + * + * For each power save mode there will be a limit in the achievable update rate. Mode 'OFF' + * can achieve the lowest power consumption but also has the lowest update rate limit + */ +typedef enum +{ + ACC_POWER_SAVE_MODE_OFF, + ACC_POWER_SAVE_MODE_SLEEP, + ACC_POWER_SAVE_MODE_READY, + ACC_POWER_SAVE_MODE_ACTIVE, + ACC_POWER_SAVE_MODE_HIBERNATE, +} acc_power_save_mode_enum_t; +typedef uint32_t acc_power_save_mode_t; + + +/** + * @brief Service profile + * + * Each profile consists of a number of settings for the sensor that configures + * the RX and TX paths. Profile 1 maximizes on the depth resolution and + * profile 5 maximizes on radar loop gain with a sliding scale in between. + */ +typedef enum +{ + ACC_SERVICE_PROFILE_1 = 1, + ACC_SERVICE_PROFILE_2, + ACC_SERVICE_PROFILE_3, + ACC_SERVICE_PROFILE_4, + ACC_SERVICE_PROFILE_5, +} acc_service_profile_t; + + +/** + * @brief Maximum Unambiguous Range + */ +typedef enum +{ + /** Maximum unambiguous range 11.5 m, maximum measurable distance 7.0 m, pulse repetition frequency 13.0 MHz */ + ACC_SERVICE_MUR_6 = 6, + /** Maximum unambiguous range 17.3 m, maximum measurable distance 12.7 m , pulse repetition frequency 8.7 MHz */ + ACC_SERVICE_MUR_9 = 9, + + /** Default maximum unambiguous range */ + ACC_SERVICE_MUR_DEFAULT = ACC_SERVICE_MUR_6, +} acc_service_mur_t; + + +/** + * Type used when retrieving and setting a sensor calibration context + */ +typedef struct +{ + uint8_t data[64]; +} acc_calibration_context_t; + + +#endif diff --git a/STM32CubeIDE/rss/include/acc_definitions_common.h b/STM32CubeIDE/rss/include/acc_definitions_common.h index 2e42896..1be076b 100644 --- a/STM32CubeIDE/rss/include/acc_definitions_common.h +++ b/STM32CubeIDE/rss/include/acc_definitions_common.h @@ -1,45 +1,45 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_DEFINITIONS_COMMON_H_ -#define ACC_DEFINITIONS_COMMON_H_ - -#include -#include - - -/** - * @brief Type representing a sensor ID - */ -typedef uint32_t acc_sensor_id_t; - -/** - * @brief Macro for printing sensor id - */ -#define PRIsensor_id PRIu32 - - -/** - * @brief This enum represents the different log levels for RSS - */ -typedef enum -{ - ACC_LOG_LEVEL_ERROR, - ACC_LOG_LEVEL_WARNING, - ACC_LOG_LEVEL_INFO, - ACC_LOG_LEVEL_VERBOSE, - ACC_LOG_LEVEL_DEBUG -} acc_log_level_t; - - -/** - * @brief Data type for interger-based representation of complex numbers - */ -typedef struct -{ - int16_t real; - int16_t imag; -} acc_int16_complex_t; - - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_DEFINITIONS_COMMON_H_ +#define ACC_DEFINITIONS_COMMON_H_ + +#include +#include + + +/** + * @brief Type representing a sensor ID + */ +typedef uint32_t acc_sensor_id_t; + +/** + * @brief Macro for printing sensor id + */ +#define PRIsensor_id PRIu32 + + +/** + * @brief This enum represents the different log levels for RSS + */ +typedef enum +{ + ACC_LOG_LEVEL_ERROR, + ACC_LOG_LEVEL_WARNING, + ACC_LOG_LEVEL_INFO, + ACC_LOG_LEVEL_VERBOSE, + ACC_LOG_LEVEL_DEBUG +} acc_log_level_t; + + +/** + * @brief Data type for interger-based representation of complex numbers + */ +typedef struct +{ + int16_t real; + int16_t imag; +} acc_int16_complex_t; + + +#endif diff --git a/STM32CubeIDE/rss/include/acc_detector_distance.h b/STM32CubeIDE/rss/include/acc_detector_distance.h index 7d26911..245f6b6 100644 --- a/STM32CubeIDE/rss/include/acc_detector_distance.h +++ b/STM32CubeIDE/rss/include/acc_detector_distance.h @@ -1,831 +1,831 @@ -// Copyright (c) Acconeer AB, 2020-2021 -// All rights reserved - -#ifndef ACC_DETECTOR_DISTANCE_H_ -#define ACC_DETECTOR_DISTANCE_H_ - - -#include -#include - -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" - - -/** - * @defgroup Distance Distance Detector - * @ingroup Detectors - * - * @brief Distance detector API description - * - * @{ - */ - - -/** - * @brief Metadata for the distance detector - */ -typedef struct -{ - /** Start of measurement in meters, derived from request set by @ref acc_detector_distance_configuration_requested_start_set */ - float start_m; - /** Length of measurement in meters, derived from request set by @ref acc_detector_distance_configuration_requested_length_set */ - float length_m; - /** Length needed for potential background, used in @ref acc_detector_distance_record_background */ - uint16_t background_length; -} acc_detector_distance_metadata_t; - - -/** - * @brief Metadata for the recorded background - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; -} acc_detector_distance_recorded_background_info_t; - - -/** - * @brief Metadata for each result provided by the distance detector - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; - /** Number of detected peaks returned to application. Maximum is number of requested peaks.*/ - uint16_t number_of_peaks; - /** Indicating if any measurement samples are above the threshold.*/ - bool measurement_sample_above_threshold; - /** The closest measurement distance above the threshold. Only valid if any measurement samples are above - * threshold. Note, it is valid even if no peaks are found.*/ - float closest_detection_m; -} acc_detector_distance_result_info_t; - - -/** - * @brief Enum for threshold type - */ -typedef enum -{ - ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_FIXED, - ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED, - ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_CFAR -} acc_detector_distance_threshold_type_t; - - -/** - * @brief Enum for peak sorting algorithms - */ -typedef enum -{ - /* Return peaks with the closest detection first. */ - ACC_DETECTOR_DISTANCE_PEAK_SORTING_CLOSEST_FIRST, - /* Return peaks with the peak with the highest amplitude first. */ - ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_FIRST, - /* Return peaks with the peak from the strongest reflector first. - The decrease in amplitude over distance is accounted for. - Cannot be combined with negative start range. */ - ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_REFLECTOR_FIRST, - /* Return peaks with the peak from the strongest flat reflector first. - The decrease in amplitude over distance is accounted for. - Cannot be combined with negative start range. */ - ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_FLAT_REFLECTOR_FIRST -} acc_detector_distance_peak_sorting_t; - - -/** - * @brief Distance detector handle - */ -struct acc_detector_distance_handle; - -typedef struct acc_detector_distance_handle *acc_detector_distance_handle_t; - - -/** - * @brief Distance detector configuration container - */ -struct acc_detector_distance_configuration; - -typedef struct acc_detector_distance_configuration *acc_detector_distance_configuration_t; - - -/** - * @brief Result type for distance detector - * - * @param[out] amplitude Absolute amplitude of peak - * @param[out] distance Distance to peak in meters - */ -typedef struct -{ - uint16_t amplitude; - float distance_m; -} acc_detector_distance_result_t; - - -/** - * @brief A callback for retrieving the service data buffer that the detector is based on - * - * @param[in] data A pointer to the buffer with envelope data - * @param[in] data_length Length of the data buffer - */ -typedef void (*acc_detector_distance_service_data_callback_t)(const uint16_t *data, uint16_t data_length); - - -/** - * @brief Create a configuration for a distance detector - * - * @return Distance detector configuration, NULL if creation was not possible - */ -acc_detector_distance_configuration_t acc_detector_distance_configuration_create(void); - - -/** - * @brief Destroy a configuration for a distance detector - * - * @param[in] distance_configuration The configuration to destroy, set to NULL - */ -void acc_detector_distance_configuration_destroy(acc_detector_distance_configuration_t *distance_configuration); - - -/** - * @brief Create a distance detector with the provided configuration - * - * Only one distance detector may exist for a specific sensor at any given time and - * invalid configurations will not allow for a distance detector creation. - * - * @param[in] distance_configuration The distance detector configuration to create a distance detector with - * @return Distance detector handle, NULL if distance detector was not possible to create - */ -acc_detector_distance_handle_t acc_detector_distance_create(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Destroy a distance detector identified with provided handle - * - * Destroy the context of a distance detector allowing another distance detector to be created using the - * same resources. The distance detector handle reference is set to NULL after destruction. - * If NULL is sent in, nothing happens - * - * @param[in] distance_handle A reference to the distance detector handle to destroy - */ -void acc_detector_distance_destroy(acc_detector_distance_handle_t *distance_handle); - - -/** - * @brief Activate the distance detector associated with the provided handle - * - * @param[in] distance_handle The distance detector handle for the distance detector to activate - * @return True if successful, otherwise false - */ -bool acc_detector_distance_activate(acc_detector_distance_handle_t distance_handle); - - -/** - * @brief Deactivate the distance detector associated with the provided handle - * - * @param[in] distance_handle The distance detector handle for the distance detector to deactivate - * @return True if successful, otherwise false - */ -bool acc_detector_distance_deactivate(acc_detector_distance_handle_t distance_handle); - - -/** - * @brief Reconfigure a distance detector with the provided configuration - * - * Only one distance detector may exist for a specific sensor at any given time. - * A distance detector may not be active when reconfiguring the detector. - * Invalid configurations will not allow for distance detector reconfiguration and - * the distance detector will be destroyed. - * - * NOTE! The old distance handle will be invalid after reconfigure. - * - * @param[in, out] distance_handle A reference to the distance detector handle to reconfigure - * @param[in] distance_configuration The distance detector configuration to reconfigure a distance detector with - * @return True if possible to reconfigure - */ -bool acc_detector_distance_reconfigure(acc_detector_distance_handle_t *distance_handle, - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Get detector metadata - * - * The detector provides metadata after being created with information that could be relevant for an application. - * - * May only be called after a detector has been created. - * - * @param[in] distance_handle The distance detector handle to get metadata for - * @param[out] metadata Metadata are provided in this parameter - * @return True if successful - */ -bool acc_detector_distance_metadata_get(acc_detector_distance_handle_t distance_handle, - acc_detector_distance_metadata_t *metadata); - - -/** - * @brief Record background - * - * Must be called after @ref acc_detector_distance_create and before @ref acc_detector_distance_activate - * when ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED is set. - * - * Can be called again to make a new recording. Detector has to be deactivated to record a new background. - * - * The background length can be retrieved from @ref acc_detector_distance_metadata_get. - * - * The result should typically be set to the detector by calling @ref acc_detector_distance_set_background - * - * @param[in] distance_handle The distance detector handle for the distance detector to record background for - * @param[out] background The recorded background will be stored here - * @param[in] background_length The length of the background - * @param[out] background_info Recorded background metadata, passing NULL is OK - * @return True if successful - */ -bool acc_detector_distance_record_background(acc_detector_distance_handle_t distance_handle, - uint16_t *background, - uint16_t background_length, - acc_detector_distance_recorded_background_info_t *background_info); - - -/** - * @brief Set a background - * - * Set a previously recorded background. The background can typically be generated using - * @ref acc_detector_distance_record_background. The background must have a length corresponding - * to the configuration that was used when creating the detector. For example, if the background - * was created using @ref acc_detector_distance_record_background, the configuration of the detector - * should be the same both when generating the background as when later setting it. - * - * Must always be called for detector to work in ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED mode. - * - * Must be called after @ref acc_detector_distance_create and before @ref acc_detector_distance_activate - * - * The background length can be retrieved from @ref acc_detector_distance_metadata_get. - * - * @param[in] distance_handle The distance detector handle for the distance detector to set background for - * @param[in] background The background to be set - * @param[in] background_length The length of the background to be set - * @return True if successful - */ -bool acc_detector_distance_set_background(acc_detector_distance_handle_t distance_handle, const uint16_t *background, uint16_t background_length); - - -/** - * @brief Retrieve the next result from the distance detector - * - * May only be called after a distance detector has been activated, blocks - * the application until result is ready. - * - * When using CFAR threshold, no detections will be made outside of range - * [range_start + (guard / 2) + window, range_end - (guard / 2) - window], if only_lower_distances is not set. - * If only_lower_distances is set, no detections will be made outside of range - * [range_start + (guard / 2) + window, range_end]. - * - * @param[in] distance_handle The distance detector handle for the distance detector to get next result for - * @param[out] result Distance detector results, can be NULL if no result is wanted - * @param[in] result_length Length of data array passed to function. Number of peaks returned <= result_length. - * @param[out] result_info Detector result info - * @return True if successful, otherwise false - */ -bool acc_detector_distance_get_next(acc_detector_distance_handle_t distance_handle, - acc_detector_distance_result_t *result, - uint16_t result_length, - acc_detector_distance_result_info_t *result_info); - - -/** - * @brief Get the sensor ID for the sensor to be configured - * - * @param[in] distance_configuration The detector distance configuration to get the sensor ID from - * @return Sensor ID - */ -acc_sensor_id_t acc_detector_distance_configuration_sensor_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the sensor ID for the sensor to be configured - * - * @param[in] distance_configuration The detector distance configuration to set the sensor ID in - * @param[in] sensor_id The sensor ID to set - */ -void acc_detector_distance_configuration_sensor_set(acc_detector_distance_configuration_t distance_configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get the requested start distance for measurement in meters - * - * @param[in] distance_configuration The detector distance configuration to get the requested start from - * @return Requested start in meters - */ -float acc_detector_distance_configuration_requested_start_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the requested start distance for measurement in meters - * - * @param[in] distance_configuration The detector distance configuration to set the requested start in - * @param[in] start_m The requested start in meters - */ -void acc_detector_distance_configuration_requested_start_set(acc_detector_distance_configuration_t distance_configuration, float start_m); - - -/** - * @brief Get the requested length of the measurement in meters - * - * @param[in] distance_configuration The detector distance configuration to get the requested length from - * @return Requested length in meters - */ -float acc_detector_distance_configuration_requested_length_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the requested length of the measurement in meters - * - * @param[in] distance_configuration The detector distance configuration to set the requested length in - * @param[in] length_m The requested length in meters - */ -void acc_detector_distance_configuration_requested_length_set(acc_detector_distance_configuration_t distance_configuration, float length_m); - - -/** - * @brief Get power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] distance_configuration The detector distance configuration to get power save mode from - * @return Power save mode - */ -acc_power_save_mode_t acc_detector_distance_configuration_power_save_mode_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] distance_configuration The detector distance configuration to set power save mode in - * @param[in] power_save_mode The power save mode to use - */ -void acc_detector_distance_configuration_power_save_mode_set(acc_detector_distance_configuration_t distance_configuration, - acc_power_save_mode_t power_save_mode); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. Only 1, 2 and 4 - * are valid numbers. - * - * @param[in] distance_configuration The detector distance configuration to get downsampling factor for - * @return Downsampling factor - */ -uint16_t acc_detector_distance_configuration_downsampling_factor_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. Only 1, 2 and 4 - * are valid numbers. - * - * @param[in] distance_configuration The detector distance configuration to set downsampling factor for - * @param[in] downsampling_factor Downsampling factor - */ -void acc_detector_distance_configuration_downsampling_factor_set(acc_detector_distance_configuration_t distance_configuration, - uint16_t downsampling_factor); - - -/** - * @brief Get the service profile - * - * See @ref acc_service_profile_t for details - * - * @param[in] distance_configuration The detector distance configuration to get service profile for - * @return The service profile - */ -acc_service_profile_t acc_detector_distance_configuration_service_profile_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the service profile - * - * See @ref acc_service_profile_t for details - * - * @param[in] distance_configuration The detector distance configuration to set service profile for - * @param[in] service_profile - */ -void acc_detector_distance_configuration_service_profile_set(acc_detector_distance_configuration_t distance_configuration, - acc_service_profile_t service_profile); - - -/** - * @brief Get Maximize signal attenuation mode - * - * Will be true if Maximize signal attenuation mode is enabled, false otherwise - * - * @param[in] distance_configuration The detector distance configuration to get Maximize signal attenuation mode for - * @return Maximize signal attenuation mode - */ -bool acc_detector_distance_configuration_maximize_signal_attenuation_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set Maximize signal attenuation mode - * - * Enable or disable Maximize signal attenuation mode to measure the direct leakage - * - * @param[in] distance_configuration The detector distance configuration to set Maximize signal attenuation mode in - * @param[in] maximize_signal_attenuation Maximize signal attenuation mode, true or false - */ -void acc_detector_distance_configuration_maximize_signal_attenuation_set(acc_detector_distance_configuration_t distance_configuration, - bool maximize_signal_attenuation); - - -/** - * @brief Get receiver gain setting - * - * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] distance_configuration The detector distance configuration to get gain setting for - * @return Receiver gain setting - */ -float acc_detector_distance_configuration_receiver_gain_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set receiver gain setting - * - * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] distance_configuration The detector distance configuration to set gain setting for - * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 - */ -void acc_detector_distance_configuration_receiver_gain_set(acc_detector_distance_configuration_t distance_configuration, float gain); - - -/** - * @brief Get the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] distance_configuration The distance configuration to get hardware accelerated average samples from - * @return Hardware accelerated average samples - */ -uint8_t acc_detector_distance_configuration_hw_accelerated_average_samples_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] distance_configuration The distance configuration to set hardware accelerated average samples in - * @param[in] samples Hardware accelerated average samples - */ -void acc_detector_distance_configuration_hw_accelerated_average_samples_set( - acc_detector_distance_configuration_t distance_configuration, uint8_t samples); - - -/** - * @brief Get asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will measure while the host is waiting. - * In asynchronous mode the sensor will measure while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * @param[in] distance_configuration The configuration to get asynchronous_measurement mode from - * @return Asynchronous measurement mode - */ -bool acc_detector_distance_configuration_asynchronous_measurement_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will measure while the host is waiting. - * In asynchronous mode the sensor will measure while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * @param[in] distance_configuration The configuration to set asynchronous_measurement mode in - * @param[in] asynchronous_measurement asynchronous measurement mode, true or false - */ -void acc_detector_distance_configuration_asynchronous_measurement_set(acc_detector_distance_configuration_t distance_configuration, - bool asynchronous_measurement); - - -/** - * @brief Get number of sweeps to calculate average for - * - * @param[in] distance_configuration The detector distance configuration to get sweep average for - * @return Number of sweeps to calculate average for - */ -uint16_t acc_detector_distance_configuration_sweep_averaging_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set number of sweeps to calculate average for - * - * @param[in] distance_configuration The detector distance configuration to set sweep average for - * @param[in] sweep_averaging Number of sweeps to calculate average for - */ -void acc_detector_distance_configuration_sweep_averaging_set(acc_detector_distance_configuration_t distance_configuration, - uint16_t sweep_averaging); - - -/** - * @brief Get threshold type - * - * @param[in] distance_configuration The detector distance configuration to set threshold type for - * @return Used threshold type - */ -acc_detector_distance_threshold_type_t acc_detector_distance_configuration_threshold_type_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set threshold type - * - * @param[in] distance_configuration The detector distance configuration to set threshold type for - * @param[in] threshold Threshold type to be used - */ -void acc_detector_distance_configuration_threshold_type_set(acc_detector_distance_configuration_t distance_configuration, - acc_detector_distance_threshold_type_t threshold); - - -/** - * @brief Get fixed threshold - * - * @param[in] distance_configuration The detector distance configuration to get fixed threshold from - * @return Fixed threshold - */ -uint16_t acc_detector_distance_configuration_fixed_threshold_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set fixed threshold - * - * @param[in] distance_configuration The detector distance configuration to set fixed threshold in - * @param[in] threshold Fixed threshold to be used by the detector - */ -void acc_detector_distance_configuration_fixed_threshold_set(acc_detector_distance_configuration_t distance_configuration, - uint16_t threshold); - - -/** - * @brief Get number of sweeps to record - * - * @param[in] distance_configuration The detector distance configuration to get number of sweeps to record for - * @return Number of sweeps to record - */ -uint16_t acc_detector_distance_configuration_record_background_sweeps_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set number of sweeps to record - * - * @param[in] distance_configuration The detector distance configuration to set number of sweeps to record in - * @param[in] record_sweeps Number of sweeps to record - */ -void acc_detector_distance_configuration_record_background_sweeps_set( - acc_detector_distance_configuration_t distance_configuration, uint16_t record_sweeps); - - -/** - * @brief Get threshold sensitivity - * - * Applicable when using recorded threshold or CFAR threshold - * - * @param[in] distance_configuration The detector distance configuration to get threshold sensitivity for - * @return Threshold sensitivity - */ -float acc_detector_distance_configuration_threshold_sensitivity_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set threshold sensitivity - * - * Applicable when using recorded threshold or CFAR threshold - * - * @param[in] distance_configuration The detector distance configuration to set threshold sensitivity in - * @param[in] sensitivity - */ -void acc_detector_distance_configuration_threshold_sensitivity_set( - acc_detector_distance_configuration_t distance_configuration, - float sensitivity); - - -/** - * @brief Get guard for CFAR threshold - * - * Range around the distance of interest that is omitted when calculating - * CFAR threshold. Can be low, ~0.04 m, for Profile 1, and should be - * increased for higher Profiles. - * - * @param[in] distance_configuration The detector distance configuration to get threshold guard for - * @return Threshold guard in meters - */ -float acc_detector_distance_configuration_cfar_threshold_guard_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set guard for CFAR threshold - * - * Range around the distance of interest that is omitted when calculating - * CFAR threshold. Can be low, ~0.04 cm, for Profile 1, and should be - * increased for higher Profiles. - * - * @param[in] distance_configuration The detector distance configuration to set threshold guard in - * @param[in] guard_m Threshold guard in meters - */ -void acc_detector_distance_configuration_cfar_threshold_guard_set( - acc_detector_distance_configuration_t distance_configuration, - float guard_m); - - -/** - * @brief Get window for CFAR threshold - * - * Range next to the CFAR guard from which the threshold level will be calculated. - * - * @param[in] distance_configuration The detector distance configuration to get threshold window for - * @return Threshold window in meters - */ -float acc_detector_distance_configuration_cfar_threshold_window_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set window for CFAR threshold - * - * Range next to the CFAR guard from which the threshold level will be calculated. - * - * @param[in] distance_configuration The detector distance configuration to set threshold window in - * @param[in] window_m Threshold window in meters - */ -void acc_detector_distance_configuration_cfar_threshold_window_set( - acc_detector_distance_configuration_t distance_configuration, - float window_m); - - -/** - * @brief Get if only lower distance is set - * - * Instead of determining the CFAR threshold from sweep amplitudes from - * distances both closer and father away, use only closer. Helpful e.g. for - * fluid level in small tanks, where many multipath signals can appear - * just after the main peak. - * - * @param[in] distance_configuration The detector distance configuration to get setting for - * @return True, if only lower distance is set - */ -bool acc_detector_distance_configuration_cfar_threshold_only_lower_distance_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set only lower distance - * - * Instead of determining the CFAR threshold from sweep amplitudes from - * distances both closer and father away, use only closer. Helpful e.g. for - * fluid level in small tanks, where many multipath signals can appear - * just after the main peak. - * - * @param[in] distance_configuration The detector distance configuration to set setting for - * @param[in] only_lower_distance True if only lower distances should be used - */ -void acc_detector_distance_configuration_cfar_threshold_only_lower_distance_set( - acc_detector_distance_configuration_t distance_configuration, - bool only_lower_distance); - - -/** - * @brief Get peak sorting algorithm - * - * Peak sorting algoritm specifies in what order peaks should be reported back to the application. - * - * @param[in] distance_configuration The detector distance configuration to get peak sorting algorithm from - * @return Peak sorting algorithm - */ -acc_detector_distance_peak_sorting_t acc_detector_distance_configuration_peak_sorting_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set peak sorting algorithm to be used - * - * Peak sorting algoritm specifies in what order peaks should be reported back to the application. - * - * @param[in] distance_configuration The detector distance configuration to set peak sorting algorithm in - * @param[in] peak_sorting Peak sorting algorithm to be used - */ -void acc_detector_distance_configuration_peak_sorting_set(acc_detector_distance_configuration_t distance_configuration, - acc_detector_distance_peak_sorting_t peak_sorting); - - -/** - * @brief Get peak merge limit in meters - * - * Defining minimum distance between peaks to be considered individual peaks - * - * @param[in] distance_configuration The detector distance configuration to get peak merge limit from - * @return Peak merge limit in meters - */ -float acc_detector_distance_configuration_peak_merge_limit_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set peak merge limit in meters - * - * Defining minimum distance between peaks to be considered individual peaks - * - * @param[in] distance_configuration The detector distance configuration to set peak merge limit in - * @param[in] peak_merge_limit_m Peak merge limit in meters - */ -void acc_detector_distance_configuration_peak_merge_limit_set(acc_detector_distance_configuration_t distance_configuration, - float peak_merge_limit_m); - - -/** - * @brief Set a callback function to get the service data - * - * A callback can be used to get the envelope service buffer that the detector is based on. - * The data is the unprocessed envelope data that is fed into the distance algorithm. - * Set service_data_callback to NULL to disable callback. - * - * @param[in] distance_configuration The configuration to set the service data callback for - * @param[in] service_data_callback The callback to get service data - */ -void acc_detector_distance_configuration_service_data_callback_set( - acc_detector_distance_configuration_t distance_configuration, - acc_detector_distance_service_data_callback_t service_data_callback); - - -/** - * @brief Set the maximum unambiguous range - * - * Experimental. - * - * See acc_service_mur_set() for more detailed information. - * - * @param[in] distance_configuration The configuration - * @param[in] max_unambiguous_range The desired maximum unambiguous range - */ -void acc_detector_distance_configuration_mur_set(acc_detector_distance_configuration_t distance_configuration, - acc_service_mur_t max_unambiguous_range); - - -/** - * @brief Get the maximum unambiguous range - * - * Experimental. - * - * See acc_service_mur_get() for more detailed information. - * - * @param[in] distance_configuration The configuration - * @return Maximum unambiguous range - */ -acc_service_mur_t acc_detector_distance_configuration_mur_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2020-2021 +// All rights reserved + +#ifndef ACC_DETECTOR_DISTANCE_H_ +#define ACC_DETECTOR_DISTANCE_H_ + + +#include +#include + +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" + + +/** + * @defgroup Distance Distance Detector + * @ingroup Detectors + * + * @brief Distance detector API description + * + * @{ + */ + + +/** + * @brief Metadata for the distance detector + */ +typedef struct +{ + /** Start of measurement in meters, derived from request set by @ref acc_detector_distance_configuration_requested_start_set */ + float start_m; + /** Length of measurement in meters, derived from request set by @ref acc_detector_distance_configuration_requested_length_set */ + float length_m; + /** Length needed for potential background, used in @ref acc_detector_distance_record_background */ + uint16_t background_length; +} acc_detector_distance_metadata_t; + + +/** + * @brief Metadata for the recorded background + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; +} acc_detector_distance_recorded_background_info_t; + + +/** + * @brief Metadata for each result provided by the distance detector + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; + /** Number of detected peaks returned to application. Maximum is number of requested peaks.*/ + uint16_t number_of_peaks; + /** Indicating if any measurement samples are above the threshold.*/ + bool measurement_sample_above_threshold; + /** The closest measurement distance above the threshold. Only valid if any measurement samples are above + * threshold. Note, it is valid even if no peaks are found.*/ + float closest_detection_m; +} acc_detector_distance_result_info_t; + + +/** + * @brief Enum for threshold type + */ +typedef enum +{ + ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_FIXED, + ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED, + ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_CFAR +} acc_detector_distance_threshold_type_t; + + +/** + * @brief Enum for peak sorting algorithms + */ +typedef enum +{ + /* Return peaks with the closest detection first. */ + ACC_DETECTOR_DISTANCE_PEAK_SORTING_CLOSEST_FIRST, + /* Return peaks with the peak with the highest amplitude first. */ + ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_FIRST, + /* Return peaks with the peak from the strongest reflector first. + The decrease in amplitude over distance is accounted for. + Cannot be combined with negative start range. */ + ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_REFLECTOR_FIRST, + /* Return peaks with the peak from the strongest flat reflector first. + The decrease in amplitude over distance is accounted for. + Cannot be combined with negative start range. */ + ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_FLAT_REFLECTOR_FIRST +} acc_detector_distance_peak_sorting_t; + + +/** + * @brief Distance detector handle + */ +struct acc_detector_distance_handle; + +typedef struct acc_detector_distance_handle *acc_detector_distance_handle_t; + + +/** + * @brief Distance detector configuration container + */ +struct acc_detector_distance_configuration; + +typedef struct acc_detector_distance_configuration *acc_detector_distance_configuration_t; + + +/** + * @brief Result type for distance detector + * + * @param[out] amplitude Absolute amplitude of peak + * @param[out] distance Distance to peak in meters + */ +typedef struct +{ + uint16_t amplitude; + float distance_m; +} acc_detector_distance_result_t; + + +/** + * @brief A callback for retrieving the service data buffer that the detector is based on + * + * @param[in] data A pointer to the buffer with envelope data + * @param[in] data_length Length of the data buffer + */ +typedef void (*acc_detector_distance_service_data_callback_t)(const uint16_t *data, uint16_t data_length); + + +/** + * @brief Create a configuration for a distance detector + * + * @return Distance detector configuration, NULL if creation was not possible + */ +acc_detector_distance_configuration_t acc_detector_distance_configuration_create(void); + + +/** + * @brief Destroy a configuration for a distance detector + * + * @param[in] distance_configuration The configuration to destroy, set to NULL + */ +void acc_detector_distance_configuration_destroy(acc_detector_distance_configuration_t *distance_configuration); + + +/** + * @brief Create a distance detector with the provided configuration + * + * Only one distance detector may exist for a specific sensor at any given time and + * invalid configurations will not allow for a distance detector creation. + * + * @param[in] distance_configuration The distance detector configuration to create a distance detector with + * @return Distance detector handle, NULL if distance detector was not possible to create + */ +acc_detector_distance_handle_t acc_detector_distance_create(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Destroy a distance detector identified with provided handle + * + * Destroy the context of a distance detector allowing another distance detector to be created using the + * same resources. The distance detector handle reference is set to NULL after destruction. + * If NULL is sent in, nothing happens + * + * @param[in] distance_handle A reference to the distance detector handle to destroy + */ +void acc_detector_distance_destroy(acc_detector_distance_handle_t *distance_handle); + + +/** + * @brief Activate the distance detector associated with the provided handle + * + * @param[in] distance_handle The distance detector handle for the distance detector to activate + * @return True if successful, otherwise false + */ +bool acc_detector_distance_activate(acc_detector_distance_handle_t distance_handle); + + +/** + * @brief Deactivate the distance detector associated with the provided handle + * + * @param[in] distance_handle The distance detector handle for the distance detector to deactivate + * @return True if successful, otherwise false + */ +bool acc_detector_distance_deactivate(acc_detector_distance_handle_t distance_handle); + + +/** + * @brief Reconfigure a distance detector with the provided configuration + * + * Only one distance detector may exist for a specific sensor at any given time. + * A distance detector may not be active when reconfiguring the detector. + * Invalid configurations will not allow for distance detector reconfiguration and + * the distance detector will be destroyed. + * + * NOTE! The old distance handle will be invalid after reconfigure. + * + * @param[in, out] distance_handle A reference to the distance detector handle to reconfigure + * @param[in] distance_configuration The distance detector configuration to reconfigure a distance detector with + * @return True if possible to reconfigure + */ +bool acc_detector_distance_reconfigure(acc_detector_distance_handle_t *distance_handle, + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Get detector metadata + * + * The detector provides metadata after being created with information that could be relevant for an application. + * + * May only be called after a detector has been created. + * + * @param[in] distance_handle The distance detector handle to get metadata for + * @param[out] metadata Metadata are provided in this parameter + * @return True if successful + */ +bool acc_detector_distance_metadata_get(acc_detector_distance_handle_t distance_handle, + acc_detector_distance_metadata_t *metadata); + + +/** + * @brief Record background + * + * Must be called after @ref acc_detector_distance_create and before @ref acc_detector_distance_activate + * when ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED is set. + * + * Can be called again to make a new recording. Detector has to be deactivated to record a new background. + * + * The background length can be retrieved from @ref acc_detector_distance_metadata_get. + * + * The result should typically be set to the detector by calling @ref acc_detector_distance_set_background + * + * @param[in] distance_handle The distance detector handle for the distance detector to record background for + * @param[out] background The recorded background will be stored here + * @param[in] background_length The length of the background + * @param[out] background_info Recorded background metadata, passing NULL is OK + * @return True if successful + */ +bool acc_detector_distance_record_background(acc_detector_distance_handle_t distance_handle, + uint16_t *background, + uint16_t background_length, + acc_detector_distance_recorded_background_info_t *background_info); + + +/** + * @brief Set a background + * + * Set a previously recorded background. The background can typically be generated using + * @ref acc_detector_distance_record_background. The background must have a length corresponding + * to the configuration that was used when creating the detector. For example, if the background + * was created using @ref acc_detector_distance_record_background, the configuration of the detector + * should be the same both when generating the background as when later setting it. + * + * Must always be called for detector to work in ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED mode. + * + * Must be called after @ref acc_detector_distance_create and before @ref acc_detector_distance_activate + * + * The background length can be retrieved from @ref acc_detector_distance_metadata_get. + * + * @param[in] distance_handle The distance detector handle for the distance detector to set background for + * @param[in] background The background to be set + * @param[in] background_length The length of the background to be set + * @return True if successful + */ +bool acc_detector_distance_set_background(acc_detector_distance_handle_t distance_handle, const uint16_t *background, uint16_t background_length); + + +/** + * @brief Retrieve the next result from the distance detector + * + * May only be called after a distance detector has been activated, blocks + * the application until result is ready. + * + * When using CFAR threshold, no detections will be made outside of range + * [range_start + (guard / 2) + window, range_end - (guard / 2) - window], if only_lower_distances is not set. + * If only_lower_distances is set, no detections will be made outside of range + * [range_start + (guard / 2) + window, range_end]. + * + * @param[in] distance_handle The distance detector handle for the distance detector to get next result for + * @param[out] result Distance detector results, can be NULL if no result is wanted + * @param[in] result_length Length of data array passed to function. Number of peaks returned <= result_length. + * @param[out] result_info Detector result info + * @return True if successful, otherwise false + */ +bool acc_detector_distance_get_next(acc_detector_distance_handle_t distance_handle, + acc_detector_distance_result_t *result, + uint16_t result_length, + acc_detector_distance_result_info_t *result_info); + + +/** + * @brief Get the sensor ID for the sensor to be configured + * + * @param[in] distance_configuration The detector distance configuration to get the sensor ID from + * @return Sensor ID + */ +acc_sensor_id_t acc_detector_distance_configuration_sensor_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the sensor ID for the sensor to be configured + * + * @param[in] distance_configuration The detector distance configuration to set the sensor ID in + * @param[in] sensor_id The sensor ID to set + */ +void acc_detector_distance_configuration_sensor_set(acc_detector_distance_configuration_t distance_configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get the requested start distance for measurement in meters + * + * @param[in] distance_configuration The detector distance configuration to get the requested start from + * @return Requested start in meters + */ +float acc_detector_distance_configuration_requested_start_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the requested start distance for measurement in meters + * + * @param[in] distance_configuration The detector distance configuration to set the requested start in + * @param[in] start_m The requested start in meters + */ +void acc_detector_distance_configuration_requested_start_set(acc_detector_distance_configuration_t distance_configuration, float start_m); + + +/** + * @brief Get the requested length of the measurement in meters + * + * @param[in] distance_configuration The detector distance configuration to get the requested length from + * @return Requested length in meters + */ +float acc_detector_distance_configuration_requested_length_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the requested length of the measurement in meters + * + * @param[in] distance_configuration The detector distance configuration to set the requested length in + * @param[in] length_m The requested length in meters + */ +void acc_detector_distance_configuration_requested_length_set(acc_detector_distance_configuration_t distance_configuration, float length_m); + + +/** + * @brief Get power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] distance_configuration The detector distance configuration to get power save mode from + * @return Power save mode + */ +acc_power_save_mode_t acc_detector_distance_configuration_power_save_mode_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] distance_configuration The detector distance configuration to set power save mode in + * @param[in] power_save_mode The power save mode to use + */ +void acc_detector_distance_configuration_power_save_mode_set(acc_detector_distance_configuration_t distance_configuration, + acc_power_save_mode_t power_save_mode); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. Only 1, 2 and 4 + * are valid numbers. + * + * @param[in] distance_configuration The detector distance configuration to get downsampling factor for + * @return Downsampling factor + */ +uint16_t acc_detector_distance_configuration_downsampling_factor_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. Only 1, 2 and 4 + * are valid numbers. + * + * @param[in] distance_configuration The detector distance configuration to set downsampling factor for + * @param[in] downsampling_factor Downsampling factor + */ +void acc_detector_distance_configuration_downsampling_factor_set(acc_detector_distance_configuration_t distance_configuration, + uint16_t downsampling_factor); + + +/** + * @brief Get the service profile + * + * See @ref acc_service_profile_t for details + * + * @param[in] distance_configuration The detector distance configuration to get service profile for + * @return The service profile + */ +acc_service_profile_t acc_detector_distance_configuration_service_profile_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the service profile + * + * See @ref acc_service_profile_t for details + * + * @param[in] distance_configuration The detector distance configuration to set service profile for + * @param[in] service_profile + */ +void acc_detector_distance_configuration_service_profile_set(acc_detector_distance_configuration_t distance_configuration, + acc_service_profile_t service_profile); + + +/** + * @brief Get Maximize signal attenuation mode + * + * Will be true if Maximize signal attenuation mode is enabled, false otherwise + * + * @param[in] distance_configuration The detector distance configuration to get Maximize signal attenuation mode for + * @return Maximize signal attenuation mode + */ +bool acc_detector_distance_configuration_maximize_signal_attenuation_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set Maximize signal attenuation mode + * + * Enable or disable Maximize signal attenuation mode to measure the direct leakage + * + * @param[in] distance_configuration The detector distance configuration to set Maximize signal attenuation mode in + * @param[in] maximize_signal_attenuation Maximize signal attenuation mode, true or false + */ +void acc_detector_distance_configuration_maximize_signal_attenuation_set(acc_detector_distance_configuration_t distance_configuration, + bool maximize_signal_attenuation); + + +/** + * @brief Get receiver gain setting + * + * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] distance_configuration The detector distance configuration to get gain setting for + * @return Receiver gain setting + */ +float acc_detector_distance_configuration_receiver_gain_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set receiver gain setting + * + * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] distance_configuration The detector distance configuration to set gain setting for + * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 + */ +void acc_detector_distance_configuration_receiver_gain_set(acc_detector_distance_configuration_t distance_configuration, float gain); + + +/** + * @brief Get the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] distance_configuration The distance configuration to get hardware accelerated average samples from + * @return Hardware accelerated average samples + */ +uint8_t acc_detector_distance_configuration_hw_accelerated_average_samples_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] distance_configuration The distance configuration to set hardware accelerated average samples in + * @param[in] samples Hardware accelerated average samples + */ +void acc_detector_distance_configuration_hw_accelerated_average_samples_set( + acc_detector_distance_configuration_t distance_configuration, uint8_t samples); + + +/** + * @brief Get asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will measure while the host is waiting. + * In asynchronous mode the sensor will measure while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * @param[in] distance_configuration The configuration to get asynchronous_measurement mode from + * @return Asynchronous measurement mode + */ +bool acc_detector_distance_configuration_asynchronous_measurement_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will measure while the host is waiting. + * In asynchronous mode the sensor will measure while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * @param[in] distance_configuration The configuration to set asynchronous_measurement mode in + * @param[in] asynchronous_measurement asynchronous measurement mode, true or false + */ +void acc_detector_distance_configuration_asynchronous_measurement_set(acc_detector_distance_configuration_t distance_configuration, + bool asynchronous_measurement); + + +/** + * @brief Get number of sweeps to calculate average for + * + * @param[in] distance_configuration The detector distance configuration to get sweep average for + * @return Number of sweeps to calculate average for + */ +uint16_t acc_detector_distance_configuration_sweep_averaging_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set number of sweeps to calculate average for + * + * @param[in] distance_configuration The detector distance configuration to set sweep average for + * @param[in] sweep_averaging Number of sweeps to calculate average for + */ +void acc_detector_distance_configuration_sweep_averaging_set(acc_detector_distance_configuration_t distance_configuration, + uint16_t sweep_averaging); + + +/** + * @brief Get threshold type + * + * @param[in] distance_configuration The detector distance configuration to set threshold type for + * @return Used threshold type + */ +acc_detector_distance_threshold_type_t acc_detector_distance_configuration_threshold_type_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set threshold type + * + * @param[in] distance_configuration The detector distance configuration to set threshold type for + * @param[in] threshold Threshold type to be used + */ +void acc_detector_distance_configuration_threshold_type_set(acc_detector_distance_configuration_t distance_configuration, + acc_detector_distance_threshold_type_t threshold); + + +/** + * @brief Get fixed threshold + * + * @param[in] distance_configuration The detector distance configuration to get fixed threshold from + * @return Fixed threshold + */ +uint16_t acc_detector_distance_configuration_fixed_threshold_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set fixed threshold + * + * @param[in] distance_configuration The detector distance configuration to set fixed threshold in + * @param[in] threshold Fixed threshold to be used by the detector + */ +void acc_detector_distance_configuration_fixed_threshold_set(acc_detector_distance_configuration_t distance_configuration, + uint16_t threshold); + + +/** + * @brief Get number of sweeps to record + * + * @param[in] distance_configuration The detector distance configuration to get number of sweeps to record for + * @return Number of sweeps to record + */ +uint16_t acc_detector_distance_configuration_record_background_sweeps_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set number of sweeps to record + * + * @param[in] distance_configuration The detector distance configuration to set number of sweeps to record in + * @param[in] record_sweeps Number of sweeps to record + */ +void acc_detector_distance_configuration_record_background_sweeps_set( + acc_detector_distance_configuration_t distance_configuration, uint16_t record_sweeps); + + +/** + * @brief Get threshold sensitivity + * + * Applicable when using recorded threshold or CFAR threshold + * + * @param[in] distance_configuration The detector distance configuration to get threshold sensitivity for + * @return Threshold sensitivity + */ +float acc_detector_distance_configuration_threshold_sensitivity_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set threshold sensitivity + * + * Applicable when using recorded threshold or CFAR threshold + * + * @param[in] distance_configuration The detector distance configuration to set threshold sensitivity in + * @param[in] sensitivity + */ +void acc_detector_distance_configuration_threshold_sensitivity_set( + acc_detector_distance_configuration_t distance_configuration, + float sensitivity); + + +/** + * @brief Get guard for CFAR threshold + * + * Range around the distance of interest that is omitted when calculating + * CFAR threshold. Can be low, ~0.04 m, for Profile 1, and should be + * increased for higher Profiles. + * + * @param[in] distance_configuration The detector distance configuration to get threshold guard for + * @return Threshold guard in meters + */ +float acc_detector_distance_configuration_cfar_threshold_guard_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set guard for CFAR threshold + * + * Range around the distance of interest that is omitted when calculating + * CFAR threshold. Can be low, ~0.04 cm, for Profile 1, and should be + * increased for higher Profiles. + * + * @param[in] distance_configuration The detector distance configuration to set threshold guard in + * @param[in] guard_m Threshold guard in meters + */ +void acc_detector_distance_configuration_cfar_threshold_guard_set( + acc_detector_distance_configuration_t distance_configuration, + float guard_m); + + +/** + * @brief Get window for CFAR threshold + * + * Range next to the CFAR guard from which the threshold level will be calculated. + * + * @param[in] distance_configuration The detector distance configuration to get threshold window for + * @return Threshold window in meters + */ +float acc_detector_distance_configuration_cfar_threshold_window_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set window for CFAR threshold + * + * Range next to the CFAR guard from which the threshold level will be calculated. + * + * @param[in] distance_configuration The detector distance configuration to set threshold window in + * @param[in] window_m Threshold window in meters + */ +void acc_detector_distance_configuration_cfar_threshold_window_set( + acc_detector_distance_configuration_t distance_configuration, + float window_m); + + +/** + * @brief Get if only lower distance is set + * + * Instead of determining the CFAR threshold from sweep amplitudes from + * distances both closer and father away, use only closer. Helpful e.g. for + * fluid level in small tanks, where many multipath signals can appear + * just after the main peak. + * + * @param[in] distance_configuration The detector distance configuration to get setting for + * @return True, if only lower distance is set + */ +bool acc_detector_distance_configuration_cfar_threshold_only_lower_distance_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set only lower distance + * + * Instead of determining the CFAR threshold from sweep amplitudes from + * distances both closer and father away, use only closer. Helpful e.g. for + * fluid level in small tanks, where many multipath signals can appear + * just after the main peak. + * + * @param[in] distance_configuration The detector distance configuration to set setting for + * @param[in] only_lower_distance True if only lower distances should be used + */ +void acc_detector_distance_configuration_cfar_threshold_only_lower_distance_set( + acc_detector_distance_configuration_t distance_configuration, + bool only_lower_distance); + + +/** + * @brief Get peak sorting algorithm + * + * Peak sorting algoritm specifies in what order peaks should be reported back to the application. + * + * @param[in] distance_configuration The detector distance configuration to get peak sorting algorithm from + * @return Peak sorting algorithm + */ +acc_detector_distance_peak_sorting_t acc_detector_distance_configuration_peak_sorting_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set peak sorting algorithm to be used + * + * Peak sorting algoritm specifies in what order peaks should be reported back to the application. + * + * @param[in] distance_configuration The detector distance configuration to set peak sorting algorithm in + * @param[in] peak_sorting Peak sorting algorithm to be used + */ +void acc_detector_distance_configuration_peak_sorting_set(acc_detector_distance_configuration_t distance_configuration, + acc_detector_distance_peak_sorting_t peak_sorting); + + +/** + * @brief Get peak merge limit in meters + * + * Defining minimum distance between peaks to be considered individual peaks + * + * @param[in] distance_configuration The detector distance configuration to get peak merge limit from + * @return Peak merge limit in meters + */ +float acc_detector_distance_configuration_peak_merge_limit_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set peak merge limit in meters + * + * Defining minimum distance between peaks to be considered individual peaks + * + * @param[in] distance_configuration The detector distance configuration to set peak merge limit in + * @param[in] peak_merge_limit_m Peak merge limit in meters + */ +void acc_detector_distance_configuration_peak_merge_limit_set(acc_detector_distance_configuration_t distance_configuration, + float peak_merge_limit_m); + + +/** + * @brief Set a callback function to get the service data + * + * A callback can be used to get the envelope service buffer that the detector is based on. + * The data is the unprocessed envelope data that is fed into the distance algorithm. + * Set service_data_callback to NULL to disable callback. + * + * @param[in] distance_configuration The configuration to set the service data callback for + * @param[in] service_data_callback The callback to get service data + */ +void acc_detector_distance_configuration_service_data_callback_set( + acc_detector_distance_configuration_t distance_configuration, + acc_detector_distance_service_data_callback_t service_data_callback); + + +/** + * @brief Set the maximum unambiguous range + * + * Experimental. + * + * See acc_service_mur_set() for more detailed information. + * + * @param[in] distance_configuration The configuration + * @param[in] max_unambiguous_range The desired maximum unambiguous range + */ +void acc_detector_distance_configuration_mur_set(acc_detector_distance_configuration_t distance_configuration, + acc_service_mur_t max_unambiguous_range); + + +/** + * @brief Get the maximum unambiguous range + * + * Experimental. + * + * See acc_service_mur_get() for more detailed information. + * + * @param[in] distance_configuration The configuration + * @return Maximum unambiguous range + */ +acc_service_mur_t acc_detector_distance_configuration_mur_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_detector_presence.h b/STM32CubeIDE/rss/include/acc_detector_presence.h index 8098327..3c94999 100644 --- a/STM32CubeIDE/rss/include/acc_detector_presence.h +++ b/STM32CubeIDE/rss/include/acc_detector_presence.h @@ -1,582 +1,582 @@ -// Copyright (c) Acconeer AB, 2019-2022 -// All rights reserved - -#ifndef ACC_DETECTOR_PRESENCE_H_ -#define ACC_DETECTOR_PRESENCE_H_ - -#include -#include -#include - -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" - -/** - * @defgroup Presence Presence Detector - * @ingroup Detectors - * - * @brief Presence detector API description - * - * @{ - */ - - -/** - * @brief Presence detector handle - */ -struct acc_detector_presence_handle; - -typedef struct acc_detector_presence_handle *acc_detector_presence_handle_t; - - -/** - * @brief Presence detector configuration container - */ -struct acc_detector_presence_configuration; - -typedef struct acc_detector_presence_configuration *acc_detector_presence_configuration_t; - - -/** - * @brief Parameter structure for data filtering settings - */ -typedef struct -{ - /** Time constant in s for inter-frame signal smoothing after the bandpass filtering */ - float inter_frame_deviation_time_const; - /** Low pass cutoff frequency in Hz for inter-frame signal bandpass filtering */ - float inter_frame_fast_cutoff; - /** High pass cutoff frequency in Hz for inter-frame signal bandpass filtering */ - float inter_frame_slow_cutoff; - /** Time constant in s for inter-frame signal smoothing */ - float intra_frame_time_const; - /** Weight between 0 and 1 for presence score interpolation between the inter-frame and intra-frame signals */ - float intra_frame_weight; - /** Time constant in s for smoothing of the presence score */ - float output_time_const; -} acc_detector_presence_configuration_filter_parameters_t; - - -/** - * @brief Presence detector results container - */ -typedef struct -{ - /** True if presence was detected, False otherwise */ - bool presence_detected; - /** A measure of the amount of motion detected */ - float presence_score; - /** The distance, in meters, to the detected object */ - float presence_distance; - - /** Indication of a sensor communication error, detector probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; -} acc_detector_presence_result_t; - - -/** - * @brief A callback for retrieving the service data buffer that the detector is based on - * - * @param[in] data A pointer to the buffer with sparse data - * @param[in] data_size Size of the data buffer in bytes - * @param[in] client_reference Pointer to a client reference - */ -typedef void (*acc_detector_presence_service_data_callback_t)(const uint16_t *data, size_t data_size, void *client_reference); - - -/** - * @brief Create a configuration for a presence detector - * - * @return Presence detector configuration, NULL if creation was not possible - */ -acc_detector_presence_configuration_t acc_detector_presence_configuration_create(void); - - -/** - * @brief Destroy a presence detector configuration - * - * @param[in] presence_configuration The configuration to destroy, set to NULL - */ -void acc_detector_presence_configuration_destroy(acc_detector_presence_configuration_t *presence_configuration); - - -/** - * @brief Create a presence detector with the provided configuration - * - * Only one presence detector may exist for a specific sensor at any given time and - * invalid configurations will not allow for presence detector creation. - * - * @param[in] presence_configuration The presence detector configuration to create a presence detector with - * @return Presence detector handle, NULL if presence detector was not possible to create - */ -acc_detector_presence_handle_t acc_detector_presence_create(acc_detector_presence_configuration_t presence_configuration); - - -/** - * @brief Destroy a presence detector identified with the provided handle - * - * Destroy the context of a presence detector allowing another presence detector to be created using the - * same resources. The presence detector handle reference is set to NULL after destruction. - * If NULL is sent in, nothing happens. - * - * @param[in] presence_handle A reference to the presence detector handle to destroy - */ -void acc_detector_presence_destroy(acc_detector_presence_handle_t *presence_handle); - - -/** - * @brief Reconfigure a presence detector with the provided configuration - * - * Only one presence detector may exist for a specific sensor at any given time and - * invalid reconfigurations will not allow for presence detector creation. - * - * @param[in] presence_handle A reference to the presence detector handle to reconfigure - * @param[in] presence_configuration The presence detector configuration to reconfigure a presence detector with - * @return True if possible to reconfigure - */ -bool acc_detector_presence_reconfigure(acc_detector_presence_handle_t *presence_handle, - acc_detector_presence_configuration_t presence_configuration); - - -/** - * @brief Activate the presence detector associated with the provided handle - * - * @param[in] presence_handle The presence detector handle for the presence detector to activate - * @return True if successful, otherwise false - */ -bool acc_detector_presence_activate(acc_detector_presence_handle_t presence_handle); - - -/** - * @brief Deactivate the presence detector associated with the provided handle - * - * @param[in] presence_handle The presence detector handle for the presence detector to deactivate - * @return True if successful, otherwise false - */ -bool acc_detector_presence_deactivate(acc_detector_presence_handle_t presence_handle); - - -/** - * @brief Retrieve the next result from the presence detector - * - * May only be called after a presence detector has been activated, blocks - * the application until a result is ready. Can still be called after vector - * output mode has been selected. - * - * @param[in] presence_handle The presence detector handle for the presence detector to get the next result for - * @param[out] result Presence detector results, can be NULL if no result is wanted. - * @return True if successful, otherwise false - */ -bool acc_detector_presence_get_next(acc_detector_presence_handle_t presence_handle, acc_detector_presence_result_t *result); - - -/** - * @brief Retrieve the next distance point vector from the presence detector - * - * May only be called after a presence detector has been activated, blocks - * the application until a result is ready. Vector output mode has to be set - * to true with the function @ref acc_detector_presence_configuration_vector_output_mode_set, - * otherwise returns with an error. Memory is owned by the detector and the client receives a pointer. - * - * @param[in] presence_handle The presence detector handle for the presence detector to get the next result for - * @param[out] distance_point_vector_length The number of elements in the distance_point_vector, can be NULL if no result is wanted - * @param[out] distance_point_vector The distance point vector, can be NULL if no result is wanted - * @param[out] result Presence detector results, same as result from acc_detector_presence_get_next - * @return True if successful, otherwise false - */ -bool acc_detector_presence_distance_point_vector_get_next(acc_detector_presence_handle_t presence_handle, - uint16_t *distance_point_vector_length, - float **distance_point_vector, - acc_detector_presence_result_t *result); - - -/** - * @brief Get start of sweep in m - * - * @param[in] configuration The configuration to get the sweep start for - * @return requested sweep start in m - */ -float acc_detector_presence_configuration_start_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set start of sweep in m - * - * @param[in] configuration The configuration to set the sweep start for - * @param[in] start The requested sweep start in m - */ -void acc_detector_presence_configuration_start_set(acc_detector_presence_configuration_t configuration, float start); - - -/** - * @brief Get length of sweep in m - * - * @param[in] configuration The configuration to get the sweep length for - * @return requested sweep length in m - */ -float acc_detector_presence_configuration_length_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set length of sweep in m - * - * @param[in] configuration The configuration to set the requested sweep length for - * @param[in] length The requested sweep length in m - */ -void acc_detector_presence_configuration_length_set(acc_detector_presence_configuration_t configuration, float length); - - -/** - * @brief Get sensor ID - * - * @param[in] configuration The configuration to get the sensor ID for - * @return sensor ID - */ -acc_sensor_id_t acc_detector_presence_configuration_sensor_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set sensor ID - * - * @param[in] configuration The configuration to set the sensor ID for - * @param[in] sensor_id The sensor ID - */ -void acc_detector_presence_configuration_sensor_set(acc_detector_presence_configuration_t configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get detection threshold - * - * @param[in] configuration The configuration to get the detection threshold for - * @return detection threshold - */ -float acc_detector_presence_configuration_detection_threshold_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set detection threshold - * - * @param[in] configuration The configuration to set the detection threshold for - * @param[in] detection_threshold The threshold - */ -void acc_detector_presence_configuration_detection_threshold_set(acc_detector_presence_configuration_t configuration, - float detection_threshold); - - -/** - * @brief Get detection update rate - * - * Set the update rate of which the client call the detector to produce data. It's the clients responsibility - * to keep the configured timing. - * - * @param[in] configuration The configuration to get the detection update rate for - * @return detection update rate - */ -float acc_detector_presence_configuration_update_rate_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set detection update rate - * - * Set the update rate of which the client call the detector to produce data. It's the clients responsibility - * to keep the configured timing. - * - * @param[in] configuration The configuration to set the detection update rate for - * @param[in] update_rate - */ -void acc_detector_presence_configuration_update_rate_set(acc_detector_presence_configuration_t configuration, - float update_rate); - - -/** - * @brief Get the number of sweeps per frame - * - * @param[in] configuration The configuration to get the number of sweeps per frame for - * @return The number of sweeps per frame - */ -uint16_t acc_detector_presence_configuration_sweeps_per_frame_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set the number of sweeps per frame - * - * @param[in] configuration The configuration to set the number of sweeps per frame for - * @param[in] sweeps_per_frame The requested number of sweeps per frame - */ -void acc_detector_presence_configuration_sweeps_per_frame_set(acc_detector_presence_configuration_t configuration, - uint16_t sweeps_per_frame); - - -/** - * @brief Get the sweep rate - * - * Gets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. - * - * @param[in] configuration The configuration to get the sweep rate from - * @return sweep_rate The sweep rate - */ -float acc_detector_presence_configuration_sweep_rate_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set sweep rate - * - * Sets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. - * - * @param[in] configuration The configuration to set the sweep rate in - * @param[in] sweep_rate The sweep rate - */ -void acc_detector_presence_configuration_sweep_rate_set(acc_detector_presence_configuration_t configuration, float sweep_rate); - - -/** - * @brief Get sensor data filtering parameters - * - * See @ref acc_detector_presence_configuration_filter_parameters_set - * - * @param[in] configuration The configuration to get the filter parameters for - * @return The filter parameters, see @ref acc_detector_presence_configuration_filter_parameters_t - */ -acc_detector_presence_configuration_filter_parameters_t acc_detector_presence_configuration_filter_parameters_get( - acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set sensor data filtering parameters - * - * Set filter parameters for the sensor data filtering that is performed before presence detection thresholding. - * - * @param[in] configuration The configuration to set the filter parameters for - * @param[in] filter_parameters The filter parameter structure, see @ref acc_detector_presence_configuration_filter_parameters_t - */ -void acc_detector_presence_configuration_filter_parameters_set(acc_detector_presence_configuration_t configuration, - const acc_detector_presence_configuration_filter_parameters_t *filter_parameters); - - -/** - * @brief Get the number of principal components removed in the PCA based noise reduction - * - * @param[in] configuration The configuration to get the number of principal components of noise to remove for - * @return The number of principal components of noise to remove, between 0 and 2 - */ -uint8_t acc_detector_presence_configuration_nbr_removed_pc_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set the number of principal components removed in the PCA based noise reduction - * - * Sets the number of principal components removed in the PCA based noise reduction. - * Filters out static reflections. - * Setting to 0 (default) disables the PCA based noise reduction completely. - * For more information on the PCA based noise reduction algorithm, see - * Read-the-Docs - * - * @param[in] configuration The configuration to set the number of principal components of noise to remove for - * @param[in] nbr_removed_pc The number of principal components of noise to remove, between 0 and 2 - */ -void acc_detector_presence_configuration_nbr_removed_pc_set(acc_detector_presence_configuration_t configuration, uint8_t nbr_removed_pc); - - -/** - * @brief Get power save mode - * - * @param[in] configuration The configuration to get the power save mode for - * @return power save mode - */ -acc_power_save_mode_t acc_detector_presence_configuration_power_save_mode_get( - acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set power save mode - * - * @param[in] configuration The configuration to set the power save mode for - * @param[in] power_save_mode The power save mode - */ -void acc_detector_presence_configuration_power_save_mode_set(acc_detector_presence_configuration_t configuration, - acc_power_save_mode_t power_save_mode); - - -/** - * @brief Get the current service profile used by the detector - * - * See @ref acc_service_profile_t for details - * - * @param[in] configuration The configuration to get a profile from - * @return The current profile, 0 if configuration is invalid - */ -acc_service_profile_t acc_detector_presence_configuration_service_profile_get( - acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set a service profile to be used by the detector - * - * See @ref acc_service_profile_t for details - * - * @param[in] configuration The configuration to set a profile for - * @param[in] service_profile The profile to set - */ -void acc_detector_presence_configuration_service_profile_set(acc_detector_presence_configuration_t configuration, - acc_service_profile_t service_profile); - - -/** - * @brief Get the current receiver gain used by the detector - * - * @param[in] configuration The configuration to get gain from - * @return The current gain - */ -float acc_detector_presence_configuration_receiver_gain_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set a receiver gain to be used by the detector - * - * @param[in] configuration The configuration to set gain for - * @param[in] gain The gain to set - */ -void acc_detector_presence_configuration_receiver_gain_set(acc_detector_presence_configuration_t configuration, - float gain); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 3 makes - * the distance between two points in the measured range ~18cm. - * - * @param[in] configuration The configuration to get downsampling factor from - * @return The downsampling factor - */ -uint16_t acc_detector_presence_configuration_downsampling_factor_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 3 makes - * the distance between two points in the measured range ~18cm. - * - * The sparse service supports setting an arbitrary downsampling factor of at least 1. - * - * @param[in] configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_detector_presence_configuration_downsampling_factor_set(acc_detector_presence_configuration_t configuration, uint16_t downsampling_factor); - - -/** - * @brief Get the hardware accelerated average samples - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The configuration to get hardware accelerated average samples from - * @return Hardware accelerated average samples - */ -uint8_t acc_detector_presence_configuration_hw_accelerated_average_samples_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set the hardware accelerated average samples - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The configuration to set hardware accelerated average samples in - * @param[in] samples Hardware accelerated average samples - */ -void acc_detector_presence_configuration_hw_accelerated_average_samples_set(acc_detector_presence_configuration_t configuration, uint8_t samples); - - -/** - * @brief Get asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will measure while the host is waiting. - * In asynchronous mode the sensor will measure while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * @param[in] configuration The configuration to get asynchronous_measurement mode from - * @return Asynchronous measurement mode - */ -bool acc_detector_presence_configuration_asynchronous_measurement_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will measure while the host is waiting. - * In asynchronous mode the sensor will measure while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * @param[in] configuration The configuration to set asynchronous_measurement mode in - * @param[in] asynchronous_measurement asynchronous measurement mode, true or false - */ -void acc_detector_presence_configuration_asynchronous_measurement_set(acc_detector_presence_configuration_t configuration, - bool asynchronous_measurement); - - -/** - * @brief Gets vector output mode - * - * vector_output_mode decides whether or not the presence detector should output a distance point vector - * from the function @ref acc_detector_presence_distance_point_vector_get_next. - * - * @param[in] configuration The configuration to get vector_output_mode from - * @return vector_output_mode - */ -bool acc_detector_presence_configuration_vector_output_mode_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Sets vector output mode - * - * vector_output_mode decides whether or not the presence detector should output a distance point vector. - * - * @param[in] configuration The configuration to set vector_output_mode in - * @param[in] vector_output_mode The vector_output_mode - */ -void acc_detector_presence_configuration_vector_output_mode_set(acc_detector_presence_configuration_t configuration, bool vector_output_mode); - - -/** - * @brief Set a callback function to get the service data - * - * A callback can be used to get the sparse service buffer. The data is the sparse data that is fed into the presence algorithm - * - * @param[in] configuration The configuration to set vector_output_mode in - * @param[in] service_data_callback The callback to get service data - * @param[in] client_reference Pointer to a client reference - */ -void acc_detector_presence_configuration_set_service_data_callback(acc_detector_presence_configuration_t configuration, - acc_detector_presence_service_data_callback_t service_data_callback, - void *client_reference); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2019-2022 +// All rights reserved + +#ifndef ACC_DETECTOR_PRESENCE_H_ +#define ACC_DETECTOR_PRESENCE_H_ + +#include +#include +#include + +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" + +/** + * @defgroup Presence Presence Detector + * @ingroup Detectors + * + * @brief Presence detector API description + * + * @{ + */ + + +/** + * @brief Presence detector handle + */ +struct acc_detector_presence_handle; + +typedef struct acc_detector_presence_handle *acc_detector_presence_handle_t; + + +/** + * @brief Presence detector configuration container + */ +struct acc_detector_presence_configuration; + +typedef struct acc_detector_presence_configuration *acc_detector_presence_configuration_t; + + +/** + * @brief Parameter structure for data filtering settings + */ +typedef struct +{ + /** Time constant in s for inter-frame signal smoothing after the bandpass filtering */ + float inter_frame_deviation_time_const; + /** Low pass cutoff frequency in Hz for inter-frame signal bandpass filtering */ + float inter_frame_fast_cutoff; + /** High pass cutoff frequency in Hz for inter-frame signal bandpass filtering */ + float inter_frame_slow_cutoff; + /** Time constant in s for inter-frame signal smoothing */ + float intra_frame_time_const; + /** Weight between 0 and 1 for presence score interpolation between the inter-frame and intra-frame signals */ + float intra_frame_weight; + /** Time constant in s for smoothing of the presence score */ + float output_time_const; +} acc_detector_presence_configuration_filter_parameters_t; + + +/** + * @brief Presence detector results container + */ +typedef struct +{ + /** True if presence was detected, False otherwise */ + bool presence_detected; + /** A measure of the amount of motion detected */ + float presence_score; + /** The distance, in meters, to the detected object */ + float presence_distance; + + /** Indication of a sensor communication error, detector probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; +} acc_detector_presence_result_t; + + +/** + * @brief A callback for retrieving the service data buffer that the detector is based on + * + * @param[in] data A pointer to the buffer with sparse data + * @param[in] data_size Size of the data buffer in bytes + * @param[in] client_reference Pointer to a client reference + */ +typedef void (*acc_detector_presence_service_data_callback_t)(const uint16_t *data, size_t data_size, void *client_reference); + + +/** + * @brief Create a configuration for a presence detector + * + * @return Presence detector configuration, NULL if creation was not possible + */ +acc_detector_presence_configuration_t acc_detector_presence_configuration_create(void); + + +/** + * @brief Destroy a presence detector configuration + * + * @param[in] presence_configuration The configuration to destroy, set to NULL + */ +void acc_detector_presence_configuration_destroy(acc_detector_presence_configuration_t *presence_configuration); + + +/** + * @brief Create a presence detector with the provided configuration + * + * Only one presence detector may exist for a specific sensor at any given time and + * invalid configurations will not allow for presence detector creation. + * + * @param[in] presence_configuration The presence detector configuration to create a presence detector with + * @return Presence detector handle, NULL if presence detector was not possible to create + */ +acc_detector_presence_handle_t acc_detector_presence_create(acc_detector_presence_configuration_t presence_configuration); + + +/** + * @brief Destroy a presence detector identified with the provided handle + * + * Destroy the context of a presence detector allowing another presence detector to be created using the + * same resources. The presence detector handle reference is set to NULL after destruction. + * If NULL is sent in, nothing happens. + * + * @param[in] presence_handle A reference to the presence detector handle to destroy + */ +void acc_detector_presence_destroy(acc_detector_presence_handle_t *presence_handle); + + +/** + * @brief Reconfigure a presence detector with the provided configuration + * + * Only one presence detector may exist for a specific sensor at any given time and + * invalid reconfigurations will not allow for presence detector creation. + * + * @param[in] presence_handle A reference to the presence detector handle to reconfigure + * @param[in] presence_configuration The presence detector configuration to reconfigure a presence detector with + * @return True if possible to reconfigure + */ +bool acc_detector_presence_reconfigure(acc_detector_presence_handle_t *presence_handle, + acc_detector_presence_configuration_t presence_configuration); + + +/** + * @brief Activate the presence detector associated with the provided handle + * + * @param[in] presence_handle The presence detector handle for the presence detector to activate + * @return True if successful, otherwise false + */ +bool acc_detector_presence_activate(acc_detector_presence_handle_t presence_handle); + + +/** + * @brief Deactivate the presence detector associated with the provided handle + * + * @param[in] presence_handle The presence detector handle for the presence detector to deactivate + * @return True if successful, otherwise false + */ +bool acc_detector_presence_deactivate(acc_detector_presence_handle_t presence_handle); + + +/** + * @brief Retrieve the next result from the presence detector + * + * May only be called after a presence detector has been activated, blocks + * the application until a result is ready. Can still be called after vector + * output mode has been selected. + * + * @param[in] presence_handle The presence detector handle for the presence detector to get the next result for + * @param[out] result Presence detector results, can be NULL if no result is wanted. + * @return True if successful, otherwise false + */ +bool acc_detector_presence_get_next(acc_detector_presence_handle_t presence_handle, acc_detector_presence_result_t *result); + + +/** + * @brief Retrieve the next distance point vector from the presence detector + * + * May only be called after a presence detector has been activated, blocks + * the application until a result is ready. Vector output mode has to be set + * to true with the function @ref acc_detector_presence_configuration_vector_output_mode_set, + * otherwise returns with an error. Memory is owned by the detector and the client receives a pointer. + * + * @param[in] presence_handle The presence detector handle for the presence detector to get the next result for + * @param[out] distance_point_vector_length The number of elements in the distance_point_vector, can be NULL if no result is wanted + * @param[out] distance_point_vector The distance point vector, can be NULL if no result is wanted + * @param[out] result Presence detector results, same as result from acc_detector_presence_get_next + * @return True if successful, otherwise false + */ +bool acc_detector_presence_distance_point_vector_get_next(acc_detector_presence_handle_t presence_handle, + uint16_t *distance_point_vector_length, + float **distance_point_vector, + acc_detector_presence_result_t *result); + + +/** + * @brief Get start of sweep in m + * + * @param[in] configuration The configuration to get the sweep start for + * @return requested sweep start in m + */ +float acc_detector_presence_configuration_start_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set start of sweep in m + * + * @param[in] configuration The configuration to set the sweep start for + * @param[in] start The requested sweep start in m + */ +void acc_detector_presence_configuration_start_set(acc_detector_presence_configuration_t configuration, float start); + + +/** + * @brief Get length of sweep in m + * + * @param[in] configuration The configuration to get the sweep length for + * @return requested sweep length in m + */ +float acc_detector_presence_configuration_length_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set length of sweep in m + * + * @param[in] configuration The configuration to set the requested sweep length for + * @param[in] length The requested sweep length in m + */ +void acc_detector_presence_configuration_length_set(acc_detector_presence_configuration_t configuration, float length); + + +/** + * @brief Get sensor ID + * + * @param[in] configuration The configuration to get the sensor ID for + * @return sensor ID + */ +acc_sensor_id_t acc_detector_presence_configuration_sensor_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set sensor ID + * + * @param[in] configuration The configuration to set the sensor ID for + * @param[in] sensor_id The sensor ID + */ +void acc_detector_presence_configuration_sensor_set(acc_detector_presence_configuration_t configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get detection threshold + * + * @param[in] configuration The configuration to get the detection threshold for + * @return detection threshold + */ +float acc_detector_presence_configuration_detection_threshold_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set detection threshold + * + * @param[in] configuration The configuration to set the detection threshold for + * @param[in] detection_threshold The threshold + */ +void acc_detector_presence_configuration_detection_threshold_set(acc_detector_presence_configuration_t configuration, + float detection_threshold); + + +/** + * @brief Get detection update rate + * + * Set the update rate of which the client call the detector to produce data. It's the clients responsibility + * to keep the configured timing. + * + * @param[in] configuration The configuration to get the detection update rate for + * @return detection update rate + */ +float acc_detector_presence_configuration_update_rate_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set detection update rate + * + * Set the update rate of which the client call the detector to produce data. It's the clients responsibility + * to keep the configured timing. + * + * @param[in] configuration The configuration to set the detection update rate for + * @param[in] update_rate + */ +void acc_detector_presence_configuration_update_rate_set(acc_detector_presence_configuration_t configuration, + float update_rate); + + +/** + * @brief Get the number of sweeps per frame + * + * @param[in] configuration The configuration to get the number of sweeps per frame for + * @return The number of sweeps per frame + */ +uint16_t acc_detector_presence_configuration_sweeps_per_frame_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set the number of sweeps per frame + * + * @param[in] configuration The configuration to set the number of sweeps per frame for + * @param[in] sweeps_per_frame The requested number of sweeps per frame + */ +void acc_detector_presence_configuration_sweeps_per_frame_set(acc_detector_presence_configuration_t configuration, + uint16_t sweeps_per_frame); + + +/** + * @brief Get the sweep rate + * + * Gets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. + * + * @param[in] configuration The configuration to get the sweep rate from + * @return sweep_rate The sweep rate + */ +float acc_detector_presence_configuration_sweep_rate_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set sweep rate + * + * Sets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. + * + * @param[in] configuration The configuration to set the sweep rate in + * @param[in] sweep_rate The sweep rate + */ +void acc_detector_presence_configuration_sweep_rate_set(acc_detector_presence_configuration_t configuration, float sweep_rate); + + +/** + * @brief Get sensor data filtering parameters + * + * See @ref acc_detector_presence_configuration_filter_parameters_set + * + * @param[in] configuration The configuration to get the filter parameters for + * @return The filter parameters, see @ref acc_detector_presence_configuration_filter_parameters_t + */ +acc_detector_presence_configuration_filter_parameters_t acc_detector_presence_configuration_filter_parameters_get( + acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set sensor data filtering parameters + * + * Set filter parameters for the sensor data filtering that is performed before presence detection thresholding. + * + * @param[in] configuration The configuration to set the filter parameters for + * @param[in] filter_parameters The filter parameter structure, see @ref acc_detector_presence_configuration_filter_parameters_t + */ +void acc_detector_presence_configuration_filter_parameters_set(acc_detector_presence_configuration_t configuration, + const acc_detector_presence_configuration_filter_parameters_t *filter_parameters); + + +/** + * @brief Get the number of principal components removed in the PCA based noise reduction + * + * @param[in] configuration The configuration to get the number of principal components of noise to remove for + * @return The number of principal components of noise to remove, between 0 and 2 + */ +uint8_t acc_detector_presence_configuration_nbr_removed_pc_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set the number of principal components removed in the PCA based noise reduction + * + * Sets the number of principal components removed in the PCA based noise reduction. + * Filters out static reflections. + * Setting to 0 (default) disables the PCA based noise reduction completely. + * For more information on the PCA based noise reduction algorithm, see + * Read-the-Docs + * + * @param[in] configuration The configuration to set the number of principal components of noise to remove for + * @param[in] nbr_removed_pc The number of principal components of noise to remove, between 0 and 2 + */ +void acc_detector_presence_configuration_nbr_removed_pc_set(acc_detector_presence_configuration_t configuration, uint8_t nbr_removed_pc); + + +/** + * @brief Get power save mode + * + * @param[in] configuration The configuration to get the power save mode for + * @return power save mode + */ +acc_power_save_mode_t acc_detector_presence_configuration_power_save_mode_get( + acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set power save mode + * + * @param[in] configuration The configuration to set the power save mode for + * @param[in] power_save_mode The power save mode + */ +void acc_detector_presence_configuration_power_save_mode_set(acc_detector_presence_configuration_t configuration, + acc_power_save_mode_t power_save_mode); + + +/** + * @brief Get the current service profile used by the detector + * + * See @ref acc_service_profile_t for details + * + * @param[in] configuration The configuration to get a profile from + * @return The current profile, 0 if configuration is invalid + */ +acc_service_profile_t acc_detector_presence_configuration_service_profile_get( + acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set a service profile to be used by the detector + * + * See @ref acc_service_profile_t for details + * + * @param[in] configuration The configuration to set a profile for + * @param[in] service_profile The profile to set + */ +void acc_detector_presence_configuration_service_profile_set(acc_detector_presence_configuration_t configuration, + acc_service_profile_t service_profile); + + +/** + * @brief Get the current receiver gain used by the detector + * + * @param[in] configuration The configuration to get gain from + * @return The current gain + */ +float acc_detector_presence_configuration_receiver_gain_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set a receiver gain to be used by the detector + * + * @param[in] configuration The configuration to set gain for + * @param[in] gain The gain to set + */ +void acc_detector_presence_configuration_receiver_gain_set(acc_detector_presence_configuration_t configuration, + float gain); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 3 makes + * the distance between two points in the measured range ~18cm. + * + * @param[in] configuration The configuration to get downsampling factor from + * @return The downsampling factor + */ +uint16_t acc_detector_presence_configuration_downsampling_factor_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 3 makes + * the distance between two points in the measured range ~18cm. + * + * The sparse service supports setting an arbitrary downsampling factor of at least 1. + * + * @param[in] configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_detector_presence_configuration_downsampling_factor_set(acc_detector_presence_configuration_t configuration, uint16_t downsampling_factor); + + +/** + * @brief Get the hardware accelerated average samples + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The configuration to get hardware accelerated average samples from + * @return Hardware accelerated average samples + */ +uint8_t acc_detector_presence_configuration_hw_accelerated_average_samples_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set the hardware accelerated average samples + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The configuration to set hardware accelerated average samples in + * @param[in] samples Hardware accelerated average samples + */ +void acc_detector_presence_configuration_hw_accelerated_average_samples_set(acc_detector_presence_configuration_t configuration, uint8_t samples); + + +/** + * @brief Get asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will measure while the host is waiting. + * In asynchronous mode the sensor will measure while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * @param[in] configuration The configuration to get asynchronous_measurement mode from + * @return Asynchronous measurement mode + */ +bool acc_detector_presence_configuration_asynchronous_measurement_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will measure while the host is waiting. + * In asynchronous mode the sensor will measure while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * @param[in] configuration The configuration to set asynchronous_measurement mode in + * @param[in] asynchronous_measurement asynchronous measurement mode, true or false + */ +void acc_detector_presence_configuration_asynchronous_measurement_set(acc_detector_presence_configuration_t configuration, + bool asynchronous_measurement); + + +/** + * @brief Gets vector output mode + * + * vector_output_mode decides whether or not the presence detector should output a distance point vector + * from the function @ref acc_detector_presence_distance_point_vector_get_next. + * + * @param[in] configuration The configuration to get vector_output_mode from + * @return vector_output_mode + */ +bool acc_detector_presence_configuration_vector_output_mode_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Sets vector output mode + * + * vector_output_mode decides whether or not the presence detector should output a distance point vector. + * + * @param[in] configuration The configuration to set vector_output_mode in + * @param[in] vector_output_mode The vector_output_mode + */ +void acc_detector_presence_configuration_vector_output_mode_set(acc_detector_presence_configuration_t configuration, bool vector_output_mode); + + +/** + * @brief Set a callback function to get the service data + * + * A callback can be used to get the sparse service buffer. The data is the sparse data that is fed into the presence algorithm + * + * @param[in] configuration The configuration to set vector_output_mode in + * @param[in] service_data_callback The callback to get service data + * @param[in] client_reference Pointer to a client reference + */ +void acc_detector_presence_configuration_set_service_data_callback(acc_detector_presence_configuration_t configuration, + acc_detector_presence_service_data_callback_t service_data_callback, + void *client_reference); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_hal_definitions.h b/STM32CubeIDE/rss/include/acc_hal_definitions.h index 931c8c7..3f085c5 100644 --- a/STM32CubeIDE/rss/include/acc_hal_definitions.h +++ b/STM32CubeIDE/rss/include/acc_hal_definitions.h @@ -1,312 +1,312 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved - -#ifndef ACC_HAL_DEFINITIONS_H_ -#define ACC_HAL_DEFINITIONS_H_ - -#include -#include -#include -#include - -#include "acc_definitions_common.h" - - -/** - * @brief Defines the largest allowed value of a sensor ID - */ -#define ACC_SENSOR_ID_MAX 42U - -/** - * @brief Specifies the minimal size in bytes that SPI transfers must be able to handle - */ -#define ACC_SPI_TRANSFER_SIZE_REQUIRED 16 - -/** - * @brief Specifies the number of clock cycles needed for sensor to enter hibernate mode - */ -#define ACC_NBR_CLOCK_CYCLES_REQUIRED_HIBERNATE_ENTER 10 - -/** - * @brief Specifies the number of clock cycles needed for the first part of the sensor exiting hibernate mode - */ -#define ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_1_HIBERNATE_EXIT 3 - -/** - * @brief Specifies the number of clock cycles needed for the second part of the sensor exiting hibernate mode - */ -#define ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_2_HIBERNATE_EXIT (13 - ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_1_HIBERNATE_EXIT) - -/** - * @brief Specifies the number of millisonds of delay needed for the Oscillator to stabilize when exiting hibernate mode - */ -#define ACC_WAIT_TIME_HIBERNATE_EXIT_MS 2 - -/** - * @defgroup OS OS Integration - * @ingroup Integration - * - * @brief Integration OS primitives - * - * @{ - */ - - -/** - * @brief Definition of a memory allocation function - * - * Allocated memory should be suitably aligned for any built-in type. Returning NULL is seen as failure. - */ -typedef void *(*acc_os_mem_alloc_function_t)(size_t); - - -/** - * @brief Definition of a memory free function - * - * Free memory which is previously allocated. - */ -typedef void (*acc_os_mem_free_function_t)(void *); - - -/** - * @brief Definition of a time retrieval function - * - * The time returned must be in milliseconds. - * - * Must be implemented by integration. - */ -typedef uint32_t (*acc_os_get_time_function_t)(void); - - -/** - * @brief Struct that contains the implementation of os integration primitives - */ -typedef struct -{ - acc_os_mem_alloc_function_t mem_alloc; - acc_os_mem_free_function_t mem_free; - acc_os_get_time_function_t gettime; -} acc_rss_integration_os_primitives_t; - -/** - * @} - */ - - -/** - * @defgroup HAL Hardware Integration - * @ingroup Integration - * - * @brief Integration of Hardware Abstraction Layer for the radar sensor - * - * @{ - */ - - -/** - * @brief Definition of a sensor power function - * - * These functions control the power of the sensor. It typically control PS_ENABLE - * and PMU_ENABLE. The hibernate functions should also toggle the CTRL pin. - * - * In the case of the power_on function: - * Any pending sensor interrupts should be cleared before returning from function. - */ -typedef void (*acc_hal_sensor_power_function_t)(acc_sensor_id_t sensor_id); - - -/** - * @brief Definition of a hal get frequency function - * - * This function shall return the frequency of the reference clock connected to the sensor. - * - */ -typedef float (*acc_hal_get_frequency_function_t)(void); - - -/** - * @brief Definition of a wait for sensor interrupt function - * - * This function shall wait at most timeout_ms for the interrupt to become active and - * then return true. It may return true immediately if an interrupt have - * occurred since last call to this function. - * - * If waited more than timeout_ms for the interrupt to become active it shall - * return false. - * - * Note that this function can be called with a timeout_ms = 0. - * - */ -typedef bool (*acc_hal_sensor_wait_for_interrupt_function_t)(acc_sensor_id_t sensor_id, uint32_t timeout_ms); - - -/** - * @brief Definition of a sensor transfer function - * - * This function shall transfer data to and from the sensor over spi. It's beneficial from a performance perspective - * to use dma if available. - * The buffer is naturally aligned to a maximum of 4 bytes. - * - */ -typedef void (*acc_hal_sensor_transfer_function_t)(acc_sensor_id_t sensor_id, uint8_t *buffer, size_t buffer_size); - - -/** - * @brief This struct contains function pointers that point to - * functions needed for communication with the radar sensor. - */ -typedef struct -{ - acc_hal_sensor_power_function_t power_on; - acc_hal_sensor_power_function_t power_off; - acc_hal_sensor_power_function_t hibernate_enter; - acc_hal_sensor_power_function_t hibernate_exit; - acc_hal_sensor_wait_for_interrupt_function_t wait_for_interrupt; - acc_hal_sensor_transfer_function_t transfer; - acc_hal_get_frequency_function_t get_reference_frequency; -} acc_rss_integration_sensor_device_t; - - -/** - * @} - */ - - -/** - * @defgroup Properties Integration Properties - * @ingroup Integration - * - * @brief Integration specific properties that is used for configuration of RSS. - * - * Number of sensors connected to each board and the maximum buffer size that the - * spi driver can handle can be different between applications. These values shall - * be configured by the client. - * - * @{ - */ - - -/** - * @brief This struct contains information about board properties that - * are needed by RSS. - * - * @ref sensor_count is the maximal sensor ID that the integration layer supports. - * This value must not exceed @ref ACC_SENSOR_ID_MAX. - * - * @ref max_spi_transfer_size is the maximal buffer size that is supported - * by the implementation of @ref acc_hal_sensor_transfer_function_t. - * This value must not be smaller than @ref ACC_SPI_TRANSFER_SIZE_REQUIRED. - */ -typedef struct -{ - uint32_t sensor_count; - size_t max_spi_transfer_size; -} acc_rss_integration_properties_t; - -/** - * @} - */ - - -/** - * @defgroup Opimization Optional optimizations - * @ingroup Integration - * - * @brief Support for different optimizations - * - * @{ - */ - - -/** - * @brief Definition of an optimized 16-bit sensor transfer function - * - * This function shall transfer data to and from the sensor over spi with 16 bits data size. - * It's beneficial from a performance perspective to use dma if available. - * The buffer is naturally aligned to a minimum of 4 bytes. - * - * If defined it will be used instead of the (8-bit) transfer function @ref acc_hal_sensor_transfer_function_t - * - */ -typedef void (*acc_sensor_transfer16_function_t)(acc_sensor_id_t sensor_id, uint16_t *buffer, size_t buffer_length); - - -/** - * @brief This struct contains function pointers that are optional to support different optimizations - * - * Optional - * - * This struct contains function pointers to support different optimizations. - * These optimizations can be utilized for some integrations. - * If they are defined, they will override the corresponding non-optimized function. - * - * For example, if the transfer16 function is implemented, it will be used instead of the transfer function. - */ -typedef struct -{ - acc_sensor_transfer16_function_t transfer16; -} acc_optimization_t; - -/** - * @} - */ - - -/** - * @defgroup Log Log Integration - * @ingroup Integration - * - * @brief Integration for log functionality - * - * @{ - */ - - -/** - * @brief Definition of a log function - */ -typedef void (*acc_log_function_t)(acc_log_level_t level, const char *module, const char *format, ...); - - -/** - * @brief This struct contains information about log properties and functions - * needed by RSS - */ -typedef struct -{ - acc_log_level_t log_level; - acc_log_function_t log; -} acc_rss_integration_log_t; - - -/** - * @} - */ - - -/** - * @defgroup Integration Integration - * @brief Driver and OS Integration - * - * @{ - */ - - -/** - * @brief This struct contains the information about the sensor - * integration that RSS needs. - */ - -typedef struct -{ - acc_rss_integration_properties_t properties; - acc_rss_integration_os_primitives_t os; - acc_rss_integration_sensor_device_t sensor_device; - acc_rss_integration_log_t log; - acc_optimization_t optimization; -} acc_hal_t; - -/** - * @} - */ -#endif +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved + +#ifndef ACC_HAL_DEFINITIONS_H_ +#define ACC_HAL_DEFINITIONS_H_ + +#include +#include +#include +#include + +#include "acc_definitions_common.h" + + +/** + * @brief Defines the largest allowed value of a sensor ID + */ +#define ACC_SENSOR_ID_MAX 42U + +/** + * @brief Specifies the minimal size in bytes that SPI transfers must be able to handle + */ +#define ACC_SPI_TRANSFER_SIZE_REQUIRED 16 + +/** + * @brief Specifies the number of clock cycles needed for sensor to enter hibernate mode + */ +#define ACC_NBR_CLOCK_CYCLES_REQUIRED_HIBERNATE_ENTER 10 + +/** + * @brief Specifies the number of clock cycles needed for the first part of the sensor exiting hibernate mode + */ +#define ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_1_HIBERNATE_EXIT 3 + +/** + * @brief Specifies the number of clock cycles needed for the second part of the sensor exiting hibernate mode + */ +#define ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_2_HIBERNATE_EXIT (13 - ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_1_HIBERNATE_EXIT) + +/** + * @brief Specifies the number of millisonds of delay needed for the Oscillator to stabilize when exiting hibernate mode + */ +#define ACC_WAIT_TIME_HIBERNATE_EXIT_MS 2 + +/** + * @defgroup OS OS Integration + * @ingroup Integration + * + * @brief Integration OS primitives + * + * @{ + */ + + +/** + * @brief Definition of a memory allocation function + * + * Allocated memory should be suitably aligned for any built-in type. Returning NULL is seen as failure. + */ +typedef void *(*acc_os_mem_alloc_function_t)(size_t); + + +/** + * @brief Definition of a memory free function + * + * Free memory which is previously allocated. + */ +typedef void (*acc_os_mem_free_function_t)(void *); + + +/** + * @brief Definition of a time retrieval function + * + * The time returned must be in milliseconds. + * + * Must be implemented by integration. + */ +typedef uint32_t (*acc_os_get_time_function_t)(void); + + +/** + * @brief Struct that contains the implementation of os integration primitives + */ +typedef struct +{ + acc_os_mem_alloc_function_t mem_alloc; + acc_os_mem_free_function_t mem_free; + acc_os_get_time_function_t gettime; +} acc_rss_integration_os_primitives_t; + +/** + * @} + */ + + +/** + * @defgroup HAL Hardware Integration + * @ingroup Integration + * + * @brief Integration of Hardware Abstraction Layer for the radar sensor + * + * @{ + */ + + +/** + * @brief Definition of a sensor power function + * + * These functions control the power of the sensor. It typically control PS_ENABLE + * and PMU_ENABLE. The hibernate functions should also toggle the CTRL pin. + * + * In the case of the power_on function: + * Any pending sensor interrupts should be cleared before returning from function. + */ +typedef void (*acc_hal_sensor_power_function_t)(acc_sensor_id_t sensor_id); + + +/** + * @brief Definition of a hal get frequency function + * + * This function shall return the frequency of the reference clock connected to the sensor. + * + */ +typedef float (*acc_hal_get_frequency_function_t)(void); + + +/** + * @brief Definition of a wait for sensor interrupt function + * + * This function shall wait at most timeout_ms for the interrupt to become active and + * then return true. It may return true immediately if an interrupt have + * occurred since last call to this function. + * + * If waited more than timeout_ms for the interrupt to become active it shall + * return false. + * + * Note that this function can be called with a timeout_ms = 0. + * + */ +typedef bool (*acc_hal_sensor_wait_for_interrupt_function_t)(acc_sensor_id_t sensor_id, uint32_t timeout_ms); + + +/** + * @brief Definition of a sensor transfer function + * + * This function shall transfer data to and from the sensor over spi. It's beneficial from a performance perspective + * to use dma if available. + * The buffer is naturally aligned to a maximum of 4 bytes. + * + */ +typedef void (*acc_hal_sensor_transfer_function_t)(acc_sensor_id_t sensor_id, uint8_t *buffer, size_t buffer_size); + + +/** + * @brief This struct contains function pointers that point to + * functions needed for communication with the radar sensor. + */ +typedef struct +{ + acc_hal_sensor_power_function_t power_on; + acc_hal_sensor_power_function_t power_off; + acc_hal_sensor_power_function_t hibernate_enter; + acc_hal_sensor_power_function_t hibernate_exit; + acc_hal_sensor_wait_for_interrupt_function_t wait_for_interrupt; + acc_hal_sensor_transfer_function_t transfer; + acc_hal_get_frequency_function_t get_reference_frequency; +} acc_rss_integration_sensor_device_t; + + +/** + * @} + */ + + +/** + * @defgroup Properties Integration Properties + * @ingroup Integration + * + * @brief Integration specific properties that is used for configuration of RSS. + * + * Number of sensors connected to each board and the maximum buffer size that the + * spi driver can handle can be different between applications. These values shall + * be configured by the client. + * + * @{ + */ + + +/** + * @brief This struct contains information about board properties that + * are needed by RSS. + * + * @ref sensor_count is the maximal sensor ID that the integration layer supports. + * This value must not exceed @ref ACC_SENSOR_ID_MAX. + * + * @ref max_spi_transfer_size is the maximal buffer size that is supported + * by the implementation of @ref acc_hal_sensor_transfer_function_t. + * This value must not be smaller than @ref ACC_SPI_TRANSFER_SIZE_REQUIRED. + */ +typedef struct +{ + uint32_t sensor_count; + size_t max_spi_transfer_size; +} acc_rss_integration_properties_t; + +/** + * @} + */ + + +/** + * @defgroup Opimization Optional optimizations + * @ingroup Integration + * + * @brief Support for different optimizations + * + * @{ + */ + + +/** + * @brief Definition of an optimized 16-bit sensor transfer function + * + * This function shall transfer data to and from the sensor over spi with 16 bits data size. + * It's beneficial from a performance perspective to use dma if available. + * The buffer is naturally aligned to a minimum of 4 bytes. + * + * If defined it will be used instead of the (8-bit) transfer function @ref acc_hal_sensor_transfer_function_t + * + */ +typedef void (*acc_sensor_transfer16_function_t)(acc_sensor_id_t sensor_id, uint16_t *buffer, size_t buffer_length); + + +/** + * @brief This struct contains function pointers that are optional to support different optimizations + * + * Optional + * + * This struct contains function pointers to support different optimizations. + * These optimizations can be utilized for some integrations. + * If they are defined, they will override the corresponding non-optimized function. + * + * For example, if the transfer16 function is implemented, it will be used instead of the transfer function. + */ +typedef struct +{ + acc_sensor_transfer16_function_t transfer16; +} acc_optimization_t; + +/** + * @} + */ + + +/** + * @defgroup Log Log Integration + * @ingroup Integration + * + * @brief Integration for log functionality + * + * @{ + */ + + +/** + * @brief Definition of a log function + */ +typedef void (*acc_log_function_t)(acc_log_level_t level, const char *module, const char *format, ...); + + +/** + * @brief This struct contains information about log properties and functions + * needed by RSS + */ +typedef struct +{ + acc_log_level_t log_level; + acc_log_function_t log; +} acc_rss_integration_log_t; + + +/** + * @} + */ + + +/** + * @defgroup Integration Integration + * @brief Driver and OS Integration + * + * @{ + */ + + +/** + * @brief This struct contains the information about the sensor + * integration that RSS needs. + */ + +typedef struct +{ + acc_rss_integration_properties_t properties; + acc_rss_integration_os_primitives_t os; + acc_rss_integration_sensor_device_t sensor_device; + acc_rss_integration_log_t log; + acc_optimization_t optimization; +} acc_hal_t; + +/** + * @} + */ +#endif diff --git a/STM32CubeIDE/rss/include/acc_rss.h b/STM32CubeIDE/rss/include/acc_rss.h index e388af9..6edc083 100644 --- a/STM32CubeIDE/rss/include/acc_rss.h +++ b/STM32CubeIDE/rss/include/acc_rss.h @@ -1,148 +1,148 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved - -#ifndef ACC_RSS_H_ -#define ACC_RSS_H_ - -#include - -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" -#include "acc_hal_definitions.h" - - -/** - * @defgroup RSS Radar System Software, RSS - * - * @brief Acconeer Radar System Software, RSS - * - * @{ - */ - - -/** - * @brief Activate the Acconeer Radar System Software, RSS - * - * A HAL struct containing integration functions (such as 'wait_for_interrupt', 'mem_alloc' and 'log') - * needed by RSS must first be populated and then sent in. See 'acc_definitions_common.h' for a full list - * of functions needed. - * - * This function must be called before any other RSS function. If it is not, or it failed, - * calling any other RSS function is undefined behaviour. - * - * @param[in] hal Reference to a HAL struct containing integration functions that is needed by RSS - * @return True if RSS activated successfully - */ -bool acc_rss_activate(const acc_hal_t *hal); - - -/** - * @brief Deactivate the Acconeer Radar System Software, RSS - */ -void acc_rss_deactivate(void); - - -/** - * @brief Get the sensor calibration context - * - * Must be called after RSS has been activated. - * A calibration will be done for the specific sensor. - * A successful call to this function will also trigger context reset. - * - * @param[in] sensor_id The sensor to get the context for - * @param[out] calibration_context Reference to struct where the context will be stored - * @return True if successful, false otherwise - */ -bool acc_rss_calibration_context_get(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); - - -/** - * @brief Set a previously saved sensor calibration context and verify that the sensor calibration context is valid - * - * Must be called after RSS has been activated. - * No active service is allowed on the sensor when setting the context. - * If this function is successfully called, a new sensor calibration will not be done during service creation step. - * - * @param[in] sensor_id The sensor to set the context on - * @param[in] calibration_context The calibration context to set - * - * @return True if successful, false otherwise - */ -bool acc_rss_calibration_context_set(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); - - -/** - * @brief Set a previously saved sensor calibration context, ignore the result from calibration context validation - * - * Must be called after RSS has been activated. Must only be used with a fresh calibration context - * immediately after a successfull call to acc_rss_calibration_context_get. - * No active service is allowed on the sensor when setting the context. - * If this function is successfully called, a new sensor calibration will not be done during service creation step. - * - * @param[in] sensor_id The sensor to set the context on - * @param[in] calibration_context The calibration context to set - * - * @return True if successful, false otherwise - */ -bool acc_rss_calibration_context_forced_set(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); - - -/** - * @brief Reset a calibration done on the specific sensor (or remove a previously set calibration context) - * - * No active service is allowed on the sensor when resetting the calibration - * If this function is successfully called, a new sensor calibration will be done during service creation step. - * - * @param[in] sensor_id The sensor to reset the calibration on - * - * @return True if successful, false otherwise - */ -bool acc_rss_calibration_reset(acc_sensor_id_t sensor_id); - - -/** - * @brief Enable or disable check of sensor id when creating a service or detector - * - * Must be called after RSS has been activated and before creating several services or detectors for the same sensor id. - * After this function is called, with enable override set to true, it is possible to create several services or - * detectors for the same sensor id. It is still only possible to have one service or detector per sensor id active - * at the same time. - * - * @param[in] enable_override True if the sensor id check override should be enabled - */ -void acc_rss_override_sensor_id_check_at_creation(bool enable_override); - - -/** - * @brief Check if a sensor is connected at the specified sensor id - * - * This function will try to communicate with the sensor at the specified sensor id. - * @details - * - This function must be called after @ref acc_rss_activate. - * - This function must be called before any service is created. - * - * @param[in] sensor_id The sensor to check the connection status for - * @param[out] connected True if a sensor is connected at the specified sensor id - * - * @return True if successful, false otherwise - */ -bool acc_rss_sensor_connected(acc_sensor_id_t sensor_id, bool *connected); - - -/** - * @brief Set the log level that determines when the integration HAL logger function is called - * - * This function enables adjustment of the log level after RSS has been activated. Shall be called when - * RSS is active as it has no effect otherwise. The severity of the logged messages is selected in the - * same way as for log.log_level in @ref acc_hal_t. - * - * @param[in] level The severity level for selection of log output via @ref acc_log_function_t. - */ -void acc_rss_log_level_set(acc_log_level_t level); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved + +#ifndef ACC_RSS_H_ +#define ACC_RSS_H_ + +#include + +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" +#include "acc_hal_definitions.h" + + +/** + * @defgroup RSS Radar System Software, RSS + * + * @brief Acconeer Radar System Software, RSS + * + * @{ + */ + + +/** + * @brief Activate the Acconeer Radar System Software, RSS + * + * A HAL struct containing integration functions (such as 'wait_for_interrupt', 'mem_alloc' and 'log') + * needed by RSS must first be populated and then sent in. See 'acc_definitions_common.h' for a full list + * of functions needed. + * + * This function must be called before any other RSS function. If it is not, or it failed, + * calling any other RSS function is undefined behaviour. + * + * @param[in] hal Reference to a HAL struct containing integration functions that is needed by RSS + * @return True if RSS activated successfully + */ +bool acc_rss_activate(const acc_hal_t *hal); + + +/** + * @brief Deactivate the Acconeer Radar System Software, RSS + */ +void acc_rss_deactivate(void); + + +/** + * @brief Get the sensor calibration context + * + * Must be called after RSS has been activated. + * A calibration will be done for the specific sensor. + * A successful call to this function will also trigger context reset. + * + * @param[in] sensor_id The sensor to get the context for + * @param[out] calibration_context Reference to struct where the context will be stored + * @return True if successful, false otherwise + */ +bool acc_rss_calibration_context_get(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); + + +/** + * @brief Set a previously saved sensor calibration context and verify that the sensor calibration context is valid + * + * Must be called after RSS has been activated. + * No active service is allowed on the sensor when setting the context. + * If this function is successfully called, a new sensor calibration will not be done during service creation step. + * + * @param[in] sensor_id The sensor to set the context on + * @param[in] calibration_context The calibration context to set + * + * @return True if successful, false otherwise + */ +bool acc_rss_calibration_context_set(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); + + +/** + * @brief Set a previously saved sensor calibration context, ignore the result from calibration context validation + * + * Must be called after RSS has been activated. Must only be used with a fresh calibration context + * immediately after a successfull call to acc_rss_calibration_context_get. + * No active service is allowed on the sensor when setting the context. + * If this function is successfully called, a new sensor calibration will not be done during service creation step. + * + * @param[in] sensor_id The sensor to set the context on + * @param[in] calibration_context The calibration context to set + * + * @return True if successful, false otherwise + */ +bool acc_rss_calibration_context_forced_set(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); + + +/** + * @brief Reset a calibration done on the specific sensor (or remove a previously set calibration context) + * + * No active service is allowed on the sensor when resetting the calibration + * If this function is successfully called, a new sensor calibration will be done during service creation step. + * + * @param[in] sensor_id The sensor to reset the calibration on + * + * @return True if successful, false otherwise + */ +bool acc_rss_calibration_reset(acc_sensor_id_t sensor_id); + + +/** + * @brief Enable or disable check of sensor id when creating a service or detector + * + * Must be called after RSS has been activated and before creating several services or detectors for the same sensor id. + * After this function is called, with enable override set to true, it is possible to create several services or + * detectors for the same sensor id. It is still only possible to have one service or detector per sensor id active + * at the same time. + * + * @param[in] enable_override True if the sensor id check override should be enabled + */ +void acc_rss_override_sensor_id_check_at_creation(bool enable_override); + + +/** + * @brief Check if a sensor is connected at the specified sensor id + * + * This function will try to communicate with the sensor at the specified sensor id. + * @details + * - This function must be called after @ref acc_rss_activate. + * - This function must be called before any service is created. + * + * @param[in] sensor_id The sensor to check the connection status for + * @param[out] connected True if a sensor is connected at the specified sensor id + * + * @return True if successful, false otherwise + */ +bool acc_rss_sensor_connected(acc_sensor_id_t sensor_id, bool *connected); + + +/** + * @brief Set the log level that determines when the integration HAL logger function is called + * + * This function enables adjustment of the log level after RSS has been activated. Shall be called when + * RSS is active as it has no effect otherwise. The severity of the logged messages is selected in the + * same way as for log.log_level in @ref acc_hal_t. + * + * @param[in] level The severity level for selection of log output via @ref acc_log_function_t. + */ +void acc_rss_log_level_set(acc_log_level_t level); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_rss_assembly_test.h b/STM32CubeIDE/rss/include/acc_rss_assembly_test.h index 7bb9cef..9640217 100644 --- a/STM32CubeIDE/rss/include/acc_rss_assembly_test.h +++ b/STM32CubeIDE/rss/include/acc_rss_assembly_test.h @@ -1,227 +1,227 @@ -// Copyright (c) Acconeer AB, 2019-2022 -// All rights reserved - -#ifndef ACC_RSS_ASSEMBLY_TEST_H_ -#define ACC_RSS_ASSEMBLY_TEST_H_ - -#include "acc_definitions_common.h" -#include - - -#define ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS (20U) - - -/** - * @defgroup Assembly_test Assembly test - * @ingroup RSS - * - * @brief RSS Assembly test - * - * @{ - */ - - -/** - * @brief The result of an assembly test run - */ -typedef struct -{ - const char *test_name; - bool test_passed; -} acc_rss_assembly_test_result_t; - - -/** - * @brief Assembly test configuration container - */ -struct acc_rss_assembly_test_configuration; - -typedef struct acc_rss_assembly_test_configuration *acc_rss_assembly_test_configuration_t; - - -/** - * @brief Create a configuration for an assembly test run - * - * @return An assembly test configuration, NULL if creation was not possible - */ -acc_rss_assembly_test_configuration_t acc_rss_assembly_test_configuration_create(void); - - -/** - * @brief Destroy an assembly test configuration - * - * The assembly test configuration reference is set to NULL after destruction. - * - * @param[in] configuration The configuration to destroy, set to NULL - */ -void acc_rss_assembly_test_configuration_destroy(acc_rss_assembly_test_configuration_t *configuration); - - -/** - * @brief Set the sensor id - * - * @param[in] configuration An assembly test configuration - * @param[in] sensor_id The sensor id to set - */ -void acc_rss_assembly_test_configuration_sensor_set(acc_rss_assembly_test_configuration_t configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get the sensor id that is configured - * - * @param[in] configuration An assembly test configuration - * @return Sensor id - */ -acc_sensor_id_t acc_rss_assembly_test_configuration_sensor_get(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the sensor communication read test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_read_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the sensor communication read test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_read_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the sensor communication write and read test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_write_read_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the sensor communication write and read test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_write_read_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enalbe the sensor communication interrupt test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_interrupt_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the sensor communication interrupt test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_interrupt_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the sensor communication hibernate test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_hibernate_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the sensor communication hibernate test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_hibernate_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the supply test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_supply_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the supply test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_supply_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the clock test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_clock_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the clock test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_clock_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the power cycle test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_power_cycle_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the power cycle test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_power_cycle_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable all tests - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_all_tests_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Run assembly test - * - * This function executes a suite of tests suitable for PCB assembly testing. - * - * @details The caller need to allocate an array of assembly test results of at least the size - * of ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS. The array size is to be provided in the - * nr_of_test_results parameter. If the size is not sufficiently large the test will - * fail. - * - * If a test fails to execute the return value will be set to false. - * If a test cannot pass its test limits the test_passed member of test_results will be - * set to false but the return value of this function will still be true. - * - * @param[in] test_configuration The test configuration - * @param[out] test_results Reference to struct where the test results will be stored - * @param[in,out] nr_of_test_results Input is the maximum number of items in the results array. - * Output is the actual number of test results available after - * the execution of the tests. - * @return True if successfully run, false otherwise - */ -bool acc_rss_assembly_test(acc_rss_assembly_test_configuration_t test_configuration, acc_rss_assembly_test_result_t *test_results, - uint16_t *nr_of_test_results); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2019-2022 +// All rights reserved + +#ifndef ACC_RSS_ASSEMBLY_TEST_H_ +#define ACC_RSS_ASSEMBLY_TEST_H_ + +#include "acc_definitions_common.h" +#include + + +#define ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS (20U) + + +/** + * @defgroup Assembly_test Assembly test + * @ingroup RSS + * + * @brief RSS Assembly test + * + * @{ + */ + + +/** + * @brief The result of an assembly test run + */ +typedef struct +{ + const char *test_name; + bool test_passed; +} acc_rss_assembly_test_result_t; + + +/** + * @brief Assembly test configuration container + */ +struct acc_rss_assembly_test_configuration; + +typedef struct acc_rss_assembly_test_configuration *acc_rss_assembly_test_configuration_t; + + +/** + * @brief Create a configuration for an assembly test run + * + * @return An assembly test configuration, NULL if creation was not possible + */ +acc_rss_assembly_test_configuration_t acc_rss_assembly_test_configuration_create(void); + + +/** + * @brief Destroy an assembly test configuration + * + * The assembly test configuration reference is set to NULL after destruction. + * + * @param[in] configuration The configuration to destroy, set to NULL + */ +void acc_rss_assembly_test_configuration_destroy(acc_rss_assembly_test_configuration_t *configuration); + + +/** + * @brief Set the sensor id + * + * @param[in] configuration An assembly test configuration + * @param[in] sensor_id The sensor id to set + */ +void acc_rss_assembly_test_configuration_sensor_set(acc_rss_assembly_test_configuration_t configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get the sensor id that is configured + * + * @param[in] configuration An assembly test configuration + * @return Sensor id + */ +acc_sensor_id_t acc_rss_assembly_test_configuration_sensor_get(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the sensor communication read test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_read_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the sensor communication read test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_read_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the sensor communication write and read test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_write_read_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the sensor communication write and read test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_write_read_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enalbe the sensor communication interrupt test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_interrupt_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the sensor communication interrupt test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_interrupt_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the sensor communication hibernate test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_hibernate_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the sensor communication hibernate test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_hibernate_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the supply test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_supply_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the supply test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_supply_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the clock test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_clock_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the clock test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_clock_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the power cycle test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_power_cycle_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the power cycle test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_power_cycle_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable all tests + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_all_tests_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Run assembly test + * + * This function executes a suite of tests suitable for PCB assembly testing. + * + * @details The caller need to allocate an array of assembly test results of at least the size + * of ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS. The array size is to be provided in the + * nr_of_test_results parameter. If the size is not sufficiently large the test will + * fail. + * + * If a test fails to execute the return value will be set to false. + * If a test cannot pass its test limits the test_passed member of test_results will be + * set to false but the return value of this function will still be true. + * + * @param[in] test_configuration The test configuration + * @param[out] test_results Reference to struct where the test results will be stored + * @param[in,out] nr_of_test_results Input is the maximum number of items in the results array. + * Output is the actual number of test results available after + * the execution of the tests. + * @return True if successfully run, false otherwise + */ +bool acc_rss_assembly_test(acc_rss_assembly_test_configuration_t test_configuration, acc_rss_assembly_test_result_t *test_results, + uint16_t *nr_of_test_results); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_rss_diagnostics.h b/STM32CubeIDE/rss/include/acc_rss_diagnostics.h index 2e30886..536c82b 100644 --- a/STM32CubeIDE/rss/include/acc_rss_diagnostics.h +++ b/STM32CubeIDE/rss/include/acc_rss_diagnostics.h @@ -1,41 +1,41 @@ -// Copyright (c) Acconeer AB, 2019-2021 -// All rights reserved - -#ifndef ACC_RSS_DIAGNOSTICS_H_ -#define ACC_RSS_DIAGNOSTICS_H_ - -#include "acc_definitions_common.h" -#include - - -/** - * @defgroup Diagnostic_test Diagnostic test - * @ingroup RSS - * - * @brief RSS Diagnostic test - * - * @{ - */ - - -/** - * @brief Run diagnostic test - * - * This function executes a suite of tests for diagnostic testing of the A111 sensor. - * - * @details - * - This function must be called after #acc_rss_activate. - * - This function must be called before any service is created. - * - If a test fails to execute the return value will be set to false. - * - * @param[in] sensor_id The sensor to run diagnostic test on - * @return True if successfully run, false otherwise - */ -bool acc_rss_diagnostic_test(acc_sensor_id_t sensor_id); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2019-2021 +// All rights reserved + +#ifndef ACC_RSS_DIAGNOSTICS_H_ +#define ACC_RSS_DIAGNOSTICS_H_ + +#include "acc_definitions_common.h" +#include + + +/** + * @defgroup Diagnostic_test Diagnostic test + * @ingroup RSS + * + * @brief RSS Diagnostic test + * + * @{ + */ + + +/** + * @brief Run diagnostic test + * + * This function executes a suite of tests for diagnostic testing of the A111 sensor. + * + * @details + * - This function must be called after #acc_rss_activate. + * - This function must be called before any service is created. + * - If a test fails to execute the return value will be set to false. + * + * @param[in] sensor_id The sensor to run diagnostic test on + * @return True if successfully run, false otherwise + */ +bool acc_rss_diagnostic_test(acc_sensor_id_t sensor_id); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_service.h b/STM32CubeIDE/rss/include/acc_service.h index e1e3907..26d9c2d 100644 --- a/STM32CubeIDE/rss/include/acc_service.h +++ b/STM32CubeIDE/rss/include/acc_service.h @@ -1,429 +1,429 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved - -#ifndef ACC_SERVICE_H_ -#define ACC_SERVICE_H_ - -#include - -#include "acc_base_configuration.h" -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" - -/** - * @defgroup Services Services - * - * @brief Radar services provided by Acconeer - * - * @defgroup Experimental Experimental - * @brief Features in an early version - * - * In our code you might encounter features tagged “Experimental”. - * This means that the feature in question is an early version that has a - * limited test scope, and the API and/or functionality might change in - * upcoming releases. - * - * The intention is to let users try these features out and we appreciate - * feedback. - * - * @defgroup Generic Generic Service API - * @ingroup Services - * - * @brief Generic service API description - * - * @{ - */ - - -/** - * @brief Generic service configuration container - */ -struct acc_service_configuration; - -typedef struct acc_service_configuration *acc_service_configuration_t; - - -/** - * @brief Generic service handle - */ -struct acc_service_handle; - -typedef struct acc_service_handle *acc_service_handle_t; - - -/** - * @brief Create a service with the provided configuration - * - * Only one service may exist for a specific sensor at any given time, - * unless @ref acc_rss_override_sensor_id_check_at_creation has been invoked. - * Invalid configurations will not allow for service creation. - * - * @param[in] configuration The service configuration to create a service with - * @return Service handle, NULL if service was not possible to create - */ -acc_service_handle_t acc_service_create(acc_service_configuration_t configuration); - - -/** - * @brief Activate the service associated with the provided handle - * - * When activated, the application can get data from the service with the - * associated handle. - * - * @param[in] service_handle The service handle for the service to activate - * @return True if successful, false otherwise - */ -bool acc_service_activate(acc_service_handle_t service_handle); - - -/** - * @brief Deactivate the service associated with the provided handle - * - * @param[in] service_handle The service handle for the service to deactivate - * @return True if successful, false otherwise - */ -bool acc_service_deactivate(acc_service_handle_t service_handle); - - -/** - * @brief Destroy a service identified with the provided service handle - * - * Destroy the context of a service allowing another service to be created using the - * same resources. The service handle reference is set to NULL after destruction. - * - * @param[in] service_handle A reference to the service handle to destroy - */ -void acc_service_destroy(acc_service_handle_t *service_handle); - - -/** - * @brief Retrieve a base configuration from a service configuration - * - * The base configuration can be used to configure the service for different use cases. - * See @ref acc_base_configuration.h for configuration parameters. - * - * @param[in] service_configuration The service configuration to get a base configuration from - * @return Base configuration, NULL if the service configuration does not contain a base configuration - */ -acc_base_configuration_t acc_service_get_base_configuration(acc_service_configuration_t service_configuration); - - -/** - * @brief Get the sensor ID for the sensor to be configured - * - * @param[in] configuration The service configuration to get the sensor id from - * @return Sensor Id - */ -acc_sensor_id_t acc_service_sensor_get(acc_service_configuration_t configuration); - - -/** - * @brief Set the sensor ID for the sensor to be configured - * - * @param[in] configuration The service configuration to set the sensor id in - * @param[in] sensor_id The sensor id to set - */ -void acc_service_sensor_set(acc_service_configuration_t configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get the requested start of the sweep - * - * @param[in] configuration The service configuration to get the requested start from - * @return Requested start - */ -float acc_service_requested_start_get(acc_service_configuration_t configuration); - - -/** - * @brief Set the requested start of the sweep - * - * @param[in] configuration The service configuration to set the requested start in - * @param[in] start_m The requested start in meters - */ -void acc_service_requested_start_set(acc_service_configuration_t configuration, float start_m); - - -/** - * @brief Get the requested length of the sweep - * - * @param[in] configuration The service configuration to get the requested length from - * @return Requested length - */ -float acc_service_requested_length_get(acc_service_configuration_t configuration); - - -/** - * @brief Set the requested length of the sweep - * - * @param[in] configuration The service configuration to set the requested length in - * @param[in] length_m The requested length in meters - */ -void acc_service_requested_length_set(acc_service_configuration_t configuration, float length_m); - - -/** - * @brief Set the service repetition mode to on demand - * - * In on demand mode, the sensor produces data when requested by the application. - * The application is also responsible for the timing between updates. - * - * This mode must be used if the configured length requires stitching in the service. - * - * @param[in] configuration The service configuration to set on demand mode in - */ -void acc_service_repetition_mode_on_demand_set(acc_service_configuration_t configuration); - - -/** - * @brief Set the service repetition mode to streaming mode - * - * The sensor produces data according to the configured update rate using sensor - * hardware timing which is very accurate. - * - * @param[in] configuration The service configuration to set streaming mode in - * @param[in] update_rate The output data rate from the service in hertz - */ -void acc_service_repetition_mode_streaming_set(acc_service_configuration_t configuration, float update_rate); - - -/** - * @brief Get power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data frame aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] configuration The service configuration to get power save mode for - * @return Power save mode - */ -acc_power_save_mode_t acc_service_power_save_mode_get(acc_service_configuration_t configuration); - - -/** - * @brief Set power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data frame aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] configuration The service configuration to set power save mode in - * @param[in] power_save_mode The power save mode to use - */ -void acc_service_power_save_mode_set(acc_service_configuration_t configuration, - acc_power_save_mode_t power_save_mode); - - -/** - * @brief Get receiver gain setting - * - * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] configuration The service configuration to get receiver gain setting for - * @return Receiver gain setting - */ -float acc_service_receiver_gain_get(acc_service_configuration_t configuration); - - -/** - * @brief Set receiver gain setting - * - * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] configuration The service configuration to set receiver gain setting in - * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 - */ -void acc_service_receiver_gain_set(acc_service_configuration_t configuration, float gain); - - -/** - * @brief Get TX disable mode - * - * Will be true if TX is disabled, false otherwise. - * - * @param[in] configuration The service configuration to get TX disable mode for - * @return TX disable mode - */ -bool acc_service_tx_disable_get(acc_service_configuration_t configuration); - - -/** - * @brief Set TX disable mode - * - * If set to true, TX disable mode is enabled. This will disable the radio transmitter. - * To measure RX noise floor, it is recommended to also switch off internal - * noise level normalization (see each service if applicable). - * - * @param[in] configuration The service configuration to set TX disable mode in - * @param[in] tx_disable TX disable mode, true or false - */ -void acc_service_tx_disable_set(acc_service_configuration_t configuration, bool tx_disable); - - -/** - * @brief Get the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The service configuration to get hardware accelerated average samples from - * @return Hardware accelerated average samples - */ -uint8_t acc_service_hw_accelerated_average_samples_get(acc_service_configuration_t configuration); - - -/** - * @brief Set the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The service configuration to set hardware accelerated average samples in - * @param[in] samples Hardware accelerated average samples - */ -void acc_service_hw_accelerated_average_samples_set(acc_service_configuration_t configuration, uint8_t samples); - - -/** - * @brief Get asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will generate sweep data while the host is waiting. - * In asynchronous mode the sensor will generate sweep data while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * Setting asynchronous measurement to false (i.e using synchronous mode) is incompatible - * with repetition mode streaming where the sensor is in control of the update rate timing. - * - * @param[in] configuration The service configuration to get asynchronous_measurement mode from - * @return asynchronous measurement mode - */ -bool acc_service_asynchronous_measurement_get(acc_service_configuration_t configuration); - - -/** - * @brief Set asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will generate sweep data while the host is waiting. - * In asynchronous mode the sensor will generate sweep data while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * Setting asynchronous measurement to false (i.e using synchronous mode) is incompatible - * with repetition mode streaming where the sensor is in control of the update rate timing. - * - * @param[in] configuration The service configuration to set asynchronous_measurement mode in - * @param[in] asynchronous_measurement asynchronous measurement mode, true or false - */ -void acc_service_asynchronous_measurement_set(acc_service_configuration_t configuration, bool asynchronous_measurement); - - -/** - * @brief Get the currently used service profile - * - * See @ref acc_service_profile_t for details - * - * @param[in] service_configuration The configuration to get a profile for - * @return The current profile, 0 if configuration is invalid - */ -acc_service_profile_t acc_service_profile_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set a service profile - * - * See @ref acc_service_profile_t for details - * - * @param[in] service_configuration The configuration to set a profile for - * @param[in] profile The profile to set - */ -void acc_service_profile_set(acc_service_configuration_t service_configuration, - acc_service_profile_t profile); - - -/** - * @brief Get Maximize signal attenuation mode - * - * Will be true if Maximize signal attenuation mode is enabled, false otherwise - * - * @param[in] service_configuration The configuration to get Maximize signal attenuation mode for - * @return Maximize signal attenuation mode - */ -bool acc_service_maximize_signal_attenuation_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set Maximize signal attenuation mode - * - * Enable or disable Maximize signal attenuation mode to measure the direct leakage - * - * @param[in] service_configuration The configuration to set Maximize signal attenuation mode in - * @param[in] maximize_signal_attenuation Maximize signal attenuation mode, true or false - */ -void acc_service_maximize_signal_attenuation_set(acc_service_configuration_t service_configuration, - bool maximize_signal_attenuation); - - -/** - * @brief Set the maximum unambiguous range - * - * Sets the maximum unambiguous range (MUR), which in turn sets the maximum measurable - * distance (MMD). - * - * The MMD is the maximum value for the range end, i.e., the range start + length. The MMD - * is smaller than the MUR due to hardware limitations. - * - * The MUR is the maximum distance at which an object can be located to guarantee that its - * reflection corresponds to the most recent transmitted pulse. Objects farther away than - * the MUR may fold into the measured range. For example, with a MUR of 10 m, an object at - * 12 m could become visible at 2 m. - * - * A higher setting gives a larger MUR/MMD, but comes at a cost of increasing the - * measurement time for a sweep. The measurement time is approximately proportional to the - * MUR. - * - * This setting changes the pulse repetition frequency (PRF) of the radar system. The - * relation between PRF and MUR is - * MUR = c / (2 * PRF) - * where c is the speed of light. - * - * | Setting | MUR | MMD | PRF | - * |------------------:|-------:|-------:|---------:| - * | ACC_SERVICE_MUR_6 | 11.5 m | 7.0 m | 13.0 MHz | - * | ACC_SERVICE_MUR_9 | 17.3 m | 12.7 m | 8.7 MHz | - * - * It is not possible to change MUR for the IQ service. - * - * @param[in] service_configuration The configuration - * @param[in] max_unambiguous_range The desired maximum unambiguous range - */ -void acc_service_mur_set(acc_service_configuration_t service_configuration, - acc_service_mur_t max_unambiguous_range); - - -/** - * @brief Get the maximum unambiguous range - * - * This gets the maximum unambiguous range. For more information see acc_service_mur_set(). - * - * @param[in] service_configuration The configuration - * @return Maximum unambiguous range - */ -acc_service_mur_t acc_service_mur_get(acc_service_configuration_t service_configuration); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved + +#ifndef ACC_SERVICE_H_ +#define ACC_SERVICE_H_ + +#include + +#include "acc_base_configuration.h" +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" + +/** + * @defgroup Services Services + * + * @brief Radar services provided by Acconeer + * + * @defgroup Experimental Experimental + * @brief Features in an early version + * + * In our code you might encounter features tagged “Experimental”. + * This means that the feature in question is an early version that has a + * limited test scope, and the API and/or functionality might change in + * upcoming releases. + * + * The intention is to let users try these features out and we appreciate + * feedback. + * + * @defgroup Generic Generic Service API + * @ingroup Services + * + * @brief Generic service API description + * + * @{ + */ + + +/** + * @brief Generic service configuration container + */ +struct acc_service_configuration; + +typedef struct acc_service_configuration *acc_service_configuration_t; + + +/** + * @brief Generic service handle + */ +struct acc_service_handle; + +typedef struct acc_service_handle *acc_service_handle_t; + + +/** + * @brief Create a service with the provided configuration + * + * Only one service may exist for a specific sensor at any given time, + * unless @ref acc_rss_override_sensor_id_check_at_creation has been invoked. + * Invalid configurations will not allow for service creation. + * + * @param[in] configuration The service configuration to create a service with + * @return Service handle, NULL if service was not possible to create + */ +acc_service_handle_t acc_service_create(acc_service_configuration_t configuration); + + +/** + * @brief Activate the service associated with the provided handle + * + * When activated, the application can get data from the service with the + * associated handle. + * + * @param[in] service_handle The service handle for the service to activate + * @return True if successful, false otherwise + */ +bool acc_service_activate(acc_service_handle_t service_handle); + + +/** + * @brief Deactivate the service associated with the provided handle + * + * @param[in] service_handle The service handle for the service to deactivate + * @return True if successful, false otherwise + */ +bool acc_service_deactivate(acc_service_handle_t service_handle); + + +/** + * @brief Destroy a service identified with the provided service handle + * + * Destroy the context of a service allowing another service to be created using the + * same resources. The service handle reference is set to NULL after destruction. + * + * @param[in] service_handle A reference to the service handle to destroy + */ +void acc_service_destroy(acc_service_handle_t *service_handle); + + +/** + * @brief Retrieve a base configuration from a service configuration + * + * The base configuration can be used to configure the service for different use cases. + * See @ref acc_base_configuration.h for configuration parameters. + * + * @param[in] service_configuration The service configuration to get a base configuration from + * @return Base configuration, NULL if the service configuration does not contain a base configuration + */ +acc_base_configuration_t acc_service_get_base_configuration(acc_service_configuration_t service_configuration); + + +/** + * @brief Get the sensor ID for the sensor to be configured + * + * @param[in] configuration The service configuration to get the sensor id from + * @return Sensor Id + */ +acc_sensor_id_t acc_service_sensor_get(acc_service_configuration_t configuration); + + +/** + * @brief Set the sensor ID for the sensor to be configured + * + * @param[in] configuration The service configuration to set the sensor id in + * @param[in] sensor_id The sensor id to set + */ +void acc_service_sensor_set(acc_service_configuration_t configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get the requested start of the sweep + * + * @param[in] configuration The service configuration to get the requested start from + * @return Requested start + */ +float acc_service_requested_start_get(acc_service_configuration_t configuration); + + +/** + * @brief Set the requested start of the sweep + * + * @param[in] configuration The service configuration to set the requested start in + * @param[in] start_m The requested start in meters + */ +void acc_service_requested_start_set(acc_service_configuration_t configuration, float start_m); + + +/** + * @brief Get the requested length of the sweep + * + * @param[in] configuration The service configuration to get the requested length from + * @return Requested length + */ +float acc_service_requested_length_get(acc_service_configuration_t configuration); + + +/** + * @brief Set the requested length of the sweep + * + * @param[in] configuration The service configuration to set the requested length in + * @param[in] length_m The requested length in meters + */ +void acc_service_requested_length_set(acc_service_configuration_t configuration, float length_m); + + +/** + * @brief Set the service repetition mode to on demand + * + * In on demand mode, the sensor produces data when requested by the application. + * The application is also responsible for the timing between updates. + * + * This mode must be used if the configured length requires stitching in the service. + * + * @param[in] configuration The service configuration to set on demand mode in + */ +void acc_service_repetition_mode_on_demand_set(acc_service_configuration_t configuration); + + +/** + * @brief Set the service repetition mode to streaming mode + * + * The sensor produces data according to the configured update rate using sensor + * hardware timing which is very accurate. + * + * @param[in] configuration The service configuration to set streaming mode in + * @param[in] update_rate The output data rate from the service in hertz + */ +void acc_service_repetition_mode_streaming_set(acc_service_configuration_t configuration, float update_rate); + + +/** + * @brief Get power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data frame aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] configuration The service configuration to get power save mode for + * @return Power save mode + */ +acc_power_save_mode_t acc_service_power_save_mode_get(acc_service_configuration_t configuration); + + +/** + * @brief Set power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data frame aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] configuration The service configuration to set power save mode in + * @param[in] power_save_mode The power save mode to use + */ +void acc_service_power_save_mode_set(acc_service_configuration_t configuration, + acc_power_save_mode_t power_save_mode); + + +/** + * @brief Get receiver gain setting + * + * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] configuration The service configuration to get receiver gain setting for + * @return Receiver gain setting + */ +float acc_service_receiver_gain_get(acc_service_configuration_t configuration); + + +/** + * @brief Set receiver gain setting + * + * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] configuration The service configuration to set receiver gain setting in + * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 + */ +void acc_service_receiver_gain_set(acc_service_configuration_t configuration, float gain); + + +/** + * @brief Get TX disable mode + * + * Will be true if TX is disabled, false otherwise. + * + * @param[in] configuration The service configuration to get TX disable mode for + * @return TX disable mode + */ +bool acc_service_tx_disable_get(acc_service_configuration_t configuration); + + +/** + * @brief Set TX disable mode + * + * If set to true, TX disable mode is enabled. This will disable the radio transmitter. + * To measure RX noise floor, it is recommended to also switch off internal + * noise level normalization (see each service if applicable). + * + * @param[in] configuration The service configuration to set TX disable mode in + * @param[in] tx_disable TX disable mode, true or false + */ +void acc_service_tx_disable_set(acc_service_configuration_t configuration, bool tx_disable); + + +/** + * @brief Get the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The service configuration to get hardware accelerated average samples from + * @return Hardware accelerated average samples + */ +uint8_t acc_service_hw_accelerated_average_samples_get(acc_service_configuration_t configuration); + + +/** + * @brief Set the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The service configuration to set hardware accelerated average samples in + * @param[in] samples Hardware accelerated average samples + */ +void acc_service_hw_accelerated_average_samples_set(acc_service_configuration_t configuration, uint8_t samples); + + +/** + * @brief Get asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will generate sweep data while the host is waiting. + * In asynchronous mode the sensor will generate sweep data while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * Setting asynchronous measurement to false (i.e using synchronous mode) is incompatible + * with repetition mode streaming where the sensor is in control of the update rate timing. + * + * @param[in] configuration The service configuration to get asynchronous_measurement mode from + * @return asynchronous measurement mode + */ +bool acc_service_asynchronous_measurement_get(acc_service_configuration_t configuration); + + +/** + * @brief Set asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will generate sweep data while the host is waiting. + * In asynchronous mode the sensor will generate sweep data while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * Setting asynchronous measurement to false (i.e using synchronous mode) is incompatible + * with repetition mode streaming where the sensor is in control of the update rate timing. + * + * @param[in] configuration The service configuration to set asynchronous_measurement mode in + * @param[in] asynchronous_measurement asynchronous measurement mode, true or false + */ +void acc_service_asynchronous_measurement_set(acc_service_configuration_t configuration, bool asynchronous_measurement); + + +/** + * @brief Get the currently used service profile + * + * See @ref acc_service_profile_t for details + * + * @param[in] service_configuration The configuration to get a profile for + * @return The current profile, 0 if configuration is invalid + */ +acc_service_profile_t acc_service_profile_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set a service profile + * + * See @ref acc_service_profile_t for details + * + * @param[in] service_configuration The configuration to set a profile for + * @param[in] profile The profile to set + */ +void acc_service_profile_set(acc_service_configuration_t service_configuration, + acc_service_profile_t profile); + + +/** + * @brief Get Maximize signal attenuation mode + * + * Will be true if Maximize signal attenuation mode is enabled, false otherwise + * + * @param[in] service_configuration The configuration to get Maximize signal attenuation mode for + * @return Maximize signal attenuation mode + */ +bool acc_service_maximize_signal_attenuation_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set Maximize signal attenuation mode + * + * Enable or disable Maximize signal attenuation mode to measure the direct leakage + * + * @param[in] service_configuration The configuration to set Maximize signal attenuation mode in + * @param[in] maximize_signal_attenuation Maximize signal attenuation mode, true or false + */ +void acc_service_maximize_signal_attenuation_set(acc_service_configuration_t service_configuration, + bool maximize_signal_attenuation); + + +/** + * @brief Set the maximum unambiguous range + * + * Sets the maximum unambiguous range (MUR), which in turn sets the maximum measurable + * distance (MMD). + * + * The MMD is the maximum value for the range end, i.e., the range start + length. The MMD + * is smaller than the MUR due to hardware limitations. + * + * The MUR is the maximum distance at which an object can be located to guarantee that its + * reflection corresponds to the most recent transmitted pulse. Objects farther away than + * the MUR may fold into the measured range. For example, with a MUR of 10 m, an object at + * 12 m could become visible at 2 m. + * + * A higher setting gives a larger MUR/MMD, but comes at a cost of increasing the + * measurement time for a sweep. The measurement time is approximately proportional to the + * MUR. + * + * This setting changes the pulse repetition frequency (PRF) of the radar system. The + * relation between PRF and MUR is + * MUR = c / (2 * PRF) + * where c is the speed of light. + * + * | Setting | MUR | MMD | PRF | + * |------------------:|-------:|-------:|---------:| + * | ACC_SERVICE_MUR_6 | 11.5 m | 7.0 m | 13.0 MHz | + * | ACC_SERVICE_MUR_9 | 17.3 m | 12.7 m | 8.7 MHz | + * + * It is not possible to change MUR for the IQ service. + * + * @param[in] service_configuration The configuration + * @param[in] max_unambiguous_range The desired maximum unambiguous range + */ +void acc_service_mur_set(acc_service_configuration_t service_configuration, + acc_service_mur_t max_unambiguous_range); + + +/** + * @brief Get the maximum unambiguous range + * + * This gets the maximum unambiguous range. For more information see acc_service_mur_set(). + * + * @param[in] service_configuration The configuration + * @return Maximum unambiguous range + */ +acc_service_mur_t acc_service_mur_get(acc_service_configuration_t service_configuration); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_service_envelope.h b/STM32CubeIDE/rss/include/acc_service_envelope.h index b5e7fc5..b8658ad 100644 --- a/STM32CubeIDE/rss/include/acc_service_envelope.h +++ b/STM32CubeIDE/rss/include/acc_service_envelope.h @@ -1,239 +1,239 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_SERVICE_ENVELOPE_H_ -#define ACC_SERVICE_ENVELOPE_H_ - -#include -#include - -#include "acc_service.h" - -/** - * @defgroup Envelope Envelope Service - * @ingroup Services - * - * @brief Envelope service API description - * - * @{ - */ - - -/** - * @brief Metadata for the envelope service - */ -typedef struct -{ - /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ - float start_m; - /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ - float length_m; - /** Number of elements in the envelope data array */ - uint16_t data_length; - /** Number of stitches in the data */ - uint16_t stitch_count; - /** Distance between adjacent data points */ - float step_length_m; -} acc_service_envelope_metadata_t; - - -/** - * @brief Metadata for each result provided by the envelope service - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; -} acc_service_envelope_result_info_t; - - -/** - * @brief Create a configuration for an envelope service - * - * A configuration is created for the envelope service and populated - * with default values. - * - * @return Service configuration, NULL if creation was not possible - */ -acc_service_configuration_t acc_service_envelope_configuration_create(void); - - -/** - * @brief Destroy an envelope configuration - * - * Destroy an envelope configuration that is no longer needed, may be done even if a - * service has been created with the specific configuration and has not yet been destroyed. - * The service configuration reference is set to NULL after destruction. - * - * @param[in] service_configuration The configuration to destroy, set to NULL - */ -void acc_service_envelope_configuration_destroy(acc_service_configuration_t *service_configuration); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the envelope service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 - * makes the distance between two points in the measured range ~2mm. - * - * @param[in] service_configuration The configuration to get downsampling factor from - * @return The downsampling factor - */ -uint16_t acc_service_envelope_downsampling_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the envelope service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 - * makes the distance between two points in the measured range ~2mm. - * - * The envelope service supports a downsampling factor of 1, 2, or 4. - * - * @param[in] service_configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_service_envelope_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); - - -/** - * @brief Get running average factor - * - * The running average factor is the factor of which the most recent sweep is weighed against previous sweeps. - * Valid range is between 0.0 and 1.0 where 0.0 means that no history is weighed in, i.e filtering is effectively disabled. - * A factor of 1.0 means that the most recent sweep has no effect on the result, - * which will result in that the first sweep is forever received as the result. - * The filtering is coherent and is done on complex valued IQ data before conversion to envelope data. - * - * @param[in] service_configuration The configuration to get the running average factor for - * @return Running average factor - */ -float acc_service_envelope_running_average_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set running average factor - * - * The running average factor is the factor of which the most recent sweep is weighed against previous sweeps. - * Valid range is between 0.0 and 1.0 where 0.0 means that no history is weighed in, i.e filtering is effectively disabled. - * A factor of 1.0 means that the most recent sweep has no effect on the result, - * which will result in that the first sweep is forever received as the result. - * The filtering is coherent and is done on complex valued IQ data before conversion to envelope data. - * - * @param[in] service_configuration The configuration to set the running average factor for - * @param[in] factor The running average factor to set - */ -void acc_service_envelope_running_average_factor_set(acc_service_configuration_t service_configuration, float factor); - - -/** - * @brief Get if noise level normalization will be done or not - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to get the noise level normalization setting for - * @return The noise level normalization flag - */ -bool acc_service_envelope_noise_level_normalization_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set if noise level normalization should be done or not - * - * This function controls if a noise level normalization will be done at the beginning - * of the envelope processing. - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to enable or disable the noise level normalization for - * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not - */ -void acc_service_envelope_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); - - -/** - * @brief Get service metadata - * - * Each service provide metadata after being created with information that could be relevant for an application. - * The metadata contain information such as data length and actual start and length. - * - * May only be called after a service has been created. - * - * @param[in] handle The service handle for the service to get metadata for - * @param[out] metadata Metadata results are provided in this parameter - */ -void acc_service_envelope_get_metadata(acc_service_handle_t handle, acc_service_envelope_metadata_t *metadata); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Envelope result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Envelope result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_envelope_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_envelope_result_info_t *result_info); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * The provided memory is only valid until the next call to get_next for the - * specified handle. The memory is specific for the handle and cannot be shared - * between handles/services. - * - * The length of the resulting data is provided in @ref acc_service_envelope_get_metadata - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Reference to Envelope result - * @param[out] result_info Envelope result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_envelope_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, - acc_service_envelope_result_info_t *result_info); - - -/** - * @brief Execute service one time - * - * Activates service, produces one result and then deactivates the service. Blocks the - * application until a service result has been produced. May fail if the service is already active. - * - * @param[in] handle The service handle for the service to execute - * @param[out] data Envelope result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Envelope result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_envelope_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_envelope_result_info_t *result_info); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_SERVICE_ENVELOPE_H_ +#define ACC_SERVICE_ENVELOPE_H_ + +#include +#include + +#include "acc_service.h" + +/** + * @defgroup Envelope Envelope Service + * @ingroup Services + * + * @brief Envelope service API description + * + * @{ + */ + + +/** + * @brief Metadata for the envelope service + */ +typedef struct +{ + /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ + float start_m; + /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ + float length_m; + /** Number of elements in the envelope data array */ + uint16_t data_length; + /** Number of stitches in the data */ + uint16_t stitch_count; + /** Distance between adjacent data points */ + float step_length_m; +} acc_service_envelope_metadata_t; + + +/** + * @brief Metadata for each result provided by the envelope service + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; +} acc_service_envelope_result_info_t; + + +/** + * @brief Create a configuration for an envelope service + * + * A configuration is created for the envelope service and populated + * with default values. + * + * @return Service configuration, NULL if creation was not possible + */ +acc_service_configuration_t acc_service_envelope_configuration_create(void); + + +/** + * @brief Destroy an envelope configuration + * + * Destroy an envelope configuration that is no longer needed, may be done even if a + * service has been created with the specific configuration and has not yet been destroyed. + * The service configuration reference is set to NULL after destruction. + * + * @param[in] service_configuration The configuration to destroy, set to NULL + */ +void acc_service_envelope_configuration_destroy(acc_service_configuration_t *service_configuration); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the envelope service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 + * makes the distance between two points in the measured range ~2mm. + * + * @param[in] service_configuration The configuration to get downsampling factor from + * @return The downsampling factor + */ +uint16_t acc_service_envelope_downsampling_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the envelope service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 + * makes the distance between two points in the measured range ~2mm. + * + * The envelope service supports a downsampling factor of 1, 2, or 4. + * + * @param[in] service_configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_service_envelope_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); + + +/** + * @brief Get running average factor + * + * The running average factor is the factor of which the most recent sweep is weighed against previous sweeps. + * Valid range is between 0.0 and 1.0 where 0.0 means that no history is weighed in, i.e filtering is effectively disabled. + * A factor of 1.0 means that the most recent sweep has no effect on the result, + * which will result in that the first sweep is forever received as the result. + * The filtering is coherent and is done on complex valued IQ data before conversion to envelope data. + * + * @param[in] service_configuration The configuration to get the running average factor for + * @return Running average factor + */ +float acc_service_envelope_running_average_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set running average factor + * + * The running average factor is the factor of which the most recent sweep is weighed against previous sweeps. + * Valid range is between 0.0 and 1.0 where 0.0 means that no history is weighed in, i.e filtering is effectively disabled. + * A factor of 1.0 means that the most recent sweep has no effect on the result, + * which will result in that the first sweep is forever received as the result. + * The filtering is coherent and is done on complex valued IQ data before conversion to envelope data. + * + * @param[in] service_configuration The configuration to set the running average factor for + * @param[in] factor The running average factor to set + */ +void acc_service_envelope_running_average_factor_set(acc_service_configuration_t service_configuration, float factor); + + +/** + * @brief Get if noise level normalization will be done or not + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to get the noise level normalization setting for + * @return The noise level normalization flag + */ +bool acc_service_envelope_noise_level_normalization_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set if noise level normalization should be done or not + * + * This function controls if a noise level normalization will be done at the beginning + * of the envelope processing. + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to enable or disable the noise level normalization for + * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not + */ +void acc_service_envelope_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); + + +/** + * @brief Get service metadata + * + * Each service provide metadata after being created with information that could be relevant for an application. + * The metadata contain information such as data length and actual start and length. + * + * May only be called after a service has been created. + * + * @param[in] handle The service handle for the service to get metadata for + * @param[out] metadata Metadata results are provided in this parameter + */ +void acc_service_envelope_get_metadata(acc_service_handle_t handle, acc_service_envelope_metadata_t *metadata); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Envelope result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Envelope result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_envelope_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_envelope_result_info_t *result_info); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * The provided memory is only valid until the next call to get_next for the + * specified handle. The memory is specific for the handle and cannot be shared + * between handles/services. + * + * The length of the resulting data is provided in @ref acc_service_envelope_get_metadata + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Reference to Envelope result + * @param[out] result_info Envelope result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_envelope_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, + acc_service_envelope_result_info_t *result_info); + + +/** + * @brief Execute service one time + * + * Activates service, produces one result and then deactivates the service. Blocks the + * application until a service result has been produced. May fail if the service is already active. + * + * @param[in] handle The service handle for the service to execute + * @param[out] data Envelope result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Envelope result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_envelope_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_envelope_result_info_t *result_info); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_service_iq.h b/STM32CubeIDE/rss/include/acc_service_iq.h index d4aa967..51f2c7c 100644 --- a/STM32CubeIDE/rss/include/acc_service_iq.h +++ b/STM32CubeIDE/rss/include/acc_service_iq.h @@ -1,288 +1,288 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved - -#ifndef ACC_SERVICE_IQ_H_ -#define ACC_SERVICE_IQ_H_ - -#include -#include -#include - -#include "acc_service.h" - -/** - * @defgroup IQ IQ Service - * @ingroup Services - * - * @brief IQ Service API description - * - * @{ - */ - - -/** - * @brief Output format - * - */ -typedef enum -{ - ACC_SERVICE_IQ_OUTPUT_FORMAT_FLOAT_COMPLEX, // The output format is float complex - ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX // The output format is acc_int16_complex_t -} acc_service_iq_output_format_enum_t; -typedef uint32_t acc_service_iq_output_format_t; - - -/** - * @brief Metadata for the iq service - */ -typedef struct -{ - /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ - float start_m; - /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ - float length_m; - /** Number of elements in the iq data array */ - uint16_t data_length; - /** Number of stitches in the data */ - uint16_t stitch_count; - /** Distance between adjacent data points */ - float step_length_m; - /** The depth domain lowpass cutoff frequency ratio */ - float depth_lowpass_cutoff_ratio; -} acc_service_iq_metadata_t; - - -/** - * @brief Metadata for each result provided by the iq service - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; -} acc_service_iq_result_info_t; - - -/** - * @brief Create a configuration for an iq service - * - * A configuration is created for the iq service and populated - * with default values. - * - * @return Service configuration, NULL if creation was not possible - */ -acc_service_configuration_t acc_service_iq_configuration_create(void); - - -/** - * @brief Destroy an iq configuration - * - * Destroy an iq configuration that is no longer needed, may be done even if a - * service has been created with the specific configuration and has not yet been destroyed. - * The service configuration reference is set to NULL after destruction. - * - * @param[in] service_configuration The configuration to destroy, set to NULL - */ -void acc_service_iq_configuration_destroy(acc_service_configuration_t *service_configuration); - - -/** - * @brief Get the distance domain lowpass filter cutoff frequency ratio override parameters - * - * The cutoff for the distance domain lowpass filter is specified as the ratio between the spatial - * frequency cutoff and the sample frequency. A ratio close to zero damps everything except the lowest - * frequencies. Increasing ratios output a wider band of spatial frequencies, and a ratio of 0.5 means - * that the filter is deactivated. - * - * If unset, i.e., if override is false, the ratio will be chosen automatically. This ratio is - * returned in the metadata upon creation of the service. - * - * @param[in] service_configuration The configuration to get the parameters from - * @param[out] override If true, the specified cutoff ratio is used - * @param[out] cutoff_ratio The cutoff ratio to use if override is true - */ -void acc_service_iq_depth_lowpass_cutoff_ratio_get(acc_service_configuration_t service_configuration, bool *override, float *cutoff_ratio); - - -/** - * @brief Set the distance domain lowpass filter cutoff frequency ratio override parameters - * - * The cutoff for the distance domain lowpass filter is specified as the ratio between the spatial - * frequency cutoff and the sample frequency. An input value of zero for the cutoff ratio will - * configure the smoothest allowed filter. A cutoff ratio of 0.5 turns the filter off. - * - * The set of available cutoff frequencies is limited due to internal properties of the filter - * implementation. - * - * If unset, i.e., if override is false, the ratio will be chosen automatically. This ratio is - * returned in the metadata upon creation of the service. - * - * @param[in] service_configuration The configuration to set the parameters for - * @param[in] override If true, the specified cutoff ratio is used - * @param[in] cutoff_ratio The cutoff ratio to use if override is true - */ -void acc_service_iq_depth_lowpass_cutoff_ratio_set(acc_service_configuration_t service_configuration, - bool override, - float cutoff_ratio); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the IQ service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 makes - * the distance between two points in the measured range ~2mm. - * - * @param[in] service_configuration The configuration to get downsampling factor from - * @return downsampling_factor The downsampling factor - */ -uint16_t acc_service_iq_downsampling_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the IQ service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 makes - * the distance between two points in the measured range ~2mm. - * - * The IQ service supports a downsampling factor of 1, 2, or 4. - * - * @param[in] service_configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_service_iq_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); - - -/** - * @brief Get if noise level normalization will be done or not - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to get the noise level normalization setting for - * @return The noise level normalization flag - */ -bool acc_service_iq_noise_level_normalization_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set if noise level normalization should be done or not - * - * This function controls if a noise level normalization will be done at the beginning - * of the envelope processing. - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to enable or disable the noise level normalization for - * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not - */ -void acc_service_iq_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); - - -/** - * @brief Configure the output format of the IQ service - * - * @param[in,out] service_configuration The configuration to set the format on - * @param[in] format The format that should be used - */ -void acc_service_iq_output_format_set(acc_service_configuration_t service_configuration, - acc_service_iq_output_format_t format); - - -/** - * @brief Get the configured output format - * - * @param[in] service_configuration The configuration to get the format from - * - * @returns The configured output format - */ -acc_service_iq_output_format_t acc_service_iq_output_format_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Get service metadata - * - * Each service provide metadata after being created with information that could be relevant for an application. - * The metadata contain information such as data length and actual start and length. - * - * May only be called after a service has been created. - * - * @param[in] handle The service handle for the service to get metadata for - * @param[out] metadata Metadata results are provided in this parameter - */ -void acc_service_iq_get_metadata(acc_service_handle_t handle, acc_service_iq_metadata_t *metadata); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. The service must be configured for floating point output. - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data IQ data result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info IQ result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_iq_get_next(acc_service_handle_t handle, void *data, uint16_t data_length, - acc_service_iq_result_info_t *result_info); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * The provided memory is only valid until the next call to get_next for the - * specified handle. The memory is specific for the handle and cannot be shared - * between handles/services. - * - * The length of the resulting data is provided in @ref acc_service_iq_get_metadata - * - * Note that this function is only compatible with the ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX - * option for @ref acc_service_iq_output_format_set - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Reference to IQ result - * @param[out] result_info IQ result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_iq_get_next_by_reference(acc_service_handle_t handle, acc_int16_complex_t **data, - acc_service_iq_result_info_t *result_info); - - -/** - * @brief Execute service one time - * - * Activates service, produces one result and then deactivates the service. Blocks the - * application until a service result has been produced. May fail if the service is already - * active. The format of the data is configured by calling acc_service_iq_output_format_set(). - * - * @param[in] handle The service handle for the service to execute - * @param[out] data IQ data result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info IQ result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_iq_execute_once(acc_service_handle_t handle, void *data, uint16_t data_length, - acc_service_iq_result_info_t *result_info); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved + +#ifndef ACC_SERVICE_IQ_H_ +#define ACC_SERVICE_IQ_H_ + +#include +#include +#include + +#include "acc_service.h" + +/** + * @defgroup IQ IQ Service + * @ingroup Services + * + * @brief IQ Service API description + * + * @{ + */ + + +/** + * @brief Output format + * + */ +typedef enum +{ + ACC_SERVICE_IQ_OUTPUT_FORMAT_FLOAT_COMPLEX, // The output format is float complex + ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX // The output format is acc_int16_complex_t +} acc_service_iq_output_format_enum_t; +typedef uint32_t acc_service_iq_output_format_t; + + +/** + * @brief Metadata for the iq service + */ +typedef struct +{ + /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ + float start_m; + /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ + float length_m; + /** Number of elements in the iq data array */ + uint16_t data_length; + /** Number of stitches in the data */ + uint16_t stitch_count; + /** Distance between adjacent data points */ + float step_length_m; + /** The depth domain lowpass cutoff frequency ratio */ + float depth_lowpass_cutoff_ratio; +} acc_service_iq_metadata_t; + + +/** + * @brief Metadata for each result provided by the iq service + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; +} acc_service_iq_result_info_t; + + +/** + * @brief Create a configuration for an iq service + * + * A configuration is created for the iq service and populated + * with default values. + * + * @return Service configuration, NULL if creation was not possible + */ +acc_service_configuration_t acc_service_iq_configuration_create(void); + + +/** + * @brief Destroy an iq configuration + * + * Destroy an iq configuration that is no longer needed, may be done even if a + * service has been created with the specific configuration and has not yet been destroyed. + * The service configuration reference is set to NULL after destruction. + * + * @param[in] service_configuration The configuration to destroy, set to NULL + */ +void acc_service_iq_configuration_destroy(acc_service_configuration_t *service_configuration); + + +/** + * @brief Get the distance domain lowpass filter cutoff frequency ratio override parameters + * + * The cutoff for the distance domain lowpass filter is specified as the ratio between the spatial + * frequency cutoff and the sample frequency. A ratio close to zero damps everything except the lowest + * frequencies. Increasing ratios output a wider band of spatial frequencies, and a ratio of 0.5 means + * that the filter is deactivated. + * + * If unset, i.e., if override is false, the ratio will be chosen automatically. This ratio is + * returned in the metadata upon creation of the service. + * + * @param[in] service_configuration The configuration to get the parameters from + * @param[out] override If true, the specified cutoff ratio is used + * @param[out] cutoff_ratio The cutoff ratio to use if override is true + */ +void acc_service_iq_depth_lowpass_cutoff_ratio_get(acc_service_configuration_t service_configuration, bool *override, float *cutoff_ratio); + + +/** + * @brief Set the distance domain lowpass filter cutoff frequency ratio override parameters + * + * The cutoff for the distance domain lowpass filter is specified as the ratio between the spatial + * frequency cutoff and the sample frequency. An input value of zero for the cutoff ratio will + * configure the smoothest allowed filter. A cutoff ratio of 0.5 turns the filter off. + * + * The set of available cutoff frequencies is limited due to internal properties of the filter + * implementation. + * + * If unset, i.e., if override is false, the ratio will be chosen automatically. This ratio is + * returned in the metadata upon creation of the service. + * + * @param[in] service_configuration The configuration to set the parameters for + * @param[in] override If true, the specified cutoff ratio is used + * @param[in] cutoff_ratio The cutoff ratio to use if override is true + */ +void acc_service_iq_depth_lowpass_cutoff_ratio_set(acc_service_configuration_t service_configuration, + bool override, + float cutoff_ratio); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the IQ service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 makes + * the distance between two points in the measured range ~2mm. + * + * @param[in] service_configuration The configuration to get downsampling factor from + * @return downsampling_factor The downsampling factor + */ +uint16_t acc_service_iq_downsampling_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the IQ service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 makes + * the distance between two points in the measured range ~2mm. + * + * The IQ service supports a downsampling factor of 1, 2, or 4. + * + * @param[in] service_configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_service_iq_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); + + +/** + * @brief Get if noise level normalization will be done or not + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to get the noise level normalization setting for + * @return The noise level normalization flag + */ +bool acc_service_iq_noise_level_normalization_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set if noise level normalization should be done or not + * + * This function controls if a noise level normalization will be done at the beginning + * of the envelope processing. + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to enable or disable the noise level normalization for + * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not + */ +void acc_service_iq_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); + + +/** + * @brief Configure the output format of the IQ service + * + * @param[in,out] service_configuration The configuration to set the format on + * @param[in] format The format that should be used + */ +void acc_service_iq_output_format_set(acc_service_configuration_t service_configuration, + acc_service_iq_output_format_t format); + + +/** + * @brief Get the configured output format + * + * @param[in] service_configuration The configuration to get the format from + * + * @returns The configured output format + */ +acc_service_iq_output_format_t acc_service_iq_output_format_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Get service metadata + * + * Each service provide metadata after being created with information that could be relevant for an application. + * The metadata contain information such as data length and actual start and length. + * + * May only be called after a service has been created. + * + * @param[in] handle The service handle for the service to get metadata for + * @param[out] metadata Metadata results are provided in this parameter + */ +void acc_service_iq_get_metadata(acc_service_handle_t handle, acc_service_iq_metadata_t *metadata); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. The service must be configured for floating point output. + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data IQ data result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info IQ result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_iq_get_next(acc_service_handle_t handle, void *data, uint16_t data_length, + acc_service_iq_result_info_t *result_info); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * The provided memory is only valid until the next call to get_next for the + * specified handle. The memory is specific for the handle and cannot be shared + * between handles/services. + * + * The length of the resulting data is provided in @ref acc_service_iq_get_metadata + * + * Note that this function is only compatible with the ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX + * option for @ref acc_service_iq_output_format_set + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Reference to IQ result + * @param[out] result_info IQ result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_iq_get_next_by_reference(acc_service_handle_t handle, acc_int16_complex_t **data, + acc_service_iq_result_info_t *result_info); + + +/** + * @brief Execute service one time + * + * Activates service, produces one result and then deactivates the service. Blocks the + * application until a service result has been produced. May fail if the service is already + * active. The format of the data is configured by calling acc_service_iq_output_format_set(). + * + * @param[in] handle The service handle for the service to execute + * @param[out] data IQ data result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info IQ result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_iq_execute_once(acc_service_handle_t handle, void *data, uint16_t data_length, + acc_service_iq_result_info_t *result_info); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_service_power_bins.h b/STM32CubeIDE/rss/include/acc_service_power_bins.h index 6cbe1d4..48e3535 100644 --- a/STM32CubeIDE/rss/include/acc_service_power_bins.h +++ b/STM32CubeIDE/rss/include/acc_service_power_bins.h @@ -1,226 +1,226 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_SERVICE_POWER_BINS_H_ -#define ACC_SERVICE_POWER_BINS_H_ - -#include -#include - -#include "acc_service.h" - - -/** - * @defgroup Power Power Bins Service - * @ingroup Services - * - * @brief Power Bins service API description - * - * @{ - */ - - -/** - * @brief Metadata for the power bins service - */ -typedef struct -{ - /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ - float start_m; - /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ - float length_m; - /** Number of elements in the power bins data array */ - uint16_t bin_count; - /** Number of stitches in the data */ - uint16_t stitch_count; - /** Distance between adjacent data points */ - float step_length_m; -} acc_service_power_bins_metadata_t; - - -/** - * @brief Metadata for each result provided by the power bins service - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; -} acc_service_power_bins_result_info_t; - - -/** - * @brief Create a configuration for a power bins service - * - * A configuration is created for the power bins service and populated - * with default values. - * - * @return Service configuration, NULL if creation was not possible - */ -acc_service_configuration_t acc_service_power_bins_configuration_create(void); - - -/** - * @brief Destroy a power bins configuration - * - * Destroy a power bins configuration that is no longer needed, may be done even if a - * service has been created with the specific configuration and has not yet been destroyed. - * The service configuration reference is set to NULL after destruction. - * - * @param[in] service_configuration The configuration to destroy, set to NULL - */ -void acc_service_power_bins_configuration_destroy(acc_service_configuration_t *service_configuration); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * @param[in] service_configuration The configuration to get downsampling factor from - * @return The downsampling factor - */ -uint16_t acc_service_power_bins_downsampling_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * The power bins service supports a downsampling factor of 1, 2, or 4. - * - * In power bins, the downsampling factor does not affect the resulting data length. - * - * @param[in] service_configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_service_power_bins_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); - - -/** - * @brief Get the requested bin count - * - * @param[in] service_configuration The service configuration to get the requested bin count from - * @return Requested bin count - */ -uint16_t acc_service_power_bins_requested_bin_count_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the requested bin count - * - * @param[in] service_configuration The service configuration to set the requested bin count in - * @param[in] requested_bin_count The requested bin count - */ -void acc_service_power_bins_requested_bin_count_set(acc_service_configuration_t service_configuration, - uint16_t requested_bin_count); - - -/** - * @brief Get if noise level normalization will be done or not - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to get the noise level normalization setting for - * @return The noise level normalization flag - */ -bool acc_service_power_bins_noise_level_normalization_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set if noise level normalization should be done or not - * - * This function controls if a noise level normalization will be done at the beginning - * of the processing. - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to enable or disable the noise level normalization for - * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not - */ -void acc_service_power_bins_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); - - -/** - * @brief Get service metadata - * - * Each service provide metadata after being created with information that could be relevant for an application. - * The metadata contain information such as data length and actual start and length. - * - * May only be called after a service has been created. - * - * @param[in] handle The service handle for the service to get metadata for - * @param[out] metadata Metadata results are provided in this parameter - */ -void acc_service_power_bins_get_metadata(acc_service_handle_t handle, acc_service_power_bins_metadata_t *metadata); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Power bins result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Power Bins result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_power_bins_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_power_bins_result_info_t *result_info); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * The provided memory is only valid until the next call to get_next for the - * specified handle. The memory is specific for the handle and cannot be shared - * between handles/services. - * - * The length of the resulting data is provided in @ref acc_service_power_bins_get_metadata - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Reference to Power Bins result - * @param[out] result_info Power Bins result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_power_bins_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, - acc_service_power_bins_result_info_t *result_info); - - -/** - * @brief Execute service one time - * - * Activates service, produces one result and then deactivates the service. Blocks the - * application until a service result has been produced. May fail if the service is already active. - * - * @param[in] handle The service handle for the service to execute - * @param[out] data Power bins result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Power Bins result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_power_bins_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_power_bins_result_info_t *result_info); - - -/** - * @} - */ - - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_SERVICE_POWER_BINS_H_ +#define ACC_SERVICE_POWER_BINS_H_ + +#include +#include + +#include "acc_service.h" + + +/** + * @defgroup Power Power Bins Service + * @ingroup Services + * + * @brief Power Bins service API description + * + * @{ + */ + + +/** + * @brief Metadata for the power bins service + */ +typedef struct +{ + /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ + float start_m; + /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ + float length_m; + /** Number of elements in the power bins data array */ + uint16_t bin_count; + /** Number of stitches in the data */ + uint16_t stitch_count; + /** Distance between adjacent data points */ + float step_length_m; +} acc_service_power_bins_metadata_t; + + +/** + * @brief Metadata for each result provided by the power bins service + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; +} acc_service_power_bins_result_info_t; + + +/** + * @brief Create a configuration for a power bins service + * + * A configuration is created for the power bins service and populated + * with default values. + * + * @return Service configuration, NULL if creation was not possible + */ +acc_service_configuration_t acc_service_power_bins_configuration_create(void); + + +/** + * @brief Destroy a power bins configuration + * + * Destroy a power bins configuration that is no longer needed, may be done even if a + * service has been created with the specific configuration and has not yet been destroyed. + * The service configuration reference is set to NULL after destruction. + * + * @param[in] service_configuration The configuration to destroy, set to NULL + */ +void acc_service_power_bins_configuration_destroy(acc_service_configuration_t *service_configuration); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * @param[in] service_configuration The configuration to get downsampling factor from + * @return The downsampling factor + */ +uint16_t acc_service_power_bins_downsampling_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * The power bins service supports a downsampling factor of 1, 2, or 4. + * + * In power bins, the downsampling factor does not affect the resulting data length. + * + * @param[in] service_configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_service_power_bins_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); + + +/** + * @brief Get the requested bin count + * + * @param[in] service_configuration The service configuration to get the requested bin count from + * @return Requested bin count + */ +uint16_t acc_service_power_bins_requested_bin_count_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the requested bin count + * + * @param[in] service_configuration The service configuration to set the requested bin count in + * @param[in] requested_bin_count The requested bin count + */ +void acc_service_power_bins_requested_bin_count_set(acc_service_configuration_t service_configuration, + uint16_t requested_bin_count); + + +/** + * @brief Get if noise level normalization will be done or not + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to get the noise level normalization setting for + * @return The noise level normalization flag + */ +bool acc_service_power_bins_noise_level_normalization_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set if noise level normalization should be done or not + * + * This function controls if a noise level normalization will be done at the beginning + * of the processing. + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to enable or disable the noise level normalization for + * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not + */ +void acc_service_power_bins_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); + + +/** + * @brief Get service metadata + * + * Each service provide metadata after being created with information that could be relevant for an application. + * The metadata contain information such as data length and actual start and length. + * + * May only be called after a service has been created. + * + * @param[in] handle The service handle for the service to get metadata for + * @param[out] metadata Metadata results are provided in this parameter + */ +void acc_service_power_bins_get_metadata(acc_service_handle_t handle, acc_service_power_bins_metadata_t *metadata); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Power bins result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Power Bins result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_power_bins_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_power_bins_result_info_t *result_info); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * The provided memory is only valid until the next call to get_next for the + * specified handle. The memory is specific for the handle and cannot be shared + * between handles/services. + * + * The length of the resulting data is provided in @ref acc_service_power_bins_get_metadata + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Reference to Power Bins result + * @param[out] result_info Power Bins result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_power_bins_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, + acc_service_power_bins_result_info_t *result_info); + + +/** + * @brief Execute service one time + * + * Activates service, produces one result and then deactivates the service. Blocks the + * application until a service result has been produced. May fail if the service is already active. + * + * @param[in] handle The service handle for the service to execute + * @param[out] data Power bins result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Power Bins result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_power_bins_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_power_bins_result_info_t *result_info); + + +/** + * @} + */ + + +#endif diff --git a/STM32CubeIDE/rss/include/acc_service_sparse.h b/STM32CubeIDE/rss/include/acc_service_sparse.h index 16063dc..a3eedc8 100644 --- a/STM32CubeIDE/rss/include/acc_service_sparse.h +++ b/STM32CubeIDE/rss/include/acc_service_sparse.h @@ -1,294 +1,294 @@ -// Copyright (c) Acconeer AB, 2019-2021 -// All rights reserved - -#ifndef ACC_SERVICE_SPARSE_H_ -#define ACC_SERVICE_SPARSE_H_ - -#include -#include - -#include "acc_service.h" - -/** - * @defgroup Sparse Sparse Service - * @ingroup Services - * - * @brief Sparse service API description - * - * @{ - */ - - -/** - * @brief Sampling mode - * - * The sampling mode changes how the hardware accelerated averaging is done. Mode A is optimized - * for maximal independence of the depth points, giving a higher depth resolution than mode B. - * Mode B is instead optimized for maximal radar loop gain per unit time spent on measuring. This - * makes it more energy efficient and suitable for cases where small movements are to be detected - * over long ranges. Mode A is more suitable for applications like gesture recognition, measuring - * the distance to a movement, and speed measurements. - * - * Mode B typically gives roughly 3 dB better SNR per unit time than mode A. However, please note - * that very short ranges of only one or a few points are suboptimal with mode B. In those cases, - * always use mode A. - */ -typedef enum -{ - ACC_SERVICE_SPARSE_SAMPLING_MODE_A, - ACC_SERVICE_SPARSE_SAMPLING_MODE_B -} acc_service_sparse_sampling_mode_enum_t; -typedef uint32_t acc_service_sparse_sampling_mode_t; - - -/** - * @brief Metadata for the sparse service - */ -typedef struct -{ - /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ - float start_m; - /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ - float length_m; - /** Number of elements in the sparse data array */ - uint16_t data_length; - /** Sweep rate used */ - float sweep_rate; - /** Distance between adjacent data points */ - float step_length_m; -} acc_service_sparse_metadata_t; - - -/** - * @brief Metadata for each result provided by the sparse service - */ -typedef struct -{ - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of missed data from the sensor */ - bool missed_data; -} acc_service_sparse_result_info_t; - - -/** - * @brief Create a configuration for a sparse service - * - * A configuration is created for the sparse service and populated - * with default values. - * - * @return Service configuration, NULL if creation was not possible - */ -acc_service_configuration_t acc_service_sparse_configuration_create(void); - - -/** - * @brief Destroy a sparse configuration - * - * Destroy a sparse configuration that is no longer needed, may be done even if a - * service has been created with the specific configuration and has not yet been destroyed. - * The service configuration reference is set to NULL after destruction. - * - * @param[in] service_configuration The configuration to destroy, set to NULL - */ -void acc_service_sparse_configuration_destroy(acc_service_configuration_t *service_configuration); - - -/** - * @brief Get the number of sweeps per service frame - * - * Gets the number of sweeps that will be returned in each frame from the service. - * - * @param[in] service_configuration The service configuration to get sweeps per result from - * @return sweeps per frame - */ -uint16_t acc_service_sparse_configuration_sweeps_per_frame_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set sweeps per service frame - * - * Sets the number of sweeps that will be returned in each frame from the service. - * - * For sampling mode B, the number of sweeps per frame must be less than or equal to 64. - * - * @param[in] service_configuration The service configuration to set sweeps per results in - * @param[in] sweeps Sweeps per frame - */ -void acc_service_sparse_configuration_sweeps_per_frame_set(acc_service_configuration_t service_configuration, uint16_t sweeps); - - -/** - * @brief Get the sweep rate - * - * Gets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. - * - * @param[in] service_configuration The service configuration to get the sweep rate from - * @return sweep_rate The sweep rate - */ -float acc_service_sparse_configuration_sweep_rate_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set sweep rate - * - * Sets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. - * - * @param[in] service_configuration The service configuration to set the sweep rate in - * @param[in] sweep_rate The sweep rate - */ -void acc_service_sparse_configuration_sweep_rate_set(acc_service_configuration_t service_configuration, float sweep_rate); - - -/** - * @brief Get sampling mode - * - * @param[in] service_configuration The configuration to get the sampling mode for - * @return sampling mode - */ -acc_service_sparse_sampling_mode_t acc_service_sparse_sampling_mode_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set sampling mode - * - * @param[in] service_configuration The configuration to set the sampling mode for - * @param[in] sampling_mode The sampling mode to use - */ -void acc_service_sparse_sampling_mode_set(acc_service_configuration_t service_configuration, acc_service_sparse_sampling_mode_t sampling_mode); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 4 makes - * the distance between two points in the measured range ~24cm. - * - * @param[in] service_configuration The configuration to get downsampling factor from - * @return The downsampling factor - */ -uint16_t acc_service_sparse_downsampling_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 4 makes - * the distance between two points in the measured range ~24cm. - * - * The sparse service supports setting the downsampling factor to 1, 2, 4, or 8. - * - * @param[in] service_configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_service_sparse_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); - - -/** - * @brief Get minimum service memory size - * - * The service memory size depends on several parameters and has a default - * minimum size of around 4kByte. The service memory usage increases with increasing range. - * This parameter changes the default minimum size from 4kByte to the used value. - * With a small value there might be a time penalty for service creation and activation. - * - * @param[in] service_configuration The service configuration to get min service memory size from - * @return The minimum service memory size - */ -uint16_t acc_service_sparse_min_service_memory_size_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set minimum service memory size - * - * The service memory size depends on several parameters and has a default - * minimum size of around 4kByte. The service memory usage increases with increasing range. - * This parameter changes the default minimum size from 4kByte to the used value. - * With a small value there might be a time penalty for service creation and activation. - * - * @param[in] service_configuration The service configuration to set min service memory size in - * @param[in] min_service_memory_size The minimum service memory size - */ -void acc_service_sparse_min_service_memory_size_set(acc_service_configuration_t service_configuration, uint16_t min_service_memory_size); - - -/** - * @brief Get service metadata - * - * Each service provide metadata after being created with information that could be relevant for an application. - * The metadata contain information such as data length and actual start and length. - * - * May only be called after a service has been created. - * - * @param[in] handle The service handle for the service to get metadata for - * @param[out] metadata Metadata results are provided in this parameter - */ -void acc_service_sparse_get_metadata(acc_service_handle_t handle, acc_service_sparse_metadata_t *metadata); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data sparse result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Sparse result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_sparse_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_sparse_result_info_t *result_info); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * The provided memory is only valid until the next call to get_next for the - * specified handle. The memory is specific for the handle and cannot be shared - * between handles/services. - * - * The length of the resulting data is provided in @ref acc_service_sparse_get_metadata - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Reference to Sparse result - * @param[out] result_info Sparse result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_sparse_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, - acc_service_sparse_result_info_t *result_info); - - -/** - * @brief Execute service one time - * - * Activates service, produces one result and then deactivates the service. Blocks the - * application until a service result has been produced. May fail if the service is already active. - * - * @param[in] handle The service handle for the service to execute - * @param[out] data sparse result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Sparse result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_sparse_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_sparse_result_info_t *result_info); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2019-2021 +// All rights reserved + +#ifndef ACC_SERVICE_SPARSE_H_ +#define ACC_SERVICE_SPARSE_H_ + +#include +#include + +#include "acc_service.h" + +/** + * @defgroup Sparse Sparse Service + * @ingroup Services + * + * @brief Sparse service API description + * + * @{ + */ + + +/** + * @brief Sampling mode + * + * The sampling mode changes how the hardware accelerated averaging is done. Mode A is optimized + * for maximal independence of the depth points, giving a higher depth resolution than mode B. + * Mode B is instead optimized for maximal radar loop gain per unit time spent on measuring. This + * makes it more energy efficient and suitable for cases where small movements are to be detected + * over long ranges. Mode A is more suitable for applications like gesture recognition, measuring + * the distance to a movement, and speed measurements. + * + * Mode B typically gives roughly 3 dB better SNR per unit time than mode A. However, please note + * that very short ranges of only one or a few points are suboptimal with mode B. In those cases, + * always use mode A. + */ +typedef enum +{ + ACC_SERVICE_SPARSE_SAMPLING_MODE_A, + ACC_SERVICE_SPARSE_SAMPLING_MODE_B +} acc_service_sparse_sampling_mode_enum_t; +typedef uint32_t acc_service_sparse_sampling_mode_t; + + +/** + * @brief Metadata for the sparse service + */ +typedef struct +{ + /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ + float start_m; + /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ + float length_m; + /** Number of elements in the sparse data array */ + uint16_t data_length; + /** Sweep rate used */ + float sweep_rate; + /** Distance between adjacent data points */ + float step_length_m; +} acc_service_sparse_metadata_t; + + +/** + * @brief Metadata for each result provided by the sparse service + */ +typedef struct +{ + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of missed data from the sensor */ + bool missed_data; +} acc_service_sparse_result_info_t; + + +/** + * @brief Create a configuration for a sparse service + * + * A configuration is created for the sparse service and populated + * with default values. + * + * @return Service configuration, NULL if creation was not possible + */ +acc_service_configuration_t acc_service_sparse_configuration_create(void); + + +/** + * @brief Destroy a sparse configuration + * + * Destroy a sparse configuration that is no longer needed, may be done even if a + * service has been created with the specific configuration and has not yet been destroyed. + * The service configuration reference is set to NULL after destruction. + * + * @param[in] service_configuration The configuration to destroy, set to NULL + */ +void acc_service_sparse_configuration_destroy(acc_service_configuration_t *service_configuration); + + +/** + * @brief Get the number of sweeps per service frame + * + * Gets the number of sweeps that will be returned in each frame from the service. + * + * @param[in] service_configuration The service configuration to get sweeps per result from + * @return sweeps per frame + */ +uint16_t acc_service_sparse_configuration_sweeps_per_frame_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set sweeps per service frame + * + * Sets the number of sweeps that will be returned in each frame from the service. + * + * For sampling mode B, the number of sweeps per frame must be less than or equal to 64. + * + * @param[in] service_configuration The service configuration to set sweeps per results in + * @param[in] sweeps Sweeps per frame + */ +void acc_service_sparse_configuration_sweeps_per_frame_set(acc_service_configuration_t service_configuration, uint16_t sweeps); + + +/** + * @brief Get the sweep rate + * + * Gets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. + * + * @param[in] service_configuration The service configuration to get the sweep rate from + * @return sweep_rate The sweep rate + */ +float acc_service_sparse_configuration_sweep_rate_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set sweep rate + * + * Sets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. + * + * @param[in] service_configuration The service configuration to set the sweep rate in + * @param[in] sweep_rate The sweep rate + */ +void acc_service_sparse_configuration_sweep_rate_set(acc_service_configuration_t service_configuration, float sweep_rate); + + +/** + * @brief Get sampling mode + * + * @param[in] service_configuration The configuration to get the sampling mode for + * @return sampling mode + */ +acc_service_sparse_sampling_mode_t acc_service_sparse_sampling_mode_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set sampling mode + * + * @param[in] service_configuration The configuration to set the sampling mode for + * @param[in] sampling_mode The sampling mode to use + */ +void acc_service_sparse_sampling_mode_set(acc_service_configuration_t service_configuration, acc_service_sparse_sampling_mode_t sampling_mode); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 4 makes + * the distance between two points in the measured range ~24cm. + * + * @param[in] service_configuration The configuration to get downsampling factor from + * @return The downsampling factor + */ +uint16_t acc_service_sparse_downsampling_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 4 makes + * the distance between two points in the measured range ~24cm. + * + * The sparse service supports setting the downsampling factor to 1, 2, 4, or 8. + * + * @param[in] service_configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_service_sparse_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); + + +/** + * @brief Get minimum service memory size + * + * The service memory size depends on several parameters and has a default + * minimum size of around 4kByte. The service memory usage increases with increasing range. + * This parameter changes the default minimum size from 4kByte to the used value. + * With a small value there might be a time penalty for service creation and activation. + * + * @param[in] service_configuration The service configuration to get min service memory size from + * @return The minimum service memory size + */ +uint16_t acc_service_sparse_min_service_memory_size_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set minimum service memory size + * + * The service memory size depends on several parameters and has a default + * minimum size of around 4kByte. The service memory usage increases with increasing range. + * This parameter changes the default minimum size from 4kByte to the used value. + * With a small value there might be a time penalty for service creation and activation. + * + * @param[in] service_configuration The service configuration to set min service memory size in + * @param[in] min_service_memory_size The minimum service memory size + */ +void acc_service_sparse_min_service_memory_size_set(acc_service_configuration_t service_configuration, uint16_t min_service_memory_size); + + +/** + * @brief Get service metadata + * + * Each service provide metadata after being created with information that could be relevant for an application. + * The metadata contain information such as data length and actual start and length. + * + * May only be called after a service has been created. + * + * @param[in] handle The service handle for the service to get metadata for + * @param[out] metadata Metadata results are provided in this parameter + */ +void acc_service_sparse_get_metadata(acc_service_handle_t handle, acc_service_sparse_metadata_t *metadata); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data sparse result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Sparse result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_sparse_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_sparse_result_info_t *result_info); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * The provided memory is only valid until the next call to get_next for the + * specified handle. The memory is specific for the handle and cannot be shared + * between handles/services. + * + * The length of the resulting data is provided in @ref acc_service_sparse_get_metadata + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Reference to Sparse result + * @param[out] result_info Sparse result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_sparse_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, + acc_service_sparse_result_info_t *result_info); + + +/** + * @brief Execute service one time + * + * Activates service, produces one result and then deactivates the service. Blocks the + * application until a service result has been produced. May fail if the service is already active. + * + * @param[in] handle The service handle for the service to execute + * @param[out] data sparse result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Sparse result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_sparse_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_sparse_result_info_t *result_info); + + +/** + * @} + */ + +#endif diff --git a/STM32CubeIDE/rss/include/acc_version.h b/STM32CubeIDE/rss/include/acc_version.h index 4cdb4e0..4e6d482 100644 --- a/STM32CubeIDE/rss/include/acc_version.h +++ b/STM32CubeIDE/rss/include/acc_version.h @@ -1,14 +1,14 @@ -// Copyright (c) Acconeer AB, 2019-2021 -// All rights reserved - -#ifndef ACC_VERSION_H_ -#define ACC_VERSION_H_ - -/** - * @brief Get the version of the Acconeer software - * - * @return A string describing the software version. - */ -const char *acc_version_get(void); - -#endif +// Copyright (c) Acconeer AB, 2019-2021 +// All rights reserved + +#ifndef ACC_VERSION_H_ +#define ACC_VERSION_H_ + +/** + * @brief Get the version of the Acconeer software + * + * @return A string describing the software version. + */ +const char *acc_version_get(void); + +#endif diff --git a/as923_1_jp.js b/as923_1_jp.js index 37a58d1..fa2c262 100644 --- a/as923_1_jp.js +++ b/as923_1_jp.js @@ -1,105 +1,105 @@ -// Decode decodes an array of bytes into an object. -// - fPort contains the LoRaWAN fPort number -// - bytes is an array of bytes, e.g. [225, 230, 255, 0] -// - variables contains the device variables e.g. {"calibration": "3.5"} (both the key / value are of type string) -// The function must return an object, e.g. {"temperature": 22.5} -function Decode(fPort, bytes, variables) { - // O5 Door contact sensor - if (fPort === 4) { - return [ - { - led_state: bytes[0]===0 ? "Off":"On", - mtm_code_1: bytes[1], - mtm_code_2: bytes[2], - hw_code: bytes[3], - battery_level: bytes[4]+"%", - size_value: bytes[5], - door_state: bytes[6] === 1 ? "Closed": "Open", - } - ]; - } - // heart-beat of O5 - else if (fPort === 5) { - return [ - { - led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", - battery_level: bytes[1] + " %", - } - ]; - } - // R4 soap/sanitizer sensor - else if (fPort === 7) { - return [ - { - led_state: bytes[0]===0 ? "Off":"On", - mtm_code_1: bytes[1], - mtm_code_2: bytes[2], - hw_code: bytes[3], - battery_level: bytes[4]+"%", - size_value: bytes[5], - measure_tech:bytes[6] === 0? "Capacitive":"Other", - liquid_level_event: bytes[7] === 0? "Liquid Detected":"No Liquid", - } - ]; - } - // R4 soap/sanitizer heart-beat - else if (fPort === 8) { - return [ - { - led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", - battery_level: bytes[1] + " %", - } - ]; - } - // R1D dual roll toilet paper sensor - else if (fPort === 57) { - return [ - { - led_state:bytes[0]===0 ? "Off":"On", - mtm_code_1:bytes[1], - mtm_code_2:bytes[2], - hw_code:bytes[3], - battery_level:bytes[4]+"%", - size_value:bytes[5], - distance_1_mm:bytes[6]*256+bytes[7], - distance_2_mm:bytes[8]*256+bytes[9], - distance_unit: "mm", - } - ]; - } - // R1D, Heart-beat - else if (fPort === 58) { - return [ - { - led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", - battery_level: bytes[1] + " %", - } - ]; - } - // R5 waste bin sensor - else if (fPort === 11) { - return [ - { - led_state:bytes[0]===0 ? "Off":"On", - mtm_code_1:bytes[1], - mtm_code_2:bytes[2], - hw_code:bytes[3], - battery_level:bytes[4]+"%", - size_value:bytes[5], - distance_mm: bytes[6]*256 + bytes[7], - distance_unit: "mm", - } - ]; - } - // R5, Heart-beat - else if (fPort === 12) { - return [ - { - led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", - battery_level: bytes[1] + " %", - } - ]; - } - - +// Decode decodes an array of bytes into an object. +// - fPort contains the LoRaWAN fPort number +// - bytes is an array of bytes, e.g. [225, 230, 255, 0] +// - variables contains the device variables e.g. {"calibration": "3.5"} (both the key / value are of type string) +// The function must return an object, e.g. {"temperature": 22.5} +function Decode(fPort, bytes, variables) { + // O5 Door contact sensor + if (fPort === 4) { + return [ + { + led_state: bytes[0]===0 ? "Off":"On", + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + hw_code: bytes[3], + battery_level: bytes[4]+"%", + size_value: bytes[5], + door_state: bytes[6] === 1 ? "Closed": "Open", + } + ]; + } + // heart-beat of O5 + else if (fPort === 5) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[1] + " %", + } + ]; + } + // R4 soap/sanitizer sensor + else if (fPort === 7) { + return [ + { + led_state: bytes[0]===0 ? "Off":"On", + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + hw_code: bytes[3], + battery_level: bytes[4]+"%", + size_value: bytes[5], + measure_tech:bytes[6] === 0? "Capacitive":"Other", + liquid_level_event: bytes[7] === 0? "Liquid Detected":"No Liquid", + } + ]; + } + // R4 soap/sanitizer heart-beat + else if (fPort === 8) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[1] + " %", + } + ]; + } + // R1D dual roll toilet paper sensor + else if (fPort === 57) { + return [ + { + led_state:bytes[0]===0 ? "Off":"On", + mtm_code_1:bytes[1], + mtm_code_2:bytes[2], + hw_code:bytes[3], + battery_level:bytes[4]+"%", + size_value:bytes[5], + distance_1_mm:bytes[6]*256+bytes[7], + distance_2_mm:bytes[8]*256+bytes[9], + distance_unit: "mm", + } + ]; + } + // R1D, Heart-beat + else if (fPort === 58) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[1] + " %", + } + ]; + } + // R5 waste bin sensor + else if (fPort === 11) { + return [ + { + led_state:bytes[0]===0 ? "Off":"On", + mtm_code_1:bytes[1], + mtm_code_2:bytes[2], + hw_code:bytes[3], + battery_level:bytes[4]+"%", + size_value:bytes[5], + distance_mm: bytes[6]*256 + bytes[7], + distance_unit: "mm", + } + ]; + } + // R5, Heart-beat + else if (fPort === 12) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[1] + " %", + } + ]; + } + + } \ No newline at end of file diff --git a/decoder.js b/decoder.js index a753652..1dccf3f 100644 --- a/decoder.js +++ b/decoder.js @@ -1,122 +1,122 @@ -// Decode decodes an array of bytes into an object. -// - fPort contains the LoRaWAN fPort number -// - bytes is an array of bytes, e.g. [225, 230, 255, 0] -// - variables contains the device variables e.g. {"calibration": "3.5"} (both the key / value are of type string) -// The function must return an object, e.g. {"temperature": 22.5} -function Decode(fPort, data, variables) { - if (fPort === 13) { - return [ - { - led_state: bytes[0] === 0 ? "Off" : "On", - mtm_code_1: bytes[1], - mtm_code_2: bytes[2], - hw_code: bytes[3], - battery_level: bytes[4] + "%", - size_value: bytes[5], - spot_cnt: bytes[6] + " blocks", - spillage_level: bytes[7] + "%", - top1_position: "X= " + bytes[8] % 10 + " Y= " + parseFloat(bytes[8] / 10).toFixed(0), - top2_position: "X= " + bytes[9] % 10 + " Y= " + parseFloat(bytes[9] / 10).toFixed(0), - top3_position: "X= " + bytes[10] % 10 + " Y= " + parseFloat(bytes[10] / 10).toFixed(0), - top4_position: "X= " + bytes[11] % 10 + " Y= " + parseFloat(bytes[11] / 10).toFixed(0), - min_temp: (bytes[12] + bytes[13] / 100) + "C", - average_temp: (bytes[14] + bytes[15] / 100) + "C", - max_temp: (bytes[16] + bytes[17] / 100) + "C", - center_temp: (bytes[18] + bytes[19] / 100) + "C", - } - ] - } - // Heart-beat port with LED state and remaining battery level % only - else if (fPort === 14) { - return [ - { - led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", - battery_level: bytes[1] + " %", - } - ]; - } - // fPort: 1, uplink of control command - else if (fPort === 1) { - - // 0x56, report HW/SW version of node - if (bytes[0] === 0x56) { - return [ - { - mtm_code_1: bytes[1], - mtm_code_2: bytes[2], - HW_Version: "HW:" + bytes[3], - SW_Version: "SW" + bytes[4] + ":" + bytes[5] + ":" + bytes[6] + ":" + bytes[7], - } - ]; - } - // 0x53, report seft testing result - else if (bytes[0] === 0x53) { - return [ - { - mtm_code_1: bytes[1], - mtm_code_2: bytes[2], - sw_code: bytes[3], - hw_code: bytes[4], - battery_level: bytes[5] + "%", - size_value: bytes[6], - average_temp: (bytes[7] + bytes[8] / 100) + "C", - center_temp: (bytes[9] + bytes[10] / 100) + "C", - min_temp: (bytes[11] + bytes[12] / 100) + "C", - max_temp: (bytes[13] + bytes[14] / 100) + "C", - } - ]; - - } - // 0x43, report config of node - else if (bytes[0] === 0x43) { - - return [ - { - mtm_code_1: bytes[1], - mtm_code_2: bytes[2], - sw_code: bytes[3], - hw_code: bytes[4], - uplink: bytes[5], - uplink_unit: bytes[6], - heart_beat_interval: bytes[7], - heart_beat_interval_unit: bytes[8], - work_mode: bytes[9], - service_mask: bytes[10], - size_value: bytes[12], - // key parameters - averageTempThreshold: (bytes[14]) + " C", - // emmisivity for water 0.96, human 0.92 - emmisivityThreshold: (bytes[16] / 100), - humanTempThreshold: (bytes[18]) + " C", - waterTempThreshold: (bytes[20] / 10) + " C", - } - - - ]; - - - } - // 0x59,0x44 report configed heart-beat interval - if (bytes[0] === 0x59) { - if (bytes[1] === 0x53) { - return [ - { - Type: "Heart Beat Interval", - HB_interval: (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30), - HB_interval_unit: String.fromCharCode(bytes[4]), - } - ]; - } - else if (bytes[1] === 0x44) { - return [ - { - Type: "Periodic Upload Interval", - Upload_interval: (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30), - Upload_interval_unit: String.fromCharCode(bytes[4]), - } - ]; - } - } - } - +// Decode decodes an array of bytes into an object. +// - fPort contains the LoRaWAN fPort number +// - bytes is an array of bytes, e.g. [225, 230, 255, 0] +// - variables contains the device variables e.g. {"calibration": "3.5"} (both the key / value are of type string) +// The function must return an object, e.g. {"temperature": 22.5} +function Decode(fPort, data, variables) { + if (fPort === 13) { + return [ + { + led_state: bytes[0] === 0 ? "Off" : "On", + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + hw_code: bytes[3], + battery_level: bytes[4] + "%", + size_value: bytes[5], + spot_cnt: bytes[6] + " blocks", + spillage_level: bytes[7] + "%", + top1_position: "X= " + bytes[8] % 10 + " Y= " + parseFloat(bytes[8] / 10).toFixed(0), + top2_position: "X= " + bytes[9] % 10 + " Y= " + parseFloat(bytes[9] / 10).toFixed(0), + top3_position: "X= " + bytes[10] % 10 + " Y= " + parseFloat(bytes[10] / 10).toFixed(0), + top4_position: "X= " + bytes[11] % 10 + " Y= " + parseFloat(bytes[11] / 10).toFixed(0), + min_temp: (bytes[12] + bytes[13] / 100) + "C", + average_temp: (bytes[14] + bytes[15] / 100) + "C", + max_temp: (bytes[16] + bytes[17] / 100) + "C", + center_temp: (bytes[18] + bytes[19] / 100) + "C", + } + ] + } + // Heart-beat port with LED state and remaining battery level % only + else if (fPort === 14) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[1] + " %", + } + ]; + } + // fPort: 1, uplink of control command + else if (fPort === 1) { + + // 0x56, report HW/SW version of node + if (bytes[0] === 0x56) { + return [ + { + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + HW_Version: "HW:" + bytes[3], + SW_Version: "SW" + bytes[4] + ":" + bytes[5] + ":" + bytes[6] + ":" + bytes[7], + } + ]; + } + // 0x53, report seft testing result + else if (bytes[0] === 0x53) { + return [ + { + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + sw_code: bytes[3], + hw_code: bytes[4], + battery_level: bytes[5] + "%", + size_value: bytes[6], + average_temp: (bytes[7] + bytes[8] / 100) + "C", + center_temp: (bytes[9] + bytes[10] / 100) + "C", + min_temp: (bytes[11] + bytes[12] / 100) + "C", + max_temp: (bytes[13] + bytes[14] / 100) + "C", + } + ]; + + } + // 0x43, report config of node + else if (bytes[0] === 0x43) { + + return [ + { + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + sw_code: bytes[3], + hw_code: bytes[4], + uplink: bytes[5], + uplink_unit: bytes[6], + heart_beat_interval: bytes[7], + heart_beat_interval_unit: bytes[8], + work_mode: bytes[9], + service_mask: bytes[10], + size_value: bytes[12], + // key parameters + averageTempThreshold: (bytes[14]) + " C", + // emmisivity for water 0.96, human 0.92 + emmisivityThreshold: (bytes[16] / 100), + humanTempThreshold: (bytes[18]) + " C", + waterTempThreshold: (bytes[20] / 10) + " C", + } + + + ]; + + + } + // 0x59,0x44 report configed heart-beat interval + if (bytes[0] === 0x59) { + if (bytes[1] === 0x53) { + return [ + { + Type: "Heart Beat Interval", + HB_interval: (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30), + HB_interval_unit: String.fromCharCode(bytes[4]), + } + ]; + } + else if (bytes[1] === 0x44) { + return [ + { + Type: "Periodic Upload Interval", + Upload_interval: (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30), + Upload_interval_unit: String.fromCharCode(bytes[4]), + } + ]; + } + } + } + }; \ No newline at end of file diff --git a/mcu/STM32WLE5CCUX_FLASH.ld_ b/mcu/STM32WLE5CCUX_FLASH.ld_ index 5673f95..40b4342 100644 --- a/mcu/STM32WLE5CCUX_FLASH.ld_ +++ b/mcu/STM32WLE5CCUX_FLASH.ld_ @@ -1,186 +1,186 @@ -/* -****************************************************************************** -** -** File : LinkerScript.ld -** -** Author : STM32CubeIDE -** -** Abstract : Linker script for STM32WLE5xC Device -** 256Kbytes FLASH -** 64Kbytes RAM -** -** Set heap size, stack size and stack location according -** to application requirements. -** -** Set memory bank area and size if external memory is used. -** -** Target : STMicroelectronics STM32 -** -** Distribution: The file is distributed as is without any warranty -** of any kind. -** -***************************************************************************** -** @attention -** -** Copyright (c) 2022 STMicroelectronics. -** All rights reserved. -** -** This software is licensed under terms that can be found in the LICENSE file -** in the root directory of this software component. -** If no LICENSE file comes with this software, it is provided AS-IS. -** -***************************************************************************** -*/ - -/* Entry Point */ -ENTRY(Reset_Handler) - -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x800; /* required amount of stack */ - -/* Memories definition */ -MEMORY -{ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K - RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K -} - -/* Sections */ -SECTIONS -{ - /* The startup code into "FLASH" Rom type memory */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* The program code and other data into "FLASH" Rom type memory */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH - - /* Constant data into "FLASH" Rom type memory */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH - - .ARM.extab : { - . = ALIGN(4); - *(.ARM.extab* .gnu.linkonce.armextab.*) - . = ALIGN(4); - } >FLASH - - .ARM : { - . = ALIGN(4); - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - . = ALIGN(4); - } >FLASH - - .preinit_array : - { - . = ALIGN(4); - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - . = ALIGN(4); - } >FLASH - - .init_array : - { - . = ALIGN(4); - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - . = ALIGN(4); - } >FLASH - - .fini_array : - { - . = ALIGN(4); - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - . = ALIGN(4); - } >FLASH - - /* Used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections into "RAM" Ram type memory */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - *(.RamFunc) /* .RamFunc sections */ - *(.RamFunc*) /* .RamFunc* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - - } >RAM AT> FLASH - - /* Uninitialized data section into "RAM" Ram type memory */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss section */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM - - /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >RAM - - /* Remove information from the compiler libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } -} +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32WLE5xC Device +** 256Kbytes FLASH +** 64Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2022 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x800; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K + RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/mcu_2_55jc.sh b/mcu_2_55jc.sh index db88291..e547b09 100644 --- a/mcu_2_55jc.sh +++ b/mcu_2_55jc.sh @@ -1,10 +1,10 @@ -cp ./mcu/STM32WL55JCIX_FLASH.ld_ ./STM32CubeIDE/STM32WL55JCIX_FLASH.ld -cp ./mcu/startup_stm32wl55jcix.s__ ./STM32CubeIDE/Application/User/Startup/startup_stm32wl55jcix.s -rm -rf ./STM32CubeIDE/STM32wlE5CCUX_FLASH.ld -rm -rf ./STM32CubeIDE/Application/User/Startup/startup_stm32wle5ccux.s - -cp ./STM32CubeIDe/.cproject ./mcu/.cproject.e5 -sed s/E5CCUX_FLASH/55JCIX_FLASH/g <./STM32CubeIDE/.cproject >./STM32CubeIDE/ccproject -mv ./STM32CubeIDE/ccproject .cproject - - +cp ./mcu/STM32WL55JCIX_FLASH.ld_ ./STM32CubeIDE/STM32WL55JCIX_FLASH.ld +cp ./mcu/startup_stm32wl55jcix.s__ ./STM32CubeIDE/Application/User/Startup/startup_stm32wl55jcix.s +rm -rf ./STM32CubeIDE/STM32wlE5CCUX_FLASH.ld +rm -rf ./STM32CubeIDE/Application/User/Startup/startup_stm32wle5ccux.s + +cp ./STM32CubeIDe/.cproject ./mcu/.cproject.e5 +sed s/E5CCUX_FLASH/55JCIX_FLASH/g <./STM32CubeIDE/.cproject >./STM32CubeIDE/ccproject +mv ./STM32CubeIDE/ccproject .cproject + + diff --git a/mcu_2_e5cc.sh b/mcu_2_e5cc.sh index 575d750..6d3abd5 100644 --- a/mcu_2_e5cc.sh +++ b/mcu_2_e5cc.sh @@ -1,9 +1,9 @@ -cp ./mcu/STM32WLE5CCUX_FLASH.ld_ ./STM32CubeIDE/STM32WLE5CCUX_FLASH.ld -cp ./mcu/startup_stm32wle5ccux.s__ ./STM32CubeIDE/Application/User/Startup/startup_stm32wle5ccux.s -rm -rf ./STM32CubeIDE/STM32WL55JCIX_FLASH.ld -rm -rf ./STM32CubeIDE/Application/User/Startup/startup_stm32wl55jcix.s - -cp ./STM32CubeIDe/.cproject ./mcu/.cproject.55 -sed s/55JCIX_FLASH/E5CCUX_FLASH/g <./STM32CubeIDE/.cproject >./STM32CubeIDE/ccproject -mv ./STM32CubeIDE/ccproject .cproject - +cp ./mcu/STM32WLE5CCUX_FLASH.ld_ ./STM32CubeIDE/STM32WLE5CCUX_FLASH.ld +cp ./mcu/startup_stm32wle5ccux.s__ ./STM32CubeIDE/Application/User/Startup/startup_stm32wle5ccux.s +rm -rf ./STM32CubeIDE/STM32WL55JCIX_FLASH.ld +rm -rf ./STM32CubeIDE/Application/User/Startup/startup_stm32wl55jcix.s + +cp ./STM32CubeIDe/.cproject ./mcu/.cproject.55 +sed s/55JCIX_FLASH/E5CCUX_FLASH/g <./STM32CubeIDE/.cproject >./STM32CubeIDE/ccproject +mv ./STM32CubeIDE/ccproject .cproject + diff --git a/mlx90640/MLX90640_API.c b/mlx90640/MLX90640_API.c index 31f5f7b..601f55d 100644 --- a/mlx90640/MLX90640_API.c +++ b/mlx90640/MLX90640_API.c @@ -1,1456 +1,1456 @@ -/** - * @copyright (C) 2017 Melexis N.V. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#include -#include -#include - -static void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -static int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640); -static int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2); -static float GetMedian(float *values, int n); -static int IsPixelBad(uint16_t pixel,paramsMLX90640 *params); -static int ValidateFrameData(uint16_t *frameData); -static int ValidateAuxData(uint16_t *auxData); - -int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData) -{ - return MLX90640_I2CRead(slaveAddr, MLX90640_EEPROM_START_ADDRESS, MLX90640_EEPROM_DUMP_NUM, eeData); -} - -int MLX90640_SynchFrame(uint8_t slaveAddr) -{ - uint16_t dataReady = 0; - uint16_t statusRegister; - int error = 1; - - error = MLX90640_I2CWrite(slaveAddr, MLX90640_STATUS_REG, MLX90640_INIT_STATUS_VALUE); - if(error == -MLX90640_I2C_NACK_ERROR) - { - return error; - } - - while(dataReady == 0) - { - error = MLX90640_I2CRead(slaveAddr, MLX90640_STATUS_REG, 1, &statusRegister); - if(error != MLX90640_NO_ERROR) - { - return error; - } - //dataReady = statusRegister & 0x0008; - dataReady = MLX90640_GET_DATA_READY(statusRegister); - } - - return MLX90640_NO_ERROR; -} - -int MLX90640_TriggerMeasurement(uint8_t slaveAddr) -{ - int error = 1; - uint16_t ctrlReg; - - error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &ctrlReg); - - if ( error != MLX90640_NO_ERROR) - { - return error; - } - - ctrlReg |= MLX90640_CTRL_TRIG_READY_MASK; - error = MLX90640_I2CWrite(slaveAddr, MLX90640_CTRL_REG, ctrlReg); - - if ( error != MLX90640_NO_ERROR) - { - return error; - } - - error = MLX90640_I2CGeneralReset(); - - if ( error != MLX90640_NO_ERROR) - { - return error; - } - - error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &ctrlReg); - - if ( error != MLX90640_NO_ERROR) - { - return error; - } - - if ((ctrlReg & MLX90640_CTRL_TRIG_READY_MASK) != 0) - { - return -MLX90640_MEAS_TRIGGER_ERROR; - } - - return MLX90640_NO_ERROR; -} - -int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData) -{ - uint16_t dataReady = 0; - uint16_t controlRegister1; - uint16_t statusRegister; - int error = 1; - uint16_t data[64]; - uint8_t cnt = 0; - - while(dataReady == 0) - { - error = MLX90640_I2CRead(slaveAddr, MLX90640_STATUS_REG, 1, &statusRegister); - if(error != MLX90640_NO_ERROR) - { - return error; - } - //dataReady = statusRegister & 0x0008; - dataReady = MLX90640_GET_DATA_READY(statusRegister); - } - - error = MLX90640_I2CWrite(slaveAddr, MLX90640_STATUS_REG, MLX90640_INIT_STATUS_VALUE); - if(error == -MLX90640_I2C_NACK_ERROR) - { - return error; - } - - error = MLX90640_I2CRead(slaveAddr, MLX90640_PIXEL_DATA_START_ADDRESS, MLX90640_PIXEL_NUM, frameData); - if(error != MLX90640_NO_ERROR) - { - return error; - } - - error = MLX90640_I2CRead(slaveAddr, MLX90640_AUX_DATA_START_ADDRESS, MLX90640_AUX_NUM, data); - if(error != MLX90640_NO_ERROR) - { - return error; - } - - error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); - frameData[832] = controlRegister1; - //frameData[833] = statusRegister & 0x0001; - frameData[833] = MLX90640_GET_FRAME(statusRegister); - - if(error != MLX90640_NO_ERROR) - { - return error; - } - - error = ValidateAuxData(data); - if(error == MLX90640_NO_ERROR) - { - for(cnt=0; cnt> MLX90640_CTRL_RESOLUTION_SHIFT; - - return resolutionRAM; -} - -//------------------------------------------------------------------------------ - -int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate) -{ - uint16_t controlRegister1; - uint16_t value; - int error; - - //value = (refreshRate & 0x07)<<7; - value = ((uint16_t)refreshRate << MLX90640_CTRL_REFRESH_SHIFT); - value &= ~MLX90640_CTRL_REFRESH_MASK; - - error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); - if(error == MLX90640_NO_ERROR) - { - value = (controlRegister1 & MLX90640_CTRL_REFRESH_MASK) | value; - error = MLX90640_I2CWrite(slaveAddr, MLX90640_CTRL_REG, value); - } - - return error; -} - -//------------------------------------------------------------------------------ - -int MLX90640_GetRefreshRate(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - int refreshRate; - int error; - - error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); - if(error != MLX90640_NO_ERROR) - { - return error; - } - refreshRate = (controlRegister1 & ~MLX90640_CTRL_REFRESH_MASK) >> MLX90640_CTRL_REFRESH_SHIFT; - - return refreshRate; -} - -//------------------------------------------------------------------------------ - -int MLX90640_SetInterleavedMode(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - uint16_t value; - int error; - - error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); - - if(error == 0) - { - value = (controlRegister1 & ~MLX90640_CTRL_MEAS_MODE_MASK); - error = MLX90640_I2CWrite(slaveAddr, MLX90640_CTRL_REG, value); - } - - return error; -} - -//------------------------------------------------------------------------------ - -int MLX90640_SetChessMode(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - uint16_t value; - int error; - - error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); - - if(error == 0) - { - value = (controlRegister1 | MLX90640_CTRL_MEAS_MODE_MASK); - error = MLX90640_I2CWrite(slaveAddr, MLX90640_CTRL_REG, value); - } - - return error; -} - -//------------------------------------------------------------------------------ - -int MLX90640_GetCurMode(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - int modeRAM; - int error; - - error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); - if(error != 0) - { - return error; - } - modeRAM = (controlRegister1 & MLX90640_CTRL_MEAS_MODE_MASK) >> MLX90640_CTRL_MEAS_MODE_SHIFT; - - return modeRAM; -} - -//------------------------------------------------------------------------------ - -void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result) -{ - float vdd; - float ta; - float ta4; - float tr4; - float taTr; - float gain; - float irDataCP[2]; - float irData; - float alphaCompensated; - uint8_t mode; - int8_t ilPattern; - int8_t chessPattern; - int8_t pattern; - int8_t conversionPattern; - float Sx; - float To; - float alphaCorrR[4]; - int8_t range; - uint16_t subPage; - float ktaScale; - float kvScale; - float alphaScale; - float kta; - float kv; - - subPage = frameData[833]; - vdd = MLX90640_GetVdd(frameData, params); - ta = MLX90640_GetTa(frameData, params); - - ta4 = (ta + 273.15); - ta4 = ta4 * ta4; - ta4 = ta4 * ta4; - tr4 = (tr + 273.15); - tr4 = tr4 * tr4; - tr4 = tr4 * tr4; - taTr = tr4 - (tr4-ta4)/emissivity; - - ktaScale = POW2(params->ktaScale); - kvScale = POW2(params->kvScale); - alphaScale = POW2(params->alphaScale); - - alphaCorrR[0] = 1 / (1 + params->ksTo[0] * 40); - alphaCorrR[1] = 1 ; - alphaCorrR[2] = (1 + params->ksTo[1] * params->ct[2]); - alphaCorrR[3] = alphaCorrR[2] * (1 + params->ksTo[2] * (params->ct[3] - params->ct[2])); - -//------------------------- Gain calculation ----------------------------------- - - gain = (float)params->gainEE / (int16_t)frameData[778]; - -//------------------------- To calculation ------------------------------------- - mode = (frameData[832] & MLX90640_CTRL_MEAS_MODE_MASK) >> 5; - - irDataCP[0] = (int16_t)frameData[776] * gain; - irDataCP[1] = (int16_t)frameData[808] * gain; - - irDataCP[0] = irDataCP[0] - params->cpOffset[0] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - if( mode == params->calibrationModeEE) - { - irDataCP[1] = irDataCP[1] - params->cpOffset[1] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - } - else - { - irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - } - - for( int pixelNumber = 0; pixelNumber < 768; pixelNumber++) - { - ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2; - chessPattern = ilPattern ^ (pixelNumber - (pixelNumber/2)*2); - conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 + (pixelNumber + 1) / 4 - pixelNumber / 4) * (1 - 2 * ilPattern); - - if(mode == 0) - { - pattern = ilPattern; - } - else - { - pattern = chessPattern; - } - - if(pattern == frameData[833]) - { - irData = (int16_t)frameData[pixelNumber] * gain; - - kta = params->kta[pixelNumber]/ktaScale; - kv = params->kv[pixelNumber]/kvScale; - irData = irData - params->offset[pixelNumber]*(1 + kta*(ta - 25))*(1 + kv*(vdd - 3.3)); - - if(mode != params->calibrationModeEE) - { - irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) - params->ilChessC[1] * conversionPattern; - } - - irData = irData - params->tgc * irDataCP[subPage]; - irData = irData / emissivity; - - alphaCompensated = SCALEALPHA*alphaScale/params->alpha[pixelNumber]; - alphaCompensated = alphaCompensated*(1 + params->KsTa * (ta - 25)); - - Sx = alphaCompensated * alphaCompensated * alphaCompensated * (irData + alphaCompensated * taTr); - Sx = sqrt(sqrt(Sx)) * params->ksTo[1]; - - To = sqrt(sqrt(irData/(alphaCompensated * (1 - params->ksTo[1] * 273.15) + Sx) + taTr)) - 273.15; - - if(To < params->ct[1]) - { - range = 0; - } - else if(To < params->ct[2]) - { - range = 1; - } - else if(To < params->ct[3]) - { - range = 2; - } - else - { - range = 3; - } - - To = sqrt(sqrt(irData / (alphaCompensated * alphaCorrR[range] * (1 + params->ksTo[range] * (To - params->ct[range]))) + taTr)) - 273.15; - - result[pixelNumber] = To; - } - } -} - -//------------------------------------------------------------------------------ - -void MLX90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params, float *result) -{ - float vdd; - float ta; - float gain; - float irDataCP[2]; - float irData; - float alphaCompensated; - uint8_t mode; - int8_t ilPattern; - int8_t chessPattern; - int8_t pattern; - int8_t conversionPattern; - float image; - uint16_t subPage; - float ktaScale; - float kvScale; - float kta; - float kv; - - subPage = frameData[833]; - vdd = MLX90640_GetVdd(frameData, params); - ta = MLX90640_GetTa(frameData, params); - - ktaScale = POW2(params->ktaScale); - kvScale = POW2(params->kvScale); - -//------------------------- Gain calculation ----------------------------------- - - gain = (float)params->gainEE / (int16_t)frameData[778]; - -//------------------------- Image calculation ------------------------------------- - - mode = (frameData[832] & MLX90640_CTRL_MEAS_MODE_MASK) >> 5; - - irDataCP[0] = (int16_t)frameData[776] * gain; - irDataCP[1] = (int16_t)frameData[808] * gain; - - irDataCP[0] = irDataCP[0] - params->cpOffset[0] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - if( mode == params->calibrationModeEE) - { - irDataCP[1] = irDataCP[1] - params->cpOffset[1] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - } - else - { - irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - } - - for( int pixelNumber = 0; pixelNumber < 768; pixelNumber++) - { - ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2; - chessPattern = ilPattern ^ (pixelNumber - (pixelNumber/2)*2); - conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 + (pixelNumber + 1) / 4 - pixelNumber / 4) * (1 - 2 * ilPattern); - - if(mode == 0) - { - pattern = ilPattern; - } - else - { - pattern = chessPattern; - } - - if(pattern == frameData[833]) - { - irData = (int16_t)frameData[pixelNumber] * gain; - - kta = params->kta[pixelNumber]/ktaScale; - kv = params->kv[pixelNumber]/kvScale; - irData = irData - params->offset[pixelNumber]*(1 + kta*(ta - 25))*(1 + kv*(vdd - 3.3)); - - if(mode != params->calibrationModeEE) - { - irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) - params->ilChessC[1] * conversionPattern; - } - - irData = irData - params->tgc * irDataCP[subPage]; - - alphaCompensated = params->alpha[pixelNumber]; - - image = irData*alphaCompensated; - - result[pixelNumber] = image; - } - } -} - -//------------------------------------------------------------------------------ - -float MLX90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params) -{ - float vdd; - float resolutionCorrection; - - uint16_t resolutionRAM; - - resolutionRAM = (frameData[832] & ~MLX90640_CTRL_RESOLUTION_MASK) >> MLX90640_CTRL_RESOLUTION_SHIFT; - resolutionCorrection = POW2(params->resolutionEE) / POW2(resolutionRAM); - vdd = (resolutionCorrection * (int16_t)frameData[810] - params->vdd25) / params->kVdd + 3.3; - - return vdd; -} - -//------------------------------------------------------------------------------ - -float MLX90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params) -{ - int16_t ptat; - float ptatArt; - float vdd; - float ta; - - vdd = MLX90640_GetVdd(frameData, params); - - ptat = (int16_t)frameData[800]; - - ptatArt = (ptat / (ptat * params->alphaPTAT + (int16_t)frameData[768])) * POW2(18); - - ta = (ptatArt / (1 + params->KvPTAT * (vdd - 3.3)) - params->vPTAT25); - ta = ta / params->KtPTAT + 25; - - return ta; -} - -//------------------------------------------------------------------------------ - -int MLX90640_GetSubPageNumber(uint16_t *frameData) -{ - return frameData[833]; - -} - -//------------------------------------------------------------------------------ -void MLX90640_BadPixelsCorrection(uint16_t *pixels, float *to, int mode, paramsMLX90640 *params) -{ - float ap[4]; - uint8_t pix; - uint8_t line; - uint8_t column; - - pix = 0; - while(pixels[pix] != 0xFFFF) - { - line = pixels[pix]>>5; - column = pixels[pix] - (line<<5); - - if(mode == 1) - { - if(line == 0) - { - if(column == 0) - { - to[pixels[pix]] = to[33]; - } - else if(column == 31) - { - to[pixels[pix]] = to[62]; - } - else - { - to[pixels[pix]] = (to[pixels[pix]+31] + to[pixels[pix]+33])/2.0; - } - } - else if(line == 23) - { - if(column == 0) - { - to[pixels[pix]] = to[705]; - } - else if(column == 31) - { - to[pixels[pix]] = to[734]; - } - else - { - to[pixels[pix]] = (to[pixels[pix]-33] + to[pixels[pix]-31])/2.0; - } - } - else if(column == 0) - { - to[pixels[pix]] = (to[pixels[pix]-31] + to[pixels[pix]+33])/2.0; - } - else if(column == 31) - { - to[pixels[pix]] = (to[pixels[pix]-33] + to[pixels[pix]+31])/2.0; - } - else - { - ap[0] = to[pixels[pix]-33]; - ap[1] = to[pixels[pix]-31]; - ap[2] = to[pixels[pix]+31]; - ap[3] = to[pixels[pix]+33]; - to[pixels[pix]] = GetMedian(ap,4); - } - } - else - { - if(column == 0) - { - to[pixels[pix]] = to[pixels[pix]+1]; - } - else if(column == 1 || column == 30) - { - to[pixels[pix]] = (to[pixels[pix]-1]+to[pixels[pix]+1])/2.0; - } - else if(column == 31) - { - to[pixels[pix]] = to[pixels[pix]-1]; - } - else - { - if(IsPixelBad(pixels[pix]-2,params) == 0 && IsPixelBad(pixels[pix]+2,params) == 0) - { - ap[0] = to[pixels[pix]+1] - to[pixels[pix]+2]; - ap[1] = to[pixels[pix]-1] - to[pixels[pix]-2]; - if(fabs(ap[0]) > fabs(ap[1])) - { - to[pixels[pix]] = to[pixels[pix]-1] + ap[1]; - } - else - { - to[pixels[pix]] = to[pixels[pix]+1] + ap[0]; - } - } - else - { - to[pixels[pix]] = (to[pixels[pix]-1]+to[pixels[pix]+1])/2.0; - } - } - } - pix = pix + 1; - } -} - -//------------------------------------------------------------------------------ - -static void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int8_t kVdd; - int16_t vdd25; - - kVdd = MLX90640_MS_BYTE(eeData[51]); - - vdd25 = MLX90640_LS_BYTE(eeData[51]); - vdd25 = ((vdd25 - 256) << 5) - 8192; - - mlx90640->kVdd = 32 * kVdd; - mlx90640->vdd25 = vdd25; -} - -//------------------------------------------------------------------------------ - -static void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - float KvPTAT; - float KtPTAT; - int16_t vPTAT25; - float alphaPTAT; - - KvPTAT = (eeData[50] & MLX90640_MSBITS_6_MASK) >> 10; - if(KvPTAT > 31) - { - KvPTAT = KvPTAT - 64; - } - KvPTAT = KvPTAT/4096; - - KtPTAT = eeData[50] & MLX90640_LSBITS_10_MASK; - if(KtPTAT > 511) - { - KtPTAT = KtPTAT - 1024; - } - KtPTAT = KtPTAT/8; - - vPTAT25 = eeData[49]; - - alphaPTAT = (eeData[16] & MLX90640_NIBBLE4_MASK) / POW2(14) + 8.0f; - - mlx90640->KvPTAT = KvPTAT; - mlx90640->KtPTAT = KtPTAT; - mlx90640->vPTAT25 = vPTAT25; - mlx90640->alphaPTAT = alphaPTAT; -} - -//------------------------------------------------------------------------------ - -static void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - mlx90640->gainEE = (int16_t)eeData[48];; -} - -//------------------------------------------------------------------------------ - -static void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - mlx90640->tgc = (int8_t)MLX90640_LS_BYTE(eeData[60]) / 32.0f; -} - -//------------------------------------------------------------------------------ - -static void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - uint8_t resolutionEE; - resolutionEE = (eeData[56] & 0x3000) >> 12; - - mlx90640->resolutionEE = resolutionEE; -} - -//------------------------------------------------------------------------------ - -static void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - mlx90640->KsTa = (int8_t)MLX90640_MS_BYTE(eeData[60]) / 8192.0f; -} - -//------------------------------------------------------------------------------ - -static void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int32_t KsToScale; - int8_t step; - - step = ((eeData[63] & 0x3000) >> 12) * 10; - - mlx90640->ct[0] = -40; - mlx90640->ct[1] = 0; - mlx90640->ct[2] = MLX90640_NIBBLE2(eeData[63]); - mlx90640->ct[3] = MLX90640_NIBBLE3(eeData[63]); - - mlx90640->ct[2] = mlx90640->ct[2]*step; - mlx90640->ct[3] = mlx90640->ct[2] + mlx90640->ct[3]*step; - mlx90640->ct[4] = 400; - - KsToScale = MLX90640_NIBBLE1(eeData[63]) + 8; - KsToScale = 1UL << KsToScale; - - mlx90640->ksTo[0] = (int8_t)MLX90640_LS_BYTE(eeData[61]) / (float)KsToScale; - mlx90640->ksTo[1] = (int8_t)MLX90640_MS_BYTE(eeData[61]) / (float)KsToScale; - mlx90640->ksTo[2] = (int8_t)MLX90640_LS_BYTE(eeData[62]) / (float)KsToScale; - mlx90640->ksTo[3] = (int8_t)MLX90640_MS_BYTE(eeData[62]) / (float)KsToScale; - mlx90640->ksTo[4] = -0.0002; -} - -//------------------------------------------------------------------------------ - -static void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int accRow[24]; - int accColumn[32]; - int p = 0; - int alphaRef; - uint8_t alphaScale; - uint8_t accRowScale; - uint8_t accColumnScale; - uint8_t accRemScale; - float alphaTemp[768]; - float temp; - - - accRemScale = MLX90640_NIBBLE1(eeData[32]); - accColumnScale = MLX90640_NIBBLE2(eeData[32]); - accRowScale = MLX90640_NIBBLE3(eeData[32]); - alphaScale = MLX90640_NIBBLE4(eeData[32]) + 30; - alphaRef = eeData[33]; - - for(int i = 0; i < 6; i++) - { - p = i * 4; - accRow[p + 0] = MLX90640_NIBBLE1(eeData[34 + i]); - accRow[p + 1] = MLX90640_NIBBLE2(eeData[34 + i]); - accRow[p + 2] = MLX90640_NIBBLE3(eeData[34 + i]); - accRow[p + 3] = MLX90640_NIBBLE4(eeData[34 + i]); - } - - for(int i = 0; i < MLX90640_LINE_NUM; i++) - { - if (accRow[i] > 7) - { - accRow[i] = accRow[i] - 16; - } - } - - for(int i = 0; i < 8; i++) - { - p = i * 4; - accColumn[p + 0] = MLX90640_NIBBLE1(eeData[40 + i]); - accColumn[p + 1] = MLX90640_NIBBLE2(eeData[40 + i]); - accColumn[p + 2] = MLX90640_NIBBLE3(eeData[40 + i]); - accColumn[p + 3] = MLX90640_NIBBLE4(eeData[40 + i]); - } - - for(int i = 0; i < MLX90640_COLUMN_NUM; i++) - { - if (accColumn[i] > 7) - { - accColumn[i] = accColumn[i] - 16; - } - } - - for(int i = 0; i < MLX90640_LINE_NUM; i++) - { - for(int j = 0; j < MLX90640_COLUMN_NUM; j ++) - { - p = 32 * i +j; - alphaTemp[p] = (eeData[64 + p] & 0x03F0) >> 4; - if (alphaTemp[p] > 31) - { - alphaTemp[p] = alphaTemp[p] - 64; - } - alphaTemp[p] = alphaTemp[p]*(1 << accRemScale); - alphaTemp[p] = (alphaRef + (accRow[i] << accRowScale) + (accColumn[j] << accColumnScale) + alphaTemp[p]); - alphaTemp[p] = alphaTemp[p] / POW2(alphaScale); - alphaTemp[p] = alphaTemp[p] - mlx90640->tgc * (mlx90640->cpAlpha[0] + mlx90640->cpAlpha[1])/2; - alphaTemp[p] = SCALEALPHA/alphaTemp[p]; - } - } - - temp = alphaTemp[0]; - for(int i = 1; i < MLX90640_PIXEL_NUM; i++) - { - if (alphaTemp[i] > temp) - { - temp = alphaTemp[i]; - } - } - - alphaScale = 0; - while(temp < 32767.4) - { - temp = temp*2; - alphaScale = alphaScale + 1; - } - - for(int i = 0; i < MLX90640_PIXEL_NUM; i++) - { - temp = alphaTemp[i] * POW2(alphaScale); - mlx90640->alpha[i] = (temp + 0.5); - - } - - mlx90640->alphaScale = alphaScale; - -} - -//------------------------------------------------------------------------------ - -static void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int occRow[24]; - int occColumn[32]; - int p = 0; - int16_t offsetRef; - uint8_t occRowScale; - uint8_t occColumnScale; - uint8_t occRemScale; - - - occRemScale = MLX90640_NIBBLE1(eeData[16]); - occColumnScale = MLX90640_NIBBLE2(eeData[16]); - occRowScale = MLX90640_NIBBLE3(eeData[16]); - offsetRef = (int16_t)eeData[17]; - - for(int i = 0; i < 6; i++) - { - p = i * 4; - occRow[p + 0] = MLX90640_NIBBLE1(eeData[18 + i]); - occRow[p + 1] = MLX90640_NIBBLE2(eeData[18 + i]); - occRow[p + 2] = MLX90640_NIBBLE3(eeData[18 + i]); - occRow[p + 3] = MLX90640_NIBBLE4(eeData[18 + i]); - } - - for(int i = 0; i < MLX90640_LINE_NUM; i++) - { - if (occRow[i] > 7) - { - occRow[i] = occRow[i] - 16; - } - } - - for(int i = 0; i < 8; i++) - { - p = i * 4; - occColumn[p + 0] = MLX90640_NIBBLE1(eeData[24 + i]); - occColumn[p + 1] = MLX90640_NIBBLE2(eeData[24 + i]); - occColumn[p + 2] = MLX90640_NIBBLE3(eeData[24 + i]); - occColumn[p + 3] = MLX90640_NIBBLE4(eeData[24 + i]); - } - - for(int i = 0; i < MLX90640_COLUMN_NUM; i ++) - { - if (occColumn[i] > 7) - { - occColumn[i] = occColumn[i] - 16; - } - } - - for(int i = 0; i < MLX90640_LINE_NUM; i++) - { - for(int j = 0; j < MLX90640_COLUMN_NUM; j ++) - { - p = 32 * i +j; - mlx90640->offset[p] = (eeData[64 + p] & MLX90640_MSBITS_6_MASK) >> 10; - if (mlx90640->offset[p] > 31) - { - mlx90640->offset[p] = mlx90640->offset[p] - 64; - } - mlx90640->offset[p] = mlx90640->offset[p]*(1 << occRemScale); - mlx90640->offset[p] = (offsetRef + (occRow[i] << occRowScale) + (occColumn[j] << occColumnScale) + mlx90640->offset[p]); - } - } -} - -//------------------------------------------------------------------------------ - -static void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int p = 0; - int8_t KtaRC[4]; - uint8_t ktaScale1; - uint8_t ktaScale2; - uint8_t split; - float ktaTemp[768]; - float temp; - - KtaRC[0] = (int8_t)MLX90640_MS_BYTE(eeData[54]);; - KtaRC[2] = (int8_t)MLX90640_LS_BYTE(eeData[54]);; - KtaRC[1] = (int8_t)MLX90640_MS_BYTE(eeData[55]);; - KtaRC[3] = (int8_t)MLX90640_LS_BYTE(eeData[55]);; - - ktaScale1 = MLX90640_NIBBLE2(eeData[56]) + 8; - ktaScale2 = MLX90640_NIBBLE1(eeData[56]); - - for(int i = 0; i < MLX90640_LINE_NUM; i++) - { - for(int j = 0; j < MLX90640_COLUMN_NUM; j ++) - { - p = 32 * i +j; - split = 2*(p/32 - (p/64)*2) + p%2; - ktaTemp[p] = (eeData[64 + p] & 0x000E) >> 1; - if (ktaTemp[p] > 3) - { - ktaTemp[p] = ktaTemp[p] - 8; - } - ktaTemp[p] = ktaTemp[p] * (1 << ktaScale2); - ktaTemp[p] = KtaRC[split] + ktaTemp[p]; - ktaTemp[p] = ktaTemp[p] / POW2(ktaScale1); - - } - } - - temp = fabs(ktaTemp[0]); - for(int i = 1; i < MLX90640_PIXEL_NUM; i++) - { - if (fabs(ktaTemp[i]) > temp) - { - temp = fabs(ktaTemp[i]); - } - } - - ktaScale1 = 0; - while(temp < 63.4) - { - temp = temp*2; - ktaScale1 = ktaScale1 + 1; - } - - for(int i = 0; i < MLX90640_PIXEL_NUM; i++) - { - temp = ktaTemp[i] * POW2(ktaScale1); - if (temp < 0) - { - mlx90640->kta[i] = (temp - 0.5); - } - else - { - mlx90640->kta[i] = (temp + 0.5); - } - - } - - mlx90640->ktaScale = ktaScale1; -} - - -//------------------------------------------------------------------------------ - -static void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int p = 0; - int8_t KvT[4]; - int8_t KvRoCo; - int8_t KvRoCe; - int8_t KvReCo; - int8_t KvReCe; - uint8_t kvScale; - uint8_t split; - float kvTemp[768]; - float temp; - - KvRoCo = MLX90640_NIBBLE4(eeData[52]); - if (KvRoCo > 7) - { - KvRoCo = KvRoCo - 16; - } - KvT[0] = KvRoCo; - - KvReCo = MLX90640_NIBBLE3(eeData[52]); - if (KvReCo > 7) - { - KvReCo = KvReCo - 16; - } - KvT[2] = KvReCo; - - KvRoCe = MLX90640_NIBBLE2(eeData[52]); - if (KvRoCe > 7) - { - KvRoCe = KvRoCe - 16; - } - KvT[1] = KvRoCe; - - KvReCe = MLX90640_NIBBLE1(eeData[52]); - if (KvReCe > 7) - { - KvReCe = KvReCe - 16; - } - KvT[3] = KvReCe; - - kvScale = MLX90640_NIBBLE3(eeData[56]); - - - for(int i = 0; i < MLX90640_LINE_NUM; i++) - { - for(int j = 0; j < MLX90640_COLUMN_NUM; j ++) - { - p = 32 * i +j; - split = 2*(p/32 - (p/64)*2) + p%2; - kvTemp[p] = KvT[split]; - kvTemp[p] = kvTemp[p] / POW2(kvScale); - } - } - - temp = fabs(kvTemp[0]); - for(int i = 1; i < MLX90640_PIXEL_NUM; i++) - { - if (fabs(kvTemp[i]) > temp) - { - temp = fabs(kvTemp[i]); - } - } - - kvScale = 0; - while(temp < 63.4) - { - temp = temp*2; - kvScale = kvScale + 1; - } - - for(int i = 0; i < MLX90640_PIXEL_NUM; i++) - { - temp = kvTemp[i] * POW2(kvScale); - if (temp < 0) - { - mlx90640->kv[i] = (temp - 0.5); - } - else - { - mlx90640->kv[i] = (temp + 0.5); - } - - } - - mlx90640->kvScale = kvScale; -} - -//------------------------------------------------------------------------------ - -static void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - float alphaSP[2]; - int16_t offsetSP[2]; - float cpKv; - float cpKta; - uint8_t alphaScale; - uint8_t ktaScale1; - uint8_t kvScale; - - alphaScale = MLX90640_NIBBLE4(eeData[32]) + 27; - - offsetSP[0] = (eeData[58] & MLX90640_LSBITS_10_MASK); - if (offsetSP[0] > 511) - { - offsetSP[0] = offsetSP[0] - 1024; - } - - offsetSP[1] = (eeData[58] & MLX90640_MSBITS_6_MASK) >> 10; - if (offsetSP[1] > 31) - { - offsetSP[1] = offsetSP[1] - 64; - } - offsetSP[1] = offsetSP[1] + offsetSP[0]; - - alphaSP[0] = (eeData[57] & MLX90640_LSBITS_10_MASK); - if (alphaSP[0] > 511) - { - alphaSP[0] = alphaSP[0] - 1024; - } - alphaSP[0] = alphaSP[0] / POW2(alphaScale); - - alphaSP[1] = (eeData[57] & MLX90640_MSBITS_6_MASK) >> 10; - if (alphaSP[1] > 31) - { - alphaSP[1] = alphaSP[1] - 64; - } - alphaSP[1] = (1 + alphaSP[1]/128) * alphaSP[0]; - - cpKta = (int8_t)MLX90640_LS_BYTE(eeData[59]); - - ktaScale1 = MLX90640_NIBBLE2(eeData[56]) + 8; - mlx90640->cpKta = cpKta / POW2(ktaScale1); - - cpKv = (int8_t)MLX90640_MS_BYTE(eeData[59]); - - kvScale = MLX90640_NIBBLE3(eeData[56]); - mlx90640->cpKv = cpKv / POW2(kvScale); - - mlx90640->cpAlpha[0] = alphaSP[0]; - mlx90640->cpAlpha[1] = alphaSP[1]; - mlx90640->cpOffset[0] = offsetSP[0]; - mlx90640->cpOffset[1] = offsetSP[1]; -} - -//------------------------------------------------------------------------------ - -static void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - float ilChessC[3]; - uint8_t calibrationModeEE; - - calibrationModeEE = (eeData[10] & 0x0800) >> 4; - calibrationModeEE = calibrationModeEE ^ 0x80; - - ilChessC[0] = (eeData[53] & 0x003F); - if (ilChessC[0] > 31) - { - ilChessC[0] = ilChessC[0] - 64; - } - ilChessC[0] = ilChessC[0] / 16.0f; - - ilChessC[1] = (eeData[53] & 0x07C0) >> 6; - if (ilChessC[1] > 15) - { - ilChessC[1] = ilChessC[1] - 32; - } - ilChessC[1] = ilChessC[1] / 2.0f; - - ilChessC[2] = (eeData[53] & 0xF800) >> 11; - if (ilChessC[2] > 15) - { - ilChessC[2] = ilChessC[2] - 32; - } - ilChessC[2] = ilChessC[2] / 8.0f; - - mlx90640->calibrationModeEE = calibrationModeEE; - mlx90640->ilChessC[0] = ilChessC[0]; - mlx90640->ilChessC[1] = ilChessC[1]; - mlx90640->ilChessC[2] = ilChessC[2]; -} - -//------------------------------------------------------------------------------ - -static int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - uint16_t pixCnt = 0; - uint16_t brokenPixCnt = 0; - uint16_t outlierPixCnt = 0; - int warn = 0; - int i; - - for(pixCnt = 0; pixCnt<5; pixCnt++) - { - mlx90640->brokenPixels[pixCnt] = 0xFFFF; - mlx90640->outlierPixels[pixCnt] = 0xFFFF; - } - - pixCnt = 0; - while (pixCnt < MLX90640_PIXEL_NUM && brokenPixCnt < 5 && outlierPixCnt < 5) - { - if(eeData[pixCnt+64] == 0) - { - mlx90640->brokenPixels[brokenPixCnt] = pixCnt; - brokenPixCnt = brokenPixCnt + 1; - } - else if((eeData[pixCnt+64] & 0x0001) != 0) - { - mlx90640->outlierPixels[outlierPixCnt] = pixCnt; - outlierPixCnt = outlierPixCnt + 1; - } - - pixCnt = pixCnt + 1; - - } - - if(brokenPixCnt > 4) - { - warn = -MLX90640_BROKEN_PIXELS_NUM_ERROR; - } - else if(outlierPixCnt > 4) - { - warn = -MLX90640_OUTLIER_PIXELS_NUM_ERROR; - } - else if((brokenPixCnt + outlierPixCnt) > 4) - { - warn = -MLX90640_BAD_PIXELS_NUM_ERROR; - } - else - { - for(pixCnt=0; pixCntbrokenPixels[pixCnt],mlx90640->brokenPixels[i]); - if(warn != 0) - { - return warn; - } - } - } - - for(pixCnt=0; pixCntoutlierPixels[pixCnt],mlx90640->outlierPixels[i]); - if(warn != 0) - { - return warn; - } - } - } - - for(pixCnt=0; pixCntbrokenPixels[pixCnt],mlx90640->outlierPixels[i]); - if(warn != 0) - { - return warn; - } - } - } - - } - - - return warn; - -} - -//------------------------------------------------------------------------------ - - static int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2) - { - - int pixPosDif; - uint16_t lp1 = pix1 >> 5; - uint16_t lp2 = pix2 >> 5; - uint16_t cp1 = pix1 - (lp1 << 5); - uint16_t cp2 = pix2 - (lp2 << 5); - - pixPosDif = lp1 - lp2; - if(pixPosDif > -2 && pixPosDif < 2) - { - pixPosDif = cp1 - cp2; - if(pixPosDif > -2 && pixPosDif < 2) - { - return -6; - } - - } - - return 0; - } - -//------------------------------------------------------------------------------ - -static float GetMedian(float *values, int n) - { - float temp; - - for(int i=0; ioutlierPixels[i] || pixel == params->brokenPixels[i]) - { - return 1; - } - } - - return 0; -} - -//------------------------------------------------------------------------------ +/** + * @copyright (C) 2017 Melexis N.V. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include + +static void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); +static int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640); +static int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2); +static float GetMedian(float *values, int n); +static int IsPixelBad(uint16_t pixel,paramsMLX90640 *params); +static int ValidateFrameData(uint16_t *frameData); +static int ValidateAuxData(uint16_t *auxData); + +int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData) +{ + return MLX90640_I2CRead(slaveAddr, MLX90640_EEPROM_START_ADDRESS, MLX90640_EEPROM_DUMP_NUM, eeData); +} + +int MLX90640_SynchFrame(uint8_t slaveAddr) +{ + uint16_t dataReady = 0; + uint16_t statusRegister; + int error = 1; + + error = MLX90640_I2CWrite(slaveAddr, MLX90640_STATUS_REG, MLX90640_INIT_STATUS_VALUE); + if(error == -MLX90640_I2C_NACK_ERROR) + { + return error; + } + + while(dataReady == 0) + { + error = MLX90640_I2CRead(slaveAddr, MLX90640_STATUS_REG, 1, &statusRegister); + if(error != MLX90640_NO_ERROR) + { + return error; + } + //dataReady = statusRegister & 0x0008; + dataReady = MLX90640_GET_DATA_READY(statusRegister); + } + + return MLX90640_NO_ERROR; +} + +int MLX90640_TriggerMeasurement(uint8_t slaveAddr) +{ + int error = 1; + uint16_t ctrlReg; + + error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &ctrlReg); + + if ( error != MLX90640_NO_ERROR) + { + return error; + } + + ctrlReg |= MLX90640_CTRL_TRIG_READY_MASK; + error = MLX90640_I2CWrite(slaveAddr, MLX90640_CTRL_REG, ctrlReg); + + if ( error != MLX90640_NO_ERROR) + { + return error; + } + + error = MLX90640_I2CGeneralReset(); + + if ( error != MLX90640_NO_ERROR) + { + return error; + } + + error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &ctrlReg); + + if ( error != MLX90640_NO_ERROR) + { + return error; + } + + if ((ctrlReg & MLX90640_CTRL_TRIG_READY_MASK) != 0) + { + return -MLX90640_MEAS_TRIGGER_ERROR; + } + + return MLX90640_NO_ERROR; +} + +int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData) +{ + uint16_t dataReady = 0; + uint16_t controlRegister1; + uint16_t statusRegister; + int error = 1; + uint16_t data[64]; + uint8_t cnt = 0; + + while(dataReady == 0) + { + error = MLX90640_I2CRead(slaveAddr, MLX90640_STATUS_REG, 1, &statusRegister); + if(error != MLX90640_NO_ERROR) + { + return error; + } + //dataReady = statusRegister & 0x0008; + dataReady = MLX90640_GET_DATA_READY(statusRegister); + } + + error = MLX90640_I2CWrite(slaveAddr, MLX90640_STATUS_REG, MLX90640_INIT_STATUS_VALUE); + if(error == -MLX90640_I2C_NACK_ERROR) + { + return error; + } + + error = MLX90640_I2CRead(slaveAddr, MLX90640_PIXEL_DATA_START_ADDRESS, MLX90640_PIXEL_NUM, frameData); + if(error != MLX90640_NO_ERROR) + { + return error; + } + + error = MLX90640_I2CRead(slaveAddr, MLX90640_AUX_DATA_START_ADDRESS, MLX90640_AUX_NUM, data); + if(error != MLX90640_NO_ERROR) + { + return error; + } + + error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); + frameData[832] = controlRegister1; + //frameData[833] = statusRegister & 0x0001; + frameData[833] = MLX90640_GET_FRAME(statusRegister); + + if(error != MLX90640_NO_ERROR) + { + return error; + } + + error = ValidateAuxData(data); + if(error == MLX90640_NO_ERROR) + { + for(cnt=0; cnt> MLX90640_CTRL_RESOLUTION_SHIFT; + + return resolutionRAM; +} + +//------------------------------------------------------------------------------ + +int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate) +{ + uint16_t controlRegister1; + uint16_t value; + int error; + + //value = (refreshRate & 0x07)<<7; + value = ((uint16_t)refreshRate << MLX90640_CTRL_REFRESH_SHIFT); + value &= ~MLX90640_CTRL_REFRESH_MASK; + + error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); + if(error == MLX90640_NO_ERROR) + { + value = (controlRegister1 & MLX90640_CTRL_REFRESH_MASK) | value; + error = MLX90640_I2CWrite(slaveAddr, MLX90640_CTRL_REG, value); + } + + return error; +} + +//------------------------------------------------------------------------------ + +int MLX90640_GetRefreshRate(uint8_t slaveAddr) +{ + uint16_t controlRegister1; + int refreshRate; + int error; + + error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); + if(error != MLX90640_NO_ERROR) + { + return error; + } + refreshRate = (controlRegister1 & ~MLX90640_CTRL_REFRESH_MASK) >> MLX90640_CTRL_REFRESH_SHIFT; + + return refreshRate; +} + +//------------------------------------------------------------------------------ + +int MLX90640_SetInterleavedMode(uint8_t slaveAddr) +{ + uint16_t controlRegister1; + uint16_t value; + int error; + + error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); + + if(error == 0) + { + value = (controlRegister1 & ~MLX90640_CTRL_MEAS_MODE_MASK); + error = MLX90640_I2CWrite(slaveAddr, MLX90640_CTRL_REG, value); + } + + return error; +} + +//------------------------------------------------------------------------------ + +int MLX90640_SetChessMode(uint8_t slaveAddr) +{ + uint16_t controlRegister1; + uint16_t value; + int error; + + error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); + + if(error == 0) + { + value = (controlRegister1 | MLX90640_CTRL_MEAS_MODE_MASK); + error = MLX90640_I2CWrite(slaveAddr, MLX90640_CTRL_REG, value); + } + + return error; +} + +//------------------------------------------------------------------------------ + +int MLX90640_GetCurMode(uint8_t slaveAddr) +{ + uint16_t controlRegister1; + int modeRAM; + int error; + + error = MLX90640_I2CRead(slaveAddr, MLX90640_CTRL_REG, 1, &controlRegister1); + if(error != 0) + { + return error; + } + modeRAM = (controlRegister1 & MLX90640_CTRL_MEAS_MODE_MASK) >> MLX90640_CTRL_MEAS_MODE_SHIFT; + + return modeRAM; +} + +//------------------------------------------------------------------------------ + +void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result) +{ + float vdd; + float ta; + float ta4; + float tr4; + float taTr; + float gain; + float irDataCP[2]; + float irData; + float alphaCompensated; + uint8_t mode; + int8_t ilPattern; + int8_t chessPattern; + int8_t pattern; + int8_t conversionPattern; + float Sx; + float To; + float alphaCorrR[4]; + int8_t range; + uint16_t subPage; + float ktaScale; + float kvScale; + float alphaScale; + float kta; + float kv; + + subPage = frameData[833]; + vdd = MLX90640_GetVdd(frameData, params); + ta = MLX90640_GetTa(frameData, params); + + ta4 = (ta + 273.15); + ta4 = ta4 * ta4; + ta4 = ta4 * ta4; + tr4 = (tr + 273.15); + tr4 = tr4 * tr4; + tr4 = tr4 * tr4; + taTr = tr4 - (tr4-ta4)/emissivity; + + ktaScale = POW2(params->ktaScale); + kvScale = POW2(params->kvScale); + alphaScale = POW2(params->alphaScale); + + alphaCorrR[0] = 1 / (1 + params->ksTo[0] * 40); + alphaCorrR[1] = 1 ; + alphaCorrR[2] = (1 + params->ksTo[1] * params->ct[2]); + alphaCorrR[3] = alphaCorrR[2] * (1 + params->ksTo[2] * (params->ct[3] - params->ct[2])); + +//------------------------- Gain calculation ----------------------------------- + + gain = (float)params->gainEE / (int16_t)frameData[778]; + +//------------------------- To calculation ------------------------------------- + mode = (frameData[832] & MLX90640_CTRL_MEAS_MODE_MASK) >> 5; + + irDataCP[0] = (int16_t)frameData[776] * gain; + irDataCP[1] = (int16_t)frameData[808] * gain; + + irDataCP[0] = irDataCP[0] - params->cpOffset[0] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); + if( mode == params->calibrationModeEE) + { + irDataCP[1] = irDataCP[1] - params->cpOffset[1] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); + } + else + { + irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); + } + + for( int pixelNumber = 0; pixelNumber < 768; pixelNumber++) + { + ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2; + chessPattern = ilPattern ^ (pixelNumber - (pixelNumber/2)*2); + conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 + (pixelNumber + 1) / 4 - pixelNumber / 4) * (1 - 2 * ilPattern); + + if(mode == 0) + { + pattern = ilPattern; + } + else + { + pattern = chessPattern; + } + + if(pattern == frameData[833]) + { + irData = (int16_t)frameData[pixelNumber] * gain; + + kta = params->kta[pixelNumber]/ktaScale; + kv = params->kv[pixelNumber]/kvScale; + irData = irData - params->offset[pixelNumber]*(1 + kta*(ta - 25))*(1 + kv*(vdd - 3.3)); + + if(mode != params->calibrationModeEE) + { + irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) - params->ilChessC[1] * conversionPattern; + } + + irData = irData - params->tgc * irDataCP[subPage]; + irData = irData / emissivity; + + alphaCompensated = SCALEALPHA*alphaScale/params->alpha[pixelNumber]; + alphaCompensated = alphaCompensated*(1 + params->KsTa * (ta - 25)); + + Sx = alphaCompensated * alphaCompensated * alphaCompensated * (irData + alphaCompensated * taTr); + Sx = sqrt(sqrt(Sx)) * params->ksTo[1]; + + To = sqrt(sqrt(irData/(alphaCompensated * (1 - params->ksTo[1] * 273.15) + Sx) + taTr)) - 273.15; + + if(To < params->ct[1]) + { + range = 0; + } + else if(To < params->ct[2]) + { + range = 1; + } + else if(To < params->ct[3]) + { + range = 2; + } + else + { + range = 3; + } + + To = sqrt(sqrt(irData / (alphaCompensated * alphaCorrR[range] * (1 + params->ksTo[range] * (To - params->ct[range]))) + taTr)) - 273.15; + + result[pixelNumber] = To; + } + } +} + +//------------------------------------------------------------------------------ + +void MLX90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params, float *result) +{ + float vdd; + float ta; + float gain; + float irDataCP[2]; + float irData; + float alphaCompensated; + uint8_t mode; + int8_t ilPattern; + int8_t chessPattern; + int8_t pattern; + int8_t conversionPattern; + float image; + uint16_t subPage; + float ktaScale; + float kvScale; + float kta; + float kv; + + subPage = frameData[833]; + vdd = MLX90640_GetVdd(frameData, params); + ta = MLX90640_GetTa(frameData, params); + + ktaScale = POW2(params->ktaScale); + kvScale = POW2(params->kvScale); + +//------------------------- Gain calculation ----------------------------------- + + gain = (float)params->gainEE / (int16_t)frameData[778]; + +//------------------------- Image calculation ------------------------------------- + + mode = (frameData[832] & MLX90640_CTRL_MEAS_MODE_MASK) >> 5; + + irDataCP[0] = (int16_t)frameData[776] * gain; + irDataCP[1] = (int16_t)frameData[808] * gain; + + irDataCP[0] = irDataCP[0] - params->cpOffset[0] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); + if( mode == params->calibrationModeEE) + { + irDataCP[1] = irDataCP[1] - params->cpOffset[1] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); + } + else + { + irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); + } + + for( int pixelNumber = 0; pixelNumber < 768; pixelNumber++) + { + ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2; + chessPattern = ilPattern ^ (pixelNumber - (pixelNumber/2)*2); + conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 + (pixelNumber + 1) / 4 - pixelNumber / 4) * (1 - 2 * ilPattern); + + if(mode == 0) + { + pattern = ilPattern; + } + else + { + pattern = chessPattern; + } + + if(pattern == frameData[833]) + { + irData = (int16_t)frameData[pixelNumber] * gain; + + kta = params->kta[pixelNumber]/ktaScale; + kv = params->kv[pixelNumber]/kvScale; + irData = irData - params->offset[pixelNumber]*(1 + kta*(ta - 25))*(1 + kv*(vdd - 3.3)); + + if(mode != params->calibrationModeEE) + { + irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) - params->ilChessC[1] * conversionPattern; + } + + irData = irData - params->tgc * irDataCP[subPage]; + + alphaCompensated = params->alpha[pixelNumber]; + + image = irData*alphaCompensated; + + result[pixelNumber] = image; + } + } +} + +//------------------------------------------------------------------------------ + +float MLX90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params) +{ + float vdd; + float resolutionCorrection; + + uint16_t resolutionRAM; + + resolutionRAM = (frameData[832] & ~MLX90640_CTRL_RESOLUTION_MASK) >> MLX90640_CTRL_RESOLUTION_SHIFT; + resolutionCorrection = POW2(params->resolutionEE) / POW2(resolutionRAM); + vdd = (resolutionCorrection * (int16_t)frameData[810] - params->vdd25) / params->kVdd + 3.3; + + return vdd; +} + +//------------------------------------------------------------------------------ + +float MLX90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params) +{ + int16_t ptat; + float ptatArt; + float vdd; + float ta; + + vdd = MLX90640_GetVdd(frameData, params); + + ptat = (int16_t)frameData[800]; + + ptatArt = (ptat / (ptat * params->alphaPTAT + (int16_t)frameData[768])) * POW2(18); + + ta = (ptatArt / (1 + params->KvPTAT * (vdd - 3.3)) - params->vPTAT25); + ta = ta / params->KtPTAT + 25; + + return ta; +} + +//------------------------------------------------------------------------------ + +int MLX90640_GetSubPageNumber(uint16_t *frameData) +{ + return frameData[833]; + +} + +//------------------------------------------------------------------------------ +void MLX90640_BadPixelsCorrection(uint16_t *pixels, float *to, int mode, paramsMLX90640 *params) +{ + float ap[4]; + uint8_t pix; + uint8_t line; + uint8_t column; + + pix = 0; + while(pixels[pix] != 0xFFFF) + { + line = pixels[pix]>>5; + column = pixels[pix] - (line<<5); + + if(mode == 1) + { + if(line == 0) + { + if(column == 0) + { + to[pixels[pix]] = to[33]; + } + else if(column == 31) + { + to[pixels[pix]] = to[62]; + } + else + { + to[pixels[pix]] = (to[pixels[pix]+31] + to[pixels[pix]+33])/2.0; + } + } + else if(line == 23) + { + if(column == 0) + { + to[pixels[pix]] = to[705]; + } + else if(column == 31) + { + to[pixels[pix]] = to[734]; + } + else + { + to[pixels[pix]] = (to[pixels[pix]-33] + to[pixels[pix]-31])/2.0; + } + } + else if(column == 0) + { + to[pixels[pix]] = (to[pixels[pix]-31] + to[pixels[pix]+33])/2.0; + } + else if(column == 31) + { + to[pixels[pix]] = (to[pixels[pix]-33] + to[pixels[pix]+31])/2.0; + } + else + { + ap[0] = to[pixels[pix]-33]; + ap[1] = to[pixels[pix]-31]; + ap[2] = to[pixels[pix]+31]; + ap[3] = to[pixels[pix]+33]; + to[pixels[pix]] = GetMedian(ap,4); + } + } + else + { + if(column == 0) + { + to[pixels[pix]] = to[pixels[pix]+1]; + } + else if(column == 1 || column == 30) + { + to[pixels[pix]] = (to[pixels[pix]-1]+to[pixels[pix]+1])/2.0; + } + else if(column == 31) + { + to[pixels[pix]] = to[pixels[pix]-1]; + } + else + { + if(IsPixelBad(pixels[pix]-2,params) == 0 && IsPixelBad(pixels[pix]+2,params) == 0) + { + ap[0] = to[pixels[pix]+1] - to[pixels[pix]+2]; + ap[1] = to[pixels[pix]-1] - to[pixels[pix]-2]; + if(fabs(ap[0]) > fabs(ap[1])) + { + to[pixels[pix]] = to[pixels[pix]-1] + ap[1]; + } + else + { + to[pixels[pix]] = to[pixels[pix]+1] + ap[0]; + } + } + else + { + to[pixels[pix]] = (to[pixels[pix]-1]+to[pixels[pix]+1])/2.0; + } + } + } + pix = pix + 1; + } +} + +//------------------------------------------------------------------------------ + +static void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + int8_t kVdd; + int16_t vdd25; + + kVdd = MLX90640_MS_BYTE(eeData[51]); + + vdd25 = MLX90640_LS_BYTE(eeData[51]); + vdd25 = ((vdd25 - 256) << 5) - 8192; + + mlx90640->kVdd = 32 * kVdd; + mlx90640->vdd25 = vdd25; +} + +//------------------------------------------------------------------------------ + +static void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + float KvPTAT; + float KtPTAT; + int16_t vPTAT25; + float alphaPTAT; + + KvPTAT = (eeData[50] & MLX90640_MSBITS_6_MASK) >> 10; + if(KvPTAT > 31) + { + KvPTAT = KvPTAT - 64; + } + KvPTAT = KvPTAT/4096; + + KtPTAT = eeData[50] & MLX90640_LSBITS_10_MASK; + if(KtPTAT > 511) + { + KtPTAT = KtPTAT - 1024; + } + KtPTAT = KtPTAT/8; + + vPTAT25 = eeData[49]; + + alphaPTAT = (eeData[16] & MLX90640_NIBBLE4_MASK) / POW2(14) + 8.0f; + + mlx90640->KvPTAT = KvPTAT; + mlx90640->KtPTAT = KtPTAT; + mlx90640->vPTAT25 = vPTAT25; + mlx90640->alphaPTAT = alphaPTAT; +} + +//------------------------------------------------------------------------------ + +static void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + mlx90640->gainEE = (int16_t)eeData[48];; +} + +//------------------------------------------------------------------------------ + +static void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + mlx90640->tgc = (int8_t)MLX90640_LS_BYTE(eeData[60]) / 32.0f; +} + +//------------------------------------------------------------------------------ + +static void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + uint8_t resolutionEE; + resolutionEE = (eeData[56] & 0x3000) >> 12; + + mlx90640->resolutionEE = resolutionEE; +} + +//------------------------------------------------------------------------------ + +static void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + mlx90640->KsTa = (int8_t)MLX90640_MS_BYTE(eeData[60]) / 8192.0f; +} + +//------------------------------------------------------------------------------ + +static void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + int32_t KsToScale; + int8_t step; + + step = ((eeData[63] & 0x3000) >> 12) * 10; + + mlx90640->ct[0] = -40; + mlx90640->ct[1] = 0; + mlx90640->ct[2] = MLX90640_NIBBLE2(eeData[63]); + mlx90640->ct[3] = MLX90640_NIBBLE3(eeData[63]); + + mlx90640->ct[2] = mlx90640->ct[2]*step; + mlx90640->ct[3] = mlx90640->ct[2] + mlx90640->ct[3]*step; + mlx90640->ct[4] = 400; + + KsToScale = MLX90640_NIBBLE1(eeData[63]) + 8; + KsToScale = 1UL << KsToScale; + + mlx90640->ksTo[0] = (int8_t)MLX90640_LS_BYTE(eeData[61]) / (float)KsToScale; + mlx90640->ksTo[1] = (int8_t)MLX90640_MS_BYTE(eeData[61]) / (float)KsToScale; + mlx90640->ksTo[2] = (int8_t)MLX90640_LS_BYTE(eeData[62]) / (float)KsToScale; + mlx90640->ksTo[3] = (int8_t)MLX90640_MS_BYTE(eeData[62]) / (float)KsToScale; + mlx90640->ksTo[4] = -0.0002; +} + +//------------------------------------------------------------------------------ + +static void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + int accRow[24]; + int accColumn[32]; + int p = 0; + int alphaRef; + uint8_t alphaScale; + uint8_t accRowScale; + uint8_t accColumnScale; + uint8_t accRemScale; + float alphaTemp[768]; + float temp; + + + accRemScale = MLX90640_NIBBLE1(eeData[32]); + accColumnScale = MLX90640_NIBBLE2(eeData[32]); + accRowScale = MLX90640_NIBBLE3(eeData[32]); + alphaScale = MLX90640_NIBBLE4(eeData[32]) + 30; + alphaRef = eeData[33]; + + for(int i = 0; i < 6; i++) + { + p = i * 4; + accRow[p + 0] = MLX90640_NIBBLE1(eeData[34 + i]); + accRow[p + 1] = MLX90640_NIBBLE2(eeData[34 + i]); + accRow[p + 2] = MLX90640_NIBBLE3(eeData[34 + i]); + accRow[p + 3] = MLX90640_NIBBLE4(eeData[34 + i]); + } + + for(int i = 0; i < MLX90640_LINE_NUM; i++) + { + if (accRow[i] > 7) + { + accRow[i] = accRow[i] - 16; + } + } + + for(int i = 0; i < 8; i++) + { + p = i * 4; + accColumn[p + 0] = MLX90640_NIBBLE1(eeData[40 + i]); + accColumn[p + 1] = MLX90640_NIBBLE2(eeData[40 + i]); + accColumn[p + 2] = MLX90640_NIBBLE3(eeData[40 + i]); + accColumn[p + 3] = MLX90640_NIBBLE4(eeData[40 + i]); + } + + for(int i = 0; i < MLX90640_COLUMN_NUM; i++) + { + if (accColumn[i] > 7) + { + accColumn[i] = accColumn[i] - 16; + } + } + + for(int i = 0; i < MLX90640_LINE_NUM; i++) + { + for(int j = 0; j < MLX90640_COLUMN_NUM; j ++) + { + p = 32 * i +j; + alphaTemp[p] = (eeData[64 + p] & 0x03F0) >> 4; + if (alphaTemp[p] > 31) + { + alphaTemp[p] = alphaTemp[p] - 64; + } + alphaTemp[p] = alphaTemp[p]*(1 << accRemScale); + alphaTemp[p] = (alphaRef + (accRow[i] << accRowScale) + (accColumn[j] << accColumnScale) + alphaTemp[p]); + alphaTemp[p] = alphaTemp[p] / POW2(alphaScale); + alphaTemp[p] = alphaTemp[p] - mlx90640->tgc * (mlx90640->cpAlpha[0] + mlx90640->cpAlpha[1])/2; + alphaTemp[p] = SCALEALPHA/alphaTemp[p]; + } + } + + temp = alphaTemp[0]; + for(int i = 1; i < MLX90640_PIXEL_NUM; i++) + { + if (alphaTemp[i] > temp) + { + temp = alphaTemp[i]; + } + } + + alphaScale = 0; + while(temp < 32767.4) + { + temp = temp*2; + alphaScale = alphaScale + 1; + } + + for(int i = 0; i < MLX90640_PIXEL_NUM; i++) + { + temp = alphaTemp[i] * POW2(alphaScale); + mlx90640->alpha[i] = (temp + 0.5); + + } + + mlx90640->alphaScale = alphaScale; + +} + +//------------------------------------------------------------------------------ + +static void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + int occRow[24]; + int occColumn[32]; + int p = 0; + int16_t offsetRef; + uint8_t occRowScale; + uint8_t occColumnScale; + uint8_t occRemScale; + + + occRemScale = MLX90640_NIBBLE1(eeData[16]); + occColumnScale = MLX90640_NIBBLE2(eeData[16]); + occRowScale = MLX90640_NIBBLE3(eeData[16]); + offsetRef = (int16_t)eeData[17]; + + for(int i = 0; i < 6; i++) + { + p = i * 4; + occRow[p + 0] = MLX90640_NIBBLE1(eeData[18 + i]); + occRow[p + 1] = MLX90640_NIBBLE2(eeData[18 + i]); + occRow[p + 2] = MLX90640_NIBBLE3(eeData[18 + i]); + occRow[p + 3] = MLX90640_NIBBLE4(eeData[18 + i]); + } + + for(int i = 0; i < MLX90640_LINE_NUM; i++) + { + if (occRow[i] > 7) + { + occRow[i] = occRow[i] - 16; + } + } + + for(int i = 0; i < 8; i++) + { + p = i * 4; + occColumn[p + 0] = MLX90640_NIBBLE1(eeData[24 + i]); + occColumn[p + 1] = MLX90640_NIBBLE2(eeData[24 + i]); + occColumn[p + 2] = MLX90640_NIBBLE3(eeData[24 + i]); + occColumn[p + 3] = MLX90640_NIBBLE4(eeData[24 + i]); + } + + for(int i = 0; i < MLX90640_COLUMN_NUM; i ++) + { + if (occColumn[i] > 7) + { + occColumn[i] = occColumn[i] - 16; + } + } + + for(int i = 0; i < MLX90640_LINE_NUM; i++) + { + for(int j = 0; j < MLX90640_COLUMN_NUM; j ++) + { + p = 32 * i +j; + mlx90640->offset[p] = (eeData[64 + p] & MLX90640_MSBITS_6_MASK) >> 10; + if (mlx90640->offset[p] > 31) + { + mlx90640->offset[p] = mlx90640->offset[p] - 64; + } + mlx90640->offset[p] = mlx90640->offset[p]*(1 << occRemScale); + mlx90640->offset[p] = (offsetRef + (occRow[i] << occRowScale) + (occColumn[j] << occColumnScale) + mlx90640->offset[p]); + } + } +} + +//------------------------------------------------------------------------------ + +static void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + int p = 0; + int8_t KtaRC[4]; + uint8_t ktaScale1; + uint8_t ktaScale2; + uint8_t split; + float ktaTemp[768]; + float temp; + + KtaRC[0] = (int8_t)MLX90640_MS_BYTE(eeData[54]);; + KtaRC[2] = (int8_t)MLX90640_LS_BYTE(eeData[54]);; + KtaRC[1] = (int8_t)MLX90640_MS_BYTE(eeData[55]);; + KtaRC[3] = (int8_t)MLX90640_LS_BYTE(eeData[55]);; + + ktaScale1 = MLX90640_NIBBLE2(eeData[56]) + 8; + ktaScale2 = MLX90640_NIBBLE1(eeData[56]); + + for(int i = 0; i < MLX90640_LINE_NUM; i++) + { + for(int j = 0; j < MLX90640_COLUMN_NUM; j ++) + { + p = 32 * i +j; + split = 2*(p/32 - (p/64)*2) + p%2; + ktaTemp[p] = (eeData[64 + p] & 0x000E) >> 1; + if (ktaTemp[p] > 3) + { + ktaTemp[p] = ktaTemp[p] - 8; + } + ktaTemp[p] = ktaTemp[p] * (1 << ktaScale2); + ktaTemp[p] = KtaRC[split] + ktaTemp[p]; + ktaTemp[p] = ktaTemp[p] / POW2(ktaScale1); + + } + } + + temp = fabs(ktaTemp[0]); + for(int i = 1; i < MLX90640_PIXEL_NUM; i++) + { + if (fabs(ktaTemp[i]) > temp) + { + temp = fabs(ktaTemp[i]); + } + } + + ktaScale1 = 0; + while(temp < 63.4) + { + temp = temp*2; + ktaScale1 = ktaScale1 + 1; + } + + for(int i = 0; i < MLX90640_PIXEL_NUM; i++) + { + temp = ktaTemp[i] * POW2(ktaScale1); + if (temp < 0) + { + mlx90640->kta[i] = (temp - 0.5); + } + else + { + mlx90640->kta[i] = (temp + 0.5); + } + + } + + mlx90640->ktaScale = ktaScale1; +} + + +//------------------------------------------------------------------------------ + +static void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + int p = 0; + int8_t KvT[4]; + int8_t KvRoCo; + int8_t KvRoCe; + int8_t KvReCo; + int8_t KvReCe; + uint8_t kvScale; + uint8_t split; + float kvTemp[768]; + float temp; + + KvRoCo = MLX90640_NIBBLE4(eeData[52]); + if (KvRoCo > 7) + { + KvRoCo = KvRoCo - 16; + } + KvT[0] = KvRoCo; + + KvReCo = MLX90640_NIBBLE3(eeData[52]); + if (KvReCo > 7) + { + KvReCo = KvReCo - 16; + } + KvT[2] = KvReCo; + + KvRoCe = MLX90640_NIBBLE2(eeData[52]); + if (KvRoCe > 7) + { + KvRoCe = KvRoCe - 16; + } + KvT[1] = KvRoCe; + + KvReCe = MLX90640_NIBBLE1(eeData[52]); + if (KvReCe > 7) + { + KvReCe = KvReCe - 16; + } + KvT[3] = KvReCe; + + kvScale = MLX90640_NIBBLE3(eeData[56]); + + + for(int i = 0; i < MLX90640_LINE_NUM; i++) + { + for(int j = 0; j < MLX90640_COLUMN_NUM; j ++) + { + p = 32 * i +j; + split = 2*(p/32 - (p/64)*2) + p%2; + kvTemp[p] = KvT[split]; + kvTemp[p] = kvTemp[p] / POW2(kvScale); + } + } + + temp = fabs(kvTemp[0]); + for(int i = 1; i < MLX90640_PIXEL_NUM; i++) + { + if (fabs(kvTemp[i]) > temp) + { + temp = fabs(kvTemp[i]); + } + } + + kvScale = 0; + while(temp < 63.4) + { + temp = temp*2; + kvScale = kvScale + 1; + } + + for(int i = 0; i < MLX90640_PIXEL_NUM; i++) + { + temp = kvTemp[i] * POW2(kvScale); + if (temp < 0) + { + mlx90640->kv[i] = (temp - 0.5); + } + else + { + mlx90640->kv[i] = (temp + 0.5); + } + + } + + mlx90640->kvScale = kvScale; +} + +//------------------------------------------------------------------------------ + +static void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + float alphaSP[2]; + int16_t offsetSP[2]; + float cpKv; + float cpKta; + uint8_t alphaScale; + uint8_t ktaScale1; + uint8_t kvScale; + + alphaScale = MLX90640_NIBBLE4(eeData[32]) + 27; + + offsetSP[0] = (eeData[58] & MLX90640_LSBITS_10_MASK); + if (offsetSP[0] > 511) + { + offsetSP[0] = offsetSP[0] - 1024; + } + + offsetSP[1] = (eeData[58] & MLX90640_MSBITS_6_MASK) >> 10; + if (offsetSP[1] > 31) + { + offsetSP[1] = offsetSP[1] - 64; + } + offsetSP[1] = offsetSP[1] + offsetSP[0]; + + alphaSP[0] = (eeData[57] & MLX90640_LSBITS_10_MASK); + if (alphaSP[0] > 511) + { + alphaSP[0] = alphaSP[0] - 1024; + } + alphaSP[0] = alphaSP[0] / POW2(alphaScale); + + alphaSP[1] = (eeData[57] & MLX90640_MSBITS_6_MASK) >> 10; + if (alphaSP[1] > 31) + { + alphaSP[1] = alphaSP[1] - 64; + } + alphaSP[1] = (1 + alphaSP[1]/128) * alphaSP[0]; + + cpKta = (int8_t)MLX90640_LS_BYTE(eeData[59]); + + ktaScale1 = MLX90640_NIBBLE2(eeData[56]) + 8; + mlx90640->cpKta = cpKta / POW2(ktaScale1); + + cpKv = (int8_t)MLX90640_MS_BYTE(eeData[59]); + + kvScale = MLX90640_NIBBLE3(eeData[56]); + mlx90640->cpKv = cpKv / POW2(kvScale); + + mlx90640->cpAlpha[0] = alphaSP[0]; + mlx90640->cpAlpha[1] = alphaSP[1]; + mlx90640->cpOffset[0] = offsetSP[0]; + mlx90640->cpOffset[1] = offsetSP[1]; +} + +//------------------------------------------------------------------------------ + +static void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + float ilChessC[3]; + uint8_t calibrationModeEE; + + calibrationModeEE = (eeData[10] & 0x0800) >> 4; + calibrationModeEE = calibrationModeEE ^ 0x80; + + ilChessC[0] = (eeData[53] & 0x003F); + if (ilChessC[0] > 31) + { + ilChessC[0] = ilChessC[0] - 64; + } + ilChessC[0] = ilChessC[0] / 16.0f; + + ilChessC[1] = (eeData[53] & 0x07C0) >> 6; + if (ilChessC[1] > 15) + { + ilChessC[1] = ilChessC[1] - 32; + } + ilChessC[1] = ilChessC[1] / 2.0f; + + ilChessC[2] = (eeData[53] & 0xF800) >> 11; + if (ilChessC[2] > 15) + { + ilChessC[2] = ilChessC[2] - 32; + } + ilChessC[2] = ilChessC[2] / 8.0f; + + mlx90640->calibrationModeEE = calibrationModeEE; + mlx90640->ilChessC[0] = ilChessC[0]; + mlx90640->ilChessC[1] = ilChessC[1]; + mlx90640->ilChessC[2] = ilChessC[2]; +} + +//------------------------------------------------------------------------------ + +static int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640) +{ + uint16_t pixCnt = 0; + uint16_t brokenPixCnt = 0; + uint16_t outlierPixCnt = 0; + int warn = 0; + int i; + + for(pixCnt = 0; pixCnt<5; pixCnt++) + { + mlx90640->brokenPixels[pixCnt] = 0xFFFF; + mlx90640->outlierPixels[pixCnt] = 0xFFFF; + } + + pixCnt = 0; + while (pixCnt < MLX90640_PIXEL_NUM && brokenPixCnt < 5 && outlierPixCnt < 5) + { + if(eeData[pixCnt+64] == 0) + { + mlx90640->brokenPixels[brokenPixCnt] = pixCnt; + brokenPixCnt = brokenPixCnt + 1; + } + else if((eeData[pixCnt+64] & 0x0001) != 0) + { + mlx90640->outlierPixels[outlierPixCnt] = pixCnt; + outlierPixCnt = outlierPixCnt + 1; + } + + pixCnt = pixCnt + 1; + + } + + if(brokenPixCnt > 4) + { + warn = -MLX90640_BROKEN_PIXELS_NUM_ERROR; + } + else if(outlierPixCnt > 4) + { + warn = -MLX90640_OUTLIER_PIXELS_NUM_ERROR; + } + else if((brokenPixCnt + outlierPixCnt) > 4) + { + warn = -MLX90640_BAD_PIXELS_NUM_ERROR; + } + else + { + for(pixCnt=0; pixCntbrokenPixels[pixCnt],mlx90640->brokenPixels[i]); + if(warn != 0) + { + return warn; + } + } + } + + for(pixCnt=0; pixCntoutlierPixels[pixCnt],mlx90640->outlierPixels[i]); + if(warn != 0) + { + return warn; + } + } + } + + for(pixCnt=0; pixCntbrokenPixels[pixCnt],mlx90640->outlierPixels[i]); + if(warn != 0) + { + return warn; + } + } + } + + } + + + return warn; + +} + +//------------------------------------------------------------------------------ + + static int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2) + { + + int pixPosDif; + uint16_t lp1 = pix1 >> 5; + uint16_t lp2 = pix2 >> 5; + uint16_t cp1 = pix1 - (lp1 << 5); + uint16_t cp2 = pix2 - (lp2 << 5); + + pixPosDif = lp1 - lp2; + if(pixPosDif > -2 && pixPosDif < 2) + { + pixPosDif = cp1 - cp2; + if(pixPosDif > -2 && pixPosDif < 2) + { + return -6; + } + + } + + return 0; + } + +//------------------------------------------------------------------------------ + +static float GetMedian(float *values, int n) + { + float temp; + + for(int i=0; ioutlierPixels[i] || pixel == params->brokenPixels[i]) + { + return 1; + } + } + + return 0; +} + +//------------------------------------------------------------------------------ diff --git a/rss/include/acc_base_configuration.h b/rss/include/acc_base_configuration.h index cdfb712..14209e9 100644 --- a/rss/include/acc_base_configuration.h +++ b/rss/include/acc_base_configuration.h @@ -1,228 +1,228 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_BASE_CONFIGURATION_H_ -#define ACC_BASE_CONFIGURATION_H_ - -#include -#include - -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" - - -/** - * @defgroup Base Service Base Configuration - * - * @brief Service base configuration API description - * - * @{ - */ - - -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_OFF ACC_POWER_SAVE_MODE_OFF -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_SLEEP ACC_POWER_SAVE_MODE_SLEEP -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_READY ACC_POWER_SAVE_MODE_READY -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_ACTIVE ACC_POWER_SAVE_MODE_ACTIVE -#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_HIBERNATE ACC_POWER_SAVE_MODE_HIBERNATE - - -/** - * @brief Power save mode data type, see @ref acc_power_save_mode_enum_t - */ -typedef acc_power_save_mode_t acc_base_configuration_power_save_mode_t; - - -/** - * @brief Service base configuration container - */ -struct acc_base_configuration; - -typedef struct acc_base_configuration *acc_base_configuration_t; - - -/** - * @brief Get the sensor ID for the sensor to be configured - * - * @param[in] configuration The base configuration to get the sensor id from - * @return Sensor Id - */ -acc_sensor_id_t acc_base_configuration_sensor_get(acc_base_configuration_t configuration); - - -/** - * @brief Set the sensor ID for the sensor to be configured - * - * @param[in] configuration The base configuration to set the sensor id in - * @param[in] sensor_id The sensor id to set - */ -void acc_base_configuration_sensor_set(acc_base_configuration_t configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get the requested start of the sweep - * - * @param[in] configuration The base configuration to get the requested start from - * @return Requested start - */ -float acc_base_configuration_requested_start_get(acc_base_configuration_t configuration); - - -/** - * @brief Set the requested start of the sweep - * - * @param[in] configuration The base configuration to set the requested start in - * @param[in] start_m The requested start in meters - */ -void acc_base_configuration_requested_start_set(acc_base_configuration_t configuration, float start_m); - - -/** - * @brief Get the requested length of the sweep - * - * @param[in] configuration The base configuration to get the requested length from - * @return Requested length - */ -float acc_base_configuration_requested_length_get(acc_base_configuration_t configuration); - - -/** - * @brief Set the requested length of the sweep - * - * @param[in] configuration The base configuration to set the requested length in - * @param[in] length_m The requested length in meters - */ -void acc_base_configuration_requested_length_set(acc_base_configuration_t configuration, float length_m); - - -/** - * @brief Set the service repetition mode to on demand - * - * In on demand mode, the sensor produces data when requested by the application. - * The application is also responsible for the timing between updates. - * - * This mode must be used if the configured length requires stitching in the service. - * - * @param[in] configuration The base configuration to set on demand mode in - */ -void acc_base_configuration_repetition_mode_on_demand_set(acc_base_configuration_t configuration); - - -/** - * @brief Set the service repetition mode to streaming mode - * - * The sensor produces data according to the configured update rate using sensor - * hardware timing which is very accurate. - * - * @param[in] configuration The base configuration to set streaming mode in - * @param[in] update_rate The output data rate from the service in hertz - */ -void acc_base_configuration_repetition_mode_streaming_set(acc_base_configuration_t configuration, float update_rate); - - -/** - * @brief Get power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data frame aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] configuration The base configuration to get power save mode for - * @return Power save mode - */ -acc_power_save_mode_t acc_base_configuration_power_save_mode_get(acc_base_configuration_t configuration); - - -/** - * @brief Set power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data frame aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] configuration The base configuration to set power save mode in - * @param[in] power_save_mode The power save mode to use - */ -void acc_base_configuration_power_save_mode_set(acc_base_configuration_t configuration, - acc_power_save_mode_t power_save_mode); - - -/** - * @brief Get receiver gain setting - * - * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] configuration The base configuration to get receiver gain setting for - * @return Receiver gain setting - */ -float acc_base_configuration_receiver_gain_get(acc_base_configuration_t configuration); - - -/** - * @brief Set receiver gain setting - * - * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] configuration The base configuration to set receiver gain setting in - * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 - */ -void acc_base_configuration_receiver_gain_set(acc_base_configuration_t configuration, float gain); - - -/** - * @brief Get TX disable mode - * - * Will be true if TX is disabled, false otherwise. - * - * @param[in] configuration The base configuration to set TX disable mode in - * @return TX disable mode - */ -bool acc_base_configuration_tx_disable_get(acc_base_configuration_t configuration); - - -/** - * @brief Set TX disable mode - * - * If set to true, TX disable mode is enabled. This will disable the radio transmitter. - * To measure RX noise floor, it is recommended to also switch off internal - * noise level normalization (see each service if applicable). - * - * @param[in] configuration The base configuration to set TX disable mode in - * @param[in] tx_disable TX disable mode, true or false - */ -void acc_base_configuration_tx_disable_set(acc_base_configuration_t configuration, bool tx_disable); - - -/** - * @brief Get the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The base configuration to get hardware accelerated average samples from - * @return Hardware accelerated average samples - */ -uint8_t acc_base_configuration_hw_accelerated_average_samples_get(acc_base_configuration_t configuration); - - -/** - * @brief Set the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The base configuration to set hardware accelerated average samples in - * @param[in] samples Hardware accelerated average samples - */ -void acc_base_configuration_hw_accelerated_average_samples_set(acc_base_configuration_t configuration, uint8_t samples); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_BASE_CONFIGURATION_H_ +#define ACC_BASE_CONFIGURATION_H_ + +#include +#include + +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" + + +/** + * @defgroup Base Service Base Configuration + * + * @brief Service base configuration API description + * + * @{ + */ + + +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_OFF ACC_POWER_SAVE_MODE_OFF +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_SLEEP ACC_POWER_SAVE_MODE_SLEEP +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_READY ACC_POWER_SAVE_MODE_READY +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_ACTIVE ACC_POWER_SAVE_MODE_ACTIVE +#define ACC_BASE_CONFIGURATION_POWER_SAVE_MODE_HIBERNATE ACC_POWER_SAVE_MODE_HIBERNATE + + +/** + * @brief Power save mode data type, see @ref acc_power_save_mode_enum_t + */ +typedef acc_power_save_mode_t acc_base_configuration_power_save_mode_t; + + +/** + * @brief Service base configuration container + */ +struct acc_base_configuration; + +typedef struct acc_base_configuration *acc_base_configuration_t; + + +/** + * @brief Get the sensor ID for the sensor to be configured + * + * @param[in] configuration The base configuration to get the sensor id from + * @return Sensor Id + */ +acc_sensor_id_t acc_base_configuration_sensor_get(acc_base_configuration_t configuration); + + +/** + * @brief Set the sensor ID for the sensor to be configured + * + * @param[in] configuration The base configuration to set the sensor id in + * @param[in] sensor_id The sensor id to set + */ +void acc_base_configuration_sensor_set(acc_base_configuration_t configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get the requested start of the sweep + * + * @param[in] configuration The base configuration to get the requested start from + * @return Requested start + */ +float acc_base_configuration_requested_start_get(acc_base_configuration_t configuration); + + +/** + * @brief Set the requested start of the sweep + * + * @param[in] configuration The base configuration to set the requested start in + * @param[in] start_m The requested start in meters + */ +void acc_base_configuration_requested_start_set(acc_base_configuration_t configuration, float start_m); + + +/** + * @brief Get the requested length of the sweep + * + * @param[in] configuration The base configuration to get the requested length from + * @return Requested length + */ +float acc_base_configuration_requested_length_get(acc_base_configuration_t configuration); + + +/** + * @brief Set the requested length of the sweep + * + * @param[in] configuration The base configuration to set the requested length in + * @param[in] length_m The requested length in meters + */ +void acc_base_configuration_requested_length_set(acc_base_configuration_t configuration, float length_m); + + +/** + * @brief Set the service repetition mode to on demand + * + * In on demand mode, the sensor produces data when requested by the application. + * The application is also responsible for the timing between updates. + * + * This mode must be used if the configured length requires stitching in the service. + * + * @param[in] configuration The base configuration to set on demand mode in + */ +void acc_base_configuration_repetition_mode_on_demand_set(acc_base_configuration_t configuration); + + +/** + * @brief Set the service repetition mode to streaming mode + * + * The sensor produces data according to the configured update rate using sensor + * hardware timing which is very accurate. + * + * @param[in] configuration The base configuration to set streaming mode in + * @param[in] update_rate The output data rate from the service in hertz + */ +void acc_base_configuration_repetition_mode_streaming_set(acc_base_configuration_t configuration, float update_rate); + + +/** + * @brief Get power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data frame aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] configuration The base configuration to get power save mode for + * @return Power save mode + */ +acc_power_save_mode_t acc_base_configuration_power_save_mode_get(acc_base_configuration_t configuration); + + +/** + * @brief Set power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data frame aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] configuration The base configuration to set power save mode in + * @param[in] power_save_mode The power save mode to use + */ +void acc_base_configuration_power_save_mode_set(acc_base_configuration_t configuration, + acc_power_save_mode_t power_save_mode); + + +/** + * @brief Get receiver gain setting + * + * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] configuration The base configuration to get receiver gain setting for + * @return Receiver gain setting + */ +float acc_base_configuration_receiver_gain_get(acc_base_configuration_t configuration); + + +/** + * @brief Set receiver gain setting + * + * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] configuration The base configuration to set receiver gain setting in + * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 + */ +void acc_base_configuration_receiver_gain_set(acc_base_configuration_t configuration, float gain); + + +/** + * @brief Get TX disable mode + * + * Will be true if TX is disabled, false otherwise. + * + * @param[in] configuration The base configuration to set TX disable mode in + * @return TX disable mode + */ +bool acc_base_configuration_tx_disable_get(acc_base_configuration_t configuration); + + +/** + * @brief Set TX disable mode + * + * If set to true, TX disable mode is enabled. This will disable the radio transmitter. + * To measure RX noise floor, it is recommended to also switch off internal + * noise level normalization (see each service if applicable). + * + * @param[in] configuration The base configuration to set TX disable mode in + * @param[in] tx_disable TX disable mode, true or false + */ +void acc_base_configuration_tx_disable_set(acc_base_configuration_t configuration, bool tx_disable); + + +/** + * @brief Get the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The base configuration to get hardware accelerated average samples from + * @return Hardware accelerated average samples + */ +uint8_t acc_base_configuration_hw_accelerated_average_samples_get(acc_base_configuration_t configuration); + + +/** + * @brief Set the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The base configuration to set hardware accelerated average samples in + * @param[in] samples Hardware accelerated average samples + */ +void acc_base_configuration_hw_accelerated_average_samples_set(acc_base_configuration_t configuration, uint8_t samples); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_definitions_a111.h b/rss/include/acc_definitions_a111.h index d775490..289301f 100644 --- a/rss/include/acc_definitions_a111.h +++ b/rss/include/acc_definitions_a111.h @@ -1,76 +1,76 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_DEFINITIONS_A111_H_ -#define ACC_DEFINITIONS_A111_H_ - -#include - - -/** - * @brief Power save mode - * - * Each power save mode corresponds to how much of the sensor hardware is shutdown - * between data frame aquisition. Mode 'OFF' means that the whole sensor is shutdown. - * Mode 'ACTIVE' means that the sensor is in its active state all the time. - * Mode 'HIBERNATE' means that the sensor is still powered but the internal oscillator is - * turned off and the application needs to clock the sensor by toggling a GPIO a pre-defined - * number of times to enter and exit this mode. Mode 'HIBERNATE' is currently only supported - * by the Sparse service - * - * For each power save mode there will be a limit in the achievable update rate. Mode 'OFF' - * can achieve the lowest power consumption but also has the lowest update rate limit - */ -typedef enum -{ - ACC_POWER_SAVE_MODE_OFF, - ACC_POWER_SAVE_MODE_SLEEP, - ACC_POWER_SAVE_MODE_READY, - ACC_POWER_SAVE_MODE_ACTIVE, - ACC_POWER_SAVE_MODE_HIBERNATE, -} acc_power_save_mode_enum_t; -typedef uint32_t acc_power_save_mode_t; - - -/** - * @brief Service profile - * - * Each profile consists of a number of settings for the sensor that configures - * the RX and TX paths. Profile 1 maximizes on the depth resolution and - * profile 5 maximizes on radar loop gain with a sliding scale in between. - */ -typedef enum -{ - ACC_SERVICE_PROFILE_1 = 1, - ACC_SERVICE_PROFILE_2, - ACC_SERVICE_PROFILE_3, - ACC_SERVICE_PROFILE_4, - ACC_SERVICE_PROFILE_5, -} acc_service_profile_t; - - -/** - * @brief Maximum Unambiguous Range - */ -typedef enum -{ - /** Maximum unambiguous range 11.5 m, maximum measurable distance 7.0 m, pulse repetition frequency 13.0 MHz */ - ACC_SERVICE_MUR_6 = 6, - /** Maximum unambiguous range 17.3 m, maximum measurable distance 12.7 m , pulse repetition frequency 8.7 MHz */ - ACC_SERVICE_MUR_9 = 9, - - /** Default maximum unambiguous range */ - ACC_SERVICE_MUR_DEFAULT = ACC_SERVICE_MUR_6, -} acc_service_mur_t; - - -/** - * Type used when retrieving and setting a sensor calibration context - */ -typedef struct -{ - uint8_t data[64]; -} acc_calibration_context_t; - - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_DEFINITIONS_A111_H_ +#define ACC_DEFINITIONS_A111_H_ + +#include + + +/** + * @brief Power save mode + * + * Each power save mode corresponds to how much of the sensor hardware is shutdown + * between data frame aquisition. Mode 'OFF' means that the whole sensor is shutdown. + * Mode 'ACTIVE' means that the sensor is in its active state all the time. + * Mode 'HIBERNATE' means that the sensor is still powered but the internal oscillator is + * turned off and the application needs to clock the sensor by toggling a GPIO a pre-defined + * number of times to enter and exit this mode. Mode 'HIBERNATE' is currently only supported + * by the Sparse service + * + * For each power save mode there will be a limit in the achievable update rate. Mode 'OFF' + * can achieve the lowest power consumption but also has the lowest update rate limit + */ +typedef enum +{ + ACC_POWER_SAVE_MODE_OFF, + ACC_POWER_SAVE_MODE_SLEEP, + ACC_POWER_SAVE_MODE_READY, + ACC_POWER_SAVE_MODE_ACTIVE, + ACC_POWER_SAVE_MODE_HIBERNATE, +} acc_power_save_mode_enum_t; +typedef uint32_t acc_power_save_mode_t; + + +/** + * @brief Service profile + * + * Each profile consists of a number of settings for the sensor that configures + * the RX and TX paths. Profile 1 maximizes on the depth resolution and + * profile 5 maximizes on radar loop gain with a sliding scale in between. + */ +typedef enum +{ + ACC_SERVICE_PROFILE_1 = 1, + ACC_SERVICE_PROFILE_2, + ACC_SERVICE_PROFILE_3, + ACC_SERVICE_PROFILE_4, + ACC_SERVICE_PROFILE_5, +} acc_service_profile_t; + + +/** + * @brief Maximum Unambiguous Range + */ +typedef enum +{ + /** Maximum unambiguous range 11.5 m, maximum measurable distance 7.0 m, pulse repetition frequency 13.0 MHz */ + ACC_SERVICE_MUR_6 = 6, + /** Maximum unambiguous range 17.3 m, maximum measurable distance 12.7 m , pulse repetition frequency 8.7 MHz */ + ACC_SERVICE_MUR_9 = 9, + + /** Default maximum unambiguous range */ + ACC_SERVICE_MUR_DEFAULT = ACC_SERVICE_MUR_6, +} acc_service_mur_t; + + +/** + * Type used when retrieving and setting a sensor calibration context + */ +typedef struct +{ + uint8_t data[64]; +} acc_calibration_context_t; + + +#endif diff --git a/rss/include/acc_definitions_common.h b/rss/include/acc_definitions_common.h index 2e42896..1be076b 100644 --- a/rss/include/acc_definitions_common.h +++ b/rss/include/acc_definitions_common.h @@ -1,45 +1,45 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_DEFINITIONS_COMMON_H_ -#define ACC_DEFINITIONS_COMMON_H_ - -#include -#include - - -/** - * @brief Type representing a sensor ID - */ -typedef uint32_t acc_sensor_id_t; - -/** - * @brief Macro for printing sensor id - */ -#define PRIsensor_id PRIu32 - - -/** - * @brief This enum represents the different log levels for RSS - */ -typedef enum -{ - ACC_LOG_LEVEL_ERROR, - ACC_LOG_LEVEL_WARNING, - ACC_LOG_LEVEL_INFO, - ACC_LOG_LEVEL_VERBOSE, - ACC_LOG_LEVEL_DEBUG -} acc_log_level_t; - - -/** - * @brief Data type for interger-based representation of complex numbers - */ -typedef struct -{ - int16_t real; - int16_t imag; -} acc_int16_complex_t; - - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_DEFINITIONS_COMMON_H_ +#define ACC_DEFINITIONS_COMMON_H_ + +#include +#include + + +/** + * @brief Type representing a sensor ID + */ +typedef uint32_t acc_sensor_id_t; + +/** + * @brief Macro for printing sensor id + */ +#define PRIsensor_id PRIu32 + + +/** + * @brief This enum represents the different log levels for RSS + */ +typedef enum +{ + ACC_LOG_LEVEL_ERROR, + ACC_LOG_LEVEL_WARNING, + ACC_LOG_LEVEL_INFO, + ACC_LOG_LEVEL_VERBOSE, + ACC_LOG_LEVEL_DEBUG +} acc_log_level_t; + + +/** + * @brief Data type for interger-based representation of complex numbers + */ +typedef struct +{ + int16_t real; + int16_t imag; +} acc_int16_complex_t; + + +#endif diff --git a/rss/include/acc_detector_distance.h b/rss/include/acc_detector_distance.h index 7d26911..245f6b6 100644 --- a/rss/include/acc_detector_distance.h +++ b/rss/include/acc_detector_distance.h @@ -1,831 +1,831 @@ -// Copyright (c) Acconeer AB, 2020-2021 -// All rights reserved - -#ifndef ACC_DETECTOR_DISTANCE_H_ -#define ACC_DETECTOR_DISTANCE_H_ - - -#include -#include - -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" - - -/** - * @defgroup Distance Distance Detector - * @ingroup Detectors - * - * @brief Distance detector API description - * - * @{ - */ - - -/** - * @brief Metadata for the distance detector - */ -typedef struct -{ - /** Start of measurement in meters, derived from request set by @ref acc_detector_distance_configuration_requested_start_set */ - float start_m; - /** Length of measurement in meters, derived from request set by @ref acc_detector_distance_configuration_requested_length_set */ - float length_m; - /** Length needed for potential background, used in @ref acc_detector_distance_record_background */ - uint16_t background_length; -} acc_detector_distance_metadata_t; - - -/** - * @brief Metadata for the recorded background - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; -} acc_detector_distance_recorded_background_info_t; - - -/** - * @brief Metadata for each result provided by the distance detector - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; - /** Number of detected peaks returned to application. Maximum is number of requested peaks.*/ - uint16_t number_of_peaks; - /** Indicating if any measurement samples are above the threshold.*/ - bool measurement_sample_above_threshold; - /** The closest measurement distance above the threshold. Only valid if any measurement samples are above - * threshold. Note, it is valid even if no peaks are found.*/ - float closest_detection_m; -} acc_detector_distance_result_info_t; - - -/** - * @brief Enum for threshold type - */ -typedef enum -{ - ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_FIXED, - ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED, - ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_CFAR -} acc_detector_distance_threshold_type_t; - - -/** - * @brief Enum for peak sorting algorithms - */ -typedef enum -{ - /* Return peaks with the closest detection first. */ - ACC_DETECTOR_DISTANCE_PEAK_SORTING_CLOSEST_FIRST, - /* Return peaks with the peak with the highest amplitude first. */ - ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_FIRST, - /* Return peaks with the peak from the strongest reflector first. - The decrease in amplitude over distance is accounted for. - Cannot be combined with negative start range. */ - ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_REFLECTOR_FIRST, - /* Return peaks with the peak from the strongest flat reflector first. - The decrease in amplitude over distance is accounted for. - Cannot be combined with negative start range. */ - ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_FLAT_REFLECTOR_FIRST -} acc_detector_distance_peak_sorting_t; - - -/** - * @brief Distance detector handle - */ -struct acc_detector_distance_handle; - -typedef struct acc_detector_distance_handle *acc_detector_distance_handle_t; - - -/** - * @brief Distance detector configuration container - */ -struct acc_detector_distance_configuration; - -typedef struct acc_detector_distance_configuration *acc_detector_distance_configuration_t; - - -/** - * @brief Result type for distance detector - * - * @param[out] amplitude Absolute amplitude of peak - * @param[out] distance Distance to peak in meters - */ -typedef struct -{ - uint16_t amplitude; - float distance_m; -} acc_detector_distance_result_t; - - -/** - * @brief A callback for retrieving the service data buffer that the detector is based on - * - * @param[in] data A pointer to the buffer with envelope data - * @param[in] data_length Length of the data buffer - */ -typedef void (*acc_detector_distance_service_data_callback_t)(const uint16_t *data, uint16_t data_length); - - -/** - * @brief Create a configuration for a distance detector - * - * @return Distance detector configuration, NULL if creation was not possible - */ -acc_detector_distance_configuration_t acc_detector_distance_configuration_create(void); - - -/** - * @brief Destroy a configuration for a distance detector - * - * @param[in] distance_configuration The configuration to destroy, set to NULL - */ -void acc_detector_distance_configuration_destroy(acc_detector_distance_configuration_t *distance_configuration); - - -/** - * @brief Create a distance detector with the provided configuration - * - * Only one distance detector may exist for a specific sensor at any given time and - * invalid configurations will not allow for a distance detector creation. - * - * @param[in] distance_configuration The distance detector configuration to create a distance detector with - * @return Distance detector handle, NULL if distance detector was not possible to create - */ -acc_detector_distance_handle_t acc_detector_distance_create(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Destroy a distance detector identified with provided handle - * - * Destroy the context of a distance detector allowing another distance detector to be created using the - * same resources. The distance detector handle reference is set to NULL after destruction. - * If NULL is sent in, nothing happens - * - * @param[in] distance_handle A reference to the distance detector handle to destroy - */ -void acc_detector_distance_destroy(acc_detector_distance_handle_t *distance_handle); - - -/** - * @brief Activate the distance detector associated with the provided handle - * - * @param[in] distance_handle The distance detector handle for the distance detector to activate - * @return True if successful, otherwise false - */ -bool acc_detector_distance_activate(acc_detector_distance_handle_t distance_handle); - - -/** - * @brief Deactivate the distance detector associated with the provided handle - * - * @param[in] distance_handle The distance detector handle for the distance detector to deactivate - * @return True if successful, otherwise false - */ -bool acc_detector_distance_deactivate(acc_detector_distance_handle_t distance_handle); - - -/** - * @brief Reconfigure a distance detector with the provided configuration - * - * Only one distance detector may exist for a specific sensor at any given time. - * A distance detector may not be active when reconfiguring the detector. - * Invalid configurations will not allow for distance detector reconfiguration and - * the distance detector will be destroyed. - * - * NOTE! The old distance handle will be invalid after reconfigure. - * - * @param[in, out] distance_handle A reference to the distance detector handle to reconfigure - * @param[in] distance_configuration The distance detector configuration to reconfigure a distance detector with - * @return True if possible to reconfigure - */ -bool acc_detector_distance_reconfigure(acc_detector_distance_handle_t *distance_handle, - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Get detector metadata - * - * The detector provides metadata after being created with information that could be relevant for an application. - * - * May only be called after a detector has been created. - * - * @param[in] distance_handle The distance detector handle to get metadata for - * @param[out] metadata Metadata are provided in this parameter - * @return True if successful - */ -bool acc_detector_distance_metadata_get(acc_detector_distance_handle_t distance_handle, - acc_detector_distance_metadata_t *metadata); - - -/** - * @brief Record background - * - * Must be called after @ref acc_detector_distance_create and before @ref acc_detector_distance_activate - * when ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED is set. - * - * Can be called again to make a new recording. Detector has to be deactivated to record a new background. - * - * The background length can be retrieved from @ref acc_detector_distance_metadata_get. - * - * The result should typically be set to the detector by calling @ref acc_detector_distance_set_background - * - * @param[in] distance_handle The distance detector handle for the distance detector to record background for - * @param[out] background The recorded background will be stored here - * @param[in] background_length The length of the background - * @param[out] background_info Recorded background metadata, passing NULL is OK - * @return True if successful - */ -bool acc_detector_distance_record_background(acc_detector_distance_handle_t distance_handle, - uint16_t *background, - uint16_t background_length, - acc_detector_distance_recorded_background_info_t *background_info); - - -/** - * @brief Set a background - * - * Set a previously recorded background. The background can typically be generated using - * @ref acc_detector_distance_record_background. The background must have a length corresponding - * to the configuration that was used when creating the detector. For example, if the background - * was created using @ref acc_detector_distance_record_background, the configuration of the detector - * should be the same both when generating the background as when later setting it. - * - * Must always be called for detector to work in ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED mode. - * - * Must be called after @ref acc_detector_distance_create and before @ref acc_detector_distance_activate - * - * The background length can be retrieved from @ref acc_detector_distance_metadata_get. - * - * @param[in] distance_handle The distance detector handle for the distance detector to set background for - * @param[in] background The background to be set - * @param[in] background_length The length of the background to be set - * @return True if successful - */ -bool acc_detector_distance_set_background(acc_detector_distance_handle_t distance_handle, const uint16_t *background, uint16_t background_length); - - -/** - * @brief Retrieve the next result from the distance detector - * - * May only be called after a distance detector has been activated, blocks - * the application until result is ready. - * - * When using CFAR threshold, no detections will be made outside of range - * [range_start + (guard / 2) + window, range_end - (guard / 2) - window], if only_lower_distances is not set. - * If only_lower_distances is set, no detections will be made outside of range - * [range_start + (guard / 2) + window, range_end]. - * - * @param[in] distance_handle The distance detector handle for the distance detector to get next result for - * @param[out] result Distance detector results, can be NULL if no result is wanted - * @param[in] result_length Length of data array passed to function. Number of peaks returned <= result_length. - * @param[out] result_info Detector result info - * @return True if successful, otherwise false - */ -bool acc_detector_distance_get_next(acc_detector_distance_handle_t distance_handle, - acc_detector_distance_result_t *result, - uint16_t result_length, - acc_detector_distance_result_info_t *result_info); - - -/** - * @brief Get the sensor ID for the sensor to be configured - * - * @param[in] distance_configuration The detector distance configuration to get the sensor ID from - * @return Sensor ID - */ -acc_sensor_id_t acc_detector_distance_configuration_sensor_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the sensor ID for the sensor to be configured - * - * @param[in] distance_configuration The detector distance configuration to set the sensor ID in - * @param[in] sensor_id The sensor ID to set - */ -void acc_detector_distance_configuration_sensor_set(acc_detector_distance_configuration_t distance_configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get the requested start distance for measurement in meters - * - * @param[in] distance_configuration The detector distance configuration to get the requested start from - * @return Requested start in meters - */ -float acc_detector_distance_configuration_requested_start_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the requested start distance for measurement in meters - * - * @param[in] distance_configuration The detector distance configuration to set the requested start in - * @param[in] start_m The requested start in meters - */ -void acc_detector_distance_configuration_requested_start_set(acc_detector_distance_configuration_t distance_configuration, float start_m); - - -/** - * @brief Get the requested length of the measurement in meters - * - * @param[in] distance_configuration The detector distance configuration to get the requested length from - * @return Requested length in meters - */ -float acc_detector_distance_configuration_requested_length_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the requested length of the measurement in meters - * - * @param[in] distance_configuration The detector distance configuration to set the requested length in - * @param[in] length_m The requested length in meters - */ -void acc_detector_distance_configuration_requested_length_set(acc_detector_distance_configuration_t distance_configuration, float length_m); - - -/** - * @brief Get power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] distance_configuration The detector distance configuration to get power save mode from - * @return Power save mode - */ -acc_power_save_mode_t acc_detector_distance_configuration_power_save_mode_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] distance_configuration The detector distance configuration to set power save mode in - * @param[in] power_save_mode The power save mode to use - */ -void acc_detector_distance_configuration_power_save_mode_set(acc_detector_distance_configuration_t distance_configuration, - acc_power_save_mode_t power_save_mode); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. Only 1, 2 and 4 - * are valid numbers. - * - * @param[in] distance_configuration The detector distance configuration to get downsampling factor for - * @return Downsampling factor - */ -uint16_t acc_detector_distance_configuration_downsampling_factor_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. Only 1, 2 and 4 - * are valid numbers. - * - * @param[in] distance_configuration The detector distance configuration to set downsampling factor for - * @param[in] downsampling_factor Downsampling factor - */ -void acc_detector_distance_configuration_downsampling_factor_set(acc_detector_distance_configuration_t distance_configuration, - uint16_t downsampling_factor); - - -/** - * @brief Get the service profile - * - * See @ref acc_service_profile_t for details - * - * @param[in] distance_configuration The detector distance configuration to get service profile for - * @return The service profile - */ -acc_service_profile_t acc_detector_distance_configuration_service_profile_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the service profile - * - * See @ref acc_service_profile_t for details - * - * @param[in] distance_configuration The detector distance configuration to set service profile for - * @param[in] service_profile - */ -void acc_detector_distance_configuration_service_profile_set(acc_detector_distance_configuration_t distance_configuration, - acc_service_profile_t service_profile); - - -/** - * @brief Get Maximize signal attenuation mode - * - * Will be true if Maximize signal attenuation mode is enabled, false otherwise - * - * @param[in] distance_configuration The detector distance configuration to get Maximize signal attenuation mode for - * @return Maximize signal attenuation mode - */ -bool acc_detector_distance_configuration_maximize_signal_attenuation_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set Maximize signal attenuation mode - * - * Enable or disable Maximize signal attenuation mode to measure the direct leakage - * - * @param[in] distance_configuration The detector distance configuration to set Maximize signal attenuation mode in - * @param[in] maximize_signal_attenuation Maximize signal attenuation mode, true or false - */ -void acc_detector_distance_configuration_maximize_signal_attenuation_set(acc_detector_distance_configuration_t distance_configuration, - bool maximize_signal_attenuation); - - -/** - * @brief Get receiver gain setting - * - * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] distance_configuration The detector distance configuration to get gain setting for - * @return Receiver gain setting - */ -float acc_detector_distance_configuration_receiver_gain_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set receiver gain setting - * - * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] distance_configuration The detector distance configuration to set gain setting for - * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 - */ -void acc_detector_distance_configuration_receiver_gain_set(acc_detector_distance_configuration_t distance_configuration, float gain); - - -/** - * @brief Get the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] distance_configuration The distance configuration to get hardware accelerated average samples from - * @return Hardware accelerated average samples - */ -uint8_t acc_detector_distance_configuration_hw_accelerated_average_samples_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] distance_configuration The distance configuration to set hardware accelerated average samples in - * @param[in] samples Hardware accelerated average samples - */ -void acc_detector_distance_configuration_hw_accelerated_average_samples_set( - acc_detector_distance_configuration_t distance_configuration, uint8_t samples); - - -/** - * @brief Get asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will measure while the host is waiting. - * In asynchronous mode the sensor will measure while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * @param[in] distance_configuration The configuration to get asynchronous_measurement mode from - * @return Asynchronous measurement mode - */ -bool acc_detector_distance_configuration_asynchronous_measurement_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will measure while the host is waiting. - * In asynchronous mode the sensor will measure while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * @param[in] distance_configuration The configuration to set asynchronous_measurement mode in - * @param[in] asynchronous_measurement asynchronous measurement mode, true or false - */ -void acc_detector_distance_configuration_asynchronous_measurement_set(acc_detector_distance_configuration_t distance_configuration, - bool asynchronous_measurement); - - -/** - * @brief Get number of sweeps to calculate average for - * - * @param[in] distance_configuration The detector distance configuration to get sweep average for - * @return Number of sweeps to calculate average for - */ -uint16_t acc_detector_distance_configuration_sweep_averaging_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set number of sweeps to calculate average for - * - * @param[in] distance_configuration The detector distance configuration to set sweep average for - * @param[in] sweep_averaging Number of sweeps to calculate average for - */ -void acc_detector_distance_configuration_sweep_averaging_set(acc_detector_distance_configuration_t distance_configuration, - uint16_t sweep_averaging); - - -/** - * @brief Get threshold type - * - * @param[in] distance_configuration The detector distance configuration to set threshold type for - * @return Used threshold type - */ -acc_detector_distance_threshold_type_t acc_detector_distance_configuration_threshold_type_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set threshold type - * - * @param[in] distance_configuration The detector distance configuration to set threshold type for - * @param[in] threshold Threshold type to be used - */ -void acc_detector_distance_configuration_threshold_type_set(acc_detector_distance_configuration_t distance_configuration, - acc_detector_distance_threshold_type_t threshold); - - -/** - * @brief Get fixed threshold - * - * @param[in] distance_configuration The detector distance configuration to get fixed threshold from - * @return Fixed threshold - */ -uint16_t acc_detector_distance_configuration_fixed_threshold_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set fixed threshold - * - * @param[in] distance_configuration The detector distance configuration to set fixed threshold in - * @param[in] threshold Fixed threshold to be used by the detector - */ -void acc_detector_distance_configuration_fixed_threshold_set(acc_detector_distance_configuration_t distance_configuration, - uint16_t threshold); - - -/** - * @brief Get number of sweeps to record - * - * @param[in] distance_configuration The detector distance configuration to get number of sweeps to record for - * @return Number of sweeps to record - */ -uint16_t acc_detector_distance_configuration_record_background_sweeps_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set number of sweeps to record - * - * @param[in] distance_configuration The detector distance configuration to set number of sweeps to record in - * @param[in] record_sweeps Number of sweeps to record - */ -void acc_detector_distance_configuration_record_background_sweeps_set( - acc_detector_distance_configuration_t distance_configuration, uint16_t record_sweeps); - - -/** - * @brief Get threshold sensitivity - * - * Applicable when using recorded threshold or CFAR threshold - * - * @param[in] distance_configuration The detector distance configuration to get threshold sensitivity for - * @return Threshold sensitivity - */ -float acc_detector_distance_configuration_threshold_sensitivity_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set threshold sensitivity - * - * Applicable when using recorded threshold or CFAR threshold - * - * @param[in] distance_configuration The detector distance configuration to set threshold sensitivity in - * @param[in] sensitivity - */ -void acc_detector_distance_configuration_threshold_sensitivity_set( - acc_detector_distance_configuration_t distance_configuration, - float sensitivity); - - -/** - * @brief Get guard for CFAR threshold - * - * Range around the distance of interest that is omitted when calculating - * CFAR threshold. Can be low, ~0.04 m, for Profile 1, and should be - * increased for higher Profiles. - * - * @param[in] distance_configuration The detector distance configuration to get threshold guard for - * @return Threshold guard in meters - */ -float acc_detector_distance_configuration_cfar_threshold_guard_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set guard for CFAR threshold - * - * Range around the distance of interest that is omitted when calculating - * CFAR threshold. Can be low, ~0.04 cm, for Profile 1, and should be - * increased for higher Profiles. - * - * @param[in] distance_configuration The detector distance configuration to set threshold guard in - * @param[in] guard_m Threshold guard in meters - */ -void acc_detector_distance_configuration_cfar_threshold_guard_set( - acc_detector_distance_configuration_t distance_configuration, - float guard_m); - - -/** - * @brief Get window for CFAR threshold - * - * Range next to the CFAR guard from which the threshold level will be calculated. - * - * @param[in] distance_configuration The detector distance configuration to get threshold window for - * @return Threshold window in meters - */ -float acc_detector_distance_configuration_cfar_threshold_window_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set window for CFAR threshold - * - * Range next to the CFAR guard from which the threshold level will be calculated. - * - * @param[in] distance_configuration The detector distance configuration to set threshold window in - * @param[in] window_m Threshold window in meters - */ -void acc_detector_distance_configuration_cfar_threshold_window_set( - acc_detector_distance_configuration_t distance_configuration, - float window_m); - - -/** - * @brief Get if only lower distance is set - * - * Instead of determining the CFAR threshold from sweep amplitudes from - * distances both closer and father away, use only closer. Helpful e.g. for - * fluid level in small tanks, where many multipath signals can appear - * just after the main peak. - * - * @param[in] distance_configuration The detector distance configuration to get setting for - * @return True, if only lower distance is set - */ -bool acc_detector_distance_configuration_cfar_threshold_only_lower_distance_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set only lower distance - * - * Instead of determining the CFAR threshold from sweep amplitudes from - * distances both closer and father away, use only closer. Helpful e.g. for - * fluid level in small tanks, where many multipath signals can appear - * just after the main peak. - * - * @param[in] distance_configuration The detector distance configuration to set setting for - * @param[in] only_lower_distance True if only lower distances should be used - */ -void acc_detector_distance_configuration_cfar_threshold_only_lower_distance_set( - acc_detector_distance_configuration_t distance_configuration, - bool only_lower_distance); - - -/** - * @brief Get peak sorting algorithm - * - * Peak sorting algoritm specifies in what order peaks should be reported back to the application. - * - * @param[in] distance_configuration The detector distance configuration to get peak sorting algorithm from - * @return Peak sorting algorithm - */ -acc_detector_distance_peak_sorting_t acc_detector_distance_configuration_peak_sorting_get( - acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set peak sorting algorithm to be used - * - * Peak sorting algoritm specifies in what order peaks should be reported back to the application. - * - * @param[in] distance_configuration The detector distance configuration to set peak sorting algorithm in - * @param[in] peak_sorting Peak sorting algorithm to be used - */ -void acc_detector_distance_configuration_peak_sorting_set(acc_detector_distance_configuration_t distance_configuration, - acc_detector_distance_peak_sorting_t peak_sorting); - - -/** - * @brief Get peak merge limit in meters - * - * Defining minimum distance between peaks to be considered individual peaks - * - * @param[in] distance_configuration The detector distance configuration to get peak merge limit from - * @return Peak merge limit in meters - */ -float acc_detector_distance_configuration_peak_merge_limit_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @brief Set peak merge limit in meters - * - * Defining minimum distance between peaks to be considered individual peaks - * - * @param[in] distance_configuration The detector distance configuration to set peak merge limit in - * @param[in] peak_merge_limit_m Peak merge limit in meters - */ -void acc_detector_distance_configuration_peak_merge_limit_set(acc_detector_distance_configuration_t distance_configuration, - float peak_merge_limit_m); - - -/** - * @brief Set a callback function to get the service data - * - * A callback can be used to get the envelope service buffer that the detector is based on. - * The data is the unprocessed envelope data that is fed into the distance algorithm. - * Set service_data_callback to NULL to disable callback. - * - * @param[in] distance_configuration The configuration to set the service data callback for - * @param[in] service_data_callback The callback to get service data - */ -void acc_detector_distance_configuration_service_data_callback_set( - acc_detector_distance_configuration_t distance_configuration, - acc_detector_distance_service_data_callback_t service_data_callback); - - -/** - * @brief Set the maximum unambiguous range - * - * Experimental. - * - * See acc_service_mur_set() for more detailed information. - * - * @param[in] distance_configuration The configuration - * @param[in] max_unambiguous_range The desired maximum unambiguous range - */ -void acc_detector_distance_configuration_mur_set(acc_detector_distance_configuration_t distance_configuration, - acc_service_mur_t max_unambiguous_range); - - -/** - * @brief Get the maximum unambiguous range - * - * Experimental. - * - * See acc_service_mur_get() for more detailed information. - * - * @param[in] distance_configuration The configuration - * @return Maximum unambiguous range - */ -acc_service_mur_t acc_detector_distance_configuration_mur_get(acc_detector_distance_configuration_t distance_configuration); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2020-2021 +// All rights reserved + +#ifndef ACC_DETECTOR_DISTANCE_H_ +#define ACC_DETECTOR_DISTANCE_H_ + + +#include +#include + +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" + + +/** + * @defgroup Distance Distance Detector + * @ingroup Detectors + * + * @brief Distance detector API description + * + * @{ + */ + + +/** + * @brief Metadata for the distance detector + */ +typedef struct +{ + /** Start of measurement in meters, derived from request set by @ref acc_detector_distance_configuration_requested_start_set */ + float start_m; + /** Length of measurement in meters, derived from request set by @ref acc_detector_distance_configuration_requested_length_set */ + float length_m; + /** Length needed for potential background, used in @ref acc_detector_distance_record_background */ + uint16_t background_length; +} acc_detector_distance_metadata_t; + + +/** + * @brief Metadata for the recorded background + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; +} acc_detector_distance_recorded_background_info_t; + + +/** + * @brief Metadata for each result provided by the distance detector + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; + /** Number of detected peaks returned to application. Maximum is number of requested peaks.*/ + uint16_t number_of_peaks; + /** Indicating if any measurement samples are above the threshold.*/ + bool measurement_sample_above_threshold; + /** The closest measurement distance above the threshold. Only valid if any measurement samples are above + * threshold. Note, it is valid even if no peaks are found.*/ + float closest_detection_m; +} acc_detector_distance_result_info_t; + + +/** + * @brief Enum for threshold type + */ +typedef enum +{ + ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_FIXED, + ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED, + ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_CFAR +} acc_detector_distance_threshold_type_t; + + +/** + * @brief Enum for peak sorting algorithms + */ +typedef enum +{ + /* Return peaks with the closest detection first. */ + ACC_DETECTOR_DISTANCE_PEAK_SORTING_CLOSEST_FIRST, + /* Return peaks with the peak with the highest amplitude first. */ + ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_FIRST, + /* Return peaks with the peak from the strongest reflector first. + The decrease in amplitude over distance is accounted for. + Cannot be combined with negative start range. */ + ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_REFLECTOR_FIRST, + /* Return peaks with the peak from the strongest flat reflector first. + The decrease in amplitude over distance is accounted for. + Cannot be combined with negative start range. */ + ACC_DETECTOR_DISTANCE_PEAK_SORTING_STRONGEST_FLAT_REFLECTOR_FIRST +} acc_detector_distance_peak_sorting_t; + + +/** + * @brief Distance detector handle + */ +struct acc_detector_distance_handle; + +typedef struct acc_detector_distance_handle *acc_detector_distance_handle_t; + + +/** + * @brief Distance detector configuration container + */ +struct acc_detector_distance_configuration; + +typedef struct acc_detector_distance_configuration *acc_detector_distance_configuration_t; + + +/** + * @brief Result type for distance detector + * + * @param[out] amplitude Absolute amplitude of peak + * @param[out] distance Distance to peak in meters + */ +typedef struct +{ + uint16_t amplitude; + float distance_m; +} acc_detector_distance_result_t; + + +/** + * @brief A callback for retrieving the service data buffer that the detector is based on + * + * @param[in] data A pointer to the buffer with envelope data + * @param[in] data_length Length of the data buffer + */ +typedef void (*acc_detector_distance_service_data_callback_t)(const uint16_t *data, uint16_t data_length); + + +/** + * @brief Create a configuration for a distance detector + * + * @return Distance detector configuration, NULL if creation was not possible + */ +acc_detector_distance_configuration_t acc_detector_distance_configuration_create(void); + + +/** + * @brief Destroy a configuration for a distance detector + * + * @param[in] distance_configuration The configuration to destroy, set to NULL + */ +void acc_detector_distance_configuration_destroy(acc_detector_distance_configuration_t *distance_configuration); + + +/** + * @brief Create a distance detector with the provided configuration + * + * Only one distance detector may exist for a specific sensor at any given time and + * invalid configurations will not allow for a distance detector creation. + * + * @param[in] distance_configuration The distance detector configuration to create a distance detector with + * @return Distance detector handle, NULL if distance detector was not possible to create + */ +acc_detector_distance_handle_t acc_detector_distance_create(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Destroy a distance detector identified with provided handle + * + * Destroy the context of a distance detector allowing another distance detector to be created using the + * same resources. The distance detector handle reference is set to NULL after destruction. + * If NULL is sent in, nothing happens + * + * @param[in] distance_handle A reference to the distance detector handle to destroy + */ +void acc_detector_distance_destroy(acc_detector_distance_handle_t *distance_handle); + + +/** + * @brief Activate the distance detector associated with the provided handle + * + * @param[in] distance_handle The distance detector handle for the distance detector to activate + * @return True if successful, otherwise false + */ +bool acc_detector_distance_activate(acc_detector_distance_handle_t distance_handle); + + +/** + * @brief Deactivate the distance detector associated with the provided handle + * + * @param[in] distance_handle The distance detector handle for the distance detector to deactivate + * @return True if successful, otherwise false + */ +bool acc_detector_distance_deactivate(acc_detector_distance_handle_t distance_handle); + + +/** + * @brief Reconfigure a distance detector with the provided configuration + * + * Only one distance detector may exist for a specific sensor at any given time. + * A distance detector may not be active when reconfiguring the detector. + * Invalid configurations will not allow for distance detector reconfiguration and + * the distance detector will be destroyed. + * + * NOTE! The old distance handle will be invalid after reconfigure. + * + * @param[in, out] distance_handle A reference to the distance detector handle to reconfigure + * @param[in] distance_configuration The distance detector configuration to reconfigure a distance detector with + * @return True if possible to reconfigure + */ +bool acc_detector_distance_reconfigure(acc_detector_distance_handle_t *distance_handle, + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Get detector metadata + * + * The detector provides metadata after being created with information that could be relevant for an application. + * + * May only be called after a detector has been created. + * + * @param[in] distance_handle The distance detector handle to get metadata for + * @param[out] metadata Metadata are provided in this parameter + * @return True if successful + */ +bool acc_detector_distance_metadata_get(acc_detector_distance_handle_t distance_handle, + acc_detector_distance_metadata_t *metadata); + + +/** + * @brief Record background + * + * Must be called after @ref acc_detector_distance_create and before @ref acc_detector_distance_activate + * when ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED is set. + * + * Can be called again to make a new recording. Detector has to be deactivated to record a new background. + * + * The background length can be retrieved from @ref acc_detector_distance_metadata_get. + * + * The result should typically be set to the detector by calling @ref acc_detector_distance_set_background + * + * @param[in] distance_handle The distance detector handle for the distance detector to record background for + * @param[out] background The recorded background will be stored here + * @param[in] background_length The length of the background + * @param[out] background_info Recorded background metadata, passing NULL is OK + * @return True if successful + */ +bool acc_detector_distance_record_background(acc_detector_distance_handle_t distance_handle, + uint16_t *background, + uint16_t background_length, + acc_detector_distance_recorded_background_info_t *background_info); + + +/** + * @brief Set a background + * + * Set a previously recorded background. The background can typically be generated using + * @ref acc_detector_distance_record_background. The background must have a length corresponding + * to the configuration that was used when creating the detector. For example, if the background + * was created using @ref acc_detector_distance_record_background, the configuration of the detector + * should be the same both when generating the background as when later setting it. + * + * Must always be called for detector to work in ACC_DETECTOR_DISTANCE_THRESHOLD_TYPE_RECORDED mode. + * + * Must be called after @ref acc_detector_distance_create and before @ref acc_detector_distance_activate + * + * The background length can be retrieved from @ref acc_detector_distance_metadata_get. + * + * @param[in] distance_handle The distance detector handle for the distance detector to set background for + * @param[in] background The background to be set + * @param[in] background_length The length of the background to be set + * @return True if successful + */ +bool acc_detector_distance_set_background(acc_detector_distance_handle_t distance_handle, const uint16_t *background, uint16_t background_length); + + +/** + * @brief Retrieve the next result from the distance detector + * + * May only be called after a distance detector has been activated, blocks + * the application until result is ready. + * + * When using CFAR threshold, no detections will be made outside of range + * [range_start + (guard / 2) + window, range_end - (guard / 2) - window], if only_lower_distances is not set. + * If only_lower_distances is set, no detections will be made outside of range + * [range_start + (guard / 2) + window, range_end]. + * + * @param[in] distance_handle The distance detector handle for the distance detector to get next result for + * @param[out] result Distance detector results, can be NULL if no result is wanted + * @param[in] result_length Length of data array passed to function. Number of peaks returned <= result_length. + * @param[out] result_info Detector result info + * @return True if successful, otherwise false + */ +bool acc_detector_distance_get_next(acc_detector_distance_handle_t distance_handle, + acc_detector_distance_result_t *result, + uint16_t result_length, + acc_detector_distance_result_info_t *result_info); + + +/** + * @brief Get the sensor ID for the sensor to be configured + * + * @param[in] distance_configuration The detector distance configuration to get the sensor ID from + * @return Sensor ID + */ +acc_sensor_id_t acc_detector_distance_configuration_sensor_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the sensor ID for the sensor to be configured + * + * @param[in] distance_configuration The detector distance configuration to set the sensor ID in + * @param[in] sensor_id The sensor ID to set + */ +void acc_detector_distance_configuration_sensor_set(acc_detector_distance_configuration_t distance_configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get the requested start distance for measurement in meters + * + * @param[in] distance_configuration The detector distance configuration to get the requested start from + * @return Requested start in meters + */ +float acc_detector_distance_configuration_requested_start_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the requested start distance for measurement in meters + * + * @param[in] distance_configuration The detector distance configuration to set the requested start in + * @param[in] start_m The requested start in meters + */ +void acc_detector_distance_configuration_requested_start_set(acc_detector_distance_configuration_t distance_configuration, float start_m); + + +/** + * @brief Get the requested length of the measurement in meters + * + * @param[in] distance_configuration The detector distance configuration to get the requested length from + * @return Requested length in meters + */ +float acc_detector_distance_configuration_requested_length_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the requested length of the measurement in meters + * + * @param[in] distance_configuration The detector distance configuration to set the requested length in + * @param[in] length_m The requested length in meters + */ +void acc_detector_distance_configuration_requested_length_set(acc_detector_distance_configuration_t distance_configuration, float length_m); + + +/** + * @brief Get power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] distance_configuration The detector distance configuration to get power save mode from + * @return Power save mode + */ +acc_power_save_mode_t acc_detector_distance_configuration_power_save_mode_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] distance_configuration The detector distance configuration to set power save mode in + * @param[in] power_save_mode The power save mode to use + */ +void acc_detector_distance_configuration_power_save_mode_set(acc_detector_distance_configuration_t distance_configuration, + acc_power_save_mode_t power_save_mode); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. Only 1, 2 and 4 + * are valid numbers. + * + * @param[in] distance_configuration The detector distance configuration to get downsampling factor for + * @return Downsampling factor + */ +uint16_t acc_detector_distance_configuration_downsampling_factor_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. Only 1, 2 and 4 + * are valid numbers. + * + * @param[in] distance_configuration The detector distance configuration to set downsampling factor for + * @param[in] downsampling_factor Downsampling factor + */ +void acc_detector_distance_configuration_downsampling_factor_set(acc_detector_distance_configuration_t distance_configuration, + uint16_t downsampling_factor); + + +/** + * @brief Get the service profile + * + * See @ref acc_service_profile_t for details + * + * @param[in] distance_configuration The detector distance configuration to get service profile for + * @return The service profile + */ +acc_service_profile_t acc_detector_distance_configuration_service_profile_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the service profile + * + * See @ref acc_service_profile_t for details + * + * @param[in] distance_configuration The detector distance configuration to set service profile for + * @param[in] service_profile + */ +void acc_detector_distance_configuration_service_profile_set(acc_detector_distance_configuration_t distance_configuration, + acc_service_profile_t service_profile); + + +/** + * @brief Get Maximize signal attenuation mode + * + * Will be true if Maximize signal attenuation mode is enabled, false otherwise + * + * @param[in] distance_configuration The detector distance configuration to get Maximize signal attenuation mode for + * @return Maximize signal attenuation mode + */ +bool acc_detector_distance_configuration_maximize_signal_attenuation_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set Maximize signal attenuation mode + * + * Enable or disable Maximize signal attenuation mode to measure the direct leakage + * + * @param[in] distance_configuration The detector distance configuration to set Maximize signal attenuation mode in + * @param[in] maximize_signal_attenuation Maximize signal attenuation mode, true or false + */ +void acc_detector_distance_configuration_maximize_signal_attenuation_set(acc_detector_distance_configuration_t distance_configuration, + bool maximize_signal_attenuation); + + +/** + * @brief Get receiver gain setting + * + * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] distance_configuration The detector distance configuration to get gain setting for + * @return Receiver gain setting + */ +float acc_detector_distance_configuration_receiver_gain_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set receiver gain setting + * + * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] distance_configuration The detector distance configuration to set gain setting for + * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 + */ +void acc_detector_distance_configuration_receiver_gain_set(acc_detector_distance_configuration_t distance_configuration, float gain); + + +/** + * @brief Get the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] distance_configuration The distance configuration to get hardware accelerated average samples from + * @return Hardware accelerated average samples + */ +uint8_t acc_detector_distance_configuration_hw_accelerated_average_samples_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] distance_configuration The distance configuration to set hardware accelerated average samples in + * @param[in] samples Hardware accelerated average samples + */ +void acc_detector_distance_configuration_hw_accelerated_average_samples_set( + acc_detector_distance_configuration_t distance_configuration, uint8_t samples); + + +/** + * @brief Get asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will measure while the host is waiting. + * In asynchronous mode the sensor will measure while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * @param[in] distance_configuration The configuration to get asynchronous_measurement mode from + * @return Asynchronous measurement mode + */ +bool acc_detector_distance_configuration_asynchronous_measurement_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will measure while the host is waiting. + * In asynchronous mode the sensor will measure while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * @param[in] distance_configuration The configuration to set asynchronous_measurement mode in + * @param[in] asynchronous_measurement asynchronous measurement mode, true or false + */ +void acc_detector_distance_configuration_asynchronous_measurement_set(acc_detector_distance_configuration_t distance_configuration, + bool asynchronous_measurement); + + +/** + * @brief Get number of sweeps to calculate average for + * + * @param[in] distance_configuration The detector distance configuration to get sweep average for + * @return Number of sweeps to calculate average for + */ +uint16_t acc_detector_distance_configuration_sweep_averaging_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set number of sweeps to calculate average for + * + * @param[in] distance_configuration The detector distance configuration to set sweep average for + * @param[in] sweep_averaging Number of sweeps to calculate average for + */ +void acc_detector_distance_configuration_sweep_averaging_set(acc_detector_distance_configuration_t distance_configuration, + uint16_t sweep_averaging); + + +/** + * @brief Get threshold type + * + * @param[in] distance_configuration The detector distance configuration to set threshold type for + * @return Used threshold type + */ +acc_detector_distance_threshold_type_t acc_detector_distance_configuration_threshold_type_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set threshold type + * + * @param[in] distance_configuration The detector distance configuration to set threshold type for + * @param[in] threshold Threshold type to be used + */ +void acc_detector_distance_configuration_threshold_type_set(acc_detector_distance_configuration_t distance_configuration, + acc_detector_distance_threshold_type_t threshold); + + +/** + * @brief Get fixed threshold + * + * @param[in] distance_configuration The detector distance configuration to get fixed threshold from + * @return Fixed threshold + */ +uint16_t acc_detector_distance_configuration_fixed_threshold_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set fixed threshold + * + * @param[in] distance_configuration The detector distance configuration to set fixed threshold in + * @param[in] threshold Fixed threshold to be used by the detector + */ +void acc_detector_distance_configuration_fixed_threshold_set(acc_detector_distance_configuration_t distance_configuration, + uint16_t threshold); + + +/** + * @brief Get number of sweeps to record + * + * @param[in] distance_configuration The detector distance configuration to get number of sweeps to record for + * @return Number of sweeps to record + */ +uint16_t acc_detector_distance_configuration_record_background_sweeps_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set number of sweeps to record + * + * @param[in] distance_configuration The detector distance configuration to set number of sweeps to record in + * @param[in] record_sweeps Number of sweeps to record + */ +void acc_detector_distance_configuration_record_background_sweeps_set( + acc_detector_distance_configuration_t distance_configuration, uint16_t record_sweeps); + + +/** + * @brief Get threshold sensitivity + * + * Applicable when using recorded threshold or CFAR threshold + * + * @param[in] distance_configuration The detector distance configuration to get threshold sensitivity for + * @return Threshold sensitivity + */ +float acc_detector_distance_configuration_threshold_sensitivity_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set threshold sensitivity + * + * Applicable when using recorded threshold or CFAR threshold + * + * @param[in] distance_configuration The detector distance configuration to set threshold sensitivity in + * @param[in] sensitivity + */ +void acc_detector_distance_configuration_threshold_sensitivity_set( + acc_detector_distance_configuration_t distance_configuration, + float sensitivity); + + +/** + * @brief Get guard for CFAR threshold + * + * Range around the distance of interest that is omitted when calculating + * CFAR threshold. Can be low, ~0.04 m, for Profile 1, and should be + * increased for higher Profiles. + * + * @param[in] distance_configuration The detector distance configuration to get threshold guard for + * @return Threshold guard in meters + */ +float acc_detector_distance_configuration_cfar_threshold_guard_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set guard for CFAR threshold + * + * Range around the distance of interest that is omitted when calculating + * CFAR threshold. Can be low, ~0.04 cm, for Profile 1, and should be + * increased for higher Profiles. + * + * @param[in] distance_configuration The detector distance configuration to set threshold guard in + * @param[in] guard_m Threshold guard in meters + */ +void acc_detector_distance_configuration_cfar_threshold_guard_set( + acc_detector_distance_configuration_t distance_configuration, + float guard_m); + + +/** + * @brief Get window for CFAR threshold + * + * Range next to the CFAR guard from which the threshold level will be calculated. + * + * @param[in] distance_configuration The detector distance configuration to get threshold window for + * @return Threshold window in meters + */ +float acc_detector_distance_configuration_cfar_threshold_window_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set window for CFAR threshold + * + * Range next to the CFAR guard from which the threshold level will be calculated. + * + * @param[in] distance_configuration The detector distance configuration to set threshold window in + * @param[in] window_m Threshold window in meters + */ +void acc_detector_distance_configuration_cfar_threshold_window_set( + acc_detector_distance_configuration_t distance_configuration, + float window_m); + + +/** + * @brief Get if only lower distance is set + * + * Instead of determining the CFAR threshold from sweep amplitudes from + * distances both closer and father away, use only closer. Helpful e.g. for + * fluid level in small tanks, where many multipath signals can appear + * just after the main peak. + * + * @param[in] distance_configuration The detector distance configuration to get setting for + * @return True, if only lower distance is set + */ +bool acc_detector_distance_configuration_cfar_threshold_only_lower_distance_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set only lower distance + * + * Instead of determining the CFAR threshold from sweep amplitudes from + * distances both closer and father away, use only closer. Helpful e.g. for + * fluid level in small tanks, where many multipath signals can appear + * just after the main peak. + * + * @param[in] distance_configuration The detector distance configuration to set setting for + * @param[in] only_lower_distance True if only lower distances should be used + */ +void acc_detector_distance_configuration_cfar_threshold_only_lower_distance_set( + acc_detector_distance_configuration_t distance_configuration, + bool only_lower_distance); + + +/** + * @brief Get peak sorting algorithm + * + * Peak sorting algoritm specifies in what order peaks should be reported back to the application. + * + * @param[in] distance_configuration The detector distance configuration to get peak sorting algorithm from + * @return Peak sorting algorithm + */ +acc_detector_distance_peak_sorting_t acc_detector_distance_configuration_peak_sorting_get( + acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set peak sorting algorithm to be used + * + * Peak sorting algoritm specifies in what order peaks should be reported back to the application. + * + * @param[in] distance_configuration The detector distance configuration to set peak sorting algorithm in + * @param[in] peak_sorting Peak sorting algorithm to be used + */ +void acc_detector_distance_configuration_peak_sorting_set(acc_detector_distance_configuration_t distance_configuration, + acc_detector_distance_peak_sorting_t peak_sorting); + + +/** + * @brief Get peak merge limit in meters + * + * Defining minimum distance between peaks to be considered individual peaks + * + * @param[in] distance_configuration The detector distance configuration to get peak merge limit from + * @return Peak merge limit in meters + */ +float acc_detector_distance_configuration_peak_merge_limit_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @brief Set peak merge limit in meters + * + * Defining minimum distance between peaks to be considered individual peaks + * + * @param[in] distance_configuration The detector distance configuration to set peak merge limit in + * @param[in] peak_merge_limit_m Peak merge limit in meters + */ +void acc_detector_distance_configuration_peak_merge_limit_set(acc_detector_distance_configuration_t distance_configuration, + float peak_merge_limit_m); + + +/** + * @brief Set a callback function to get the service data + * + * A callback can be used to get the envelope service buffer that the detector is based on. + * The data is the unprocessed envelope data that is fed into the distance algorithm. + * Set service_data_callback to NULL to disable callback. + * + * @param[in] distance_configuration The configuration to set the service data callback for + * @param[in] service_data_callback The callback to get service data + */ +void acc_detector_distance_configuration_service_data_callback_set( + acc_detector_distance_configuration_t distance_configuration, + acc_detector_distance_service_data_callback_t service_data_callback); + + +/** + * @brief Set the maximum unambiguous range + * + * Experimental. + * + * See acc_service_mur_set() for more detailed information. + * + * @param[in] distance_configuration The configuration + * @param[in] max_unambiguous_range The desired maximum unambiguous range + */ +void acc_detector_distance_configuration_mur_set(acc_detector_distance_configuration_t distance_configuration, + acc_service_mur_t max_unambiguous_range); + + +/** + * @brief Get the maximum unambiguous range + * + * Experimental. + * + * See acc_service_mur_get() for more detailed information. + * + * @param[in] distance_configuration The configuration + * @return Maximum unambiguous range + */ +acc_service_mur_t acc_detector_distance_configuration_mur_get(acc_detector_distance_configuration_t distance_configuration); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_detector_presence.h b/rss/include/acc_detector_presence.h index 8098327..3c94999 100644 --- a/rss/include/acc_detector_presence.h +++ b/rss/include/acc_detector_presence.h @@ -1,582 +1,582 @@ -// Copyright (c) Acconeer AB, 2019-2022 -// All rights reserved - -#ifndef ACC_DETECTOR_PRESENCE_H_ -#define ACC_DETECTOR_PRESENCE_H_ - -#include -#include -#include - -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" - -/** - * @defgroup Presence Presence Detector - * @ingroup Detectors - * - * @brief Presence detector API description - * - * @{ - */ - - -/** - * @brief Presence detector handle - */ -struct acc_detector_presence_handle; - -typedef struct acc_detector_presence_handle *acc_detector_presence_handle_t; - - -/** - * @brief Presence detector configuration container - */ -struct acc_detector_presence_configuration; - -typedef struct acc_detector_presence_configuration *acc_detector_presence_configuration_t; - - -/** - * @brief Parameter structure for data filtering settings - */ -typedef struct -{ - /** Time constant in s for inter-frame signal smoothing after the bandpass filtering */ - float inter_frame_deviation_time_const; - /** Low pass cutoff frequency in Hz for inter-frame signal bandpass filtering */ - float inter_frame_fast_cutoff; - /** High pass cutoff frequency in Hz for inter-frame signal bandpass filtering */ - float inter_frame_slow_cutoff; - /** Time constant in s for inter-frame signal smoothing */ - float intra_frame_time_const; - /** Weight between 0 and 1 for presence score interpolation between the inter-frame and intra-frame signals */ - float intra_frame_weight; - /** Time constant in s for smoothing of the presence score */ - float output_time_const; -} acc_detector_presence_configuration_filter_parameters_t; - - -/** - * @brief Presence detector results container - */ -typedef struct -{ - /** True if presence was detected, False otherwise */ - bool presence_detected; - /** A measure of the amount of motion detected */ - float presence_score; - /** The distance, in meters, to the detected object */ - float presence_distance; - - /** Indication of a sensor communication error, detector probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; -} acc_detector_presence_result_t; - - -/** - * @brief A callback for retrieving the service data buffer that the detector is based on - * - * @param[in] data A pointer to the buffer with sparse data - * @param[in] data_size Size of the data buffer in bytes - * @param[in] client_reference Pointer to a client reference - */ -typedef void (*acc_detector_presence_service_data_callback_t)(const uint16_t *data, size_t data_size, void *client_reference); - - -/** - * @brief Create a configuration for a presence detector - * - * @return Presence detector configuration, NULL if creation was not possible - */ -acc_detector_presence_configuration_t acc_detector_presence_configuration_create(void); - - -/** - * @brief Destroy a presence detector configuration - * - * @param[in] presence_configuration The configuration to destroy, set to NULL - */ -void acc_detector_presence_configuration_destroy(acc_detector_presence_configuration_t *presence_configuration); - - -/** - * @brief Create a presence detector with the provided configuration - * - * Only one presence detector may exist for a specific sensor at any given time and - * invalid configurations will not allow for presence detector creation. - * - * @param[in] presence_configuration The presence detector configuration to create a presence detector with - * @return Presence detector handle, NULL if presence detector was not possible to create - */ -acc_detector_presence_handle_t acc_detector_presence_create(acc_detector_presence_configuration_t presence_configuration); - - -/** - * @brief Destroy a presence detector identified with the provided handle - * - * Destroy the context of a presence detector allowing another presence detector to be created using the - * same resources. The presence detector handle reference is set to NULL after destruction. - * If NULL is sent in, nothing happens. - * - * @param[in] presence_handle A reference to the presence detector handle to destroy - */ -void acc_detector_presence_destroy(acc_detector_presence_handle_t *presence_handle); - - -/** - * @brief Reconfigure a presence detector with the provided configuration - * - * Only one presence detector may exist for a specific sensor at any given time and - * invalid reconfigurations will not allow for presence detector creation. - * - * @param[in] presence_handle A reference to the presence detector handle to reconfigure - * @param[in] presence_configuration The presence detector configuration to reconfigure a presence detector with - * @return True if possible to reconfigure - */ -bool acc_detector_presence_reconfigure(acc_detector_presence_handle_t *presence_handle, - acc_detector_presence_configuration_t presence_configuration); - - -/** - * @brief Activate the presence detector associated with the provided handle - * - * @param[in] presence_handle The presence detector handle for the presence detector to activate - * @return True if successful, otherwise false - */ -bool acc_detector_presence_activate(acc_detector_presence_handle_t presence_handle); - - -/** - * @brief Deactivate the presence detector associated with the provided handle - * - * @param[in] presence_handle The presence detector handle for the presence detector to deactivate - * @return True if successful, otherwise false - */ -bool acc_detector_presence_deactivate(acc_detector_presence_handle_t presence_handle); - - -/** - * @brief Retrieve the next result from the presence detector - * - * May only be called after a presence detector has been activated, blocks - * the application until a result is ready. Can still be called after vector - * output mode has been selected. - * - * @param[in] presence_handle The presence detector handle for the presence detector to get the next result for - * @param[out] result Presence detector results, can be NULL if no result is wanted. - * @return True if successful, otherwise false - */ -bool acc_detector_presence_get_next(acc_detector_presence_handle_t presence_handle, acc_detector_presence_result_t *result); - - -/** - * @brief Retrieve the next distance point vector from the presence detector - * - * May only be called after a presence detector has been activated, blocks - * the application until a result is ready. Vector output mode has to be set - * to true with the function @ref acc_detector_presence_configuration_vector_output_mode_set, - * otherwise returns with an error. Memory is owned by the detector and the client receives a pointer. - * - * @param[in] presence_handle The presence detector handle for the presence detector to get the next result for - * @param[out] distance_point_vector_length The number of elements in the distance_point_vector, can be NULL if no result is wanted - * @param[out] distance_point_vector The distance point vector, can be NULL if no result is wanted - * @param[out] result Presence detector results, same as result from acc_detector_presence_get_next - * @return True if successful, otherwise false - */ -bool acc_detector_presence_distance_point_vector_get_next(acc_detector_presence_handle_t presence_handle, - uint16_t *distance_point_vector_length, - float **distance_point_vector, - acc_detector_presence_result_t *result); - - -/** - * @brief Get start of sweep in m - * - * @param[in] configuration The configuration to get the sweep start for - * @return requested sweep start in m - */ -float acc_detector_presence_configuration_start_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set start of sweep in m - * - * @param[in] configuration The configuration to set the sweep start for - * @param[in] start The requested sweep start in m - */ -void acc_detector_presence_configuration_start_set(acc_detector_presence_configuration_t configuration, float start); - - -/** - * @brief Get length of sweep in m - * - * @param[in] configuration The configuration to get the sweep length for - * @return requested sweep length in m - */ -float acc_detector_presence_configuration_length_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set length of sweep in m - * - * @param[in] configuration The configuration to set the requested sweep length for - * @param[in] length The requested sweep length in m - */ -void acc_detector_presence_configuration_length_set(acc_detector_presence_configuration_t configuration, float length); - - -/** - * @brief Get sensor ID - * - * @param[in] configuration The configuration to get the sensor ID for - * @return sensor ID - */ -acc_sensor_id_t acc_detector_presence_configuration_sensor_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set sensor ID - * - * @param[in] configuration The configuration to set the sensor ID for - * @param[in] sensor_id The sensor ID - */ -void acc_detector_presence_configuration_sensor_set(acc_detector_presence_configuration_t configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get detection threshold - * - * @param[in] configuration The configuration to get the detection threshold for - * @return detection threshold - */ -float acc_detector_presence_configuration_detection_threshold_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set detection threshold - * - * @param[in] configuration The configuration to set the detection threshold for - * @param[in] detection_threshold The threshold - */ -void acc_detector_presence_configuration_detection_threshold_set(acc_detector_presence_configuration_t configuration, - float detection_threshold); - - -/** - * @brief Get detection update rate - * - * Set the update rate of which the client call the detector to produce data. It's the clients responsibility - * to keep the configured timing. - * - * @param[in] configuration The configuration to get the detection update rate for - * @return detection update rate - */ -float acc_detector_presence_configuration_update_rate_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set detection update rate - * - * Set the update rate of which the client call the detector to produce data. It's the clients responsibility - * to keep the configured timing. - * - * @param[in] configuration The configuration to set the detection update rate for - * @param[in] update_rate - */ -void acc_detector_presence_configuration_update_rate_set(acc_detector_presence_configuration_t configuration, - float update_rate); - - -/** - * @brief Get the number of sweeps per frame - * - * @param[in] configuration The configuration to get the number of sweeps per frame for - * @return The number of sweeps per frame - */ -uint16_t acc_detector_presence_configuration_sweeps_per_frame_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set the number of sweeps per frame - * - * @param[in] configuration The configuration to set the number of sweeps per frame for - * @param[in] sweeps_per_frame The requested number of sweeps per frame - */ -void acc_detector_presence_configuration_sweeps_per_frame_set(acc_detector_presence_configuration_t configuration, - uint16_t sweeps_per_frame); - - -/** - * @brief Get the sweep rate - * - * Gets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. - * - * @param[in] configuration The configuration to get the sweep rate from - * @return sweep_rate The sweep rate - */ -float acc_detector_presence_configuration_sweep_rate_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set sweep rate - * - * Sets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. - * - * @param[in] configuration The configuration to set the sweep rate in - * @param[in] sweep_rate The sweep rate - */ -void acc_detector_presence_configuration_sweep_rate_set(acc_detector_presence_configuration_t configuration, float sweep_rate); - - -/** - * @brief Get sensor data filtering parameters - * - * See @ref acc_detector_presence_configuration_filter_parameters_set - * - * @param[in] configuration The configuration to get the filter parameters for - * @return The filter parameters, see @ref acc_detector_presence_configuration_filter_parameters_t - */ -acc_detector_presence_configuration_filter_parameters_t acc_detector_presence_configuration_filter_parameters_get( - acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set sensor data filtering parameters - * - * Set filter parameters for the sensor data filtering that is performed before presence detection thresholding. - * - * @param[in] configuration The configuration to set the filter parameters for - * @param[in] filter_parameters The filter parameter structure, see @ref acc_detector_presence_configuration_filter_parameters_t - */ -void acc_detector_presence_configuration_filter_parameters_set(acc_detector_presence_configuration_t configuration, - const acc_detector_presence_configuration_filter_parameters_t *filter_parameters); - - -/** - * @brief Get the number of principal components removed in the PCA based noise reduction - * - * @param[in] configuration The configuration to get the number of principal components of noise to remove for - * @return The number of principal components of noise to remove, between 0 and 2 - */ -uint8_t acc_detector_presence_configuration_nbr_removed_pc_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set the number of principal components removed in the PCA based noise reduction - * - * Sets the number of principal components removed in the PCA based noise reduction. - * Filters out static reflections. - * Setting to 0 (default) disables the PCA based noise reduction completely. - * For more information on the PCA based noise reduction algorithm, see - * Read-the-Docs - * - * @param[in] configuration The configuration to set the number of principal components of noise to remove for - * @param[in] nbr_removed_pc The number of principal components of noise to remove, between 0 and 2 - */ -void acc_detector_presence_configuration_nbr_removed_pc_set(acc_detector_presence_configuration_t configuration, uint8_t nbr_removed_pc); - - -/** - * @brief Get power save mode - * - * @param[in] configuration The configuration to get the power save mode for - * @return power save mode - */ -acc_power_save_mode_t acc_detector_presence_configuration_power_save_mode_get( - acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set power save mode - * - * @param[in] configuration The configuration to set the power save mode for - * @param[in] power_save_mode The power save mode - */ -void acc_detector_presence_configuration_power_save_mode_set(acc_detector_presence_configuration_t configuration, - acc_power_save_mode_t power_save_mode); - - -/** - * @brief Get the current service profile used by the detector - * - * See @ref acc_service_profile_t for details - * - * @param[in] configuration The configuration to get a profile from - * @return The current profile, 0 if configuration is invalid - */ -acc_service_profile_t acc_detector_presence_configuration_service_profile_get( - acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set a service profile to be used by the detector - * - * See @ref acc_service_profile_t for details - * - * @param[in] configuration The configuration to set a profile for - * @param[in] service_profile The profile to set - */ -void acc_detector_presence_configuration_service_profile_set(acc_detector_presence_configuration_t configuration, - acc_service_profile_t service_profile); - - -/** - * @brief Get the current receiver gain used by the detector - * - * @param[in] configuration The configuration to get gain from - * @return The current gain - */ -float acc_detector_presence_configuration_receiver_gain_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set a receiver gain to be used by the detector - * - * @param[in] configuration The configuration to set gain for - * @param[in] gain The gain to set - */ -void acc_detector_presence_configuration_receiver_gain_set(acc_detector_presence_configuration_t configuration, - float gain); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 3 makes - * the distance between two points in the measured range ~18cm. - * - * @param[in] configuration The configuration to get downsampling factor from - * @return The downsampling factor - */ -uint16_t acc_detector_presence_configuration_downsampling_factor_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 3 makes - * the distance between two points in the measured range ~18cm. - * - * The sparse service supports setting an arbitrary downsampling factor of at least 1. - * - * @param[in] configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_detector_presence_configuration_downsampling_factor_set(acc_detector_presence_configuration_t configuration, uint16_t downsampling_factor); - - -/** - * @brief Get the hardware accelerated average samples - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The configuration to get hardware accelerated average samples from - * @return Hardware accelerated average samples - */ -uint8_t acc_detector_presence_configuration_hw_accelerated_average_samples_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set the hardware accelerated average samples - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The configuration to set hardware accelerated average samples in - * @param[in] samples Hardware accelerated average samples - */ -void acc_detector_presence_configuration_hw_accelerated_average_samples_set(acc_detector_presence_configuration_t configuration, uint8_t samples); - - -/** - * @brief Get asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will measure while the host is waiting. - * In asynchronous mode the sensor will measure while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * @param[in] configuration The configuration to get asynchronous_measurement mode from - * @return Asynchronous measurement mode - */ -bool acc_detector_presence_configuration_asynchronous_measurement_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Set asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will measure while the host is waiting. - * In asynchronous mode the sensor will measure while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * @param[in] configuration The configuration to set asynchronous_measurement mode in - * @param[in] asynchronous_measurement asynchronous measurement mode, true or false - */ -void acc_detector_presence_configuration_asynchronous_measurement_set(acc_detector_presence_configuration_t configuration, - bool asynchronous_measurement); - - -/** - * @brief Gets vector output mode - * - * vector_output_mode decides whether or not the presence detector should output a distance point vector - * from the function @ref acc_detector_presence_distance_point_vector_get_next. - * - * @param[in] configuration The configuration to get vector_output_mode from - * @return vector_output_mode - */ -bool acc_detector_presence_configuration_vector_output_mode_get(acc_detector_presence_configuration_t configuration); - - -/** - * @brief Sets vector output mode - * - * vector_output_mode decides whether or not the presence detector should output a distance point vector. - * - * @param[in] configuration The configuration to set vector_output_mode in - * @param[in] vector_output_mode The vector_output_mode - */ -void acc_detector_presence_configuration_vector_output_mode_set(acc_detector_presence_configuration_t configuration, bool vector_output_mode); - - -/** - * @brief Set a callback function to get the service data - * - * A callback can be used to get the sparse service buffer. The data is the sparse data that is fed into the presence algorithm - * - * @param[in] configuration The configuration to set vector_output_mode in - * @param[in] service_data_callback The callback to get service data - * @param[in] client_reference Pointer to a client reference - */ -void acc_detector_presence_configuration_set_service_data_callback(acc_detector_presence_configuration_t configuration, - acc_detector_presence_service_data_callback_t service_data_callback, - void *client_reference); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2019-2022 +// All rights reserved + +#ifndef ACC_DETECTOR_PRESENCE_H_ +#define ACC_DETECTOR_PRESENCE_H_ + +#include +#include +#include + +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" + +/** + * @defgroup Presence Presence Detector + * @ingroup Detectors + * + * @brief Presence detector API description + * + * @{ + */ + + +/** + * @brief Presence detector handle + */ +struct acc_detector_presence_handle; + +typedef struct acc_detector_presence_handle *acc_detector_presence_handle_t; + + +/** + * @brief Presence detector configuration container + */ +struct acc_detector_presence_configuration; + +typedef struct acc_detector_presence_configuration *acc_detector_presence_configuration_t; + + +/** + * @brief Parameter structure for data filtering settings + */ +typedef struct +{ + /** Time constant in s for inter-frame signal smoothing after the bandpass filtering */ + float inter_frame_deviation_time_const; + /** Low pass cutoff frequency in Hz for inter-frame signal bandpass filtering */ + float inter_frame_fast_cutoff; + /** High pass cutoff frequency in Hz for inter-frame signal bandpass filtering */ + float inter_frame_slow_cutoff; + /** Time constant in s for inter-frame signal smoothing */ + float intra_frame_time_const; + /** Weight between 0 and 1 for presence score interpolation between the inter-frame and intra-frame signals */ + float intra_frame_weight; + /** Time constant in s for smoothing of the presence score */ + float output_time_const; +} acc_detector_presence_configuration_filter_parameters_t; + + +/** + * @brief Presence detector results container + */ +typedef struct +{ + /** True if presence was detected, False otherwise */ + bool presence_detected; + /** A measure of the amount of motion detected */ + float presence_score; + /** The distance, in meters, to the detected object */ + float presence_distance; + + /** Indication of a sensor communication error, detector probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; +} acc_detector_presence_result_t; + + +/** + * @brief A callback for retrieving the service data buffer that the detector is based on + * + * @param[in] data A pointer to the buffer with sparse data + * @param[in] data_size Size of the data buffer in bytes + * @param[in] client_reference Pointer to a client reference + */ +typedef void (*acc_detector_presence_service_data_callback_t)(const uint16_t *data, size_t data_size, void *client_reference); + + +/** + * @brief Create a configuration for a presence detector + * + * @return Presence detector configuration, NULL if creation was not possible + */ +acc_detector_presence_configuration_t acc_detector_presence_configuration_create(void); + + +/** + * @brief Destroy a presence detector configuration + * + * @param[in] presence_configuration The configuration to destroy, set to NULL + */ +void acc_detector_presence_configuration_destroy(acc_detector_presence_configuration_t *presence_configuration); + + +/** + * @brief Create a presence detector with the provided configuration + * + * Only one presence detector may exist for a specific sensor at any given time and + * invalid configurations will not allow for presence detector creation. + * + * @param[in] presence_configuration The presence detector configuration to create a presence detector with + * @return Presence detector handle, NULL if presence detector was not possible to create + */ +acc_detector_presence_handle_t acc_detector_presence_create(acc_detector_presence_configuration_t presence_configuration); + + +/** + * @brief Destroy a presence detector identified with the provided handle + * + * Destroy the context of a presence detector allowing another presence detector to be created using the + * same resources. The presence detector handle reference is set to NULL after destruction. + * If NULL is sent in, nothing happens. + * + * @param[in] presence_handle A reference to the presence detector handle to destroy + */ +void acc_detector_presence_destroy(acc_detector_presence_handle_t *presence_handle); + + +/** + * @brief Reconfigure a presence detector with the provided configuration + * + * Only one presence detector may exist for a specific sensor at any given time and + * invalid reconfigurations will not allow for presence detector creation. + * + * @param[in] presence_handle A reference to the presence detector handle to reconfigure + * @param[in] presence_configuration The presence detector configuration to reconfigure a presence detector with + * @return True if possible to reconfigure + */ +bool acc_detector_presence_reconfigure(acc_detector_presence_handle_t *presence_handle, + acc_detector_presence_configuration_t presence_configuration); + + +/** + * @brief Activate the presence detector associated with the provided handle + * + * @param[in] presence_handle The presence detector handle for the presence detector to activate + * @return True if successful, otherwise false + */ +bool acc_detector_presence_activate(acc_detector_presence_handle_t presence_handle); + + +/** + * @brief Deactivate the presence detector associated with the provided handle + * + * @param[in] presence_handle The presence detector handle for the presence detector to deactivate + * @return True if successful, otherwise false + */ +bool acc_detector_presence_deactivate(acc_detector_presence_handle_t presence_handle); + + +/** + * @brief Retrieve the next result from the presence detector + * + * May only be called after a presence detector has been activated, blocks + * the application until a result is ready. Can still be called after vector + * output mode has been selected. + * + * @param[in] presence_handle The presence detector handle for the presence detector to get the next result for + * @param[out] result Presence detector results, can be NULL if no result is wanted. + * @return True if successful, otherwise false + */ +bool acc_detector_presence_get_next(acc_detector_presence_handle_t presence_handle, acc_detector_presence_result_t *result); + + +/** + * @brief Retrieve the next distance point vector from the presence detector + * + * May only be called after a presence detector has been activated, blocks + * the application until a result is ready. Vector output mode has to be set + * to true with the function @ref acc_detector_presence_configuration_vector_output_mode_set, + * otherwise returns with an error. Memory is owned by the detector and the client receives a pointer. + * + * @param[in] presence_handle The presence detector handle for the presence detector to get the next result for + * @param[out] distance_point_vector_length The number of elements in the distance_point_vector, can be NULL if no result is wanted + * @param[out] distance_point_vector The distance point vector, can be NULL if no result is wanted + * @param[out] result Presence detector results, same as result from acc_detector_presence_get_next + * @return True if successful, otherwise false + */ +bool acc_detector_presence_distance_point_vector_get_next(acc_detector_presence_handle_t presence_handle, + uint16_t *distance_point_vector_length, + float **distance_point_vector, + acc_detector_presence_result_t *result); + + +/** + * @brief Get start of sweep in m + * + * @param[in] configuration The configuration to get the sweep start for + * @return requested sweep start in m + */ +float acc_detector_presence_configuration_start_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set start of sweep in m + * + * @param[in] configuration The configuration to set the sweep start for + * @param[in] start The requested sweep start in m + */ +void acc_detector_presence_configuration_start_set(acc_detector_presence_configuration_t configuration, float start); + + +/** + * @brief Get length of sweep in m + * + * @param[in] configuration The configuration to get the sweep length for + * @return requested sweep length in m + */ +float acc_detector_presence_configuration_length_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set length of sweep in m + * + * @param[in] configuration The configuration to set the requested sweep length for + * @param[in] length The requested sweep length in m + */ +void acc_detector_presence_configuration_length_set(acc_detector_presence_configuration_t configuration, float length); + + +/** + * @brief Get sensor ID + * + * @param[in] configuration The configuration to get the sensor ID for + * @return sensor ID + */ +acc_sensor_id_t acc_detector_presence_configuration_sensor_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set sensor ID + * + * @param[in] configuration The configuration to set the sensor ID for + * @param[in] sensor_id The sensor ID + */ +void acc_detector_presence_configuration_sensor_set(acc_detector_presence_configuration_t configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get detection threshold + * + * @param[in] configuration The configuration to get the detection threshold for + * @return detection threshold + */ +float acc_detector_presence_configuration_detection_threshold_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set detection threshold + * + * @param[in] configuration The configuration to set the detection threshold for + * @param[in] detection_threshold The threshold + */ +void acc_detector_presence_configuration_detection_threshold_set(acc_detector_presence_configuration_t configuration, + float detection_threshold); + + +/** + * @brief Get detection update rate + * + * Set the update rate of which the client call the detector to produce data. It's the clients responsibility + * to keep the configured timing. + * + * @param[in] configuration The configuration to get the detection update rate for + * @return detection update rate + */ +float acc_detector_presence_configuration_update_rate_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set detection update rate + * + * Set the update rate of which the client call the detector to produce data. It's the clients responsibility + * to keep the configured timing. + * + * @param[in] configuration The configuration to set the detection update rate for + * @param[in] update_rate + */ +void acc_detector_presence_configuration_update_rate_set(acc_detector_presence_configuration_t configuration, + float update_rate); + + +/** + * @brief Get the number of sweeps per frame + * + * @param[in] configuration The configuration to get the number of sweeps per frame for + * @return The number of sweeps per frame + */ +uint16_t acc_detector_presence_configuration_sweeps_per_frame_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set the number of sweeps per frame + * + * @param[in] configuration The configuration to set the number of sweeps per frame for + * @param[in] sweeps_per_frame The requested number of sweeps per frame + */ +void acc_detector_presence_configuration_sweeps_per_frame_set(acc_detector_presence_configuration_t configuration, + uint16_t sweeps_per_frame); + + +/** + * @brief Get the sweep rate + * + * Gets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. + * + * @param[in] configuration The configuration to get the sweep rate from + * @return sweep_rate The sweep rate + */ +float acc_detector_presence_configuration_sweep_rate_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set sweep rate + * + * Sets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. + * + * @param[in] configuration The configuration to set the sweep rate in + * @param[in] sweep_rate The sweep rate + */ +void acc_detector_presence_configuration_sweep_rate_set(acc_detector_presence_configuration_t configuration, float sweep_rate); + + +/** + * @brief Get sensor data filtering parameters + * + * See @ref acc_detector_presence_configuration_filter_parameters_set + * + * @param[in] configuration The configuration to get the filter parameters for + * @return The filter parameters, see @ref acc_detector_presence_configuration_filter_parameters_t + */ +acc_detector_presence_configuration_filter_parameters_t acc_detector_presence_configuration_filter_parameters_get( + acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set sensor data filtering parameters + * + * Set filter parameters for the sensor data filtering that is performed before presence detection thresholding. + * + * @param[in] configuration The configuration to set the filter parameters for + * @param[in] filter_parameters The filter parameter structure, see @ref acc_detector_presence_configuration_filter_parameters_t + */ +void acc_detector_presence_configuration_filter_parameters_set(acc_detector_presence_configuration_t configuration, + const acc_detector_presence_configuration_filter_parameters_t *filter_parameters); + + +/** + * @brief Get the number of principal components removed in the PCA based noise reduction + * + * @param[in] configuration The configuration to get the number of principal components of noise to remove for + * @return The number of principal components of noise to remove, between 0 and 2 + */ +uint8_t acc_detector_presence_configuration_nbr_removed_pc_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set the number of principal components removed in the PCA based noise reduction + * + * Sets the number of principal components removed in the PCA based noise reduction. + * Filters out static reflections. + * Setting to 0 (default) disables the PCA based noise reduction completely. + * For more information on the PCA based noise reduction algorithm, see + * Read-the-Docs + * + * @param[in] configuration The configuration to set the number of principal components of noise to remove for + * @param[in] nbr_removed_pc The number of principal components of noise to remove, between 0 and 2 + */ +void acc_detector_presence_configuration_nbr_removed_pc_set(acc_detector_presence_configuration_t configuration, uint8_t nbr_removed_pc); + + +/** + * @brief Get power save mode + * + * @param[in] configuration The configuration to get the power save mode for + * @return power save mode + */ +acc_power_save_mode_t acc_detector_presence_configuration_power_save_mode_get( + acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set power save mode + * + * @param[in] configuration The configuration to set the power save mode for + * @param[in] power_save_mode The power save mode + */ +void acc_detector_presence_configuration_power_save_mode_set(acc_detector_presence_configuration_t configuration, + acc_power_save_mode_t power_save_mode); + + +/** + * @brief Get the current service profile used by the detector + * + * See @ref acc_service_profile_t for details + * + * @param[in] configuration The configuration to get a profile from + * @return The current profile, 0 if configuration is invalid + */ +acc_service_profile_t acc_detector_presence_configuration_service_profile_get( + acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set a service profile to be used by the detector + * + * See @ref acc_service_profile_t for details + * + * @param[in] configuration The configuration to set a profile for + * @param[in] service_profile The profile to set + */ +void acc_detector_presence_configuration_service_profile_set(acc_detector_presence_configuration_t configuration, + acc_service_profile_t service_profile); + + +/** + * @brief Get the current receiver gain used by the detector + * + * @param[in] configuration The configuration to get gain from + * @return The current gain + */ +float acc_detector_presence_configuration_receiver_gain_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set a receiver gain to be used by the detector + * + * @param[in] configuration The configuration to set gain for + * @param[in] gain The gain to set + */ +void acc_detector_presence_configuration_receiver_gain_set(acc_detector_presence_configuration_t configuration, + float gain); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 3 makes + * the distance between two points in the measured range ~18cm. + * + * @param[in] configuration The configuration to get downsampling factor from + * @return The downsampling factor + */ +uint16_t acc_detector_presence_configuration_downsampling_factor_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 3 makes + * the distance between two points in the measured range ~18cm. + * + * The sparse service supports setting an arbitrary downsampling factor of at least 1. + * + * @param[in] configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_detector_presence_configuration_downsampling_factor_set(acc_detector_presence_configuration_t configuration, uint16_t downsampling_factor); + + +/** + * @brief Get the hardware accelerated average samples + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The configuration to get hardware accelerated average samples from + * @return Hardware accelerated average samples + */ +uint8_t acc_detector_presence_configuration_hw_accelerated_average_samples_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set the hardware accelerated average samples + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The configuration to set hardware accelerated average samples in + * @param[in] samples Hardware accelerated average samples + */ +void acc_detector_presence_configuration_hw_accelerated_average_samples_set(acc_detector_presence_configuration_t configuration, uint8_t samples); + + +/** + * @brief Get asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will measure while the host is waiting. + * In asynchronous mode the sensor will measure while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * @param[in] configuration The configuration to get asynchronous_measurement mode from + * @return Asynchronous measurement mode + */ +bool acc_detector_presence_configuration_asynchronous_measurement_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Set asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will measure while the host is waiting. + * In asynchronous mode the sensor will measure while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * @param[in] configuration The configuration to set asynchronous_measurement mode in + * @param[in] asynchronous_measurement asynchronous measurement mode, true or false + */ +void acc_detector_presence_configuration_asynchronous_measurement_set(acc_detector_presence_configuration_t configuration, + bool asynchronous_measurement); + + +/** + * @brief Gets vector output mode + * + * vector_output_mode decides whether or not the presence detector should output a distance point vector + * from the function @ref acc_detector_presence_distance_point_vector_get_next. + * + * @param[in] configuration The configuration to get vector_output_mode from + * @return vector_output_mode + */ +bool acc_detector_presence_configuration_vector_output_mode_get(acc_detector_presence_configuration_t configuration); + + +/** + * @brief Sets vector output mode + * + * vector_output_mode decides whether or not the presence detector should output a distance point vector. + * + * @param[in] configuration The configuration to set vector_output_mode in + * @param[in] vector_output_mode The vector_output_mode + */ +void acc_detector_presence_configuration_vector_output_mode_set(acc_detector_presence_configuration_t configuration, bool vector_output_mode); + + +/** + * @brief Set a callback function to get the service data + * + * A callback can be used to get the sparse service buffer. The data is the sparse data that is fed into the presence algorithm + * + * @param[in] configuration The configuration to set vector_output_mode in + * @param[in] service_data_callback The callback to get service data + * @param[in] client_reference Pointer to a client reference + */ +void acc_detector_presence_configuration_set_service_data_callback(acc_detector_presence_configuration_t configuration, + acc_detector_presence_service_data_callback_t service_data_callback, + void *client_reference); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_hal_definitions.h b/rss/include/acc_hal_definitions.h index 931c8c7..3f085c5 100644 --- a/rss/include/acc_hal_definitions.h +++ b/rss/include/acc_hal_definitions.h @@ -1,312 +1,312 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved - -#ifndef ACC_HAL_DEFINITIONS_H_ -#define ACC_HAL_DEFINITIONS_H_ - -#include -#include -#include -#include - -#include "acc_definitions_common.h" - - -/** - * @brief Defines the largest allowed value of a sensor ID - */ -#define ACC_SENSOR_ID_MAX 42U - -/** - * @brief Specifies the minimal size in bytes that SPI transfers must be able to handle - */ -#define ACC_SPI_TRANSFER_SIZE_REQUIRED 16 - -/** - * @brief Specifies the number of clock cycles needed for sensor to enter hibernate mode - */ -#define ACC_NBR_CLOCK_CYCLES_REQUIRED_HIBERNATE_ENTER 10 - -/** - * @brief Specifies the number of clock cycles needed for the first part of the sensor exiting hibernate mode - */ -#define ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_1_HIBERNATE_EXIT 3 - -/** - * @brief Specifies the number of clock cycles needed for the second part of the sensor exiting hibernate mode - */ -#define ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_2_HIBERNATE_EXIT (13 - ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_1_HIBERNATE_EXIT) - -/** - * @brief Specifies the number of millisonds of delay needed for the Oscillator to stabilize when exiting hibernate mode - */ -#define ACC_WAIT_TIME_HIBERNATE_EXIT_MS 2 - -/** - * @defgroup OS OS Integration - * @ingroup Integration - * - * @brief Integration OS primitives - * - * @{ - */ - - -/** - * @brief Definition of a memory allocation function - * - * Allocated memory should be suitably aligned for any built-in type. Returning NULL is seen as failure. - */ -typedef void *(*acc_os_mem_alloc_function_t)(size_t); - - -/** - * @brief Definition of a memory free function - * - * Free memory which is previously allocated. - */ -typedef void (*acc_os_mem_free_function_t)(void *); - - -/** - * @brief Definition of a time retrieval function - * - * The time returned must be in milliseconds. - * - * Must be implemented by integration. - */ -typedef uint32_t (*acc_os_get_time_function_t)(void); - - -/** - * @brief Struct that contains the implementation of os integration primitives - */ -typedef struct -{ - acc_os_mem_alloc_function_t mem_alloc; - acc_os_mem_free_function_t mem_free; - acc_os_get_time_function_t gettime; -} acc_rss_integration_os_primitives_t; - -/** - * @} - */ - - -/** - * @defgroup HAL Hardware Integration - * @ingroup Integration - * - * @brief Integration of Hardware Abstraction Layer for the radar sensor - * - * @{ - */ - - -/** - * @brief Definition of a sensor power function - * - * These functions control the power of the sensor. It typically control PS_ENABLE - * and PMU_ENABLE. The hibernate functions should also toggle the CTRL pin. - * - * In the case of the power_on function: - * Any pending sensor interrupts should be cleared before returning from function. - */ -typedef void (*acc_hal_sensor_power_function_t)(acc_sensor_id_t sensor_id); - - -/** - * @brief Definition of a hal get frequency function - * - * This function shall return the frequency of the reference clock connected to the sensor. - * - */ -typedef float (*acc_hal_get_frequency_function_t)(void); - - -/** - * @brief Definition of a wait for sensor interrupt function - * - * This function shall wait at most timeout_ms for the interrupt to become active and - * then return true. It may return true immediately if an interrupt have - * occurred since last call to this function. - * - * If waited more than timeout_ms for the interrupt to become active it shall - * return false. - * - * Note that this function can be called with a timeout_ms = 0. - * - */ -typedef bool (*acc_hal_sensor_wait_for_interrupt_function_t)(acc_sensor_id_t sensor_id, uint32_t timeout_ms); - - -/** - * @brief Definition of a sensor transfer function - * - * This function shall transfer data to and from the sensor over spi. It's beneficial from a performance perspective - * to use dma if available. - * The buffer is naturally aligned to a maximum of 4 bytes. - * - */ -typedef void (*acc_hal_sensor_transfer_function_t)(acc_sensor_id_t sensor_id, uint8_t *buffer, size_t buffer_size); - - -/** - * @brief This struct contains function pointers that point to - * functions needed for communication with the radar sensor. - */ -typedef struct -{ - acc_hal_sensor_power_function_t power_on; - acc_hal_sensor_power_function_t power_off; - acc_hal_sensor_power_function_t hibernate_enter; - acc_hal_sensor_power_function_t hibernate_exit; - acc_hal_sensor_wait_for_interrupt_function_t wait_for_interrupt; - acc_hal_sensor_transfer_function_t transfer; - acc_hal_get_frequency_function_t get_reference_frequency; -} acc_rss_integration_sensor_device_t; - - -/** - * @} - */ - - -/** - * @defgroup Properties Integration Properties - * @ingroup Integration - * - * @brief Integration specific properties that is used for configuration of RSS. - * - * Number of sensors connected to each board and the maximum buffer size that the - * spi driver can handle can be different between applications. These values shall - * be configured by the client. - * - * @{ - */ - - -/** - * @brief This struct contains information about board properties that - * are needed by RSS. - * - * @ref sensor_count is the maximal sensor ID that the integration layer supports. - * This value must not exceed @ref ACC_SENSOR_ID_MAX. - * - * @ref max_spi_transfer_size is the maximal buffer size that is supported - * by the implementation of @ref acc_hal_sensor_transfer_function_t. - * This value must not be smaller than @ref ACC_SPI_TRANSFER_SIZE_REQUIRED. - */ -typedef struct -{ - uint32_t sensor_count; - size_t max_spi_transfer_size; -} acc_rss_integration_properties_t; - -/** - * @} - */ - - -/** - * @defgroup Opimization Optional optimizations - * @ingroup Integration - * - * @brief Support for different optimizations - * - * @{ - */ - - -/** - * @brief Definition of an optimized 16-bit sensor transfer function - * - * This function shall transfer data to and from the sensor over spi with 16 bits data size. - * It's beneficial from a performance perspective to use dma if available. - * The buffer is naturally aligned to a minimum of 4 bytes. - * - * If defined it will be used instead of the (8-bit) transfer function @ref acc_hal_sensor_transfer_function_t - * - */ -typedef void (*acc_sensor_transfer16_function_t)(acc_sensor_id_t sensor_id, uint16_t *buffer, size_t buffer_length); - - -/** - * @brief This struct contains function pointers that are optional to support different optimizations - * - * Optional - * - * This struct contains function pointers to support different optimizations. - * These optimizations can be utilized for some integrations. - * If they are defined, they will override the corresponding non-optimized function. - * - * For example, if the transfer16 function is implemented, it will be used instead of the transfer function. - */ -typedef struct -{ - acc_sensor_transfer16_function_t transfer16; -} acc_optimization_t; - -/** - * @} - */ - - -/** - * @defgroup Log Log Integration - * @ingroup Integration - * - * @brief Integration for log functionality - * - * @{ - */ - - -/** - * @brief Definition of a log function - */ -typedef void (*acc_log_function_t)(acc_log_level_t level, const char *module, const char *format, ...); - - -/** - * @brief This struct contains information about log properties and functions - * needed by RSS - */ -typedef struct -{ - acc_log_level_t log_level; - acc_log_function_t log; -} acc_rss_integration_log_t; - - -/** - * @} - */ - - -/** - * @defgroup Integration Integration - * @brief Driver and OS Integration - * - * @{ - */ - - -/** - * @brief This struct contains the information about the sensor - * integration that RSS needs. - */ - -typedef struct -{ - acc_rss_integration_properties_t properties; - acc_rss_integration_os_primitives_t os; - acc_rss_integration_sensor_device_t sensor_device; - acc_rss_integration_log_t log; - acc_optimization_t optimization; -} acc_hal_t; - -/** - * @} - */ -#endif +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved + +#ifndef ACC_HAL_DEFINITIONS_H_ +#define ACC_HAL_DEFINITIONS_H_ + +#include +#include +#include +#include + +#include "acc_definitions_common.h" + + +/** + * @brief Defines the largest allowed value of a sensor ID + */ +#define ACC_SENSOR_ID_MAX 42U + +/** + * @brief Specifies the minimal size in bytes that SPI transfers must be able to handle + */ +#define ACC_SPI_TRANSFER_SIZE_REQUIRED 16 + +/** + * @brief Specifies the number of clock cycles needed for sensor to enter hibernate mode + */ +#define ACC_NBR_CLOCK_CYCLES_REQUIRED_HIBERNATE_ENTER 10 + +/** + * @brief Specifies the number of clock cycles needed for the first part of the sensor exiting hibernate mode + */ +#define ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_1_HIBERNATE_EXIT 3 + +/** + * @brief Specifies the number of clock cycles needed for the second part of the sensor exiting hibernate mode + */ +#define ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_2_HIBERNATE_EXIT (13 - ACC_NBR_CLOCK_CYCLES_REQUIRED_STEP_1_HIBERNATE_EXIT) + +/** + * @brief Specifies the number of millisonds of delay needed for the Oscillator to stabilize when exiting hibernate mode + */ +#define ACC_WAIT_TIME_HIBERNATE_EXIT_MS 2 + +/** + * @defgroup OS OS Integration + * @ingroup Integration + * + * @brief Integration OS primitives + * + * @{ + */ + + +/** + * @brief Definition of a memory allocation function + * + * Allocated memory should be suitably aligned for any built-in type. Returning NULL is seen as failure. + */ +typedef void *(*acc_os_mem_alloc_function_t)(size_t); + + +/** + * @brief Definition of a memory free function + * + * Free memory which is previously allocated. + */ +typedef void (*acc_os_mem_free_function_t)(void *); + + +/** + * @brief Definition of a time retrieval function + * + * The time returned must be in milliseconds. + * + * Must be implemented by integration. + */ +typedef uint32_t (*acc_os_get_time_function_t)(void); + + +/** + * @brief Struct that contains the implementation of os integration primitives + */ +typedef struct +{ + acc_os_mem_alloc_function_t mem_alloc; + acc_os_mem_free_function_t mem_free; + acc_os_get_time_function_t gettime; +} acc_rss_integration_os_primitives_t; + +/** + * @} + */ + + +/** + * @defgroup HAL Hardware Integration + * @ingroup Integration + * + * @brief Integration of Hardware Abstraction Layer for the radar sensor + * + * @{ + */ + + +/** + * @brief Definition of a sensor power function + * + * These functions control the power of the sensor. It typically control PS_ENABLE + * and PMU_ENABLE. The hibernate functions should also toggle the CTRL pin. + * + * In the case of the power_on function: + * Any pending sensor interrupts should be cleared before returning from function. + */ +typedef void (*acc_hal_sensor_power_function_t)(acc_sensor_id_t sensor_id); + + +/** + * @brief Definition of a hal get frequency function + * + * This function shall return the frequency of the reference clock connected to the sensor. + * + */ +typedef float (*acc_hal_get_frequency_function_t)(void); + + +/** + * @brief Definition of a wait for sensor interrupt function + * + * This function shall wait at most timeout_ms for the interrupt to become active and + * then return true. It may return true immediately if an interrupt have + * occurred since last call to this function. + * + * If waited more than timeout_ms for the interrupt to become active it shall + * return false. + * + * Note that this function can be called with a timeout_ms = 0. + * + */ +typedef bool (*acc_hal_sensor_wait_for_interrupt_function_t)(acc_sensor_id_t sensor_id, uint32_t timeout_ms); + + +/** + * @brief Definition of a sensor transfer function + * + * This function shall transfer data to and from the sensor over spi. It's beneficial from a performance perspective + * to use dma if available. + * The buffer is naturally aligned to a maximum of 4 bytes. + * + */ +typedef void (*acc_hal_sensor_transfer_function_t)(acc_sensor_id_t sensor_id, uint8_t *buffer, size_t buffer_size); + + +/** + * @brief This struct contains function pointers that point to + * functions needed for communication with the radar sensor. + */ +typedef struct +{ + acc_hal_sensor_power_function_t power_on; + acc_hal_sensor_power_function_t power_off; + acc_hal_sensor_power_function_t hibernate_enter; + acc_hal_sensor_power_function_t hibernate_exit; + acc_hal_sensor_wait_for_interrupt_function_t wait_for_interrupt; + acc_hal_sensor_transfer_function_t transfer; + acc_hal_get_frequency_function_t get_reference_frequency; +} acc_rss_integration_sensor_device_t; + + +/** + * @} + */ + + +/** + * @defgroup Properties Integration Properties + * @ingroup Integration + * + * @brief Integration specific properties that is used for configuration of RSS. + * + * Number of sensors connected to each board and the maximum buffer size that the + * spi driver can handle can be different between applications. These values shall + * be configured by the client. + * + * @{ + */ + + +/** + * @brief This struct contains information about board properties that + * are needed by RSS. + * + * @ref sensor_count is the maximal sensor ID that the integration layer supports. + * This value must not exceed @ref ACC_SENSOR_ID_MAX. + * + * @ref max_spi_transfer_size is the maximal buffer size that is supported + * by the implementation of @ref acc_hal_sensor_transfer_function_t. + * This value must not be smaller than @ref ACC_SPI_TRANSFER_SIZE_REQUIRED. + */ +typedef struct +{ + uint32_t sensor_count; + size_t max_spi_transfer_size; +} acc_rss_integration_properties_t; + +/** + * @} + */ + + +/** + * @defgroup Opimization Optional optimizations + * @ingroup Integration + * + * @brief Support for different optimizations + * + * @{ + */ + + +/** + * @brief Definition of an optimized 16-bit sensor transfer function + * + * This function shall transfer data to and from the sensor over spi with 16 bits data size. + * It's beneficial from a performance perspective to use dma if available. + * The buffer is naturally aligned to a minimum of 4 bytes. + * + * If defined it will be used instead of the (8-bit) transfer function @ref acc_hal_sensor_transfer_function_t + * + */ +typedef void (*acc_sensor_transfer16_function_t)(acc_sensor_id_t sensor_id, uint16_t *buffer, size_t buffer_length); + + +/** + * @brief This struct contains function pointers that are optional to support different optimizations + * + * Optional + * + * This struct contains function pointers to support different optimizations. + * These optimizations can be utilized for some integrations. + * If they are defined, they will override the corresponding non-optimized function. + * + * For example, if the transfer16 function is implemented, it will be used instead of the transfer function. + */ +typedef struct +{ + acc_sensor_transfer16_function_t transfer16; +} acc_optimization_t; + +/** + * @} + */ + + +/** + * @defgroup Log Log Integration + * @ingroup Integration + * + * @brief Integration for log functionality + * + * @{ + */ + + +/** + * @brief Definition of a log function + */ +typedef void (*acc_log_function_t)(acc_log_level_t level, const char *module, const char *format, ...); + + +/** + * @brief This struct contains information about log properties and functions + * needed by RSS + */ +typedef struct +{ + acc_log_level_t log_level; + acc_log_function_t log; +} acc_rss_integration_log_t; + + +/** + * @} + */ + + +/** + * @defgroup Integration Integration + * @brief Driver and OS Integration + * + * @{ + */ + + +/** + * @brief This struct contains the information about the sensor + * integration that RSS needs. + */ + +typedef struct +{ + acc_rss_integration_properties_t properties; + acc_rss_integration_os_primitives_t os; + acc_rss_integration_sensor_device_t sensor_device; + acc_rss_integration_log_t log; + acc_optimization_t optimization; +} acc_hal_t; + +/** + * @} + */ +#endif diff --git a/rss/include/acc_rss.h b/rss/include/acc_rss.h index e388af9..6edc083 100644 --- a/rss/include/acc_rss.h +++ b/rss/include/acc_rss.h @@ -1,148 +1,148 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved - -#ifndef ACC_RSS_H_ -#define ACC_RSS_H_ - -#include - -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" -#include "acc_hal_definitions.h" - - -/** - * @defgroup RSS Radar System Software, RSS - * - * @brief Acconeer Radar System Software, RSS - * - * @{ - */ - - -/** - * @brief Activate the Acconeer Radar System Software, RSS - * - * A HAL struct containing integration functions (such as 'wait_for_interrupt', 'mem_alloc' and 'log') - * needed by RSS must first be populated and then sent in. See 'acc_definitions_common.h' for a full list - * of functions needed. - * - * This function must be called before any other RSS function. If it is not, or it failed, - * calling any other RSS function is undefined behaviour. - * - * @param[in] hal Reference to a HAL struct containing integration functions that is needed by RSS - * @return True if RSS activated successfully - */ -bool acc_rss_activate(const acc_hal_t *hal); - - -/** - * @brief Deactivate the Acconeer Radar System Software, RSS - */ -void acc_rss_deactivate(void); - - -/** - * @brief Get the sensor calibration context - * - * Must be called after RSS has been activated. - * A calibration will be done for the specific sensor. - * A successful call to this function will also trigger context reset. - * - * @param[in] sensor_id The sensor to get the context for - * @param[out] calibration_context Reference to struct where the context will be stored - * @return True if successful, false otherwise - */ -bool acc_rss_calibration_context_get(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); - - -/** - * @brief Set a previously saved sensor calibration context and verify that the sensor calibration context is valid - * - * Must be called after RSS has been activated. - * No active service is allowed on the sensor when setting the context. - * If this function is successfully called, a new sensor calibration will not be done during service creation step. - * - * @param[in] sensor_id The sensor to set the context on - * @param[in] calibration_context The calibration context to set - * - * @return True if successful, false otherwise - */ -bool acc_rss_calibration_context_set(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); - - -/** - * @brief Set a previously saved sensor calibration context, ignore the result from calibration context validation - * - * Must be called after RSS has been activated. Must only be used with a fresh calibration context - * immediately after a successfull call to acc_rss_calibration_context_get. - * No active service is allowed on the sensor when setting the context. - * If this function is successfully called, a new sensor calibration will not be done during service creation step. - * - * @param[in] sensor_id The sensor to set the context on - * @param[in] calibration_context The calibration context to set - * - * @return True if successful, false otherwise - */ -bool acc_rss_calibration_context_forced_set(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); - - -/** - * @brief Reset a calibration done on the specific sensor (or remove a previously set calibration context) - * - * No active service is allowed on the sensor when resetting the calibration - * If this function is successfully called, a new sensor calibration will be done during service creation step. - * - * @param[in] sensor_id The sensor to reset the calibration on - * - * @return True if successful, false otherwise - */ -bool acc_rss_calibration_reset(acc_sensor_id_t sensor_id); - - -/** - * @brief Enable or disable check of sensor id when creating a service or detector - * - * Must be called after RSS has been activated and before creating several services or detectors for the same sensor id. - * After this function is called, with enable override set to true, it is possible to create several services or - * detectors for the same sensor id. It is still only possible to have one service or detector per sensor id active - * at the same time. - * - * @param[in] enable_override True if the sensor id check override should be enabled - */ -void acc_rss_override_sensor_id_check_at_creation(bool enable_override); - - -/** - * @brief Check if a sensor is connected at the specified sensor id - * - * This function will try to communicate with the sensor at the specified sensor id. - * @details - * - This function must be called after @ref acc_rss_activate. - * - This function must be called before any service is created. - * - * @param[in] sensor_id The sensor to check the connection status for - * @param[out] connected True if a sensor is connected at the specified sensor id - * - * @return True if successful, false otherwise - */ -bool acc_rss_sensor_connected(acc_sensor_id_t sensor_id, bool *connected); - - -/** - * @brief Set the log level that determines when the integration HAL logger function is called - * - * This function enables adjustment of the log level after RSS has been activated. Shall be called when - * RSS is active as it has no effect otherwise. The severity of the logged messages is selected in the - * same way as for log.log_level in @ref acc_hal_t. - * - * @param[in] level The severity level for selection of log output via @ref acc_log_function_t. - */ -void acc_rss_log_level_set(acc_log_level_t level); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved + +#ifndef ACC_RSS_H_ +#define ACC_RSS_H_ + +#include + +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" +#include "acc_hal_definitions.h" + + +/** + * @defgroup RSS Radar System Software, RSS + * + * @brief Acconeer Radar System Software, RSS + * + * @{ + */ + + +/** + * @brief Activate the Acconeer Radar System Software, RSS + * + * A HAL struct containing integration functions (such as 'wait_for_interrupt', 'mem_alloc' and 'log') + * needed by RSS must first be populated and then sent in. See 'acc_definitions_common.h' for a full list + * of functions needed. + * + * This function must be called before any other RSS function. If it is not, or it failed, + * calling any other RSS function is undefined behaviour. + * + * @param[in] hal Reference to a HAL struct containing integration functions that is needed by RSS + * @return True if RSS activated successfully + */ +bool acc_rss_activate(const acc_hal_t *hal); + + +/** + * @brief Deactivate the Acconeer Radar System Software, RSS + */ +void acc_rss_deactivate(void); + + +/** + * @brief Get the sensor calibration context + * + * Must be called after RSS has been activated. + * A calibration will be done for the specific sensor. + * A successful call to this function will also trigger context reset. + * + * @param[in] sensor_id The sensor to get the context for + * @param[out] calibration_context Reference to struct where the context will be stored + * @return True if successful, false otherwise + */ +bool acc_rss_calibration_context_get(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); + + +/** + * @brief Set a previously saved sensor calibration context and verify that the sensor calibration context is valid + * + * Must be called after RSS has been activated. + * No active service is allowed on the sensor when setting the context. + * If this function is successfully called, a new sensor calibration will not be done during service creation step. + * + * @param[in] sensor_id The sensor to set the context on + * @param[in] calibration_context The calibration context to set + * + * @return True if successful, false otherwise + */ +bool acc_rss_calibration_context_set(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); + + +/** + * @brief Set a previously saved sensor calibration context, ignore the result from calibration context validation + * + * Must be called after RSS has been activated. Must only be used with a fresh calibration context + * immediately after a successfull call to acc_rss_calibration_context_get. + * No active service is allowed on the sensor when setting the context. + * If this function is successfully called, a new sensor calibration will not be done during service creation step. + * + * @param[in] sensor_id The sensor to set the context on + * @param[in] calibration_context The calibration context to set + * + * @return True if successful, false otherwise + */ +bool acc_rss_calibration_context_forced_set(acc_sensor_id_t sensor_id, acc_calibration_context_t *calibration_context); + + +/** + * @brief Reset a calibration done on the specific sensor (or remove a previously set calibration context) + * + * No active service is allowed on the sensor when resetting the calibration + * If this function is successfully called, a new sensor calibration will be done during service creation step. + * + * @param[in] sensor_id The sensor to reset the calibration on + * + * @return True if successful, false otherwise + */ +bool acc_rss_calibration_reset(acc_sensor_id_t sensor_id); + + +/** + * @brief Enable or disable check of sensor id when creating a service or detector + * + * Must be called after RSS has been activated and before creating several services or detectors for the same sensor id. + * After this function is called, with enable override set to true, it is possible to create several services or + * detectors for the same sensor id. It is still only possible to have one service or detector per sensor id active + * at the same time. + * + * @param[in] enable_override True if the sensor id check override should be enabled + */ +void acc_rss_override_sensor_id_check_at_creation(bool enable_override); + + +/** + * @brief Check if a sensor is connected at the specified sensor id + * + * This function will try to communicate with the sensor at the specified sensor id. + * @details + * - This function must be called after @ref acc_rss_activate. + * - This function must be called before any service is created. + * + * @param[in] sensor_id The sensor to check the connection status for + * @param[out] connected True if a sensor is connected at the specified sensor id + * + * @return True if successful, false otherwise + */ +bool acc_rss_sensor_connected(acc_sensor_id_t sensor_id, bool *connected); + + +/** + * @brief Set the log level that determines when the integration HAL logger function is called + * + * This function enables adjustment of the log level after RSS has been activated. Shall be called when + * RSS is active as it has no effect otherwise. The severity of the logged messages is selected in the + * same way as for log.log_level in @ref acc_hal_t. + * + * @param[in] level The severity level for selection of log output via @ref acc_log_function_t. + */ +void acc_rss_log_level_set(acc_log_level_t level); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_rss_assembly_test.h b/rss/include/acc_rss_assembly_test.h index 7bb9cef..9640217 100644 --- a/rss/include/acc_rss_assembly_test.h +++ b/rss/include/acc_rss_assembly_test.h @@ -1,227 +1,227 @@ -// Copyright (c) Acconeer AB, 2019-2022 -// All rights reserved - -#ifndef ACC_RSS_ASSEMBLY_TEST_H_ -#define ACC_RSS_ASSEMBLY_TEST_H_ - -#include "acc_definitions_common.h" -#include - - -#define ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS (20U) - - -/** - * @defgroup Assembly_test Assembly test - * @ingroup RSS - * - * @brief RSS Assembly test - * - * @{ - */ - - -/** - * @brief The result of an assembly test run - */ -typedef struct -{ - const char *test_name; - bool test_passed; -} acc_rss_assembly_test_result_t; - - -/** - * @brief Assembly test configuration container - */ -struct acc_rss_assembly_test_configuration; - -typedef struct acc_rss_assembly_test_configuration *acc_rss_assembly_test_configuration_t; - - -/** - * @brief Create a configuration for an assembly test run - * - * @return An assembly test configuration, NULL if creation was not possible - */ -acc_rss_assembly_test_configuration_t acc_rss_assembly_test_configuration_create(void); - - -/** - * @brief Destroy an assembly test configuration - * - * The assembly test configuration reference is set to NULL after destruction. - * - * @param[in] configuration The configuration to destroy, set to NULL - */ -void acc_rss_assembly_test_configuration_destroy(acc_rss_assembly_test_configuration_t *configuration); - - -/** - * @brief Set the sensor id - * - * @param[in] configuration An assembly test configuration - * @param[in] sensor_id The sensor id to set - */ -void acc_rss_assembly_test_configuration_sensor_set(acc_rss_assembly_test_configuration_t configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get the sensor id that is configured - * - * @param[in] configuration An assembly test configuration - * @return Sensor id - */ -acc_sensor_id_t acc_rss_assembly_test_configuration_sensor_get(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the sensor communication read test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_read_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the sensor communication read test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_read_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the sensor communication write and read test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_write_read_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the sensor communication write and read test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_write_read_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enalbe the sensor communication interrupt test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_interrupt_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the sensor communication interrupt test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_interrupt_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the sensor communication hibernate test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_hibernate_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the sensor communication hibernate test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_communication_hibernate_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the supply test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_supply_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the supply test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_supply_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the clock test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_clock_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the clock test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_clock_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Enable the power cycle test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_power_cycle_test_enable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable the power cycle test - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_power_cycle_test_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Disable all tests - * - * @param[in] configuration An assembly test configuration - */ -void acc_rss_assembly_test_configuration_all_tests_disable(acc_rss_assembly_test_configuration_t configuration); - - -/** - * @brief Run assembly test - * - * This function executes a suite of tests suitable for PCB assembly testing. - * - * @details The caller need to allocate an array of assembly test results of at least the size - * of ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS. The array size is to be provided in the - * nr_of_test_results parameter. If the size is not sufficiently large the test will - * fail. - * - * If a test fails to execute the return value will be set to false. - * If a test cannot pass its test limits the test_passed member of test_results will be - * set to false but the return value of this function will still be true. - * - * @param[in] test_configuration The test configuration - * @param[out] test_results Reference to struct where the test results will be stored - * @param[in,out] nr_of_test_results Input is the maximum number of items in the results array. - * Output is the actual number of test results available after - * the execution of the tests. - * @return True if successfully run, false otherwise - */ -bool acc_rss_assembly_test(acc_rss_assembly_test_configuration_t test_configuration, acc_rss_assembly_test_result_t *test_results, - uint16_t *nr_of_test_results); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2019-2022 +// All rights reserved + +#ifndef ACC_RSS_ASSEMBLY_TEST_H_ +#define ACC_RSS_ASSEMBLY_TEST_H_ + +#include "acc_definitions_common.h" +#include + + +#define ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS (20U) + + +/** + * @defgroup Assembly_test Assembly test + * @ingroup RSS + * + * @brief RSS Assembly test + * + * @{ + */ + + +/** + * @brief The result of an assembly test run + */ +typedef struct +{ + const char *test_name; + bool test_passed; +} acc_rss_assembly_test_result_t; + + +/** + * @brief Assembly test configuration container + */ +struct acc_rss_assembly_test_configuration; + +typedef struct acc_rss_assembly_test_configuration *acc_rss_assembly_test_configuration_t; + + +/** + * @brief Create a configuration for an assembly test run + * + * @return An assembly test configuration, NULL if creation was not possible + */ +acc_rss_assembly_test_configuration_t acc_rss_assembly_test_configuration_create(void); + + +/** + * @brief Destroy an assembly test configuration + * + * The assembly test configuration reference is set to NULL after destruction. + * + * @param[in] configuration The configuration to destroy, set to NULL + */ +void acc_rss_assembly_test_configuration_destroy(acc_rss_assembly_test_configuration_t *configuration); + + +/** + * @brief Set the sensor id + * + * @param[in] configuration An assembly test configuration + * @param[in] sensor_id The sensor id to set + */ +void acc_rss_assembly_test_configuration_sensor_set(acc_rss_assembly_test_configuration_t configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get the sensor id that is configured + * + * @param[in] configuration An assembly test configuration + * @return Sensor id + */ +acc_sensor_id_t acc_rss_assembly_test_configuration_sensor_get(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the sensor communication read test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_read_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the sensor communication read test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_read_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the sensor communication write and read test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_write_read_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the sensor communication write and read test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_write_read_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enalbe the sensor communication interrupt test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_interrupt_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the sensor communication interrupt test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_interrupt_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the sensor communication hibernate test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_hibernate_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the sensor communication hibernate test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_communication_hibernate_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the supply test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_supply_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the supply test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_supply_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the clock test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_clock_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the clock test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_clock_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Enable the power cycle test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_power_cycle_test_enable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable the power cycle test + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_power_cycle_test_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Disable all tests + * + * @param[in] configuration An assembly test configuration + */ +void acc_rss_assembly_test_configuration_all_tests_disable(acc_rss_assembly_test_configuration_t configuration); + + +/** + * @brief Run assembly test + * + * This function executes a suite of tests suitable for PCB assembly testing. + * + * @details The caller need to allocate an array of assembly test results of at least the size + * of ACC_RSS_ASSEMBLY_TEST_MAX_NUMBER_OF_TESTS. The array size is to be provided in the + * nr_of_test_results parameter. If the size is not sufficiently large the test will + * fail. + * + * If a test fails to execute the return value will be set to false. + * If a test cannot pass its test limits the test_passed member of test_results will be + * set to false but the return value of this function will still be true. + * + * @param[in] test_configuration The test configuration + * @param[out] test_results Reference to struct where the test results will be stored + * @param[in,out] nr_of_test_results Input is the maximum number of items in the results array. + * Output is the actual number of test results available after + * the execution of the tests. + * @return True if successfully run, false otherwise + */ +bool acc_rss_assembly_test(acc_rss_assembly_test_configuration_t test_configuration, acc_rss_assembly_test_result_t *test_results, + uint16_t *nr_of_test_results); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_rss_diagnostics.h b/rss/include/acc_rss_diagnostics.h index 2e30886..536c82b 100644 --- a/rss/include/acc_rss_diagnostics.h +++ b/rss/include/acc_rss_diagnostics.h @@ -1,41 +1,41 @@ -// Copyright (c) Acconeer AB, 2019-2021 -// All rights reserved - -#ifndef ACC_RSS_DIAGNOSTICS_H_ -#define ACC_RSS_DIAGNOSTICS_H_ - -#include "acc_definitions_common.h" -#include - - -/** - * @defgroup Diagnostic_test Diagnostic test - * @ingroup RSS - * - * @brief RSS Diagnostic test - * - * @{ - */ - - -/** - * @brief Run diagnostic test - * - * This function executes a suite of tests for diagnostic testing of the A111 sensor. - * - * @details - * - This function must be called after #acc_rss_activate. - * - This function must be called before any service is created. - * - If a test fails to execute the return value will be set to false. - * - * @param[in] sensor_id The sensor to run diagnostic test on - * @return True if successfully run, false otherwise - */ -bool acc_rss_diagnostic_test(acc_sensor_id_t sensor_id); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2019-2021 +// All rights reserved + +#ifndef ACC_RSS_DIAGNOSTICS_H_ +#define ACC_RSS_DIAGNOSTICS_H_ + +#include "acc_definitions_common.h" +#include + + +/** + * @defgroup Diagnostic_test Diagnostic test + * @ingroup RSS + * + * @brief RSS Diagnostic test + * + * @{ + */ + + +/** + * @brief Run diagnostic test + * + * This function executes a suite of tests for diagnostic testing of the A111 sensor. + * + * @details + * - This function must be called after #acc_rss_activate. + * - This function must be called before any service is created. + * - If a test fails to execute the return value will be set to false. + * + * @param[in] sensor_id The sensor to run diagnostic test on + * @return True if successfully run, false otherwise + */ +bool acc_rss_diagnostic_test(acc_sensor_id_t sensor_id); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_service.h b/rss/include/acc_service.h index e1e3907..26d9c2d 100644 --- a/rss/include/acc_service.h +++ b/rss/include/acc_service.h @@ -1,429 +1,429 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved - -#ifndef ACC_SERVICE_H_ -#define ACC_SERVICE_H_ - -#include - -#include "acc_base_configuration.h" -#include "acc_definitions_a111.h" -#include "acc_definitions_common.h" - -/** - * @defgroup Services Services - * - * @brief Radar services provided by Acconeer - * - * @defgroup Experimental Experimental - * @brief Features in an early version - * - * In our code you might encounter features tagged “Experimental”. - * This means that the feature in question is an early version that has a - * limited test scope, and the API and/or functionality might change in - * upcoming releases. - * - * The intention is to let users try these features out and we appreciate - * feedback. - * - * @defgroup Generic Generic Service API - * @ingroup Services - * - * @brief Generic service API description - * - * @{ - */ - - -/** - * @brief Generic service configuration container - */ -struct acc_service_configuration; - -typedef struct acc_service_configuration *acc_service_configuration_t; - - -/** - * @brief Generic service handle - */ -struct acc_service_handle; - -typedef struct acc_service_handle *acc_service_handle_t; - - -/** - * @brief Create a service with the provided configuration - * - * Only one service may exist for a specific sensor at any given time, - * unless @ref acc_rss_override_sensor_id_check_at_creation has been invoked. - * Invalid configurations will not allow for service creation. - * - * @param[in] configuration The service configuration to create a service with - * @return Service handle, NULL if service was not possible to create - */ -acc_service_handle_t acc_service_create(acc_service_configuration_t configuration); - - -/** - * @brief Activate the service associated with the provided handle - * - * When activated, the application can get data from the service with the - * associated handle. - * - * @param[in] service_handle The service handle for the service to activate - * @return True if successful, false otherwise - */ -bool acc_service_activate(acc_service_handle_t service_handle); - - -/** - * @brief Deactivate the service associated with the provided handle - * - * @param[in] service_handle The service handle for the service to deactivate - * @return True if successful, false otherwise - */ -bool acc_service_deactivate(acc_service_handle_t service_handle); - - -/** - * @brief Destroy a service identified with the provided service handle - * - * Destroy the context of a service allowing another service to be created using the - * same resources. The service handle reference is set to NULL after destruction. - * - * @param[in] service_handle A reference to the service handle to destroy - */ -void acc_service_destroy(acc_service_handle_t *service_handle); - - -/** - * @brief Retrieve a base configuration from a service configuration - * - * The base configuration can be used to configure the service for different use cases. - * See @ref acc_base_configuration.h for configuration parameters. - * - * @param[in] service_configuration The service configuration to get a base configuration from - * @return Base configuration, NULL if the service configuration does not contain a base configuration - */ -acc_base_configuration_t acc_service_get_base_configuration(acc_service_configuration_t service_configuration); - - -/** - * @brief Get the sensor ID for the sensor to be configured - * - * @param[in] configuration The service configuration to get the sensor id from - * @return Sensor Id - */ -acc_sensor_id_t acc_service_sensor_get(acc_service_configuration_t configuration); - - -/** - * @brief Set the sensor ID for the sensor to be configured - * - * @param[in] configuration The service configuration to set the sensor id in - * @param[in] sensor_id The sensor id to set - */ -void acc_service_sensor_set(acc_service_configuration_t configuration, acc_sensor_id_t sensor_id); - - -/** - * @brief Get the requested start of the sweep - * - * @param[in] configuration The service configuration to get the requested start from - * @return Requested start - */ -float acc_service_requested_start_get(acc_service_configuration_t configuration); - - -/** - * @brief Set the requested start of the sweep - * - * @param[in] configuration The service configuration to set the requested start in - * @param[in] start_m The requested start in meters - */ -void acc_service_requested_start_set(acc_service_configuration_t configuration, float start_m); - - -/** - * @brief Get the requested length of the sweep - * - * @param[in] configuration The service configuration to get the requested length from - * @return Requested length - */ -float acc_service_requested_length_get(acc_service_configuration_t configuration); - - -/** - * @brief Set the requested length of the sweep - * - * @param[in] configuration The service configuration to set the requested length in - * @param[in] length_m The requested length in meters - */ -void acc_service_requested_length_set(acc_service_configuration_t configuration, float length_m); - - -/** - * @brief Set the service repetition mode to on demand - * - * In on demand mode, the sensor produces data when requested by the application. - * The application is also responsible for the timing between updates. - * - * This mode must be used if the configured length requires stitching in the service. - * - * @param[in] configuration The service configuration to set on demand mode in - */ -void acc_service_repetition_mode_on_demand_set(acc_service_configuration_t configuration); - - -/** - * @brief Set the service repetition mode to streaming mode - * - * The sensor produces data according to the configured update rate using sensor - * hardware timing which is very accurate. - * - * @param[in] configuration The service configuration to set streaming mode in - * @param[in] update_rate The output data rate from the service in hertz - */ -void acc_service_repetition_mode_streaming_set(acc_service_configuration_t configuration, float update_rate); - - -/** - * @brief Get power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data frame aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] configuration The service configuration to get power save mode for - * @return Power save mode - */ -acc_power_save_mode_t acc_service_power_save_mode_get(acc_service_configuration_t configuration); - - -/** - * @brief Set power save mode - * - * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown - * between data frame aquisition. The supported power save modes are defined in - * @ref acc_power_save_mode_enum_t. - * - * @param[in] configuration The service configuration to set power save mode in - * @param[in] power_save_mode The power save mode to use - */ -void acc_service_power_save_mode_set(acc_service_configuration_t configuration, - acc_power_save_mode_t power_save_mode); - - -/** - * @brief Get receiver gain setting - * - * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] configuration The service configuration to get receiver gain setting for - * @return Receiver gain setting - */ -float acc_service_receiver_gain_get(acc_service_configuration_t configuration); - - -/** - * @brief Set receiver gain setting - * - * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. - * - * @param[in] configuration The service configuration to set receiver gain setting in - * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 - */ -void acc_service_receiver_gain_set(acc_service_configuration_t configuration, float gain); - - -/** - * @brief Get TX disable mode - * - * Will be true if TX is disabled, false otherwise. - * - * @param[in] configuration The service configuration to get TX disable mode for - * @return TX disable mode - */ -bool acc_service_tx_disable_get(acc_service_configuration_t configuration); - - -/** - * @brief Set TX disable mode - * - * If set to true, TX disable mode is enabled. This will disable the radio transmitter. - * To measure RX noise floor, it is recommended to also switch off internal - * noise level normalization (see each service if applicable). - * - * @param[in] configuration The service configuration to set TX disable mode in - * @param[in] tx_disable TX disable mode, true or false - */ -void acc_service_tx_disable_set(acc_service_configuration_t configuration, bool tx_disable); - - -/** - * @brief Get the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The service configuration to get hardware accelerated average samples from - * @return Hardware accelerated average samples - */ -uint8_t acc_service_hw_accelerated_average_samples_get(acc_service_configuration_t configuration); - - -/** - * @brief Set the hardware accelerated average samples (HWAAS) - * - * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then - * produces an average value of those samples. The time needed to measure a sweep is roughly proportional - * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS - * could be decreased but this leads to lower SNR. - * - * @param[in] configuration The service configuration to set hardware accelerated average samples in - * @param[in] samples Hardware accelerated average samples - */ -void acc_service_hw_accelerated_average_samples_set(acc_service_configuration_t configuration, uint8_t samples); - - -/** - * @brief Get asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will generate sweep data while the host is waiting. - * In asynchronous mode the sensor will generate sweep data while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * Setting asynchronous measurement to false (i.e using synchronous mode) is incompatible - * with repetition mode streaming where the sensor is in control of the update rate timing. - * - * @param[in] configuration The service configuration to get asynchronous_measurement mode from - * @return asynchronous measurement mode - */ -bool acc_service_asynchronous_measurement_get(acc_service_configuration_t configuration); - - -/** - * @brief Set asynchronous measurement mode - * - * If set to true, asynchronous measurement is enabled. - * In synchronous mode the sensor will generate sweep data while the host is waiting. - * In asynchronous mode the sensor will generate sweep data while the host is working. - * - * This means that if in synchronous mode, the sensor will only measure during - * a get_next call, while in asynchronous mode the sensor can measure outside - * of the get_next call. - * - * Setting asynchronous measurement to false (i.e using synchronous mode) is incompatible - * with repetition mode streaming where the sensor is in control of the update rate timing. - * - * @param[in] configuration The service configuration to set asynchronous_measurement mode in - * @param[in] asynchronous_measurement asynchronous measurement mode, true or false - */ -void acc_service_asynchronous_measurement_set(acc_service_configuration_t configuration, bool asynchronous_measurement); - - -/** - * @brief Get the currently used service profile - * - * See @ref acc_service_profile_t for details - * - * @param[in] service_configuration The configuration to get a profile for - * @return The current profile, 0 if configuration is invalid - */ -acc_service_profile_t acc_service_profile_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set a service profile - * - * See @ref acc_service_profile_t for details - * - * @param[in] service_configuration The configuration to set a profile for - * @param[in] profile The profile to set - */ -void acc_service_profile_set(acc_service_configuration_t service_configuration, - acc_service_profile_t profile); - - -/** - * @brief Get Maximize signal attenuation mode - * - * Will be true if Maximize signal attenuation mode is enabled, false otherwise - * - * @param[in] service_configuration The configuration to get Maximize signal attenuation mode for - * @return Maximize signal attenuation mode - */ -bool acc_service_maximize_signal_attenuation_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set Maximize signal attenuation mode - * - * Enable or disable Maximize signal attenuation mode to measure the direct leakage - * - * @param[in] service_configuration The configuration to set Maximize signal attenuation mode in - * @param[in] maximize_signal_attenuation Maximize signal attenuation mode, true or false - */ -void acc_service_maximize_signal_attenuation_set(acc_service_configuration_t service_configuration, - bool maximize_signal_attenuation); - - -/** - * @brief Set the maximum unambiguous range - * - * Sets the maximum unambiguous range (MUR), which in turn sets the maximum measurable - * distance (MMD). - * - * The MMD is the maximum value for the range end, i.e., the range start + length. The MMD - * is smaller than the MUR due to hardware limitations. - * - * The MUR is the maximum distance at which an object can be located to guarantee that its - * reflection corresponds to the most recent transmitted pulse. Objects farther away than - * the MUR may fold into the measured range. For example, with a MUR of 10 m, an object at - * 12 m could become visible at 2 m. - * - * A higher setting gives a larger MUR/MMD, but comes at a cost of increasing the - * measurement time for a sweep. The measurement time is approximately proportional to the - * MUR. - * - * This setting changes the pulse repetition frequency (PRF) of the radar system. The - * relation between PRF and MUR is - * MUR = c / (2 * PRF) - * where c is the speed of light. - * - * | Setting | MUR | MMD | PRF | - * |------------------:|-------:|-------:|---------:| - * | ACC_SERVICE_MUR_6 | 11.5 m | 7.0 m | 13.0 MHz | - * | ACC_SERVICE_MUR_9 | 17.3 m | 12.7 m | 8.7 MHz | - * - * It is not possible to change MUR for the IQ service. - * - * @param[in] service_configuration The configuration - * @param[in] max_unambiguous_range The desired maximum unambiguous range - */ -void acc_service_mur_set(acc_service_configuration_t service_configuration, - acc_service_mur_t max_unambiguous_range); - - -/** - * @brief Get the maximum unambiguous range - * - * This gets the maximum unambiguous range. For more information see acc_service_mur_set(). - * - * @param[in] service_configuration The configuration - * @return Maximum unambiguous range - */ -acc_service_mur_t acc_service_mur_get(acc_service_configuration_t service_configuration); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved + +#ifndef ACC_SERVICE_H_ +#define ACC_SERVICE_H_ + +#include + +#include "acc_base_configuration.h" +#include "acc_definitions_a111.h" +#include "acc_definitions_common.h" + +/** + * @defgroup Services Services + * + * @brief Radar services provided by Acconeer + * + * @defgroup Experimental Experimental + * @brief Features in an early version + * + * In our code you might encounter features tagged “Experimental”. + * This means that the feature in question is an early version that has a + * limited test scope, and the API and/or functionality might change in + * upcoming releases. + * + * The intention is to let users try these features out and we appreciate + * feedback. + * + * @defgroup Generic Generic Service API + * @ingroup Services + * + * @brief Generic service API description + * + * @{ + */ + + +/** + * @brief Generic service configuration container + */ +struct acc_service_configuration; + +typedef struct acc_service_configuration *acc_service_configuration_t; + + +/** + * @brief Generic service handle + */ +struct acc_service_handle; + +typedef struct acc_service_handle *acc_service_handle_t; + + +/** + * @brief Create a service with the provided configuration + * + * Only one service may exist for a specific sensor at any given time, + * unless @ref acc_rss_override_sensor_id_check_at_creation has been invoked. + * Invalid configurations will not allow for service creation. + * + * @param[in] configuration The service configuration to create a service with + * @return Service handle, NULL if service was not possible to create + */ +acc_service_handle_t acc_service_create(acc_service_configuration_t configuration); + + +/** + * @brief Activate the service associated with the provided handle + * + * When activated, the application can get data from the service with the + * associated handle. + * + * @param[in] service_handle The service handle for the service to activate + * @return True if successful, false otherwise + */ +bool acc_service_activate(acc_service_handle_t service_handle); + + +/** + * @brief Deactivate the service associated with the provided handle + * + * @param[in] service_handle The service handle for the service to deactivate + * @return True if successful, false otherwise + */ +bool acc_service_deactivate(acc_service_handle_t service_handle); + + +/** + * @brief Destroy a service identified with the provided service handle + * + * Destroy the context of a service allowing another service to be created using the + * same resources. The service handle reference is set to NULL after destruction. + * + * @param[in] service_handle A reference to the service handle to destroy + */ +void acc_service_destroy(acc_service_handle_t *service_handle); + + +/** + * @brief Retrieve a base configuration from a service configuration + * + * The base configuration can be used to configure the service for different use cases. + * See @ref acc_base_configuration.h for configuration parameters. + * + * @param[in] service_configuration The service configuration to get a base configuration from + * @return Base configuration, NULL if the service configuration does not contain a base configuration + */ +acc_base_configuration_t acc_service_get_base_configuration(acc_service_configuration_t service_configuration); + + +/** + * @brief Get the sensor ID for the sensor to be configured + * + * @param[in] configuration The service configuration to get the sensor id from + * @return Sensor Id + */ +acc_sensor_id_t acc_service_sensor_get(acc_service_configuration_t configuration); + + +/** + * @brief Set the sensor ID for the sensor to be configured + * + * @param[in] configuration The service configuration to set the sensor id in + * @param[in] sensor_id The sensor id to set + */ +void acc_service_sensor_set(acc_service_configuration_t configuration, acc_sensor_id_t sensor_id); + + +/** + * @brief Get the requested start of the sweep + * + * @param[in] configuration The service configuration to get the requested start from + * @return Requested start + */ +float acc_service_requested_start_get(acc_service_configuration_t configuration); + + +/** + * @brief Set the requested start of the sweep + * + * @param[in] configuration The service configuration to set the requested start in + * @param[in] start_m The requested start in meters + */ +void acc_service_requested_start_set(acc_service_configuration_t configuration, float start_m); + + +/** + * @brief Get the requested length of the sweep + * + * @param[in] configuration The service configuration to get the requested length from + * @return Requested length + */ +float acc_service_requested_length_get(acc_service_configuration_t configuration); + + +/** + * @brief Set the requested length of the sweep + * + * @param[in] configuration The service configuration to set the requested length in + * @param[in] length_m The requested length in meters + */ +void acc_service_requested_length_set(acc_service_configuration_t configuration, float length_m); + + +/** + * @brief Set the service repetition mode to on demand + * + * In on demand mode, the sensor produces data when requested by the application. + * The application is also responsible for the timing between updates. + * + * This mode must be used if the configured length requires stitching in the service. + * + * @param[in] configuration The service configuration to set on demand mode in + */ +void acc_service_repetition_mode_on_demand_set(acc_service_configuration_t configuration); + + +/** + * @brief Set the service repetition mode to streaming mode + * + * The sensor produces data according to the configured update rate using sensor + * hardware timing which is very accurate. + * + * @param[in] configuration The service configuration to set streaming mode in + * @param[in] update_rate The output data rate from the service in hertz + */ +void acc_service_repetition_mode_streaming_set(acc_service_configuration_t configuration, float update_rate); + + +/** + * @brief Get power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data frame aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] configuration The service configuration to get power save mode for + * @return Power save mode + */ +acc_power_save_mode_t acc_service_power_save_mode_get(acc_service_configuration_t configuration); + + +/** + * @brief Set power save mode + * + * The power save modes of the sensor correspond to how much of the sensor hardware is shutdown + * between data frame aquisition. The supported power save modes are defined in + * @ref acc_power_save_mode_enum_t. + * + * @param[in] configuration The service configuration to set power save mode in + * @param[in] power_save_mode The power save mode to use + */ +void acc_service_power_save_mode_set(acc_service_configuration_t configuration, + acc_power_save_mode_t power_save_mode); + + +/** + * @brief Get receiver gain setting + * + * Will be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] configuration The service configuration to get receiver gain setting for + * @return Receiver gain setting + */ +float acc_service_receiver_gain_get(acc_service_configuration_t configuration); + + +/** + * @brief Set receiver gain setting + * + * Must be a value between 0.0 and 1.0, where 0.0 is the lowest gain and 1.0 is the highest gain. + * + * @param[in] configuration The service configuration to set receiver gain setting in + * @param[in] gain Receiver gain setting, must be between 0.0 and 1.0 + */ +void acc_service_receiver_gain_set(acc_service_configuration_t configuration, float gain); + + +/** + * @brief Get TX disable mode + * + * Will be true if TX is disabled, false otherwise. + * + * @param[in] configuration The service configuration to get TX disable mode for + * @return TX disable mode + */ +bool acc_service_tx_disable_get(acc_service_configuration_t configuration); + + +/** + * @brief Set TX disable mode + * + * If set to true, TX disable mode is enabled. This will disable the radio transmitter. + * To measure RX noise floor, it is recommended to also switch off internal + * noise level normalization (see each service if applicable). + * + * @param[in] configuration The service configuration to set TX disable mode in + * @param[in] tx_disable TX disable mode, true or false + */ +void acc_service_tx_disable_set(acc_service_configuration_t configuration, bool tx_disable); + + +/** + * @brief Get the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The service configuration to get hardware accelerated average samples from + * @return Hardware accelerated average samples + */ +uint8_t acc_service_hw_accelerated_average_samples_get(acc_service_configuration_t configuration); + + +/** + * @brief Set the hardware accelerated average samples (HWAAS) + * + * Each data point can be sampled between 1 and 63 times, inclusive, and the sensor hardware then + * produces an average value of those samples. The time needed to measure a sweep is roughly proportional + * to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS + * could be decreased but this leads to lower SNR. + * + * @param[in] configuration The service configuration to set hardware accelerated average samples in + * @param[in] samples Hardware accelerated average samples + */ +void acc_service_hw_accelerated_average_samples_set(acc_service_configuration_t configuration, uint8_t samples); + + +/** + * @brief Get asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will generate sweep data while the host is waiting. + * In asynchronous mode the sensor will generate sweep data while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * Setting asynchronous measurement to false (i.e using synchronous mode) is incompatible + * with repetition mode streaming where the sensor is in control of the update rate timing. + * + * @param[in] configuration The service configuration to get asynchronous_measurement mode from + * @return asynchronous measurement mode + */ +bool acc_service_asynchronous_measurement_get(acc_service_configuration_t configuration); + + +/** + * @brief Set asynchronous measurement mode + * + * If set to true, asynchronous measurement is enabled. + * In synchronous mode the sensor will generate sweep data while the host is waiting. + * In asynchronous mode the sensor will generate sweep data while the host is working. + * + * This means that if in synchronous mode, the sensor will only measure during + * a get_next call, while in asynchronous mode the sensor can measure outside + * of the get_next call. + * + * Setting asynchronous measurement to false (i.e using synchronous mode) is incompatible + * with repetition mode streaming where the sensor is in control of the update rate timing. + * + * @param[in] configuration The service configuration to set asynchronous_measurement mode in + * @param[in] asynchronous_measurement asynchronous measurement mode, true or false + */ +void acc_service_asynchronous_measurement_set(acc_service_configuration_t configuration, bool asynchronous_measurement); + + +/** + * @brief Get the currently used service profile + * + * See @ref acc_service_profile_t for details + * + * @param[in] service_configuration The configuration to get a profile for + * @return The current profile, 0 if configuration is invalid + */ +acc_service_profile_t acc_service_profile_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set a service profile + * + * See @ref acc_service_profile_t for details + * + * @param[in] service_configuration The configuration to set a profile for + * @param[in] profile The profile to set + */ +void acc_service_profile_set(acc_service_configuration_t service_configuration, + acc_service_profile_t profile); + + +/** + * @brief Get Maximize signal attenuation mode + * + * Will be true if Maximize signal attenuation mode is enabled, false otherwise + * + * @param[in] service_configuration The configuration to get Maximize signal attenuation mode for + * @return Maximize signal attenuation mode + */ +bool acc_service_maximize_signal_attenuation_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set Maximize signal attenuation mode + * + * Enable or disable Maximize signal attenuation mode to measure the direct leakage + * + * @param[in] service_configuration The configuration to set Maximize signal attenuation mode in + * @param[in] maximize_signal_attenuation Maximize signal attenuation mode, true or false + */ +void acc_service_maximize_signal_attenuation_set(acc_service_configuration_t service_configuration, + bool maximize_signal_attenuation); + + +/** + * @brief Set the maximum unambiguous range + * + * Sets the maximum unambiguous range (MUR), which in turn sets the maximum measurable + * distance (MMD). + * + * The MMD is the maximum value for the range end, i.e., the range start + length. The MMD + * is smaller than the MUR due to hardware limitations. + * + * The MUR is the maximum distance at which an object can be located to guarantee that its + * reflection corresponds to the most recent transmitted pulse. Objects farther away than + * the MUR may fold into the measured range. For example, with a MUR of 10 m, an object at + * 12 m could become visible at 2 m. + * + * A higher setting gives a larger MUR/MMD, but comes at a cost of increasing the + * measurement time for a sweep. The measurement time is approximately proportional to the + * MUR. + * + * This setting changes the pulse repetition frequency (PRF) of the radar system. The + * relation between PRF and MUR is + * MUR = c / (2 * PRF) + * where c is the speed of light. + * + * | Setting | MUR | MMD | PRF | + * |------------------:|-------:|-------:|---------:| + * | ACC_SERVICE_MUR_6 | 11.5 m | 7.0 m | 13.0 MHz | + * | ACC_SERVICE_MUR_9 | 17.3 m | 12.7 m | 8.7 MHz | + * + * It is not possible to change MUR for the IQ service. + * + * @param[in] service_configuration The configuration + * @param[in] max_unambiguous_range The desired maximum unambiguous range + */ +void acc_service_mur_set(acc_service_configuration_t service_configuration, + acc_service_mur_t max_unambiguous_range); + + +/** + * @brief Get the maximum unambiguous range + * + * This gets the maximum unambiguous range. For more information see acc_service_mur_set(). + * + * @param[in] service_configuration The configuration + * @return Maximum unambiguous range + */ +acc_service_mur_t acc_service_mur_get(acc_service_configuration_t service_configuration); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_service_envelope.h b/rss/include/acc_service_envelope.h index b5e7fc5..b8658ad 100644 --- a/rss/include/acc_service_envelope.h +++ b/rss/include/acc_service_envelope.h @@ -1,239 +1,239 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_SERVICE_ENVELOPE_H_ -#define ACC_SERVICE_ENVELOPE_H_ - -#include -#include - -#include "acc_service.h" - -/** - * @defgroup Envelope Envelope Service - * @ingroup Services - * - * @brief Envelope service API description - * - * @{ - */ - - -/** - * @brief Metadata for the envelope service - */ -typedef struct -{ - /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ - float start_m; - /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ - float length_m; - /** Number of elements in the envelope data array */ - uint16_t data_length; - /** Number of stitches in the data */ - uint16_t stitch_count; - /** Distance between adjacent data points */ - float step_length_m; -} acc_service_envelope_metadata_t; - - -/** - * @brief Metadata for each result provided by the envelope service - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; -} acc_service_envelope_result_info_t; - - -/** - * @brief Create a configuration for an envelope service - * - * A configuration is created for the envelope service and populated - * with default values. - * - * @return Service configuration, NULL if creation was not possible - */ -acc_service_configuration_t acc_service_envelope_configuration_create(void); - - -/** - * @brief Destroy an envelope configuration - * - * Destroy an envelope configuration that is no longer needed, may be done even if a - * service has been created with the specific configuration and has not yet been destroyed. - * The service configuration reference is set to NULL after destruction. - * - * @param[in] service_configuration The configuration to destroy, set to NULL - */ -void acc_service_envelope_configuration_destroy(acc_service_configuration_t *service_configuration); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the envelope service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 - * makes the distance between two points in the measured range ~2mm. - * - * @param[in] service_configuration The configuration to get downsampling factor from - * @return The downsampling factor - */ -uint16_t acc_service_envelope_downsampling_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the envelope service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 - * makes the distance between two points in the measured range ~2mm. - * - * The envelope service supports a downsampling factor of 1, 2, or 4. - * - * @param[in] service_configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_service_envelope_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); - - -/** - * @brief Get running average factor - * - * The running average factor is the factor of which the most recent sweep is weighed against previous sweeps. - * Valid range is between 0.0 and 1.0 where 0.0 means that no history is weighed in, i.e filtering is effectively disabled. - * A factor of 1.0 means that the most recent sweep has no effect on the result, - * which will result in that the first sweep is forever received as the result. - * The filtering is coherent and is done on complex valued IQ data before conversion to envelope data. - * - * @param[in] service_configuration The configuration to get the running average factor for - * @return Running average factor - */ -float acc_service_envelope_running_average_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set running average factor - * - * The running average factor is the factor of which the most recent sweep is weighed against previous sweeps. - * Valid range is between 0.0 and 1.0 where 0.0 means that no history is weighed in, i.e filtering is effectively disabled. - * A factor of 1.0 means that the most recent sweep has no effect on the result, - * which will result in that the first sweep is forever received as the result. - * The filtering is coherent and is done on complex valued IQ data before conversion to envelope data. - * - * @param[in] service_configuration The configuration to set the running average factor for - * @param[in] factor The running average factor to set - */ -void acc_service_envelope_running_average_factor_set(acc_service_configuration_t service_configuration, float factor); - - -/** - * @brief Get if noise level normalization will be done or not - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to get the noise level normalization setting for - * @return The noise level normalization flag - */ -bool acc_service_envelope_noise_level_normalization_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set if noise level normalization should be done or not - * - * This function controls if a noise level normalization will be done at the beginning - * of the envelope processing. - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to enable or disable the noise level normalization for - * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not - */ -void acc_service_envelope_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); - - -/** - * @brief Get service metadata - * - * Each service provide metadata after being created with information that could be relevant for an application. - * The metadata contain information such as data length and actual start and length. - * - * May only be called after a service has been created. - * - * @param[in] handle The service handle for the service to get metadata for - * @param[out] metadata Metadata results are provided in this parameter - */ -void acc_service_envelope_get_metadata(acc_service_handle_t handle, acc_service_envelope_metadata_t *metadata); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Envelope result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Envelope result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_envelope_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_envelope_result_info_t *result_info); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * The provided memory is only valid until the next call to get_next for the - * specified handle. The memory is specific for the handle and cannot be shared - * between handles/services. - * - * The length of the resulting data is provided in @ref acc_service_envelope_get_metadata - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Reference to Envelope result - * @param[out] result_info Envelope result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_envelope_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, - acc_service_envelope_result_info_t *result_info); - - -/** - * @brief Execute service one time - * - * Activates service, produces one result and then deactivates the service. Blocks the - * application until a service result has been produced. May fail if the service is already active. - * - * @param[in] handle The service handle for the service to execute - * @param[out] data Envelope result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Envelope result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_envelope_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_envelope_result_info_t *result_info); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_SERVICE_ENVELOPE_H_ +#define ACC_SERVICE_ENVELOPE_H_ + +#include +#include + +#include "acc_service.h" + +/** + * @defgroup Envelope Envelope Service + * @ingroup Services + * + * @brief Envelope service API description + * + * @{ + */ + + +/** + * @brief Metadata for the envelope service + */ +typedef struct +{ + /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ + float start_m; + /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ + float length_m; + /** Number of elements in the envelope data array */ + uint16_t data_length; + /** Number of stitches in the data */ + uint16_t stitch_count; + /** Distance between adjacent data points */ + float step_length_m; +} acc_service_envelope_metadata_t; + + +/** + * @brief Metadata for each result provided by the envelope service + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; +} acc_service_envelope_result_info_t; + + +/** + * @brief Create a configuration for an envelope service + * + * A configuration is created for the envelope service and populated + * with default values. + * + * @return Service configuration, NULL if creation was not possible + */ +acc_service_configuration_t acc_service_envelope_configuration_create(void); + + +/** + * @brief Destroy an envelope configuration + * + * Destroy an envelope configuration that is no longer needed, may be done even if a + * service has been created with the specific configuration and has not yet been destroyed. + * The service configuration reference is set to NULL after destruction. + * + * @param[in] service_configuration The configuration to destroy, set to NULL + */ +void acc_service_envelope_configuration_destroy(acc_service_configuration_t *service_configuration); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the envelope service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 + * makes the distance between two points in the measured range ~2mm. + * + * @param[in] service_configuration The configuration to get downsampling factor from + * @return The downsampling factor + */ +uint16_t acc_service_envelope_downsampling_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the envelope service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 + * makes the distance between two points in the measured range ~2mm. + * + * The envelope service supports a downsampling factor of 1, 2, or 4. + * + * @param[in] service_configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_service_envelope_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); + + +/** + * @brief Get running average factor + * + * The running average factor is the factor of which the most recent sweep is weighed against previous sweeps. + * Valid range is between 0.0 and 1.0 where 0.0 means that no history is weighed in, i.e filtering is effectively disabled. + * A factor of 1.0 means that the most recent sweep has no effect on the result, + * which will result in that the first sweep is forever received as the result. + * The filtering is coherent and is done on complex valued IQ data before conversion to envelope data. + * + * @param[in] service_configuration The configuration to get the running average factor for + * @return Running average factor + */ +float acc_service_envelope_running_average_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set running average factor + * + * The running average factor is the factor of which the most recent sweep is weighed against previous sweeps. + * Valid range is between 0.0 and 1.0 where 0.0 means that no history is weighed in, i.e filtering is effectively disabled. + * A factor of 1.0 means that the most recent sweep has no effect on the result, + * which will result in that the first sweep is forever received as the result. + * The filtering is coherent and is done on complex valued IQ data before conversion to envelope data. + * + * @param[in] service_configuration The configuration to set the running average factor for + * @param[in] factor The running average factor to set + */ +void acc_service_envelope_running_average_factor_set(acc_service_configuration_t service_configuration, float factor); + + +/** + * @brief Get if noise level normalization will be done or not + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to get the noise level normalization setting for + * @return The noise level normalization flag + */ +bool acc_service_envelope_noise_level_normalization_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set if noise level normalization should be done or not + * + * This function controls if a noise level normalization will be done at the beginning + * of the envelope processing. + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to enable or disable the noise level normalization for + * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not + */ +void acc_service_envelope_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); + + +/** + * @brief Get service metadata + * + * Each service provide metadata after being created with information that could be relevant for an application. + * The metadata contain information such as data length and actual start and length. + * + * May only be called after a service has been created. + * + * @param[in] handle The service handle for the service to get metadata for + * @param[out] metadata Metadata results are provided in this parameter + */ +void acc_service_envelope_get_metadata(acc_service_handle_t handle, acc_service_envelope_metadata_t *metadata); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Envelope result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Envelope result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_envelope_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_envelope_result_info_t *result_info); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * The provided memory is only valid until the next call to get_next for the + * specified handle. The memory is specific for the handle and cannot be shared + * between handles/services. + * + * The length of the resulting data is provided in @ref acc_service_envelope_get_metadata + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Reference to Envelope result + * @param[out] result_info Envelope result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_envelope_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, + acc_service_envelope_result_info_t *result_info); + + +/** + * @brief Execute service one time + * + * Activates service, produces one result and then deactivates the service. Blocks the + * application until a service result has been produced. May fail if the service is already active. + * + * @param[in] handle The service handle for the service to execute + * @param[out] data Envelope result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Envelope result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_envelope_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_envelope_result_info_t *result_info); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_service_iq.h b/rss/include/acc_service_iq.h index d4aa967..51f2c7c 100644 --- a/rss/include/acc_service_iq.h +++ b/rss/include/acc_service_iq.h @@ -1,288 +1,288 @@ -// Copyright (c) Acconeer AB, 2018-2022 -// All rights reserved - -#ifndef ACC_SERVICE_IQ_H_ -#define ACC_SERVICE_IQ_H_ - -#include -#include -#include - -#include "acc_service.h" - -/** - * @defgroup IQ IQ Service - * @ingroup Services - * - * @brief IQ Service API description - * - * @{ - */ - - -/** - * @brief Output format - * - */ -typedef enum -{ - ACC_SERVICE_IQ_OUTPUT_FORMAT_FLOAT_COMPLEX, // The output format is float complex - ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX // The output format is acc_int16_complex_t -} acc_service_iq_output_format_enum_t; -typedef uint32_t acc_service_iq_output_format_t; - - -/** - * @brief Metadata for the iq service - */ -typedef struct -{ - /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ - float start_m; - /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ - float length_m; - /** Number of elements in the iq data array */ - uint16_t data_length; - /** Number of stitches in the data */ - uint16_t stitch_count; - /** Distance between adjacent data points */ - float step_length_m; - /** The depth domain lowpass cutoff frequency ratio */ - float depth_lowpass_cutoff_ratio; -} acc_service_iq_metadata_t; - - -/** - * @brief Metadata for each result provided by the iq service - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; -} acc_service_iq_result_info_t; - - -/** - * @brief Create a configuration for an iq service - * - * A configuration is created for the iq service and populated - * with default values. - * - * @return Service configuration, NULL if creation was not possible - */ -acc_service_configuration_t acc_service_iq_configuration_create(void); - - -/** - * @brief Destroy an iq configuration - * - * Destroy an iq configuration that is no longer needed, may be done even if a - * service has been created with the specific configuration and has not yet been destroyed. - * The service configuration reference is set to NULL after destruction. - * - * @param[in] service_configuration The configuration to destroy, set to NULL - */ -void acc_service_iq_configuration_destroy(acc_service_configuration_t *service_configuration); - - -/** - * @brief Get the distance domain lowpass filter cutoff frequency ratio override parameters - * - * The cutoff for the distance domain lowpass filter is specified as the ratio between the spatial - * frequency cutoff and the sample frequency. A ratio close to zero damps everything except the lowest - * frequencies. Increasing ratios output a wider band of spatial frequencies, and a ratio of 0.5 means - * that the filter is deactivated. - * - * If unset, i.e., if override is false, the ratio will be chosen automatically. This ratio is - * returned in the metadata upon creation of the service. - * - * @param[in] service_configuration The configuration to get the parameters from - * @param[out] override If true, the specified cutoff ratio is used - * @param[out] cutoff_ratio The cutoff ratio to use if override is true - */ -void acc_service_iq_depth_lowpass_cutoff_ratio_get(acc_service_configuration_t service_configuration, bool *override, float *cutoff_ratio); - - -/** - * @brief Set the distance domain lowpass filter cutoff frequency ratio override parameters - * - * The cutoff for the distance domain lowpass filter is specified as the ratio between the spatial - * frequency cutoff and the sample frequency. An input value of zero for the cutoff ratio will - * configure the smoothest allowed filter. A cutoff ratio of 0.5 turns the filter off. - * - * The set of available cutoff frequencies is limited due to internal properties of the filter - * implementation. - * - * If unset, i.e., if override is false, the ratio will be chosen automatically. This ratio is - * returned in the metadata upon creation of the service. - * - * @param[in] service_configuration The configuration to set the parameters for - * @param[in] override If true, the specified cutoff ratio is used - * @param[in] cutoff_ratio The cutoff ratio to use if override is true - */ -void acc_service_iq_depth_lowpass_cutoff_ratio_set(acc_service_configuration_t service_configuration, - bool override, - float cutoff_ratio); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the IQ service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 makes - * the distance between two points in the measured range ~2mm. - * - * @param[in] service_configuration The configuration to get downsampling factor from - * @return downsampling_factor The downsampling factor - */ -uint16_t acc_service_iq_downsampling_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the IQ service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 makes - * the distance between two points in the measured range ~2mm. - * - * The IQ service supports a downsampling factor of 1, 2, or 4. - * - * @param[in] service_configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_service_iq_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); - - -/** - * @brief Get if noise level normalization will be done or not - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to get the noise level normalization setting for - * @return The noise level normalization flag - */ -bool acc_service_iq_noise_level_normalization_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set if noise level normalization should be done or not - * - * This function controls if a noise level normalization will be done at the beginning - * of the envelope processing. - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to enable or disable the noise level normalization for - * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not - */ -void acc_service_iq_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); - - -/** - * @brief Configure the output format of the IQ service - * - * @param[in,out] service_configuration The configuration to set the format on - * @param[in] format The format that should be used - */ -void acc_service_iq_output_format_set(acc_service_configuration_t service_configuration, - acc_service_iq_output_format_t format); - - -/** - * @brief Get the configured output format - * - * @param[in] service_configuration The configuration to get the format from - * - * @returns The configured output format - */ -acc_service_iq_output_format_t acc_service_iq_output_format_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Get service metadata - * - * Each service provide metadata after being created with information that could be relevant for an application. - * The metadata contain information such as data length and actual start and length. - * - * May only be called after a service has been created. - * - * @param[in] handle The service handle for the service to get metadata for - * @param[out] metadata Metadata results are provided in this parameter - */ -void acc_service_iq_get_metadata(acc_service_handle_t handle, acc_service_iq_metadata_t *metadata); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. The service must be configured for floating point output. - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data IQ data result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info IQ result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_iq_get_next(acc_service_handle_t handle, void *data, uint16_t data_length, - acc_service_iq_result_info_t *result_info); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * The provided memory is only valid until the next call to get_next for the - * specified handle. The memory is specific for the handle and cannot be shared - * between handles/services. - * - * The length of the resulting data is provided in @ref acc_service_iq_get_metadata - * - * Note that this function is only compatible with the ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX - * option for @ref acc_service_iq_output_format_set - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Reference to IQ result - * @param[out] result_info IQ result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_iq_get_next_by_reference(acc_service_handle_t handle, acc_int16_complex_t **data, - acc_service_iq_result_info_t *result_info); - - -/** - * @brief Execute service one time - * - * Activates service, produces one result and then deactivates the service. Blocks the - * application until a service result has been produced. May fail if the service is already - * active. The format of the data is configured by calling acc_service_iq_output_format_set(). - * - * @param[in] handle The service handle for the service to execute - * @param[out] data IQ data result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info IQ result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_iq_execute_once(acc_service_handle_t handle, void *data, uint16_t data_length, - acc_service_iq_result_info_t *result_info); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2018-2022 +// All rights reserved + +#ifndef ACC_SERVICE_IQ_H_ +#define ACC_SERVICE_IQ_H_ + +#include +#include +#include + +#include "acc_service.h" + +/** + * @defgroup IQ IQ Service + * @ingroup Services + * + * @brief IQ Service API description + * + * @{ + */ + + +/** + * @brief Output format + * + */ +typedef enum +{ + ACC_SERVICE_IQ_OUTPUT_FORMAT_FLOAT_COMPLEX, // The output format is float complex + ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX // The output format is acc_int16_complex_t +} acc_service_iq_output_format_enum_t; +typedef uint32_t acc_service_iq_output_format_t; + + +/** + * @brief Metadata for the iq service + */ +typedef struct +{ + /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ + float start_m; + /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ + float length_m; + /** Number of elements in the iq data array */ + uint16_t data_length; + /** Number of stitches in the data */ + uint16_t stitch_count; + /** Distance between adjacent data points */ + float step_length_m; + /** The depth domain lowpass cutoff frequency ratio */ + float depth_lowpass_cutoff_ratio; +} acc_service_iq_metadata_t; + + +/** + * @brief Metadata for each result provided by the iq service + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; +} acc_service_iq_result_info_t; + + +/** + * @brief Create a configuration for an iq service + * + * A configuration is created for the iq service and populated + * with default values. + * + * @return Service configuration, NULL if creation was not possible + */ +acc_service_configuration_t acc_service_iq_configuration_create(void); + + +/** + * @brief Destroy an iq configuration + * + * Destroy an iq configuration that is no longer needed, may be done even if a + * service has been created with the specific configuration and has not yet been destroyed. + * The service configuration reference is set to NULL after destruction. + * + * @param[in] service_configuration The configuration to destroy, set to NULL + */ +void acc_service_iq_configuration_destroy(acc_service_configuration_t *service_configuration); + + +/** + * @brief Get the distance domain lowpass filter cutoff frequency ratio override parameters + * + * The cutoff for the distance domain lowpass filter is specified as the ratio between the spatial + * frequency cutoff and the sample frequency. A ratio close to zero damps everything except the lowest + * frequencies. Increasing ratios output a wider band of spatial frequencies, and a ratio of 0.5 means + * that the filter is deactivated. + * + * If unset, i.e., if override is false, the ratio will be chosen automatically. This ratio is + * returned in the metadata upon creation of the service. + * + * @param[in] service_configuration The configuration to get the parameters from + * @param[out] override If true, the specified cutoff ratio is used + * @param[out] cutoff_ratio The cutoff ratio to use if override is true + */ +void acc_service_iq_depth_lowpass_cutoff_ratio_get(acc_service_configuration_t service_configuration, bool *override, float *cutoff_ratio); + + +/** + * @brief Set the distance domain lowpass filter cutoff frequency ratio override parameters + * + * The cutoff for the distance domain lowpass filter is specified as the ratio between the spatial + * frequency cutoff and the sample frequency. An input value of zero for the cutoff ratio will + * configure the smoothest allowed filter. A cutoff ratio of 0.5 turns the filter off. + * + * The set of available cutoff frequencies is limited due to internal properties of the filter + * implementation. + * + * If unset, i.e., if override is false, the ratio will be chosen automatically. This ratio is + * returned in the metadata upon creation of the service. + * + * @param[in] service_configuration The configuration to set the parameters for + * @param[in] override If true, the specified cutoff ratio is used + * @param[in] cutoff_ratio The cutoff ratio to use if override is true + */ +void acc_service_iq_depth_lowpass_cutoff_ratio_set(acc_service_configuration_t service_configuration, + bool override, + float cutoff_ratio); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the IQ service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 makes + * the distance between two points in the measured range ~2mm. + * + * @param[in] service_configuration The configuration to get downsampling factor from + * @return downsampling_factor The downsampling factor + */ +uint16_t acc_service_iq_downsampling_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the IQ service, the base step length is ~0.5mm. Thus, for example setting downsampling factor to 4 makes + * the distance between two points in the measured range ~2mm. + * + * The IQ service supports a downsampling factor of 1, 2, or 4. + * + * @param[in] service_configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_service_iq_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); + + +/** + * @brief Get if noise level normalization will be done or not + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to get the noise level normalization setting for + * @return The noise level normalization flag + */ +bool acc_service_iq_noise_level_normalization_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set if noise level normalization should be done or not + * + * This function controls if a noise level normalization will be done at the beginning + * of the envelope processing. + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to enable or disable the noise level normalization for + * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not + */ +void acc_service_iq_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); + + +/** + * @brief Configure the output format of the IQ service + * + * @param[in,out] service_configuration The configuration to set the format on + * @param[in] format The format that should be used + */ +void acc_service_iq_output_format_set(acc_service_configuration_t service_configuration, + acc_service_iq_output_format_t format); + + +/** + * @brief Get the configured output format + * + * @param[in] service_configuration The configuration to get the format from + * + * @returns The configured output format + */ +acc_service_iq_output_format_t acc_service_iq_output_format_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Get service metadata + * + * Each service provide metadata after being created with information that could be relevant for an application. + * The metadata contain information such as data length and actual start and length. + * + * May only be called after a service has been created. + * + * @param[in] handle The service handle for the service to get metadata for + * @param[out] metadata Metadata results are provided in this parameter + */ +void acc_service_iq_get_metadata(acc_service_handle_t handle, acc_service_iq_metadata_t *metadata); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. The service must be configured for floating point output. + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data IQ data result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info IQ result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_iq_get_next(acc_service_handle_t handle, void *data, uint16_t data_length, + acc_service_iq_result_info_t *result_info); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * The provided memory is only valid until the next call to get_next for the + * specified handle. The memory is specific for the handle and cannot be shared + * between handles/services. + * + * The length of the resulting data is provided in @ref acc_service_iq_get_metadata + * + * Note that this function is only compatible with the ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX + * option for @ref acc_service_iq_output_format_set + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Reference to IQ result + * @param[out] result_info IQ result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_iq_get_next_by_reference(acc_service_handle_t handle, acc_int16_complex_t **data, + acc_service_iq_result_info_t *result_info); + + +/** + * @brief Execute service one time + * + * Activates service, produces one result and then deactivates the service. Blocks the + * application until a service result has been produced. May fail if the service is already + * active. The format of the data is configured by calling acc_service_iq_output_format_set(). + * + * @param[in] handle The service handle for the service to execute + * @param[out] data IQ data result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info IQ result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_iq_execute_once(acc_service_handle_t handle, void *data, uint16_t data_length, + acc_service_iq_result_info_t *result_info); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_service_power_bins.h b/rss/include/acc_service_power_bins.h index 6cbe1d4..48e3535 100644 --- a/rss/include/acc_service_power_bins.h +++ b/rss/include/acc_service_power_bins.h @@ -1,226 +1,226 @@ -// Copyright (c) Acconeer AB, 2018-2021 -// All rights reserved - -#ifndef ACC_SERVICE_POWER_BINS_H_ -#define ACC_SERVICE_POWER_BINS_H_ - -#include -#include - -#include "acc_service.h" - - -/** - * @defgroup Power Power Bins Service - * @ingroup Services - * - * @brief Power Bins service API description - * - * @{ - */ - - -/** - * @brief Metadata for the power bins service - */ -typedef struct -{ - /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ - float start_m; - /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ - float length_m; - /** Number of elements in the power bins data array */ - uint16_t bin_count; - /** Number of stitches in the data */ - uint16_t stitch_count; - /** Distance between adjacent data points */ - float step_length_m; -} acc_service_power_bins_metadata_t; - - -/** - * @brief Metadata for each result provided by the power bins service - */ -typedef struct -{ - /** Indication of missed data from the sensor */ - bool missed_data; - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ - bool data_quality_warning; -} acc_service_power_bins_result_info_t; - - -/** - * @brief Create a configuration for a power bins service - * - * A configuration is created for the power bins service and populated - * with default values. - * - * @return Service configuration, NULL if creation was not possible - */ -acc_service_configuration_t acc_service_power_bins_configuration_create(void); - - -/** - * @brief Destroy a power bins configuration - * - * Destroy a power bins configuration that is no longer needed, may be done even if a - * service has been created with the specific configuration and has not yet been destroyed. - * The service configuration reference is set to NULL after destruction. - * - * @param[in] service_configuration The configuration to destroy, set to NULL - */ -void acc_service_power_bins_configuration_destroy(acc_service_configuration_t *service_configuration); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * @param[in] service_configuration The configuration to get downsampling factor from - * @return The downsampling factor - */ -uint16_t acc_service_power_bins_downsampling_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * The power bins service supports a downsampling factor of 1, 2, or 4. - * - * In power bins, the downsampling factor does not affect the resulting data length. - * - * @param[in] service_configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_service_power_bins_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); - - -/** - * @brief Get the requested bin count - * - * @param[in] service_configuration The service configuration to get the requested bin count from - * @return Requested bin count - */ -uint16_t acc_service_power_bins_requested_bin_count_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the requested bin count - * - * @param[in] service_configuration The service configuration to set the requested bin count in - * @param[in] requested_bin_count The requested bin count - */ -void acc_service_power_bins_requested_bin_count_set(acc_service_configuration_t service_configuration, - uint16_t requested_bin_count); - - -/** - * @brief Get if noise level normalization will be done or not - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to get the noise level normalization setting for - * @return The noise level normalization flag - */ -bool acc_service_power_bins_noise_level_normalization_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set if noise level normalization should be done or not - * - * This function controls if a noise level normalization will be done at the beginning - * of the processing. - * - * The purpose of the noise level normalization is to scale the signal according to the - * sensor noise level to decrease the signal amplitude variation between individual sensors. - * - * @param[in] service_configuration The configuration to enable or disable the noise level normalization for - * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not - */ -void acc_service_power_bins_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); - - -/** - * @brief Get service metadata - * - * Each service provide metadata after being created with information that could be relevant for an application. - * The metadata contain information such as data length and actual start and length. - * - * May only be called after a service has been created. - * - * @param[in] handle The service handle for the service to get metadata for - * @param[out] metadata Metadata results are provided in this parameter - */ -void acc_service_power_bins_get_metadata(acc_service_handle_t handle, acc_service_power_bins_metadata_t *metadata); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Power bins result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Power Bins result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_power_bins_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_power_bins_result_info_t *result_info); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * The provided memory is only valid until the next call to get_next for the - * specified handle. The memory is specific for the handle and cannot be shared - * between handles/services. - * - * The length of the resulting data is provided in @ref acc_service_power_bins_get_metadata - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Reference to Power Bins result - * @param[out] result_info Power Bins result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_power_bins_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, - acc_service_power_bins_result_info_t *result_info); - - -/** - * @brief Execute service one time - * - * Activates service, produces one result and then deactivates the service. Blocks the - * application until a service result has been produced. May fail if the service is already active. - * - * @param[in] handle The service handle for the service to execute - * @param[out] data Power bins result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Power Bins result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_power_bins_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_power_bins_result_info_t *result_info); - - -/** - * @} - */ - - -#endif +// Copyright (c) Acconeer AB, 2018-2021 +// All rights reserved + +#ifndef ACC_SERVICE_POWER_BINS_H_ +#define ACC_SERVICE_POWER_BINS_H_ + +#include +#include + +#include "acc_service.h" + + +/** + * @defgroup Power Power Bins Service + * @ingroup Services + * + * @brief Power Bins service API description + * + * @{ + */ + + +/** + * @brief Metadata for the power bins service + */ +typedef struct +{ + /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ + float start_m; + /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ + float length_m; + /** Number of elements in the power bins data array */ + uint16_t bin_count; + /** Number of stitches in the data */ + uint16_t stitch_count; + /** Distance between adjacent data points */ + float step_length_m; +} acc_service_power_bins_metadata_t; + + +/** + * @brief Metadata for each result provided by the power bins service + */ +typedef struct +{ + /** Indication of missed data from the sensor */ + bool missed_data; + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of bad data quality that may be addressed by restarting the service to recalibrate the sensor */ + bool data_quality_warning; +} acc_service_power_bins_result_info_t; + + +/** + * @brief Create a configuration for a power bins service + * + * A configuration is created for the power bins service and populated + * with default values. + * + * @return Service configuration, NULL if creation was not possible + */ +acc_service_configuration_t acc_service_power_bins_configuration_create(void); + + +/** + * @brief Destroy a power bins configuration + * + * Destroy a power bins configuration that is no longer needed, may be done even if a + * service has been created with the specific configuration and has not yet been destroyed. + * The service configuration reference is set to NULL after destruction. + * + * @param[in] service_configuration The configuration to destroy, set to NULL + */ +void acc_service_power_bins_configuration_destroy(acc_service_configuration_t *service_configuration); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * @param[in] service_configuration The configuration to get downsampling factor from + * @return The downsampling factor + */ +uint16_t acc_service_power_bins_downsampling_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * The power bins service supports a downsampling factor of 1, 2, or 4. + * + * In power bins, the downsampling factor does not affect the resulting data length. + * + * @param[in] service_configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_service_power_bins_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); + + +/** + * @brief Get the requested bin count + * + * @param[in] service_configuration The service configuration to get the requested bin count from + * @return Requested bin count + */ +uint16_t acc_service_power_bins_requested_bin_count_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the requested bin count + * + * @param[in] service_configuration The service configuration to set the requested bin count in + * @param[in] requested_bin_count The requested bin count + */ +void acc_service_power_bins_requested_bin_count_set(acc_service_configuration_t service_configuration, + uint16_t requested_bin_count); + + +/** + * @brief Get if noise level normalization will be done or not + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to get the noise level normalization setting for + * @return The noise level normalization flag + */ +bool acc_service_power_bins_noise_level_normalization_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set if noise level normalization should be done or not + * + * This function controls if a noise level normalization will be done at the beginning + * of the processing. + * + * The purpose of the noise level normalization is to scale the signal according to the + * sensor noise level to decrease the signal amplitude variation between individual sensors. + * + * @param[in] service_configuration The configuration to enable or disable the noise level normalization for + * @param[in] noise_level_normalization Flag to determine if noise level normalization should be done or not + */ +void acc_service_power_bins_noise_level_normalization_set(acc_service_configuration_t service_configuration, bool noise_level_normalization); + + +/** + * @brief Get service metadata + * + * Each service provide metadata after being created with information that could be relevant for an application. + * The metadata contain information such as data length and actual start and length. + * + * May only be called after a service has been created. + * + * @param[in] handle The service handle for the service to get metadata for + * @param[out] metadata Metadata results are provided in this parameter + */ +void acc_service_power_bins_get_metadata(acc_service_handle_t handle, acc_service_power_bins_metadata_t *metadata); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Power bins result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Power Bins result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_power_bins_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_power_bins_result_info_t *result_info); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * The provided memory is only valid until the next call to get_next for the + * specified handle. The memory is specific for the handle and cannot be shared + * between handles/services. + * + * The length of the resulting data is provided in @ref acc_service_power_bins_get_metadata + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Reference to Power Bins result + * @param[out] result_info Power Bins result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_power_bins_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, + acc_service_power_bins_result_info_t *result_info); + + +/** + * @brief Execute service one time + * + * Activates service, produces one result and then deactivates the service. Blocks the + * application until a service result has been produced. May fail if the service is already active. + * + * @param[in] handle The service handle for the service to execute + * @param[out] data Power bins result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Power Bins result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_power_bins_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_power_bins_result_info_t *result_info); + + +/** + * @} + */ + + +#endif diff --git a/rss/include/acc_service_sparse.h b/rss/include/acc_service_sparse.h index 16063dc..a3eedc8 100644 --- a/rss/include/acc_service_sparse.h +++ b/rss/include/acc_service_sparse.h @@ -1,294 +1,294 @@ -// Copyright (c) Acconeer AB, 2019-2021 -// All rights reserved - -#ifndef ACC_SERVICE_SPARSE_H_ -#define ACC_SERVICE_SPARSE_H_ - -#include -#include - -#include "acc_service.h" - -/** - * @defgroup Sparse Sparse Service - * @ingroup Services - * - * @brief Sparse service API description - * - * @{ - */ - - -/** - * @brief Sampling mode - * - * The sampling mode changes how the hardware accelerated averaging is done. Mode A is optimized - * for maximal independence of the depth points, giving a higher depth resolution than mode B. - * Mode B is instead optimized for maximal radar loop gain per unit time spent on measuring. This - * makes it more energy efficient and suitable for cases where small movements are to be detected - * over long ranges. Mode A is more suitable for applications like gesture recognition, measuring - * the distance to a movement, and speed measurements. - * - * Mode B typically gives roughly 3 dB better SNR per unit time than mode A. However, please note - * that very short ranges of only one or a few points are suboptimal with mode B. In those cases, - * always use mode A. - */ -typedef enum -{ - ACC_SERVICE_SPARSE_SAMPLING_MODE_A, - ACC_SERVICE_SPARSE_SAMPLING_MODE_B -} acc_service_sparse_sampling_mode_enum_t; -typedef uint32_t acc_service_sparse_sampling_mode_t; - - -/** - * @brief Metadata for the sparse service - */ -typedef struct -{ - /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ - float start_m; - /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ - float length_m; - /** Number of elements in the sparse data array */ - uint16_t data_length; - /** Sweep rate used */ - float sweep_rate; - /** Distance between adjacent data points */ - float step_length_m; -} acc_service_sparse_metadata_t; - - -/** - * @brief Metadata for each result provided by the sparse service - */ -typedef struct -{ - /** Indication of a sensor communication error, service probably needs to be restarted */ - bool sensor_communication_error; - /** Indication of sensor data being saturated, can cause result instability */ - bool data_saturated; - /** Indication of missed data from the sensor */ - bool missed_data; -} acc_service_sparse_result_info_t; - - -/** - * @brief Create a configuration for a sparse service - * - * A configuration is created for the sparse service and populated - * with default values. - * - * @return Service configuration, NULL if creation was not possible - */ -acc_service_configuration_t acc_service_sparse_configuration_create(void); - - -/** - * @brief Destroy a sparse configuration - * - * Destroy a sparse configuration that is no longer needed, may be done even if a - * service has been created with the specific configuration and has not yet been destroyed. - * The service configuration reference is set to NULL after destruction. - * - * @param[in] service_configuration The configuration to destroy, set to NULL - */ -void acc_service_sparse_configuration_destroy(acc_service_configuration_t *service_configuration); - - -/** - * @brief Get the number of sweeps per service frame - * - * Gets the number of sweeps that will be returned in each frame from the service. - * - * @param[in] service_configuration The service configuration to get sweeps per result from - * @return sweeps per frame - */ -uint16_t acc_service_sparse_configuration_sweeps_per_frame_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set sweeps per service frame - * - * Sets the number of sweeps that will be returned in each frame from the service. - * - * For sampling mode B, the number of sweeps per frame must be less than or equal to 64. - * - * @param[in] service_configuration The service configuration to set sweeps per results in - * @param[in] sweeps Sweeps per frame - */ -void acc_service_sparse_configuration_sweeps_per_frame_set(acc_service_configuration_t service_configuration, uint16_t sweeps); - - -/** - * @brief Get the sweep rate - * - * Gets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. - * - * @param[in] service_configuration The service configuration to get the sweep rate from - * @return sweep_rate The sweep rate - */ -float acc_service_sparse_configuration_sweep_rate_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set sweep rate - * - * Sets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. - * - * @param[in] service_configuration The service configuration to set the sweep rate in - * @param[in] sweep_rate The sweep rate - */ -void acc_service_sparse_configuration_sweep_rate_set(acc_service_configuration_t service_configuration, float sweep_rate); - - -/** - * @brief Get sampling mode - * - * @param[in] service_configuration The configuration to get the sampling mode for - * @return sampling mode - */ -acc_service_sparse_sampling_mode_t acc_service_sparse_sampling_mode_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set sampling mode - * - * @param[in] service_configuration The configuration to set the sampling mode for - * @param[in] sampling_mode The sampling mode to use - */ -void acc_service_sparse_sampling_mode_set(acc_service_configuration_t service_configuration, acc_service_sparse_sampling_mode_t sampling_mode); - - -/** - * @brief Get the sensor downsampling factor - * - * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 4 makes - * the distance between two points in the measured range ~24cm. - * - * @param[in] service_configuration The configuration to get downsampling factor from - * @return The downsampling factor - */ -uint16_t acc_service_sparse_downsampling_factor_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set the sensor downsampling factor - * - * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples - * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. - * - * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 4 makes - * the distance between two points in the measured range ~24cm. - * - * The sparse service supports setting the downsampling factor to 1, 2, 4, or 8. - * - * @param[in] service_configuration The configuration to set downsampling factor in - * @param[in] downsampling_factor The downsampling factor - */ -void acc_service_sparse_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); - - -/** - * @brief Get minimum service memory size - * - * The service memory size depends on several parameters and has a default - * minimum size of around 4kByte. The service memory usage increases with increasing range. - * This parameter changes the default minimum size from 4kByte to the used value. - * With a small value there might be a time penalty for service creation and activation. - * - * @param[in] service_configuration The service configuration to get min service memory size from - * @return The minimum service memory size - */ -uint16_t acc_service_sparse_min_service_memory_size_get(acc_service_configuration_t service_configuration); - - -/** - * @brief Set minimum service memory size - * - * The service memory size depends on several parameters and has a default - * minimum size of around 4kByte. The service memory usage increases with increasing range. - * This parameter changes the default minimum size from 4kByte to the used value. - * With a small value there might be a time penalty for service creation and activation. - * - * @param[in] service_configuration The service configuration to set min service memory size in - * @param[in] min_service_memory_size The minimum service memory size - */ -void acc_service_sparse_min_service_memory_size_set(acc_service_configuration_t service_configuration, uint16_t min_service_memory_size); - - -/** - * @brief Get service metadata - * - * Each service provide metadata after being created with information that could be relevant for an application. - * The metadata contain information such as data length and actual start and length. - * - * May only be called after a service has been created. - * - * @param[in] handle The service handle for the service to get metadata for - * @param[out] metadata Metadata results are provided in this parameter - */ -void acc_service_sparse_get_metadata(acc_service_handle_t handle, acc_service_sparse_metadata_t *metadata); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data sparse result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Sparse result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_sparse_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_sparse_result_info_t *result_info); - - -/** - * @brief Retrieve the next result from the service - * - * May only be called after a service has been activated to retrieve the next result, blocks - * the application until a result is ready. - * - * The provided memory is only valid until the next call to get_next for the - * specified handle. The memory is specific for the handle and cannot be shared - * between handles/services. - * - * The length of the resulting data is provided in @ref acc_service_sparse_get_metadata - * - * @param[in] handle The service handle for the service to get the next result for - * @param[out] data Reference to Sparse result - * @param[out] result_info Sparse result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_sparse_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, - acc_service_sparse_result_info_t *result_info); - - -/** - * @brief Execute service one time - * - * Activates service, produces one result and then deactivates the service. Blocks the - * application until a service result has been produced. May fail if the service is already active. - * - * @param[in] handle The service handle for the service to execute - * @param[out] data sparse result - * @param[in] data_length The length of the buffer provided for the result - * @param[out] result_info Sparse result info, sending in NULL is ok - * @return True if successful, false otherwise - */ -bool acc_service_sparse_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, - acc_service_sparse_result_info_t *result_info); - - -/** - * @} - */ - -#endif +// Copyright (c) Acconeer AB, 2019-2021 +// All rights reserved + +#ifndef ACC_SERVICE_SPARSE_H_ +#define ACC_SERVICE_SPARSE_H_ + +#include +#include + +#include "acc_service.h" + +/** + * @defgroup Sparse Sparse Service + * @ingroup Services + * + * @brief Sparse service API description + * + * @{ + */ + + +/** + * @brief Sampling mode + * + * The sampling mode changes how the hardware accelerated averaging is done. Mode A is optimized + * for maximal independence of the depth points, giving a higher depth resolution than mode B. + * Mode B is instead optimized for maximal radar loop gain per unit time spent on measuring. This + * makes it more energy efficient and suitable for cases where small movements are to be detected + * over long ranges. Mode A is more suitable for applications like gesture recognition, measuring + * the distance to a movement, and speed measurements. + * + * Mode B typically gives roughly 3 dB better SNR per unit time than mode A. However, please note + * that very short ranges of only one or a few points are suboptimal with mode B. In those cases, + * always use mode A. + */ +typedef enum +{ + ACC_SERVICE_SPARSE_SAMPLING_MODE_A, + ACC_SERVICE_SPARSE_SAMPLING_MODE_B +} acc_service_sparse_sampling_mode_enum_t; +typedef uint32_t acc_service_sparse_sampling_mode_t; + + +/** + * @brief Metadata for the sparse service + */ +typedef struct +{ + /** Start of sweep, derived from request set by @ref acc_service_requested_start_set */ + float start_m; + /** Length of sweep, derived from request set by @ref acc_service_requested_length_set */ + float length_m; + /** Number of elements in the sparse data array */ + uint16_t data_length; + /** Sweep rate used */ + float sweep_rate; + /** Distance between adjacent data points */ + float step_length_m; +} acc_service_sparse_metadata_t; + + +/** + * @brief Metadata for each result provided by the sparse service + */ +typedef struct +{ + /** Indication of a sensor communication error, service probably needs to be restarted */ + bool sensor_communication_error; + /** Indication of sensor data being saturated, can cause result instability */ + bool data_saturated; + /** Indication of missed data from the sensor */ + bool missed_data; +} acc_service_sparse_result_info_t; + + +/** + * @brief Create a configuration for a sparse service + * + * A configuration is created for the sparse service and populated + * with default values. + * + * @return Service configuration, NULL if creation was not possible + */ +acc_service_configuration_t acc_service_sparse_configuration_create(void); + + +/** + * @brief Destroy a sparse configuration + * + * Destroy a sparse configuration that is no longer needed, may be done even if a + * service has been created with the specific configuration and has not yet been destroyed. + * The service configuration reference is set to NULL after destruction. + * + * @param[in] service_configuration The configuration to destroy, set to NULL + */ +void acc_service_sparse_configuration_destroy(acc_service_configuration_t *service_configuration); + + +/** + * @brief Get the number of sweeps per service frame + * + * Gets the number of sweeps that will be returned in each frame from the service. + * + * @param[in] service_configuration The service configuration to get sweeps per result from + * @return sweeps per frame + */ +uint16_t acc_service_sparse_configuration_sweeps_per_frame_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set sweeps per service frame + * + * Sets the number of sweeps that will be returned in each frame from the service. + * + * For sampling mode B, the number of sweeps per frame must be less than or equal to 64. + * + * @param[in] service_configuration The service configuration to set sweeps per results in + * @param[in] sweeps Sweeps per frame + */ +void acc_service_sparse_configuration_sweeps_per_frame_set(acc_service_configuration_t service_configuration, uint16_t sweeps); + + +/** + * @brief Get the sweep rate + * + * Gets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. + * + * @param[in] service_configuration The service configuration to get the sweep rate from + * @return sweep_rate The sweep rate + */ +float acc_service_sparse_configuration_sweep_rate_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set sweep rate + * + * Sets the requested sweep rate. Values of zero of lower are treated as the maximum possible rate. + * + * @param[in] service_configuration The service configuration to set the sweep rate in + * @param[in] sweep_rate The sweep rate + */ +void acc_service_sparse_configuration_sweep_rate_set(acc_service_configuration_t service_configuration, float sweep_rate); + + +/** + * @brief Get sampling mode + * + * @param[in] service_configuration The configuration to get the sampling mode for + * @return sampling mode + */ +acc_service_sparse_sampling_mode_t acc_service_sparse_sampling_mode_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set sampling mode + * + * @param[in] service_configuration The configuration to set the sampling mode for + * @param[in] sampling_mode The sampling mode to use + */ +void acc_service_sparse_sampling_mode_set(acc_service_configuration_t service_configuration, acc_service_sparse_sampling_mode_t sampling_mode); + + +/** + * @brief Get the sensor downsampling factor + * + * Gets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 4 makes + * the distance between two points in the measured range ~24cm. + * + * @param[in] service_configuration The configuration to get downsampling factor from + * @return The downsampling factor + */ +uint16_t acc_service_sparse_downsampling_factor_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set the sensor downsampling factor + * + * Sets the downsampling factor - the number of steps taken between each data point. A downsampling factor of 1 samples + * every possible point in the range. A downsampling factor of 2 samples every other point, and so on. + * + * In the sparse service, the base step length is ~6cm. Thus, for example setting downsampling factor to 4 makes + * the distance between two points in the measured range ~24cm. + * + * The sparse service supports setting the downsampling factor to 1, 2, 4, or 8. + * + * @param[in] service_configuration The configuration to set downsampling factor in + * @param[in] downsampling_factor The downsampling factor + */ +void acc_service_sparse_downsampling_factor_set(acc_service_configuration_t service_configuration, uint16_t downsampling_factor); + + +/** + * @brief Get minimum service memory size + * + * The service memory size depends on several parameters and has a default + * minimum size of around 4kByte. The service memory usage increases with increasing range. + * This parameter changes the default minimum size from 4kByte to the used value. + * With a small value there might be a time penalty for service creation and activation. + * + * @param[in] service_configuration The service configuration to get min service memory size from + * @return The minimum service memory size + */ +uint16_t acc_service_sparse_min_service_memory_size_get(acc_service_configuration_t service_configuration); + + +/** + * @brief Set minimum service memory size + * + * The service memory size depends on several parameters and has a default + * minimum size of around 4kByte. The service memory usage increases with increasing range. + * This parameter changes the default minimum size from 4kByte to the used value. + * With a small value there might be a time penalty for service creation and activation. + * + * @param[in] service_configuration The service configuration to set min service memory size in + * @param[in] min_service_memory_size The minimum service memory size + */ +void acc_service_sparse_min_service_memory_size_set(acc_service_configuration_t service_configuration, uint16_t min_service_memory_size); + + +/** + * @brief Get service metadata + * + * Each service provide metadata after being created with information that could be relevant for an application. + * The metadata contain information such as data length and actual start and length. + * + * May only be called after a service has been created. + * + * @param[in] handle The service handle for the service to get metadata for + * @param[out] metadata Metadata results are provided in this parameter + */ +void acc_service_sparse_get_metadata(acc_service_handle_t handle, acc_service_sparse_metadata_t *metadata); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data sparse result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Sparse result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_sparse_get_next(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_sparse_result_info_t *result_info); + + +/** + * @brief Retrieve the next result from the service + * + * May only be called after a service has been activated to retrieve the next result, blocks + * the application until a result is ready. + * + * The provided memory is only valid until the next call to get_next for the + * specified handle. The memory is specific for the handle and cannot be shared + * between handles/services. + * + * The length of the resulting data is provided in @ref acc_service_sparse_get_metadata + * + * @param[in] handle The service handle for the service to get the next result for + * @param[out] data Reference to Sparse result + * @param[out] result_info Sparse result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_sparse_get_next_by_reference(acc_service_handle_t handle, uint16_t **data, + acc_service_sparse_result_info_t *result_info); + + +/** + * @brief Execute service one time + * + * Activates service, produces one result and then deactivates the service. Blocks the + * application until a service result has been produced. May fail if the service is already active. + * + * @param[in] handle The service handle for the service to execute + * @param[out] data sparse result + * @param[in] data_length The length of the buffer provided for the result + * @param[out] result_info Sparse result info, sending in NULL is ok + * @return True if successful, false otherwise + */ +bool acc_service_sparse_execute_once(acc_service_handle_t handle, uint16_t *data, uint16_t data_length, + acc_service_sparse_result_info_t *result_info); + + +/** + * @} + */ + +#endif diff --git a/rss/include/acc_version.h b/rss/include/acc_version.h index 4cdb4e0..4e6d482 100644 --- a/rss/include/acc_version.h +++ b/rss/include/acc_version.h @@ -1,14 +1,14 @@ -// Copyright (c) Acconeer AB, 2019-2021 -// All rights reserved - -#ifndef ACC_VERSION_H_ -#define ACC_VERSION_H_ - -/** - * @brief Get the version of the Acconeer software - * - * @return A string describing the software version. - */ -const char *acc_version_get(void); - -#endif +// Copyright (c) Acconeer AB, 2019-2021 +// All rights reserved + +#ifndef ACC_VERSION_H_ +#define ACC_VERSION_H_ + +/** + * @brief Get the version of the Acconeer software + * + * @return A string describing the software version. + */ +const char *acc_version_get(void); + +#endif