flipperzero-firmware/firmware/targets/f5/ble-glue/hrs_app.c

257 lines
7.5 KiB
C
Raw Normal View History

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file hrs_app.c
* @author MCD Application Team
* @brief Heart Rate Service Application
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "ble.h"
#include "hrs_app.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
typedef struct
{
HRS_BodySensorLocation_t BodySensorLocationChar;
HRS_MeasVal_t MeasurementvalueChar;
uint8_t ResetEnergyExpended;
uint8_t TimerMeasurement_Id;
} HRSAPP_Context_t;
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private defines ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macros ------------------------------------------------------------*/
#define HRSAPP_MEASUREMENT_INTERVAL (1000000/CFG_TS_TICK_VAL) /**< 1s */
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/**
* START of Section BLE_APP_CONTEXT
*/
PLACE_IN_SECTION("BLE_APP_CONTEXT") static HRSAPP_Context_t HRSAPP_Context;
/**
* END of Section BLE_APP_CONTEXT
*/
osThreadId_t HrsProcessId;
const osThreadAttr_t HrsProcess_attr = {
.name = CFG_HRS_PROCESS_NAME,
.attr_bits = CFG_HRS_PROCESS_ATTR_BITS,
.cb_mem = CFG_HRS_PROCESS_CB_MEM,
.cb_size = CFG_HRS_PROCESS_CB_SIZE,
.stack_mem = CFG_HRS_PROCESS_STACK_MEM,
.priority = CFG_HRS_PROCESS_PRIORITY,
.stack_size = CFG_HRS_PROCESS_STACK_SIZE
};
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private functions prototypes-----------------------------------------------*/
static void HrMeas( void );
static void HrsProcess(void *argument);
static void HRSAPP_Measurement(void);
static uint32_t HRSAPP_Read_RTC_SSR_SS ( void );
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Functions Definition ------------------------------------------------------*/
void HRS_Notification(HRS_App_Notification_evt_t *pNotification)
{
/* USER CODE BEGIN HRS_Notification_1 */
/* USER CODE END HRS_Notification_1 */
switch(pNotification->HRS_Evt_Opcode)
{
/* USER CODE BEGIN HRS_Notification_HRS_Evt_Opcode */
/* USER CODE END HRS_Notification_HRS_Evt_Opcode */
#if (BLE_CFG_HRS_ENERGY_EXPENDED_INFO_FLAG != 0)
case HRS_RESET_ENERGY_EXPENDED_EVT:
/* USER CODE BEGIN HRS_RESET_ENERGY_EXPENDED_EVT */
HRSAPP_Context.MeasurementvalueChar.EnergyExpended = 0;
HRSAPP_Context.ResetEnergyExpended = 1;
/* USER CODE END HRS_RESET_ENERGY_EXPENDED_EVT */
break;
#endif
case HRS_NOTIFICATION_ENABLED:
/* USER CODE BEGIN HRS_NOTIFICATION_ENABLED */
/**
* It could be the enable notification is received twice without the disable notification in between
*/
HW_TS_Stop(HRSAPP_Context.TimerMeasurement_Id);
HW_TS_Start(HRSAPP_Context.TimerMeasurement_Id, HRSAPP_MEASUREMENT_INTERVAL);
/* USER CODE END HRS_NOTIFICATION_ENABLED */
break;
case HRS_NOTIFICATION_DISABLED:
/* USER CODE BEGIN HRS_NOTIFICATION_DISABLED */
HW_TS_Stop(HRSAPP_Context.TimerMeasurement_Id);
/* USER CODE END HRS_NOTIFICATION_DISABLED */
break;
#if (BLE_CFG_OTA_REBOOT_CHAR != 0)
case HRS_STM_BOOT_REQUEST_EVT:
/* USER CODE BEGIN HRS_STM_BOOT_REQUEST_EVT */
*(uint32_t*)SRAM1_BASE = *(uint32_t*)pNotification->DataTransfered.pPayload;
NVIC_SystemReset();
/* USER CODE END HRS_STM_BOOT_REQUEST_EVT */
break;
#endif
default:
/* USER CODE BEGIN HRS_Notification_Default */
/* USER CODE END HRS_Notification_Default */
break;
}
/* USER CODE BEGIN HRS_Notification_2 */
/* USER CODE END HRS_Notification_2 */
return;
}
void HRSAPP_Init(void)
{
HrsProcessId = osThreadNew(HrsProcess, NULL, &HrsProcess_attr);
/* USER CODE BEGIN HRSAPP_Init */
/**
* Set Body Sensor Location
*/
HRSAPP_Context.ResetEnergyExpended = 0;
HRSAPP_Context.BodySensorLocationChar = HRS_BODY_SENSOR_LOCATION_HAND;
HRS_UpdateChar(SENSOR_LOCATION_UUID, (uint8_t *)&HRSAPP_Context.BodySensorLocationChar);
/**
* Set Flags for measurement value
*/
HRSAPP_Context.MeasurementvalueChar.Flags = ( HRS_HRM_VALUE_FORMAT_UINT16 |
HRS_HRM_SENSOR_CONTACTS_PRESENT |
HRS_HRM_SENSOR_CONTACTS_SUPPORTED |
HRS_HRM_ENERGY_EXPENDED_PRESENT |
HRS_HRM_RR_INTERVAL_PRESENT );
#if (BLE_CFG_HRS_ENERGY_EXPENDED_INFO_FLAG != 0)
if(HRSAPP_Context.MeasurementvalueChar.Flags & HRS_HRM_ENERGY_EXPENDED_PRESENT)
HRSAPP_Context.MeasurementvalueChar.EnergyExpended = 10;
#endif
#if (BLE_CFG_HRS_ENERGY_RR_INTERVAL_FLAG != 0)
if(HRSAPP_Context.MeasurementvalueChar.Flags & HRS_HRM_RR_INTERVAL_PRESENT)
{
uint8_t i;
HRSAPP_Context.MeasurementvalueChar.NbreOfValidRRIntervalValues = BLE_CFG_HRS_ENERGY_RR_INTERVAL_FLAG;
for(i = 0; i < BLE_CFG_HRS_ENERGY_RR_INTERVAL_FLAG; i++)
HRSAPP_Context.MeasurementvalueChar.aRRIntervalValues[i] = 1024;
}
#endif
/**
* Create timer for Heart Rate Measurement
*/
HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(HRSAPP_Context.TimerMeasurement_Id), hw_ts_Repeated, HrMeas);
/* USER CODE END HRSAPP_Init */
return;
}
static void HrsProcess(void *argument)
{
UNUSED(argument);
for(;;)
{
osThreadFlagsWait( 1, osFlagsWaitAny, osWaitForever);
HRSAPP_Measurement( );
}
}
static void HRSAPP_Measurement(void)
{
/* USER CODE BEGIN HRSAPP_Measurement */
uint32_t measurement;
measurement = ((HRSAPP_Read_RTC_SSR_SS()) & 0x07) + 65;
HRSAPP_Context.MeasurementvalueChar.MeasurementValue = measurement;
#if (BLE_CFG_HRS_ENERGY_EXPENDED_INFO_FLAG != 0)
if((HRSAPP_Context.MeasurementvalueChar.Flags & HRS_HRM_ENERGY_EXPENDED_PRESENT) &&
(HRSAPP_Context.ResetEnergyExpended == 0))
HRSAPP_Context.MeasurementvalueChar.EnergyExpended += 5;
else if(HRSAPP_Context.ResetEnergyExpended == 1)
HRSAPP_Context.ResetEnergyExpended = 0;
#endif
HRS_UpdateChar(HEART_RATE_MEASURMENT_UUID, (uint8_t *)&HRSAPP_Context.MeasurementvalueChar);
/* USER CODE END HRSAPP_Measurement */
return;
}
static void HrMeas( void )
{
/**
* The code shall be executed in the background as aci command may be sent
* The background is the only place where the application can make sure a new aci command
* is not sent if there is a pending one
*/
osThreadFlagsSet( HrsProcessId, 1 );
/* USER CODE BEGIN HrMeas */
/* USER CODE END HrMeas */
return;
}
static uint32_t HRSAPP_Read_RTC_SSR_SS ( void )
{
return ((uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS)));
}
/* USER CODE BEGIN FD */
/* USER CODE END FD */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/