257 lines
7.5 KiB
C
257 lines
7.5 KiB
C
|
/* USER CODE BEGIN Header */
|
||
|
/**
|
||
|
******************************************************************************
|
||
|
* @file hrs_app.c
|
||
|
* @author MCD Application Team
|
||
|
* @brief Heart Rate Service Application
|
||
|
******************************************************************************
|
||
|
* @attention
|
||
|
*
|
||
|
* <h2><center>© 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****/
|