mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-10 15:04:19 +00:00
[FL-1722] BLE custom serial service (#685)
* ble: remove heart rate profile * ble-glue: delete dead code * ble-glue: dis refactoring * ble-glue: add battery service * broken ble_common refactoring * ble-glue: advertise 128 bit service uid * ble-glue: remove dead code * ble: advertise service 16 bit uid depending on flipper color * ble-glue: remove debug * ble: intriduce serial service * ble: serial over ble * bt: serial echo server * bt: serial service process indicate acknowledge * bt: serial service event handler update * bt: refactore battery service * bt: add battery level apdate API * power: update battery level on change * bt: refactore device information service Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
710f33981a
commit
9bce160ca6
23 changed files with 438 additions and 1121 deletions
11
applications/bt/bt_service/bt.c
Normal file → Executable file
11
applications/bt/bt_service/bt.c
Normal file → Executable file
|
@ -1,4 +1,5 @@
|
|||
#include "bt_i.h"
|
||||
#include "battery_service.h"
|
||||
|
||||
#define BT_SERVICE_TAG "BT"
|
||||
|
||||
|
@ -43,6 +44,12 @@ Bt* bt_alloc() {
|
|||
return bt;
|
||||
}
|
||||
|
||||
bool bt_update_battery_level(Bt* bt, uint8_t battery_level) {
|
||||
BtMessage message = {
|
||||
.type = BtMessageTypeUpdateBatteryLevel, .data.battery_level = battery_level};
|
||||
return osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK;
|
||||
}
|
||||
|
||||
int32_t bt_srv() {
|
||||
Bt* bt = bt_alloc();
|
||||
furi_record_create("bt", bt);
|
||||
|
@ -68,6 +75,10 @@ int32_t bt_srv() {
|
|||
if(message.type == BtMessageTypeUpdateStatusbar) {
|
||||
// Update statusbar
|
||||
view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_alive());
|
||||
} else if(message.type == BtMessageTypeUpdateBatteryLevel) {
|
||||
if(furi_hal_bt_is_alive()) {
|
||||
battery_svc_update_level(message.data.battery_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct Bt Bt;
|
||||
|
||||
bool bt_update_battery_level(Bt* bt, uint8_t battery_level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -13,11 +13,16 @@
|
|||
|
||||
typedef enum {
|
||||
BtMessageTypeUpdateStatusbar,
|
||||
BtMessageTypeUpdateBatteryLevel,
|
||||
} BtMessageType;
|
||||
|
||||
typedef union {
|
||||
uint8_t battery_level;
|
||||
} BtMessageData;
|
||||
|
||||
typedef struct {
|
||||
BtMessageType type;
|
||||
void* param;
|
||||
BtMessageData data;
|
||||
} BtMessage;
|
||||
|
||||
struct Bt {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <stm32wbxx.h>
|
||||
|
||||
#include <notification/notification-messages.h>
|
||||
#include <applications/bt/bt_service/bt.h>
|
||||
|
||||
#define POWER_OFF_TIMEOUT 30
|
||||
|
||||
|
@ -39,6 +40,7 @@ struct Power {
|
|||
|
||||
ValueMutex* menu_vm;
|
||||
Cli* cli;
|
||||
Bt* bt;
|
||||
MenuItem* menu;
|
||||
|
||||
PowerState state;
|
||||
|
@ -108,6 +110,8 @@ Power* power_alloc() {
|
|||
power->cli = furi_record_open("cli");
|
||||
power_cli_init(power->cli, power);
|
||||
|
||||
power->bt = furi_record_open("bt");
|
||||
|
||||
power->menu = menu_item_alloc_menu("Power", icon_animation_alloc(&A_Power_14));
|
||||
menu_item_subitem_add(
|
||||
power->menu, menu_item_alloc_function("Off", NULL, power_menu_off_callback, power));
|
||||
|
@ -206,13 +210,15 @@ int32_t power_srv(void* p) {
|
|||
power->menu_vm, (Menu * menu) { menu_item_add(menu, power->menu); });
|
||||
|
||||
furi_record_create("power", power);
|
||||
|
||||
uint8_t battery_level = 0;
|
||||
uint8_t battery_level_prev = 0;
|
||||
while(1) {
|
||||
bool battery_low = false;
|
||||
|
||||
with_view_model(
|
||||
power->info_view, (PowerInfoModel * model) {
|
||||
model->charge = furi_hal_power_get_pct();
|
||||
battery_level = model->charge;
|
||||
model->health = furi_hal_power_get_bat_health_pct();
|
||||
model->capacity_remaining = furi_hal_power_get_battery_remaining_capacity();
|
||||
model->capacity_full = furi_hal_power_get_battery_full_capacity();
|
||||
|
@ -258,6 +264,11 @@ int32_t power_srv(void* p) {
|
|||
|
||||
power_charging_indication_handler(power, notifications);
|
||||
|
||||
if(battery_level_prev != battery_level) {
|
||||
battery_level_prev = battery_level;
|
||||
bt_update_battery_level(power->bt, battery_level);
|
||||
}
|
||||
|
||||
view_port_update(power->battery_view_port);
|
||||
|
||||
osDelay(1024);
|
||||
|
|
|
@ -40,3 +40,11 @@
|
|||
y = SWAP; \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#ifndef PLACE_IN_SECTION
|
||||
#define PLACE_IN_SECTION(x) __attribute__((section(x)))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN
|
||||
#define ALIGN(n) __attribute__((aligned(n)))
|
||||
#endif
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
#include "cmsis_os.h"
|
||||
#include "shci.h"
|
||||
#include "otp.h"
|
||||
#include "dis_app.h"
|
||||
#include "hrs_app.h"
|
||||
#include "dev_info_service.h"
|
||||
#include "battery_service.h"
|
||||
#include "serial_service.h"
|
||||
|
||||
#include <furi-hal.h>
|
||||
|
||||
|
@ -123,7 +124,6 @@ static void Ble_Tl_Init( void );
|
|||
static void Ble_Hci_Gap_Gatt_Init();
|
||||
static const uint8_t* BleGetBdAddress( void );
|
||||
static void Adv_Request( APP_BLE_ConnStatus_t New_Status );
|
||||
static void Add_Advertisment_Service_UUID( uint16_t servUUID );
|
||||
static void Adv_Mgr( void );
|
||||
static void AdvUpdateProcess(void *argument);
|
||||
static void Adv_Update( void );
|
||||
|
@ -160,6 +160,8 @@ bool APP_BLE_Init() {
|
|||
return (SHCI_C2_BLE_Init( &ble_init_cmd_packet ) == SHCI_Success);
|
||||
}
|
||||
|
||||
static void set_advertisment_service_uid(uint8_t* uid, uint8_t uin_len);
|
||||
|
||||
bool APP_BLE_Start() {
|
||||
if (APPE_Status() != BleGlueStatusStarted) {
|
||||
return false;
|
||||
|
@ -180,16 +182,18 @@ bool APP_BLE_Start() {
|
|||
#endif
|
||||
|
||||
// Initialize DIS Application
|
||||
DISAPP_Init();
|
||||
// Initialize HRS Application
|
||||
HRSAPP_Init();
|
||||
dev_info_service_init();
|
||||
// Initialize BAS Application
|
||||
battery_svc_init();
|
||||
// Initialize Serial application
|
||||
serial_svc_init();
|
||||
// Create timer to handle the connection state machine
|
||||
HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(BleApplicationContext.Advertising_mgr_timer_Id), hw_ts_SingleShot, Adv_Mgr);
|
||||
uint8_t adv_service_uid[2];
|
||||
adv_service_uid[0] = 0x80 | furi_hal_version_get_hw_color();
|
||||
adv_service_uid[1] = 0x30;
|
||||
|
||||
// Make device discoverable
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_16_BIT_SERV_UUID;
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 1;
|
||||
Add_Advertisment_Service_UUID(HEART_RATE_SERVICE_UUID);
|
||||
set_advertisment_service_uid(adv_service_uid, sizeof(adv_service_uid));
|
||||
/* Initialize intervals for reconnexion without intervals update */
|
||||
AdvIntervalMin = CFG_FAST_CONN_ADV_INTERVAL_MIN;
|
||||
AdvIntervalMax = CFG_FAST_CONN_ADV_INTERVAL_MAX;
|
||||
|
@ -198,6 +202,11 @@ bool APP_BLE_Start() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void SVCCTL_SvcInit() {
|
||||
// Dummy function to prevent unused services initialization
|
||||
// TODO refactore
|
||||
}
|
||||
|
||||
SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
|
||||
{
|
||||
hci_event_pckt *event_pckt;
|
||||
|
@ -382,56 +391,23 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
|
|||
return (SVCCTL_UserEvtFlowEnable);
|
||||
}
|
||||
|
||||
static void set_advertisment_service_uid(uint8_t* uid, uint8_t uid_len) {
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 1;
|
||||
if(uid_len == 2) {
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_16_BIT_SERV_UUID;
|
||||
} else if (uid_len == 4) {
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_32_BIT_SERV_UUID;
|
||||
} else if(uid_len == 16) {
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST;
|
||||
}
|
||||
memcpy(&BleApplicationContext.BleApplicationContext_legacy.advtServUUID[1], uid, uid_len);
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen += uid_len;
|
||||
}
|
||||
|
||||
APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status() {
|
||||
return BleApplicationContext.Device_Connection_Status;
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN FD*/
|
||||
void APP_BLE_Key_Button1_Action() {
|
||||
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
|
||||
ret = aci_gap_clear_security_db();
|
||||
if (ret == BLE_STATUS_SUCCESS) {
|
||||
APP_DBG_MSG("Successfully aci_gap_clear_security_db()\r\n");
|
||||
} else {
|
||||
APP_DBG_MSG("aci_gap_clear_security_db() Failed , result: %d \r\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
void APP_BLE_Key_Button2_Action() {
|
||||
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
|
||||
ret = aci_gap_slave_security_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
|
||||
if (ret == BLE_STATUS_SUCCESS) {
|
||||
APP_DBG_MSG("Successfully aci_gap_slave_security_req()");
|
||||
} else {
|
||||
APP_DBG_MSG("aci_gap_slave_security_req() Failed , result: %d \r\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
void APP_BLE_Key_Button3_Action() {
|
||||
uint8_t TX_PHY, RX_PHY;
|
||||
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
|
||||
ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY);
|
||||
if (ret == BLE_STATUS_SUCCESS) {
|
||||
APP_DBG_MSG("Read_PHY success \r\n");
|
||||
APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
|
||||
if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M)) {
|
||||
APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_1M, RX_1M);
|
||||
ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_1M,RX_1M,0);
|
||||
} else {
|
||||
APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_2M_PREFERRED, RX_2M_PREFERRED);
|
||||
ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_2M_PREFERRED,RX_2M_PREFERRED,0);
|
||||
}
|
||||
} else {
|
||||
APP_DBG_MSG("Read conf not succeess \r\n");
|
||||
}
|
||||
|
||||
if (ret == BLE_STATUS_SUCCESS) {
|
||||
APP_DBG_MSG("set PHY cmd ok\r\n");
|
||||
} else {
|
||||
APP_DBG_MSG("set PHY cmd NOK\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void Ble_Tl_Init( void ) {
|
||||
HCI_TL_HciInitConf_t Hci_Tl_Init_Conf;
|
||||
|
||||
|
@ -654,6 +630,9 @@ static void Adv_Request(APP_BLE_ConnStatus_t New_Status)
|
|||
BleApplicationContext.BleApplicationContext_legacy.advtServUUID,
|
||||
0,
|
||||
0);
|
||||
if(ret) {
|
||||
FURI_LOG_E("APP ble", "Set discoverable err: %d", ret);
|
||||
}
|
||||
|
||||
/* Update Advertising data */
|
||||
ret = aci_gap_update_adv_data(sizeof(manuf_data), (uint8_t*) manuf_data);
|
||||
|
@ -712,16 +691,6 @@ const uint8_t* BleGetBdAddress( void ) {
|
|||
*SPECIFIC FUNCTIONS
|
||||
*
|
||||
*************************************************************/
|
||||
static void Add_Advertisment_Service_UUID( uint16_t servUUID ) {
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen] =
|
||||
(uint8_t) (servUUID & 0xFF);
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen++;
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen] =
|
||||
(uint8_t) (servUUID >> 8) & 0xFF;
|
||||
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen++;
|
||||
|
||||
}
|
||||
|
||||
static void Adv_Mgr( void ) {
|
||||
/**
|
||||
* The code shall be executed in the background as an aci command may be sent
|
||||
|
|
|
@ -22,10 +22,6 @@ bool APP_BLE_Start();
|
|||
|
||||
APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status();
|
||||
|
||||
void APP_BLE_Key_Button1_Action();
|
||||
void APP_BLE_Key_Button2_Action();
|
||||
void APP_BLE_Key_Button3_Action();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,81 +32,12 @@ extern "C"{
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <furi/common_defines.h>
|
||||
|
||||
#include "app_conf.h"
|
||||
|
||||
/* -------------------------------- *
|
||||
* Basic definitions *
|
||||
* -------------------------------- */
|
||||
|
||||
#undef NULL
|
||||
#define NULL 0
|
||||
|
||||
#undef FALSE
|
||||
#define FALSE 0
|
||||
|
||||
#undef TRUE
|
||||
#define TRUE (!0)
|
||||
|
||||
/* -------------------------------- *
|
||||
* Critical Section definition *
|
||||
* -------------------------------- */
|
||||
#define BACKUP_PRIMASK() uint32_t primask_bit= __get_PRIMASK()
|
||||
#define DISABLE_IRQ() __disable_irq()
|
||||
#define RESTORE_PRIMASK() __set_PRIMASK(primask_bit)
|
||||
|
||||
/* -------------------------------- *
|
||||
* Macro delimiters *
|
||||
* -------------------------------- */
|
||||
|
||||
#define M_BEGIN do {
|
||||
|
||||
#define M_END } while(0)
|
||||
|
||||
/* -------------------------------- *
|
||||
* Some useful macro definitions *
|
||||
* -------------------------------- */
|
||||
|
||||
|
||||
#define MODINC( a, m ) M_BEGIN (a)++; if ((a)>=(m)) (a)=0; M_END
|
||||
|
||||
#define MODDEC( a, m ) M_BEGIN if ((a)==0) (a)=(m); (a)--; M_END
|
||||
|
||||
#define MODADD( a, b, m ) M_BEGIN (a)+=(b); if ((a)>=(m)) (a)-=(m); M_END
|
||||
|
||||
#define MODSUB( a, b, m ) MODADD( a, (m)-(b), m )
|
||||
|
||||
#define PAUSE( t ) M_BEGIN \
|
||||
__IO int _i; \
|
||||
for ( _i = t; _i > 0; _i -- ); \
|
||||
M_END
|
||||
|
||||
#define DIVF( x, y ) ((x)/(y))
|
||||
|
||||
#define DIVC( x, y ) (((x)+(y)-1)/(y))
|
||||
|
||||
#define DIVR( x, y ) (((x)+((y)/2))/(y))
|
||||
|
||||
#define SHRR( x, n ) ((((x)>>((n)-1))+1)>>1)
|
||||
|
||||
#define BITN( w, n ) (((w)[(n)/32] >> ((n)%32)) & 1)
|
||||
|
||||
#define BITNSET( w, n, b ) M_BEGIN (w)[(n)/32] |= ((U32)(b))<<((n)%32); M_END
|
||||
|
||||
/* -------------------------------- *
|
||||
* Compiler *
|
||||
* -------------------------------- */
|
||||
#define PLACE_IN_SECTION( __x__ ) __attribute__((section (__x__)))
|
||||
|
||||
#ifdef WIN32
|
||||
#define ALIGN(n)
|
||||
#else
|
||||
#define ALIGN(n) __attribute__((aligned(n)))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*APP_COMMON_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
#endif
|
|
@ -1,367 +0,0 @@
|
|||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : app_debug.c
|
||||
* Description : Debug capabilities source file for STM32WPAN Middleware
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2020 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 ------------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "app_common.h"
|
||||
|
||||
#include "app_debug.h"
|
||||
#include "utilities_common.h"
|
||||
#include "shci.h"
|
||||
#include "tl.h"
|
||||
#include "dbg_trace.h"
|
||||
#include <furi-hal.h>
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
GPIO_TypeDef* port;
|
||||
uint16_t pin;
|
||||
uint8_t enable;
|
||||
uint8_t reserved;
|
||||
} APPD_GpioConfig_t;
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
#define GPIO_NBR_OF_RF_SIGNALS 9
|
||||
#define GPIO_CFG_NBR_OF_FEATURES 34
|
||||
#define NBR_OF_TRACES_CONFIG_PARAMETERS 4
|
||||
#define NBR_OF_GENERAL_CONFIG_PARAMETERS 4
|
||||
|
||||
/**
|
||||
* THIS SHALL BE SET TO A VALUE DIFFERENT FROM 0 ONLY ON REQUEST FROM ST SUPPORT
|
||||
*/
|
||||
#define BLE_DTB_CFG 0
|
||||
#define SYS_DBG_CFG1 (SHCI_C2_DEBUG_OPTIONS_IPCORE_LP | SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_EN)
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static SHCI_C2_DEBUG_TracesConfig_t APPD_TracesConfig={0, 0, 0, 0};
|
||||
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static SHCI_C2_DEBUG_GeneralConfig_t APPD_GeneralConfig={BLE_DTB_CFG, SYS_DBG_CFG1, {0, 0}};
|
||||
|
||||
/**
|
||||
* THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT
|
||||
* It provides timing information on the CPU2 activity.
|
||||
* All configuration of (port, pin) is supported for each features and can be selected by the user
|
||||
* depending on the availability
|
||||
*/
|
||||
static const APPD_GpioConfig_t aGpioConfigList[GPIO_CFG_NBR_OF_FEATURES] =
|
||||
{
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_ISR - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_STACK_TICK - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_CMD_PROCESS - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_ACL_DATA_PROCESS - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* SYS_CMD_PROCESS - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* RNG_PROCESS - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVM_PROCESS - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_GENERAL - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_BLE_CMD_RX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_BLE_EVT_TX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_BLE_ACL_DATA_RX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_SYS_CMD_RX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_SYS_EVT_TX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_CLI_CMD_RX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_OT_CMD_RX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_OT_ACK_TX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_CLI_ACK_TX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_MEM_MANAGER_RX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_TRACES_TX - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* HARD_FAULT - Set on Entry / Reset on Exit */
|
||||
/* From v1.1.1 */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IP_CORE_LP_STATUS - Set on Entry / Reset on Exit */
|
||||
/* From v1.2.0 */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* END_OF_CONNECTION_EVENT - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* TIMER_SERVER_CALLBACK - Toggle on Entry */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* PES_ACTIVITY - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* MB_BLE_SEND_EVT - Set on Entry / Reset on Exit */
|
||||
/* From v1.3.0 */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_NO_DELAY - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_STACK_STORE_NVM_CB - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVMA_WRITE_ONGOING - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVMA_WRITE_COMPLETE - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVMA_CLEANUP - Set on Entry / Reset on Exit */
|
||||
/* From v1.4.0 */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVMA_START - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* FLASH_EOP - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* FLASH_WRITE - Set on Entry / Reset on Exit */
|
||||
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* FLASH_ERASE - Set on Entry / Reset on Exit */
|
||||
};
|
||||
|
||||
/**
|
||||
* THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT
|
||||
* This table is relevant only for BLE
|
||||
* It provides timing information on BLE RF activity.
|
||||
* New signals may be allocated at any location when requested by ST
|
||||
* The GPIO allocated to each signal depend on the BLE_DTB_CFG value and cannot be changed
|
||||
*/
|
||||
#if( BLE_DTB_CFG == 7)
|
||||
static const APPD_GpioConfig_t aRfConfigList[GPIO_NBR_OF_RF_SIGNALS] =
|
||||
{
|
||||
{ GPIOB, LL_GPIO_PIN_2, 0, 0}, /* DTB10 - Tx/Rx SPI */
|
||||
{ GPIOB, LL_GPIO_PIN_7, 0, 0}, /* DTB11 - Tx/Tx SPI Clk */
|
||||
{ GPIOA, LL_GPIO_PIN_8, 0, 0}, /* DTB12 - Tx/Rx Ready & SPI Select */
|
||||
{ GPIOA, LL_GPIO_PIN_9, 0, 0}, /* DTB13 - Tx/Rx Start */
|
||||
{ GPIOA, LL_GPIO_PIN_10, 0, 0}, /* DTB14 - FSM0 */
|
||||
{ GPIOA, LL_GPIO_PIN_11, 0, 0}, /* DTB15 - FSM1 */
|
||||
{ GPIOB, LL_GPIO_PIN_8, 0, 0}, /* DTB16 - FSM2 */
|
||||
{ GPIOB, LL_GPIO_PIN_11, 0, 0}, /* DTB17 - FSM3 */
|
||||
{ GPIOB, LL_GPIO_PIN_10, 0, 0}, /* DTB18 - FSM4 */
|
||||
};
|
||||
#endif
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN GV */
|
||||
/* USER CODE END GV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
static void APPD_SetCPU2GpioConfig( void );
|
||||
static void APPD_BleDtbCfg( void );
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
void APPD_Init( void )
|
||||
{
|
||||
/* USER CODE BEGIN APPD_Init */
|
||||
#if (CFG_DEBUGGER_SUPPORTED == 1)
|
||||
/**
|
||||
* Keep debugger enabled while in any low power mode
|
||||
*/
|
||||
HAL_DBGMCU_EnableDBGSleepMode();
|
||||
HAL_DBGMCU_EnableDBGStopMode();
|
||||
|
||||
/***************** ENABLE DEBUGGER *************************************/
|
||||
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
|
||||
|
||||
#else
|
||||
GPIO_InitTypeDef gpio_config = {0};
|
||||
|
||||
gpio_config.Pull = GPIO_NOPULL;
|
||||
gpio_config.Mode = GPIO_MODE_ANALOG;
|
||||
|
||||
gpio_config.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13;
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOA, &gpio_config);
|
||||
__HAL_RCC_GPIOA_CLK_DISABLE();
|
||||
|
||||
gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_3;
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOB, &gpio_config);
|
||||
__HAL_RCC_GPIOB_CLK_DISABLE();
|
||||
|
||||
HAL_DBGMCU_DisableDBGSleepMode();
|
||||
HAL_DBGMCU_DisableDBGStopMode();
|
||||
HAL_DBGMCU_DisableDBGStandbyMode();
|
||||
|
||||
#endif /* (CFG_DEBUGGER_SUPPORTED == 1) */
|
||||
|
||||
#if(CFG_DEBUG_TRACE != 0)
|
||||
DbgTraceInit();
|
||||
#endif
|
||||
|
||||
APPD_SetCPU2GpioConfig( );
|
||||
APPD_BleDtbCfg( );
|
||||
|
||||
/* USER CODE END APPD_Init */
|
||||
return;
|
||||
}
|
||||
|
||||
void APPD_EnableCPU2( void )
|
||||
{
|
||||
/* USER CODE BEGIN APPD_EnableCPU2 */
|
||||
SHCI_C2_DEBUG_Init_Cmd_Packet_t DebugCmdPacket =
|
||||
{
|
||||
{{0,0,0}}, /**< Does not need to be initialized */
|
||||
{(uint8_t *)aGpioConfigList,
|
||||
(uint8_t *)&APPD_TracesConfig,
|
||||
(uint8_t *)&APPD_GeneralConfig,
|
||||
GPIO_CFG_NBR_OF_FEATURES,
|
||||
NBR_OF_TRACES_CONFIG_PARAMETERS,
|
||||
NBR_OF_GENERAL_CONFIG_PARAMETERS}
|
||||
};
|
||||
|
||||
/**< Traces channel initialization */
|
||||
TL_TRACES_Init( );
|
||||
|
||||
/** GPIO DEBUG Initialization */
|
||||
SHCI_C2_DEBUG_Init( &DebugCmdPacket );
|
||||
|
||||
/* USER CODE END APPD_EnableCPU2 */
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* LOCAL FUNCTIONS
|
||||
*
|
||||
*************************************************************/
|
||||
static void APPD_SetCPU2GpioConfig( void )
|
||||
{
|
||||
/* USER CODE BEGIN APPD_SetCPU2GpioConfig */
|
||||
GPIO_InitTypeDef gpio_config = {0};
|
||||
uint8_t local_loop;
|
||||
uint16_t gpioa_pin_list;
|
||||
uint16_t gpiob_pin_list;
|
||||
uint16_t gpioc_pin_list;
|
||||
|
||||
gpioa_pin_list = 0;
|
||||
gpiob_pin_list = 0;
|
||||
gpioc_pin_list = 0;
|
||||
|
||||
for(local_loop = 0 ; local_loop < GPIO_CFG_NBR_OF_FEATURES; local_loop++)
|
||||
{
|
||||
if( aGpioConfigList[local_loop].enable != 0)
|
||||
{
|
||||
switch((uint32_t)aGpioConfigList[local_loop].port)
|
||||
{
|
||||
case (uint32_t)GPIOA:
|
||||
gpioa_pin_list |= aGpioConfigList[local_loop].pin;
|
||||
break;
|
||||
|
||||
case (uint32_t)GPIOB:
|
||||
gpiob_pin_list |= aGpioConfigList[local_loop].pin;
|
||||
break;
|
||||
|
||||
case (uint32_t)GPIOC:
|
||||
gpioc_pin_list |= aGpioConfigList[local_loop].pin;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gpio_config.Pull = GPIO_NOPULL;
|
||||
gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
|
||||
if(gpioa_pin_list != 0)
|
||||
{
|
||||
gpio_config.Pin = gpioa_pin_list;
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_C2GPIOA_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOA, &gpio_config);
|
||||
HAL_GPIO_WritePin(GPIOA, gpioa_pin_list, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
if(gpiob_pin_list != 0)
|
||||
{
|
||||
gpio_config.Pin = gpiob_pin_list;
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_C2GPIOB_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOB, &gpio_config);
|
||||
HAL_GPIO_WritePin(GPIOB, gpiob_pin_list, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
if(gpioc_pin_list != 0)
|
||||
{
|
||||
gpio_config.Pin = gpioc_pin_list;
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_C2GPIOC_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOC, &gpio_config);
|
||||
HAL_GPIO_WritePin(GPIOC, gpioc_pin_list, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
/* USER CODE END APPD_SetCPU2GpioConfig */
|
||||
return;
|
||||
}
|
||||
|
||||
static void APPD_BleDtbCfg( void )
|
||||
{
|
||||
/* USER CODE BEGIN APPD_BleDtbCfg */
|
||||
#if (BLE_DTB_CFG != 0)
|
||||
GPIO_InitTypeDef gpio_config = {0};
|
||||
uint8_t local_loop;
|
||||
uint16_t gpioa_pin_list;
|
||||
uint16_t gpiob_pin_list;
|
||||
|
||||
gpioa_pin_list = 0;
|
||||
gpiob_pin_list = 0;
|
||||
|
||||
for(local_loop = 0 ; local_loop < GPIO_NBR_OF_RF_SIGNALS; local_loop++)
|
||||
{
|
||||
if( aRfConfigList[local_loop].enable != 0)
|
||||
{
|
||||
switch((uint32_t)aRfConfigList[local_loop].port)
|
||||
{
|
||||
case (uint32_t)GPIOA:
|
||||
gpioa_pin_list |= aRfConfigList[local_loop].pin;
|
||||
break;
|
||||
|
||||
case (uint32_t)GPIOB:
|
||||
gpiob_pin_list |= aRfConfigList[local_loop].pin;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gpio_config.Pull = GPIO_NOPULL;
|
||||
gpio_config.Mode = GPIO_MODE_AF_PP;
|
||||
gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
gpio_config.Alternate = GPIO_AF6_RF_DTB7;
|
||||
|
||||
if(gpioa_pin_list != 0)
|
||||
{
|
||||
gpio_config.Pin = gpioa_pin_list;
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_C2GPIOA_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOA, &gpio_config);
|
||||
}
|
||||
|
||||
if(gpiob_pin_list != 0)
|
||||
{
|
||||
gpio_config.Pin = gpiob_pin_list;
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_C2GPIOB_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOB, &gpio_config);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* USER CODE END APPD_BleDtbCfg */
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* WRAP FUNCTIONS
|
||||
*
|
||||
*************************************************************/
|
||||
#if(CFG_DEBUG_TRACE != 0)
|
||||
void DbgOutputInit( void )
|
||||
{
|
||||
}
|
||||
|
||||
void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) )
|
||||
{
|
||||
furi_hal_console_tx(p_data, size);
|
||||
cb();
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -1,69 +0,0 @@
|
|||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : app_debug.h
|
||||
* Description : Header for app_debug.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2020 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 */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __APP_DEBUG_H
|
||||
#define __APP_DEBUG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/* Exported macros ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions ---------------------------------------------*/
|
||||
void APPD_Init( void );
|
||||
void APPD_EnableCPU2( void );
|
||||
/* USER CODE BEGIN EF */
|
||||
|
||||
/* USER CODE END EF */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*__APP_DEBUG_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -6,7 +6,6 @@
|
|||
#include "tl.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "shci_tl.h"
|
||||
#include "app_debug.h"
|
||||
#include <furi-hal.h>
|
||||
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
|
@ -178,3 +177,16 @@ void shci_cmd_resp_wait(uint32_t timeout) {
|
|||
UNUSED(timeout);
|
||||
osSemaphoreAcquire( SemShciId, osWaitForever );
|
||||
}
|
||||
|
||||
#if(CFG_DEBUG_TRACE != 0)
|
||||
void DbgOutputInit( void )
|
||||
{
|
||||
}
|
||||
|
||||
void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) )
|
||||
{
|
||||
furi_hal_console_tx(p_data, size);
|
||||
cb();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
55
firmware/targets/f6/ble-glue/battery_service.c
Normal file
55
firmware/targets/f6/ble-glue/battery_service.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include "battery_service.h"
|
||||
#include "app_common.h"
|
||||
#include "ble.h"
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#define BATTERY_SERVICE_TAG "battery service"
|
||||
|
||||
typedef struct {
|
||||
uint16_t svc_handle;
|
||||
uint16_t char_level_handle;
|
||||
} BatterySvc;
|
||||
|
||||
static BatterySvc battery_svc;
|
||||
|
||||
bool battery_svc_init() {
|
||||
tBleStatus status;
|
||||
const uint16_t service_uuid = BATTERY_SERVICE_UUID;
|
||||
const uint16_t char_battery_level_uuid = BATTERY_LEVEL_CHAR_UUID;
|
||||
|
||||
// Add Battery service
|
||||
status = aci_gatt_add_service(UUID_TYPE_16, (Service_UUID_t*)&service_uuid, PRIMARY_SERVICE, 4, &battery_svc.svc_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(BATTERY_SERVICE_TAG, "Failed to add Battery service: %d", status);
|
||||
}
|
||||
|
||||
// Add Battery level characteristic
|
||||
status = aci_gatt_add_char(battery_svc.svc_handle,
|
||||
UUID_TYPE_16,
|
||||
(Char_UUID_t *) &char_battery_level_uuid,
|
||||
1,
|
||||
CHAR_PROP_READ | CHAR_PROP_NOTIFY,
|
||||
ATTR_PERMISSION_NONE,
|
||||
GATT_DONT_NOTIFY_EVENTS,
|
||||
10,
|
||||
CHAR_VALUE_LEN_CONSTANT,
|
||||
&battery_svc.char_level_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(BATTERY_SERVICE_TAG, "Failed to add Battery level characteristic: %d", status);
|
||||
}
|
||||
return status != BLE_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bool battery_svc_update_level(uint8_t battery_charge) {
|
||||
FURI_LOG_I(BATTERY_SERVICE_TAG, "Updating battery level characteristic");
|
||||
tBleStatus result = aci_gatt_update_char_value(battery_svc.svc_handle,
|
||||
battery_svc.char_level_handle,
|
||||
0,
|
||||
1,
|
||||
&battery_charge);
|
||||
if(result) {
|
||||
FURI_LOG_E(BATTERY_SERVICE_TAG, "Failed updating RX characteristic: %d", result);
|
||||
}
|
||||
return result != BLE_STATUS_SUCCESS;
|
||||
}
|
16
firmware/targets/f6/ble-glue/battery_service.h
Normal file
16
firmware/targets/f6/ble-glue/battery_service.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool battery_svc_init();
|
||||
|
||||
bool battery_svc_update_level(uint8_t battery_level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -53,47 +53,12 @@
|
|||
|
||||
#define BLE_CFG_CLT_MAX_NBR_CB 0
|
||||
|
||||
/******************************************************************************
|
||||
* Device Information Service (DIS)
|
||||
******************************************************************************/
|
||||
/**< Options: Supported(1) or Not Supported(0) */
|
||||
#define BLE_CFG_DIS_MANUFACTURER_NAME_STRING 1
|
||||
#define BLE_CFG_DIS_MODEL_NUMBER_STRING 1
|
||||
#define BLE_CFG_DIS_SERIAL_NUMBER_STRING 0
|
||||
#define BLE_CFG_DIS_HARDWARE_REVISION_STRING 0
|
||||
#define BLE_CFG_DIS_FIRMWARE_REVISION_STRING 1
|
||||
#define BLE_CFG_DIS_SOFTWARE_REVISION_STRING 1
|
||||
#define BLE_CFG_DIS_SYSTEM_ID 0
|
||||
#define BLE_CFG_DIS_IEEE_CERTIFICATION 0
|
||||
#define BLE_CFG_DIS_PNP_ID 0
|
||||
|
||||
/**
|
||||
* device information service characteristic lengths
|
||||
*/
|
||||
#define BLE_CFG_DIS_SYSTEM_ID_LEN_MAX (8)
|
||||
#define BLE_CFG_DIS_MODEL_NUMBER_STRING_LEN_MAX (32)
|
||||
#define BLE_CFG_DIS_SERIAL_NUMBER_STRING_LEN_MAX (32)
|
||||
#define BLE_CFG_DIS_FIRMWARE_REVISION_STRING_LEN_MAX (32)
|
||||
#define BLE_CFG_DIS_HARDWARE_REVISION_STRING_LEN_MAX (32)
|
||||
#define BLE_CFG_DIS_SOFTWARE_REVISION_STRING_LEN_MAX (64)
|
||||
#define BLE_CFG_DIS_MANUFACTURER_NAME_STRING_LEN_MAX (32)
|
||||
#define BLE_CFG_DIS_IEEE_CERTIFICATION_LEN_MAX (32)
|
||||
#define BLE_CFG_DIS_PNP_ID_LEN_MAX (7)
|
||||
|
||||
/******************************************************************************
|
||||
* Heart Rate Service (HRS)
|
||||
******************************************************************************/
|
||||
#define BLE_CFG_HRS_BODY_SENSOR_LOCATION_CHAR 1/**< BODY SENSOR LOCATION CHARACTERISTIC */
|
||||
#define BLE_CFG_HRS_ENERGY_EXPENDED_INFO_FLAG 1/**< ENERGY EXTENDED INFO FLAG */
|
||||
#define BLE_CFG_HRS_ENERGY_RR_INTERVAL_FLAG 1/**< Max number of RR interval values - Shall not be greater than 9 */
|
||||
|
||||
/******************************************************************************
|
||||
* GAP Service - Apprearance
|
||||
******************************************************************************/
|
||||
|
||||
#define BLE_CFG_UNKNOWN_APPEARANCE (0)
|
||||
#define BLE_CFG_HR_SENSOR_APPEARANCE (832)
|
||||
#define BLE_CFG_GAP_APPEARANCE (BLE_CFG_HR_SENSOR_APPEARANCE)
|
||||
#define BLE_CFG_GAP_APPEARANCE (0x0086)
|
||||
|
||||
/******************************************************************************
|
||||
* Over The Air Feature (OTA) - STM Proprietary
|
||||
|
|
121
firmware/targets/f6/ble-glue/dev_info_service.c
Normal file
121
firmware/targets/f6/ble-glue/dev_info_service.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include "dev_info_service.h"
|
||||
#include "app_common.h"
|
||||
#include "ble.h"
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#define DEV_INFO_SERVICE_TAG "dev info service"
|
||||
|
||||
typedef struct {
|
||||
uint16_t service_handle;
|
||||
uint16_t man_name_char_handle;
|
||||
uint16_t serial_num_char_handle;
|
||||
uint16_t firmware_rev_char_handle;
|
||||
uint16_t software_rev_char_handle;
|
||||
} DevInfoSvc;
|
||||
|
||||
bool dev_info_service_init() {
|
||||
tBleStatus status;
|
||||
DevInfoSvc dev_info_svc;
|
||||
|
||||
// Add Device Information Service
|
||||
uint16_t uuid = DEVICE_INFORMATION_SERVICE_UUID;
|
||||
status = aci_gatt_add_service(UUID_TYPE_16, (Service_UUID_t*)&uuid, PRIMARY_SERVICE, 9, &dev_info_svc.service_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add Device Information Service: %d", status);
|
||||
}
|
||||
|
||||
// Add characteristics
|
||||
uuid = MANUFACTURER_NAME_UUID;
|
||||
status = aci_gatt_add_char(dev_info_svc.service_handle,
|
||||
UUID_TYPE_16,
|
||||
(Char_UUID_t*)&uuid,
|
||||
strlen(DEV_INFO_MANUFACTURER_NAME),
|
||||
CHAR_PROP_READ,
|
||||
ATTR_PERMISSION_NONE,
|
||||
GATT_DONT_NOTIFY_EVENTS,
|
||||
10,
|
||||
CHAR_VALUE_LEN_CONSTANT,
|
||||
&dev_info_svc.man_name_char_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add manufacturer name char: %d", status);
|
||||
|
||||
}
|
||||
uuid = SERIAL_NUMBER_UUID;
|
||||
status = aci_gatt_add_char(dev_info_svc.service_handle,
|
||||
UUID_TYPE_16,
|
||||
(Char_UUID_t*)&uuid,
|
||||
strlen(DEV_INFO_SERIAL_NUMBER),
|
||||
CHAR_PROP_READ,
|
||||
ATTR_PERMISSION_NONE,
|
||||
GATT_DONT_NOTIFY_EVENTS,
|
||||
10,
|
||||
CHAR_VALUE_LEN_CONSTANT,
|
||||
&dev_info_svc.serial_num_char_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add serial number char: %d", status);
|
||||
}
|
||||
uuid = FIRMWARE_REVISION_UUID;
|
||||
status = aci_gatt_add_char(dev_info_svc.service_handle,
|
||||
UUID_TYPE_16,
|
||||
(Char_UUID_t*)&uuid,
|
||||
strlen(DEV_INFO_FIRMWARE_REVISION_NUMBER),
|
||||
CHAR_PROP_READ,
|
||||
ATTR_PERMISSION_NONE,
|
||||
GATT_DONT_NOTIFY_EVENTS,
|
||||
10,
|
||||
CHAR_VALUE_LEN_CONSTANT,
|
||||
&dev_info_svc.firmware_rev_char_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add firmware revision char: %d", status);
|
||||
}
|
||||
uuid = SOFTWARE_REVISION_UUID;
|
||||
status = aci_gatt_add_char(dev_info_svc.service_handle,
|
||||
UUID_TYPE_16,
|
||||
(Char_UUID_t*)&uuid,
|
||||
strlen(DEV_INFO_SOFTWARE_REVISION_NUMBER),
|
||||
CHAR_PROP_READ,
|
||||
ATTR_PERMISSION_NONE,
|
||||
GATT_DONT_NOTIFY_EVENTS,
|
||||
10,
|
||||
CHAR_VALUE_LEN_CONSTANT,
|
||||
&dev_info_svc.software_rev_char_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add software revision char: %d", status);
|
||||
}
|
||||
|
||||
// Update characteristics
|
||||
status = aci_gatt_update_char_value(dev_info_svc.service_handle,
|
||||
dev_info_svc.man_name_char_handle,
|
||||
0,
|
||||
strlen(DEV_INFO_MANUFACTURER_NAME),
|
||||
(uint8_t*)DEV_INFO_MANUFACTURER_NAME);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to update manufacturer name char: %d", status);
|
||||
}
|
||||
status = aci_gatt_update_char_value(dev_info_svc.service_handle,
|
||||
dev_info_svc.serial_num_char_handle,
|
||||
0,
|
||||
strlen(DEV_INFO_SERIAL_NUMBER),
|
||||
(uint8_t*)DEV_INFO_SERIAL_NUMBER);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to update serial number char: %d", status);
|
||||
}
|
||||
status = aci_gatt_update_char_value(dev_info_svc.service_handle,
|
||||
dev_info_svc.firmware_rev_char_handle,
|
||||
0,
|
||||
strlen(DEV_INFO_FIRMWARE_REVISION_NUMBER),
|
||||
(uint8_t*)DEV_INFO_FIRMWARE_REVISION_NUMBER);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to update firmware revision char: %d", status);
|
||||
}
|
||||
status = aci_gatt_update_char_value(dev_info_svc.service_handle,
|
||||
dev_info_svc.software_rev_char_handle,
|
||||
0,
|
||||
strlen(DEV_INFO_SOFTWARE_REVISION_NUMBER),
|
||||
(uint8_t*)DEV_INFO_SOFTWARE_REVISION_NUMBER);
|
||||
if(status) {
|
||||
FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to update software revision char: %d", status);
|
||||
}
|
||||
return status != BLE_STATUS_SUCCESS;
|
||||
}
|
20
firmware/targets/f6/ble-glue/dev_info_service.h
Normal file
20
firmware/targets/f6/ble-glue/dev_info_service.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DEV_INFO_MANUFACTURER_NAME "Flipper Devices Inc."
|
||||
#define DEV_INFO_SERIAL_NUMBER "1.0"
|
||||
#define DEV_INFO_FIRMWARE_REVISION_NUMBER TARGET
|
||||
#define DEV_INFO_SOFTWARE_REVISION_NUMBER GIT_COMMIT " " GIT_BRANCH " " GIT_BRANCH_NUM " " BUILD_DATE
|
||||
|
||||
|
||||
bool dev_info_service_init();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,157 +0,0 @@
|
|||
#include "app_common.h"
|
||||
#include "ble.h"
|
||||
#include "dis_app.h"
|
||||
#include <furi-hal-version.h>
|
||||
|
||||
#if ((BLE_CFG_DIS_SYSTEM_ID != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
static const uint8_t system_id[BLE_CFG_DIS_SYSTEM_ID_LEN_MAX] = {
|
||||
(uint8_t)((DISAPP_MANUFACTURER_ID & 0xFF0000) >> 16),
|
||||
(uint8_t)((DISAPP_MANUFACTURER_ID & 0x00FF00) >> 8),
|
||||
(uint8_t)(DISAPP_MANUFACTURER_ID & 0x0000FF),
|
||||
0xFE,
|
||||
0xFF,
|
||||
(uint8_t)((DISAPP_OUI & 0xFF0000) >> 16),
|
||||
(uint8_t)((DISAPP_OUI & 0x00FF00) >> 8),
|
||||
(uint8_t)(DISAPP_OUI & 0x0000FF)
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_IEEE_CERTIFICATION != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
static const uint8_t ieee_id[BLE_CFG_DIS_IEEE_CERTIFICATION_LEN_MAX] = {
|
||||
0xFE, 0xCA, 0xFE, 0xCA, 0xFE, 0xCA, 0xFE, 0xCA,
|
||||
0xFE, 0xCA, 0xFE, 0xCA, 0xFE, 0xCA, 0xFE, 0xCA,
|
||||
0xFE, 0xCA, 0xFE, 0xCA, 0xFE, 0xCA, 0xFE, 0xCA,
|
||||
0xFE, 0xCA, 0xFE, 0xCA, 0xFE, 0xCA, 0xFE, 0xCA,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_PNP_ID != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
static const uint8_t pnp_id[BLE_CFG_DIS_PNP_ID_LEN_MAX] = {
|
||||
0x1,
|
||||
0xAD, 0xDE,
|
||||
0xDE, 0xDA,
|
||||
0x01, 0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
void DISAPP_Init(void) {
|
||||
DIS_Data_t dis_information_data;
|
||||
|
||||
#if ((BLE_CFG_DIS_MANUFACTURER_NAME_STRING != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update MANUFACTURER NAME Information
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
dis_information_data.pPayload = (uint8_t*)DISAPP_MANUFACTURER_NAME;
|
||||
dis_information_data.Length = sizeof(DISAPP_MANUFACTURER_NAME);
|
||||
DIS_UpdateChar(MANUFACTURER_NAME_UUID, &dis_information_data);
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_MODEL_NUMBER_STRING != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update MODEL NUMBERInformation
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
const char* name = furi_hal_version_get_device_name_ptr();
|
||||
dis_information_data.pPayload = (uint8_t*)name;
|
||||
dis_information_data.Length = strlen(name) + 1;
|
||||
DIS_UpdateChar(MODEL_NUMBER_UUID, &dis_information_data);
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_SERIAL_NUMBER_STRING != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update SERIAL NUMBERInformation
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
dis_information_data.pPayload = (uint8_t*)DISAPP_SERIAL_NUMBER;
|
||||
dis_information_data.Length = sizeof(DISAPP_SERIAL_NUMBER);
|
||||
DIS_UpdateChar(SERIAL_NUMBER_UUID, &dis_information_data);
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_HARDWARE_REVISION_STRING != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update HARDWARE REVISION NUMBERInformation
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
dis_information_data.pPayload = (uint8_t*)DISAPP_HARDWARE_REVISION_NUMBER;
|
||||
dis_information_data.Length = sizeof(DISAPP_HARDWARE_REVISION_NUMBER);
|
||||
DIS_UpdateChar(HARDWARE_REVISION_UUID, &dis_information_data);
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_FIRMWARE_REVISION_STRING != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update FIRMWARE REVISION NUMBERInformation
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
dis_information_data.pPayload = (uint8_t*)DISAPP_FIRMWARE_REVISION_NUMBER;
|
||||
dis_information_data.Length = sizeof(DISAPP_FIRMWARE_REVISION_NUMBER);
|
||||
DIS_UpdateChar(FIRMWARE_REVISION_UUID, &dis_information_data);
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_SOFTWARE_REVISION_STRING != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update SOFTWARE REVISION NUMBERInformation
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
dis_information_data.pPayload = (uint8_t*)DISAPP_SOFTWARE_REVISION_NUMBER;
|
||||
dis_information_data.Length = sizeof(DISAPP_SOFTWARE_REVISION_NUMBER);
|
||||
DIS_UpdateChar(SOFTWARE_REVISION_UUID, &dis_information_data);
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_SYSTEM_ID != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update SYSTEM ID Information
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
dis_information_data.pPayload = (uint8_t *)system_id;
|
||||
dis_information_data.Length = BLE_CFG_DIS_SYSTEM_ID_LEN_MAX;
|
||||
DIS_UpdateChar(SYSTEM_ID_UUID, &dis_information_data);
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_IEEE_CERTIFICATION != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update IEEE CERTIFICATION ID Information
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
dis_information_data.pPayload = (uint8_t *)ieee_id;
|
||||
dis_information_data.Length = BLE_CFG_DIS_IEEE_CERTIFICATION_LEN_MAX;
|
||||
DIS_UpdateChar(IEEE_CERTIFICATION_UUID, &dis_information_data);
|
||||
#endif
|
||||
|
||||
#if ((BLE_CFG_DIS_PNP_ID != 0) || (CFG_MENU_DEVICE_INFORMATION != 0))
|
||||
/**
|
||||
* Update PNP ID Information
|
||||
*
|
||||
* @param UUID
|
||||
* @param pPData
|
||||
* @return
|
||||
*/
|
||||
dis_information_data.pPayload = (uint8_t *)pnp_id;
|
||||
dis_information_data.Length = BLE_CFG_DIS_PNP_ID_LEN_MAX;
|
||||
DIS_UpdateChar(PNP_ID_UUID, &dis_information_data);
|
||||
#endif
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DISAPP_MANUFACTURER_NAME "Flipperdevice Inc."
|
||||
//#define DISAPP_MODEL_NUMBER "FlipperZero"
|
||||
#define DISAPP_SERIAL_NUMBER "1.0"
|
||||
#define DISAPP_HARDWARE_REVISION_NUMBER "1.0"
|
||||
#define DISAPP_FIRMWARE_REVISION_NUMBER TARGET
|
||||
#define DISAPP_SOFTWARE_REVISION_NUMBER GIT_COMMIT " " GIT_BRANCH " " GIT_BRANCH_NUM " " BUILD_DATE
|
||||
#define DISAPP_OUI 0x123456
|
||||
#define DISAPP_MANUFACTURER_ID 0x9ABCDE
|
||||
|
||||
void DISAPP_Init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,256 +0,0 @@
|
|||
/* 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****/
|
|
@ -1,69 +0,0 @@
|
|||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hrs_app.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for hrs_application.c module
|
||||
******************************************************************************
|
||||
* @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 */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __HRS_APP_H
|
||||
#define __HRS_APP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/* Exported macros ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions ---------------------------------------------*/
|
||||
void HRSAPP_Init( void );
|
||||
/* USER CODE BEGIN EF */
|
||||
|
||||
/* USER CODE END EF */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__HRS_APP_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
102
firmware/targets/f6/ble-glue/serial_service.c
Normal file
102
firmware/targets/f6/ble-glue/serial_service.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
#include "serial_service.h"
|
||||
#include "app_common.h"
|
||||
#include "ble.h"
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#define SERIAL_SERVICE_TAG "serial service"
|
||||
|
||||
typedef struct {
|
||||
uint16_t svc_handle;
|
||||
uint16_t rx_char_handle;
|
||||
uint16_t tx_char_handle;
|
||||
} SerialSvc;
|
||||
|
||||
static SerialSvc serial_svc;
|
||||
|
||||
static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) {
|
||||
SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck;
|
||||
hci_event_pckt* event_pckt = (hci_event_pckt *)(((hci_uart_pckt*)event)->data);
|
||||
evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data;
|
||||
aci_gatt_attribute_modified_event_rp0* attribute_modified;
|
||||
if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) {
|
||||
if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) {
|
||||
attribute_modified = (aci_gatt_attribute_modified_event_rp0*)blecore_evt->data;
|
||||
if(attribute_modified->Attr_Handle == serial_svc.tx_char_handle + 2) {
|
||||
// Descriptor handle
|
||||
ret = SVCCTL_EvtAckFlowEnable;
|
||||
FURI_LOG_D(SERIAL_SERVICE_TAG, "TX descriptor event");
|
||||
} else if(attribute_modified->Attr_Handle == serial_svc.tx_char_handle + 1) {
|
||||
FURI_LOG_I(SERIAL_SERVICE_TAG, "Data len: %d", attribute_modified->Attr_Data_Length);
|
||||
for(uint8_t i = 0; i < attribute_modified->Attr_Data_Length; i++) {
|
||||
printf("%02X ", attribute_modified->Attr_Data[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
serial_svc_update_rx(attribute_modified->Attr_Data, attribute_modified->Attr_Data_Length);
|
||||
ret = SVCCTL_EvtAckFlowEnable;
|
||||
}
|
||||
} else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) {
|
||||
FURI_LOG_I(SERIAL_SERVICE_TAG, "Ack received", blecore_evt->ecode);
|
||||
ret = SVCCTL_EvtAckFlowEnable;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool serial_svc_init() {
|
||||
tBleStatus status;
|
||||
const uint8_t service_uuid[] = {SERIAL_SVC_UUID_128};
|
||||
const uint8_t char_rx_uuid[] = {SERIAL_CHAR_RX_UUID_128};
|
||||
const uint8_t char_tx_uuid[] = {SERIAL_CHAR_TX_UUID_128};
|
||||
|
||||
// Register event handler
|
||||
SVCCTL_RegisterSvcHandler(serial_svc_event_handler);
|
||||
|
||||
// Add service
|
||||
status = aci_gatt_add_service(UUID_TYPE_128, (Service_UUID_t *)service_uuid, PRIMARY_SERVICE, 6, &serial_svc.svc_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add Serial service: %d", status);
|
||||
}
|
||||
|
||||
// Add TX characteristics
|
||||
status = aci_gatt_add_char(serial_svc.svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_tx_uuid ,
|
||||
SERIAL_SVC_DATA_LEN_MAX,
|
||||
CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ,
|
||||
ATTR_PERMISSION_NONE,
|
||||
GATT_NOTIFY_ATTRIBUTE_WRITE,
|
||||
10,
|
||||
CHAR_VALUE_LEN_VARIABLE,
|
||||
&serial_svc.tx_char_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add TX characteristic: %d", status);
|
||||
}
|
||||
|
||||
// Add RX characteristic
|
||||
status = aci_gatt_add_char(serial_svc.svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_rx_uuid ,
|
||||
SERIAL_SVC_DATA_LEN_MAX,
|
||||
CHAR_PROP_READ | CHAR_PROP_INDICATE,
|
||||
ATTR_PERMISSION_NONE,
|
||||
GATT_DONT_NOTIFY_EVENTS,
|
||||
10,
|
||||
CHAR_VALUE_LEN_VARIABLE,
|
||||
&serial_svc.rx_char_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add RX characteristic: %d", status);
|
||||
}
|
||||
|
||||
return status != BLE_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bool serial_svc_update_rx(uint8_t* data, uint8_t data_len) {
|
||||
furi_assert(data_len < SERIAL_SVC_DATA_LEN_MAX);
|
||||
|
||||
tBleStatus result = aci_gatt_update_char_value(serial_svc.svc_handle,
|
||||
serial_svc.rx_char_handle,
|
||||
0,
|
||||
data_len,
|
||||
data);
|
||||
if(result) {
|
||||
FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed updating RX characteristic: %d", result);
|
||||
}
|
||||
return result != BLE_STATUS_SUCCESS;
|
||||
}
|
22
firmware/targets/f6/ble-glue/serial_service.h
Normal file
22
firmware/targets/f6/ble-glue/serial_service.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SERIAL_SVC_DATA_LEN_MAX 255
|
||||
|
||||
#define SERIAL_SVC_UUID_128 0x00, 0x00, 0xfe, 0x60, 0xcc, 0x7a, 0x48, 0x2a, 0x98, 0x4a, 0x7f, 0x2e, 0xd5, 0xb3, 0xe5, 0x8f
|
||||
#define SERIAL_CHAR_RX_UUID_128 0x00, 0x00, 0xfe, 0x61, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19
|
||||
#define SERIAL_CHAR_TX_UUID_128 0x00, 0x00, 0xfe, 0x62, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19
|
||||
|
||||
bool serial_svc_init();
|
||||
|
||||
bool serial_svc_update_rx(uint8_t* data, uint8_t data_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -108,8 +108,6 @@ C_SOURCES += \
|
|||
$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/utilities/stm_list.c \
|
||||
$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/utilities/dbg_trace.c \
|
||||
$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/svc/Src/svc_ctl.c \
|
||||
$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/svc/Src/dis.c \
|
||||
$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/svc/Src/hrs.c \
|
||||
$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/template/osal.c \
|
||||
$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_hci_le.c \
|
||||
$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gap_aci.c \
|
||||
|
|
Loading…
Reference in a new issue