wb1mmc uart reception working

This commit is contained in:
ggw
2026-04-29 18:19:56 -05:00
parent 9e84f39fb1
commit ab8d4e672a
319 changed files with 2559 additions and 243803 deletions
-695
View File
@@ -1,695 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/app_ble.c
* @author MCD Application Team
* @brief BLE Application
*****************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "app_common.h"
#include "dbg_trace.h"
#include "ble.h"
#include "tl.h"
#include "app_ble.h"
#include "stm32_seq.h"
#include "shci.h"
#include "stm32_lpm.h"
#include "otp.h"
#include "eddystone_beacon.h"
#include "eddystone_uid_service.h"
#include "eddystone_url_service.h"
#include "eddystone_tlm_service.h"
#include "ibeacon_service.h"
#include "ibeacon.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private defines -----------------------------------------------------------*/
#define APPBLE_GAP_DEVICE_NAME_LENGTH 7
/**
* Boot Mode: 1 (OTA)
* Sector Index: 6
* Nb Sectors : 1
*/
#define BOOT_MODE_AND_SECTOR 0x010601
#define APP_SECTORS 7
#define DATA_SECTOR 6
#define BD_ADDR_SIZE_LOCAL 6
#define BLE_DEFAULT_PIN (111111)
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer;
static const uint8_t a_MBdAddr[BD_ADDR_SIZE_LOCAL] =
{
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000000000FF)),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x00000000FF00) >> 8),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x000000FF0000) >> 16),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000FF000000) >> 24),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x00FF00000000) >> 32),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0xFF0000000000) >> 40)
};
static uint8_t a_BdAddrUdn[BD_ADDR_SIZE_LOCAL];
/**
* Identity root key used to derive IRK and DHK(Legacy)
*/
static const uint8_t a_BLE_CfgIrValue[16] = CFG_BLE_IR;
/**
* Encryption root key used to derive LTK(Legacy) and CSRK
*/
static const uint8_t a_BLE_CfgErValue[16] = CFG_BLE_ER;
static uint8_t sector_type;
/**
* These are the two tags used to manage a power failure during OTA
* The MagicKeywordAdress shall be mapped @0x140 from start of the binary image
* The MagicKeywordvalue is checked in the ble_ota application
*/
PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ;
PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
static void BLE_UserEvtRx(void *p_Payload);
static void BLE_StatusNot(HCI_TL_CmdStatus_t Status);
static void Ble_Tl_Init(void);
static void Ble_Hci_Gap_Gatt_Init(void);
static const uint8_t* BleGetBdAddress(void);
static void Beacon_Update(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Functions Definition ------------------------------------------------------*/
void APP_BLE_Init(void)
{
SHCI_CmdStatus_t status;
/* USER CODE BEGIN APP_BLE_Init_1 */
/* USER CODE END APP_BLE_Init_1 */
SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet =
{
{{0,0,0}}, /**< Header unused */
{0, /** pBleBufferAddress not used */
0, /** BleBufferSize not used */
CFG_BLE_NUM_GATT_ATTRIBUTES,
CFG_BLE_NUM_GATT_SERVICES,
CFG_BLE_ATT_VALUE_ARRAY_SIZE,
CFG_BLE_NUM_LINK,
CFG_BLE_DATA_LENGTH_EXTENSION,
CFG_BLE_PREPARE_WRITE_LIST_SIZE,
CFG_BLE_MBLOCK_COUNT,
CFG_BLE_MAX_ATT_MTU,
CFG_BLE_PERIPHERAL_SCA,
CFG_BLE_CENTRAL_SCA,
CFG_BLE_LS_SOURCE,
CFG_BLE_MAX_CONN_EVENT_LENGTH,
CFG_BLE_HSE_STARTUP_TIME,
CFG_BLE_VITERBI_MODE,
CFG_BLE_OPTIONS,
0,
CFG_BLE_MAX_COC_INITIATOR_NBR,
CFG_BLE_MIN_TX_POWER,
CFG_BLE_MAX_TX_POWER,
CFG_BLE_RX_MODEL_CONFIG,
CFG_BLE_MAX_ADV_SET_NBR,
CFG_BLE_MAX_ADV_DATA_LEN,
CFG_BLE_TX_PATH_COMPENS,
CFG_BLE_RX_PATH_COMPENS,
CFG_BLE_CORE_VERSION,
CFG_BLE_OPTIONS_EXT,
CFG_BLE_MAX_ADD_EATT_BEARERS
}
};
/**
* Initialize Ble Transport Layer
*/
Ble_Tl_Init();
#if (CFG_LPM_STANDBY_SUPPORTED == 0)
UTIL_LPM_SetOffMode(1U << CFG_LPM_APP_BLE, UTIL_LPM_DISABLE);
#endif /* CFG_LPM_STANDBY_SUPPORTED == 0 */
/**
* Register the hci transport layer to handle BLE User Asynchronous Events
*/
UTIL_SEQ_RegTask(1<<CFG_TASK_HCI_ASYNCH_EVT_ID, UTIL_SEQ_RFU, hci_user_evt_proc);
/**
* Starts the BLE Stack on CPU2
*/
status = SHCI_C2_BLE_Init(&ble_init_cmd_packet);
if (status != SHCI_Success)
{
APP_DBG_MSG(" Fail : SHCI_C2_BLE_Init command, result: 0x%02x\n\r", status);
/* if you are here, maybe CPU2 doesn't contain STM32WB_Copro_Wireless_Binaries, see Release_Notes.html */
Error_Handler();
}
else
{
APP_DBG_MSG(" Success: SHCI_C2_BLE_Init command\n\r");
}
/**
* Initialization of HCI & GATT & GAP layer
*/
Ble_Hci_Gap_Gatt_Init();
/**
* Initialization of the BLE Services
*/
SVCCTL_Init();
/**
* From here, all initialization are BLE application specific
*/
UTIL_SEQ_RegTask(1<<CFG_TASK_BEACON_UPDATE_REQ_ID, UTIL_SEQ_RFU, Beacon_Update);
/* USER CODE BEGIN APP_BLE_Init_3 */
/* USER CODE END APP_BLE_Init_3 */
/**
* Make device discoverable
*/
if (CFG_BEACON_TYPE & CFG_EDDYSTONE_UID_BEACON_TYPE)
{
APP_DBG_MSG("Eddystone UID beacon advertise\n\r");
EddystoneUID_Process();
}
else if (CFG_BEACON_TYPE & CFG_EDDYSTONE_URL_BEACON_TYPE)
{
APP_DBG_MSG("Eddystone URL beacon advertise\n\r");
EddystoneURL_Process();
}
else if (CFG_BEACON_TYPE & CFG_EDDYSTONE_TLM_BEACON_TYPE)
{
APP_DBG_MSG("Eddystone TLM beacon advertise\n\r");
EddystoneTLM_Process();
}
else if (CFG_BEACON_TYPE & CFG_IBEACON)
{
APP_DBG_MSG("Ibeacon advertise\n\r");
IBeacon_Process();
}
/* USER CODE BEGIN APP_BLE_Init_2 */
/* USER CODE END APP_BLE_Init_2 */
return;
}
SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void *p_Pckt)
{
hci_event_pckt *p_event_pckt;
evt_le_meta_event *p_meta_evt;
evt_blecore_aci *p_blecore_evt;
/* USER CODE BEGIN SVCCTL_App_Notification */
/* USER CODE END SVCCTL_App_Notification */
p_event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) p_Pckt)->data;
switch (p_event_pckt->evt)
{
case HCI_DISCONNECTION_COMPLETE_EVT_CODE:
/* USER CODE BEGIN EVT_DISCONN_COMPLETE */
/* USER CODE END EVT_DISCONN_COMPLETE */
break; /* HCI_DISCONNECTION_COMPLETE_EVT_CODE */
case HCI_LE_META_EVT_CODE:
p_meta_evt = (evt_le_meta_event*) p_event_pckt->data;
/* USER CODE BEGIN EVT_LE_META_EVENT */
/* USER CODE END EVT_LE_META_EVENT */
switch (p_meta_evt->subevent)
{
case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE:
/* USER CODE BEGIN SUBEVENT_DEFAULT */
/* USER CODE END SUBEVENT_DEFAULT */
break;
default:
/* USER CODE BEGIN SUBEVENT_DEFAULT */
/* USER CODE END SUBEVENT_DEFAULT */
break;
}
/* USER CODE BEGIN META_EVT */
/* USER CODE END META_EVT */
break; /* HCI_LE_META_EVT_CODE */
case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE:
p_blecore_evt = (evt_blecore_aci*) p_event_pckt->data;
/* USER CODE BEGIN EVT_VENDOR */
/* USER CODE END EVT_VENDOR */
switch (p_blecore_evt->ecode)
{
/* USER CODE BEGIN ecode */
/* USER CODE END ecode */
case ACI_GAP_PROC_COMPLETE_VSEVT_CODE:
/* USER CODE BEGIN EVT_BLUE_GAP_PROCEDURE_COMPLETE */
/* USER CODE END EVT_BLUE_GAP_PROCEDURE_COMPLETE */
break; /* ACI_GAP_PROC_COMPLETE_VSEVT_CODE */
/* USER CODE BEGIN BLUE_EVT */
/* USER CODE END BLUE_EVT */
}
break; /* HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE */
/* USER CODE BEGIN EVENT_PCKT */
/* USER CODE END EVENT_PCKT */
default:
/* USER CODE BEGIN ECODE_DEFAULT*/
/* USER CODE END ECODE_DEFAULT*/
break;
}
return (SVCCTL_UserEvtFlowEnable);
}
/* USER CODE BEGIN FD*/
/* USER CODE END FD*/
/*************************************************************
*
* LOCAL FUNCTIONS
*
*************************************************************/
static void Ble_Tl_Init(void)
{
HCI_TL_HciInitConf_t Hci_Tl_Init_Conf;
Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&BleCmdBuffer;
Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot;
hci_init(BLE_UserEvtRx, (void*) &Hci_Tl_Init_Conf);
return;
}
static void Ble_Hci_Gap_Gatt_Init(void)
{
uint8_t role;
uint16_t gap_service_handle, gap_dev_name_char_handle, gap_appearance_char_handle;
const uint8_t *p_bd_addr;
uint16_t a_appearance[1] = {BLE_CFG_GAP_APPEARANCE};
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
/* USER CODE BEGIN Ble_Hci_Gap_Gatt_Init*/
/* USER CODE END Ble_Hci_Gap_Gatt_Init*/
APP_DBG_MSG("==>> Start Ble_Hci_Gap_Gatt_Init function\n");
/**
* Initialize HCI layer
*/
/*HCI Reset to synchronise BLE Stack*/
ret = hci_reset();
if (ret != BLE_STATUS_SUCCESS)
{
APP_DBG_MSG(" Fail : hci_reset command, result: 0x%x \n", ret);
}
else
{
APP_DBG_MSG(" Success: hci_reset command\n");
}
/**
* Write the BD Address
*/
p_bd_addr = BleGetBdAddress();
ret = aci_hal_write_config_data(CONFIG_DATA_PUBLIC_ADDRESS_OFFSET, CONFIG_DATA_PUBLIC_ADDRESS_LEN, (uint8_t*) p_bd_addr);
if (ret != BLE_STATUS_SUCCESS)
{
APP_DBG_MSG(" Fail : aci_hal_write_config_data command - CONFIG_DATA_PUBLIC_ADDRESS_OFFSET, result: 0x%x \n", ret);
}
else
{
APP_DBG_MSG(" Success: aci_hal_write_config_data command - CONFIG_DATA_PUBLIC_ADDRESS_OFFSET\n");
APP_DBG_MSG(" Public Bluetooth Address: %02x:%02x:%02x:%02x:%02x:%02x\n",p_bd_addr[5],p_bd_addr[4],p_bd_addr[3],p_bd_addr[2],p_bd_addr[1],p_bd_addr[0]);
}
/**
* Write Identity root key used to derive IRK and DHK(Legacy)
*/
ret = aci_hal_write_config_data(CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t*)a_BLE_CfgIrValue);
if (ret != BLE_STATUS_SUCCESS)
{
APP_DBG_MSG(" Fail : aci_hal_write_config_data command - CONFIG_DATA_IR_OFFSET, result: 0x%x \n", ret);
}
else
{
APP_DBG_MSG(" Success: aci_hal_write_config_data command - CONFIG_DATA_IR_OFFSET\n");
}
/**
* Write Encryption root key used to derive LTK and CSRK
*/
ret = aci_hal_write_config_data(CONFIG_DATA_ER_OFFSET, CONFIG_DATA_ER_LEN, (uint8_t*)a_BLE_CfgErValue);
if (ret != BLE_STATUS_SUCCESS)
{
APP_DBG_MSG(" Fail : aci_hal_write_config_data command - CONFIG_DATA_ER_OFFSET, result: 0x%x \n", ret);
}
else
{
APP_DBG_MSG(" Success: aci_hal_write_config_data command - CONFIG_DATA_ER_OFFSET\n");
}
/**
* Set TX Power.
*/
ret = aci_hal_set_tx_power_level(1, CFG_TX_POWER);
if (ret != BLE_STATUS_SUCCESS)
{
APP_DBG_MSG(" Fail : aci_hal_set_tx_power_level command, result: 0x%x \n", ret);
}
else
{
APP_DBG_MSG(" Success: aci_hal_set_tx_power_level command\n");
}
/**
* Initialize GATT interface
*/
ret = aci_gatt_init();
if (ret != BLE_STATUS_SUCCESS)
{
APP_DBG_MSG(" Fail : aci_gatt_init command, result: 0x%x \n", ret);
}
else
{
APP_DBG_MSG(" Success: aci_gatt_init command\n");
}
/**
* Initialize GAP interface
*/
role = 0;
#if (BLE_CFG_PERIPHERAL == 1)
role |= GAP_PERIPHERAL_ROLE;
#endif /* BLE_CFG_PERIPHERAL == 1 */
#if (BLE_CFG_CENTRAL == 1)
role |= GAP_CENTRAL_ROLE;
#endif /* BLE_CFG_CENTRAL == 1 */
/* USER CODE BEGIN Role_Mngt*/
/* USER CODE END Role_Mngt */
if (role > 0)
{
const char *name = "STM32WB";
ret = aci_gap_init(role,
0,
APPBLE_GAP_DEVICE_NAME_LENGTH,
&gap_service_handle,
&gap_dev_name_char_handle,
&gap_appearance_char_handle);
if (ret != BLE_STATUS_SUCCESS)
{
APP_DBG_MSG(" Fail : aci_gap_init command, result: 0x%x \n", ret);
}
else
{
APP_DBG_MSG(" Success: aci_gap_init command\n");
}
ret = aci_gatt_update_char_value(gap_service_handle, gap_dev_name_char_handle, 0, strlen(name), (uint8_t *) name);
if (ret != BLE_STATUS_SUCCESS)
{
BLE_DBG_SVCCTL_MSG(" Fail : aci_gatt_update_char_value - Device Name\n");
}
else
{
BLE_DBG_SVCCTL_MSG(" Success: aci_gatt_update_char_value - Device Name\n");
}
}
ret = aci_gatt_update_char_value(gap_service_handle,
gap_appearance_char_handle,
0,
2,
(uint8_t *)&a_appearance);
if (ret != BLE_STATUS_SUCCESS)
{
BLE_DBG_SVCCTL_MSG(" Fail : aci_gatt_update_char_value - Appearance\n");
}
else
{
BLE_DBG_SVCCTL_MSG(" Success: aci_gatt_update_char_value - Appearance\n");
}
}
static void Beacon_Update(void)
{
FLASH_EraseInitTypeDef erase;
uint32_t pageError = 0;
if (sector_type != 0)
{
erase.TypeErase = FLASH_TYPEERASE_PAGES;
erase.Page = sector_type;
if (sector_type == APP_SECTORS)
{
erase.NbPages = 2; /* 2 sectors for beacon application */
}
else
{
erase.NbPages = 1; /* 1 sector for beacon user data */
}
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_OPTVERR);
HAL_FLASHEx_Erase(&erase, &pageError);
HAL_FLASH_Lock();
}
*(uint32_t*) SRAM1_BASE = BOOT_MODE_AND_SECTOR;
/**
* Boot Mode: 1 (OTA)
* Sector Index: 6
* Nb Sectors : 1
*/
NVIC_SystemReset();
}
const uint8_t* BleGetBdAddress(void)
{
uint8_t *p_otp_addr;
const uint8_t *p_bd_addr;
uint32_t udn;
uint32_t company_id;
uint32_t device_id;
udn = LL_FLASH_GetUDN();
if (udn != 0xFFFFFFFF)
{
company_id = LL_FLASH_GetSTCompanyID();
device_id = LL_FLASH_GetDeviceID();
/**
* Public Address with the ST company ID
* bit[47:24] : 24bits (OUI) equal to the company ID
* bit[23:16] : Device ID.
* bit[15:0] : The last 16bits from the UDN
* Note: In order to use the Public Address in a final product, a dedicated
* 24bits company ID (OUI) shall be bought.
*/
a_BdAddrUdn[0] = (uint8_t)(udn & 0x000000FF);
a_BdAddrUdn[1] = (uint8_t)((udn & 0x0000FF00) >> 8);
a_BdAddrUdn[2] = (uint8_t)device_id;
a_BdAddrUdn[3] = (uint8_t)(company_id & 0x000000FF);
a_BdAddrUdn[4] = (uint8_t)((company_id & 0x0000FF00) >> 8);
a_BdAddrUdn[5] = (uint8_t)((company_id & 0x00FF0000) >> 16);
p_bd_addr = (const uint8_t *)a_BdAddrUdn;
}
else
{
p_otp_addr = OTP_Read(0);
if (p_otp_addr)
{
p_bd_addr = ((OTP_ID0_t*)p_otp_addr)->bd_address;
}
else
{
p_bd_addr = a_MBdAddr;
}
}
return p_bd_addr;
}
/* USER CODE BEGIN FD_LOCAL_FUNCTION */
/* USER CODE END FD_LOCAL_FUNCTION */
/* USER CODE BEGIN FD_SPECIFIC_FUNCTIONS */
/* USER CODE END FD_SPECIFIC_FUNCTIONS */
/*************************************************************
*
* WRAP FUNCTIONS
*
*************************************************************/
void hci_notify_asynch_evt(void* p_Data)
{
UTIL_SEQ_SetTask(1 << CFG_TASK_HCI_ASYNCH_EVT_ID, CFG_SCH_PRIO_0);
return;
}
void hci_cmd_resp_release(uint32_t Flag)
{
UTIL_SEQ_SetEvt(1 << CFG_IDLEEVT_HCI_CMD_EVT_RSP_ID);
return;
}
void hci_cmd_resp_wait(uint32_t Timeout)
{
UTIL_SEQ_WaitEvt(1 << CFG_IDLEEVT_HCI_CMD_EVT_RSP_ID);
return;
}
static void BLE_UserEvtRx(void *p_Payload)
{
SVCCTL_UserEvtFlowStatus_t svctl_return_status;
tHCI_UserEvtRxParam *p_param;
p_param = (tHCI_UserEvtRxParam *)p_Payload;
svctl_return_status = SVCCTL_UserEvtRx((void *)&(p_param->pckt->evtserial));
if (svctl_return_status != SVCCTL_UserEvtFlowDisable)
{
p_param->status = HCI_TL_UserEventFlow_Enable;
}
else
{
p_param->status = HCI_TL_UserEventFlow_Disable;
}
return;
}
static void BLE_StatusNot(HCI_TL_CmdStatus_t Status)
{
uint32_t task_id_list;
switch (Status)
{
case HCI_TL_CmdBusy:
/**
* All tasks that may send an aci/hci commands shall be listed here
* This is to prevent a new command is sent while one is already pending
*/
task_id_list = (1 << CFG_LAST_TASK_ID_WITH_HCICMD) - 1;
UTIL_SEQ_PauseTask(task_id_list);
/* USER CODE BEGIN HCI_TL_CmdBusy */
/* USER CODE END HCI_TL_CmdBusy */
break;
case HCI_TL_CmdAvailable:
/**
* All tasks that may send an aci/hci commands shall be listed here
* This is to prevent a new command is sent while one is already pending
*/
task_id_list = (1 << CFG_LAST_TASK_ID_WITH_HCICMD) - 1;
UTIL_SEQ_ResumeTask(task_id_list);
/* USER CODE BEGIN HCI_TL_CmdAvailable */
/* USER CODE END HCI_TL_CmdAvailable */
break;
default:
/* USER CODE BEGIN Status */
/* USER CODE END Status */
break;
}
return;
}
void SVCCTL_ResumeUserEventFlow(void)
{
hci_resume_flow();
return;
}
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
/* USER CODE END FD_WRAP_FUNCTIONS */
-69
View File
@@ -1,69 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/app_ble.h
* @author MCD Application Team
* @brief Header for ble application
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 APP_BLE_H
#define APP_BLE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "hci_tl.h"
/* 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 macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions ---------------------------------------------*/
void APP_BLE_Init(void);
/* USER CODE BEGIN EF */
/* USER CODE END EF */
#ifdef __cplusplus
}
#endif
#endif /*APP_BLE_H */
@@ -1,65 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file ble_conf.h
* @author MCD Application Team
* @brief Configuration file for BLE Middleware.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 BLE_CONF_H
#define BLE_CONF_H
#include "app_conf.h"
/******************************************************************************
*
* BLE SERVICES CONFIGURATION
* blesvc
*
******************************************************************************/
/**
* This setting shall be set to '1' if the device needs to support the Peripheral Role
* In the MS configuration, both BLE_CFG_PERIPHERAL and BLE_CFG_CENTRAL shall be set to '1'
*/
#define BLE_CFG_PERIPHERAL 1
/**
* This setting shall be set to '1' if the device needs to support the Central Role
* In the MS configuration, both BLE_CFG_PERIPHERAL and BLE_CFG_CENTRAL shall be set to '1'
*/
#define BLE_CFG_CENTRAL 0
/**
* There is one handler per service enabled
* Note: There is no handler for the Device Information Service
*
* This shall take into account all registered handlers
* (from either the provided services or the custom services)
*/
#define BLE_CFG_SVC_MAX_NBR_CB 7
#define BLE_CFG_CLT_MAX_NBR_CB 0
/******************************************************************************
* GAP Service - Appearance
******************************************************************************/
#define BLE_CFG_UNKNOWN_APPEARANCE (0)
#define BLE_CFG_HR_SENSOR_APPEARANCE (832)
#define BLE_CFG_GAP_APPEARANCE (BLE_CFG_UNKNOWN_APPEARANCE)
#endif /*BLE_CONF_H */
@@ -1,198 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/ble_dbg_conf.h
* @author MCD Application Team
* @brief Debug configuration file for BLE Middleware.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 BLE_DBG_CONF_H
#define BLE_DBG_CONF_H
/**
* Enable or Disable traces from BLE
*/
#define BLE_DBG_APP_EN 0
#define BLE_DBG_DIS_EN 0
#define BLE_DBG_HRS_EN 0
#define BLE_DBG_SVCCTL_EN 0
#define BLE_DBG_BLS_EN 0
#define BLE_DBG_HTS_EN 0
#define BLE_DBG_P2P_STM_EN 0
/**
* Macro definition
*/
#if (BLE_DBG_APP_EN != 0)
#define BLE_DBG_APP_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_APP_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_DIS_EN != 0)
#define BLE_DBG_DIS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_DIS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_HRS_EN != 0)
#define BLE_DBG_HRS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_HRS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_P2P_STM_EN != 0)
#define BLE_DBG_P2P_STM_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_P2P_STM_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_TEMPLATE_STM_EN != 0)
#define BLE_DBG_TEMPLATE_STM_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_TEMPLATE_STM_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_EDS_STM_EN != 0)
#define BLE_DBG_EDS_STM_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_EDS_STM_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_LBS_STM_EN != 0)
#define BLE_DBG_LBS_STM_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_LBS_STM_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_SVCCTL_EN != 0)
#define BLE_DBG_SVCCTL_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_SVCCTL_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_CTS_EN != 0)
#define BLE_DBG_CTS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_CTS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_HIDS_EN != 0)
#define BLE_DBG_HIDS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_HIDS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_PASS_EN != 0)
#define BLE_DBG_PASS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_PASS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_BLS_EN != 0)
#define BLE_DBG_BLS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_BLS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_HTS_EN != 0)
#define BLE_DBG_HTS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_HTS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_ANS_EN != 0)
#define BLE_DBG_ANS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_ANS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_ESS_EN != 0)
#define BLE_DBG_ESS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_ESS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_GLS_EN != 0)
#define BLE_DBG_GLS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_GLS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_BAS_EN != 0)
#define BLE_DBG_BAS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_BAS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_RTUS_EN != 0)
#define BLE_DBG_RTUS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_RTUS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_HPS_EN != 0)
#define BLE_DBG_HPS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_HPS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_TPS_EN != 0)
#define BLE_DBG_TPS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_TPS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_LLS_EN != 0)
#define BLE_DBG_LLS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_LLS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_IAS_EN != 0)
#define BLE_DBG_IAS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_IAS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_WSS_EN != 0)
#define BLE_DBG_WSS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_WSS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_LNS_EN != 0)
#define BLE_DBG_LNS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_LNS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_SCPS_EN != 0)
#define BLE_DBG_SCPS_MSG PRINT_MESG_DBG
#else
#define BLE_DBG_SCPS_MSG PRINT_NO_MESG
#endif
#if (BLE_DBG_DTS_EN != 0)
#define BLE_DBG_DTS_MSG PRINT_MESG_DBG
#define BLE_DBG_DTS_BUF PRINT_LOG_BUFF_DBG
#else
#define BLE_DBG_DTS_MSG PRINT_NO_MESG
#define BLE_DBG_DTS_BUF PRINT_NO_MESG
#endif
#endif /*BLE_DBG_CONF_H */
@@ -1,96 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/eddystone_beacon.h
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 EDDYSTONE_BEACON_H
#define EDDYSTONE_BEACON_H
#ifdef __cplusplus
extern "C"
{
#endif
/* Includes ------------------------------------------------------------------*/
#if defined (__CC_ARM) || defined (__ARMCC_VERSION)
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
/* These can't be used after statements in c89. */
#ifdef __COUNTER__
#define STATIC_ASSERT(e,m) \
;enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }
#else
/* This can't be used twice on the same line so ensure if using in headers
* that the headers are not included twice (by wrapping in #ifndef...#endif)
* Note it doesn't cause an issue when used on same line of separate modules
* compiled with gcc -combine -fwhole-program. */
#define static_assert(e,m) \
;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
#endif
#endif
/* Exported types ------------------------------------------------------------*/
enum
{
NOT_CONNECTED,
CONNECTED
};
/* Exported constants --------------------------------------------------------*/
#define ADVERTISING_INTERVAL_IN_MS (1000)
#define CALIBRATED_TX_POWER_AT_0_M ((uint8_t) (-22))
#define NAMESPACE_ID 'w', 'w', 'w', '.', 's', 't', '.', 'c', 'o', 'm'
#define BEACON_ID 0, 0, 0, 0, 0, 1
#define URL_PREFIX HTTP
#define PHYSICAL_WEB_URL "www.st.com"
#define NORMAL_TIME_ADV 10000000
#define TLM_TIME_ADV 1000000
#if (0 != (CFG_BEACON_TYPE & (CFG_BEACON_TYPE - 1)))
#error "Please select only a single beacon type!"
#endif
#if ((ADVERTISING_INTERVAL_IN_MS <= 0) || (ADVERTISING_INTERVAL_IN_MS > 40959))
#error "Invalid advertising interval! Please select a value between 0 and 40959 ms."
#endif
#if (0 != (CFG_BEACON_TYPE & CFG_EDDYSTONE_TLM_BEACON_TYPE))
#if ((ADVERTISING_INTERVAL_IN_MS < 1000) || ((ADVERTISING_INTERVAL_IN_MS % 1000) != 0))
#error "EDDYSTONE_TLM only supports intervals in increments of 1 s!"
#endif
#endif
#if (0 != (CFG_BEACON_TYPE & CFG_EDDYSTONE_URL_BEACON_TYPE))
#if defined (__CC_ARM) || defined (__ARMCC_VERSION)
STATIC_ASSERT(sizeof(PHYSICAL_WEB_URL) < 17, "The URL must be less than 17 characters.");
#elif defined (__ICCARM__)
static_assert(sizeof(PHYSICAL_WEB_URL) < 17, "The URL must be less than 17 characters.");
#else
#warning Please check that sizeof(PHYSICAL_WEB_URL) < 17
#endif
#endif
/* Exported Macros -----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* EDDYSTONE_BEACON_H */
@@ -1,425 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/eddystone_tlm_service.c
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "ble.h"
#include "eddystone_beacon.h"
#include "eddystone_url_service.h"
#include "eddystone_uid_service.h"
#include "system_stm32wbxx.h"
#include "eddystone_tlm_service.h"
/* Exported types ------------------------------------------------------------*/
typedef struct
{
uint16_t AdvertisingInterval;/*!< Specifies the desired advertising interval. */
uint8_t TLM_Version; /*!< Specifies the version of the TLM frame. */
uint16_t BatteryVoltage; /*!< Specifies the battery voltage, in 1 mV/bit. */
uint16_t BeaconTemperature; /*!< Specifies the beacon temperature, in Signed 8.8 Fixed Point notation. */
uint32_t AdvertisingCount; /*!< Specifies the running count of all advertisement frames. */
uint32_t Uptime; /*!< Specifies the time sinbe the beacon was powered-up or rebooted. */
} EddystoneTLM_InitTypeDef;
/* Private types -------------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADVERTISING_INTERVAL_INCREMENT (16)
#define DEFAULT_BEACON_SEC (1000000/CFG_TS_TICK_VAL) /**< 1s */
/* Private variables ---------------------------------------------------------*/
uint8_t tlm_adv;
uint8_t TimerTLM_Id;
EddystoneURL_InitTypeDef EddystoneURL_InitStruct;
EddystoneUID_InitTypeDef EddystoneUID_InitStruct;
EddystoneTLM_InitTypeDef EddystoneTLM_InitStruct;
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Global variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static tBleStatus EddystoneTLM_Init(EddystoneTLM_InitTypeDef *EddystoneTLM_Init)
{
tBleStatus ret = BLE_STATUS_SUCCESS;
uint16_t AdvertisingInterval = (EddystoneTLM_Init->AdvertisingInterval * ADVERTISING_INTERVAL_INCREMENT / 10);
uint8_t service_data[] =
{
17, /*< Length. */
AD_TYPE_SERVICE_DATA, /*< Service Data data type value. */
0xAA, 0xFE, /*< 16-bit Eddystone UUID. */
0x20, /*< TLM frame type. */
(EddystoneTLM_Init->TLM_Version), /*< TLM version. */
(EddystoneTLM_Init->BatteryVoltage & 0xFF00) >> 8, /*< Battery voltage. */
(EddystoneTLM_Init->BatteryVoltage & 0x00FF),
(EddystoneTLM_Init->BeaconTemperature & 0xFF00) >> 8, /*< Beacon temperature. */
(EddystoneTLM_Init->BeaconTemperature & 0x00FF),
(EddystoneTLM_Init->AdvertisingCount & 0xFF000000) >> 24, /*< Advertising PDU count. */
(EddystoneTLM_Init->AdvertisingCount & 0x00FF0000) >> 16,
(EddystoneTLM_Init->AdvertisingCount & 0x0000FF00) >> 8,
(EddystoneTLM_Init->AdvertisingCount & 0x000000FF),
(EddystoneTLM_Init->Uptime & 0xFF000000) >> 24, /*< Time since power-on or reboot. */
(EddystoneTLM_Init->Uptime & 0x00FF0000) >> 16,
(EddystoneTLM_Init->Uptime & 0x0000FF00) >> 8,
(EddystoneTLM_Init->Uptime & 0x000000FF)
};
uint8_t service_uuid_list[] =
{
3, /*< Length. */
AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST, /*< Complete list of 16-bit Service UUIDs data type value. */
0xAA, 0xFE /*< 16-bit Eddystone UUID. */
};
uint8_t flags[] =
{
2, /*< Length. */
AD_TYPE_FLAGS, /*< Flags data type value. */
(FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE | FLAG_BIT_BR_EDR_NOT_SUPPORTED) /*< BLE general discoverable, without BR/EDR support. */
};
/* Disable scan response. */
hci_le_set_scan_response_data(0, NULL);
/* Put the device in a non-connectable mode. */
ret = aci_gap_set_discoverable(ADV_NONCONN_IND, /*< Advertise as non-connectable, undirected. */
AdvertisingInterval, AdvertisingInterval, /*< Set the advertising interval as 700 ms (0.625 us increment). */
GAP_PUBLIC_ADDR, NO_WHITE_LIST_USE, /*< Use the public address, with no white list. */
0, NULL, /*< Do not use a local name. */
0, NULL, /*< Do not include the service UUID list. */
0, 0); /*< Do not set a slave connection interval. */
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Remove the TX power level advertisement (this is done to decrease the packet size). */
ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the service data. */
ret = aci_gap_update_adv_data(sizeof(service_data), service_data);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the service UUID list. */
ret = aci_gap_update_adv_data(sizeof(service_uuid_list), service_uuid_list);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the adverstising flags. */
ret = aci_gap_update_adv_data(sizeof(flags), flags);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
return ret;
}
static void EddystoneTLM(void)
{
tBleStatus ret;
#ifdef USE_OTA
uint32_t data_address = OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_LENGTH; /* 0x8006009 */
#endif
if(tlm_adv == TRUE)
{ /* Advertising of TLM */
ret = aci_gap_set_non_discoverable();
if (ret != BLE_STATUS_SUCCESS)
{
while(1);
}
#ifdef USE_OTA
if(((*(uint8_t *)OTA_BEACON_DATA_ADDRESS) != 0xFF) &&
((*(uint8_t *)(OTA_BEACON_DATA_ADDRESS + 8)) == 0x01))
{ /* TLM present and User Data downloaded */
EddystoneTLM_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
if((*(uint8_t *)(data_address + 9) == 0x00))
{ /* 0x8006012: EDDYSTONE UUID => TLM Data start at 0x8006027 */
data_address += 0x09 + 0x15; /* 0x8006009 -> 0x8006027: 0x1E */
}
else
{ /* 0x8006012: EDDYSTONE URL => TLM Data start at 0x8006012 + 3 + (URL length - 6) */
data_address += 0x09 + 0x03 + (EddystoneURL_InitStruct.UrlLength - 6);
}
EddystoneTLM_InitStruct.TLM_Version = *(uint8_t *)data_address;
if((*(uint8_t *)data_address) != 0xFF)
{ /* Battery Voltage downloaded */
EddystoneTLM_InitStruct.BatteryVoltage = (*(uint8_t *)data_address) +
((*(uint8_t *)(data_address + 1)) << 8);
data_address += 2;
if((*(uint8_t *)data_address) != 0xFF)
{ /* Temperature downloaded */
EddystoneTLM_InitStruct.BeaconTemperature = (*(uint8_t *)data_address) +
((*(uint8_t *)(data_address + 1)) << 8);
data_address += 2;
if((*(uint8_t *)data_address) != 0xFF)
{ /* Uptime downloaded */
EddystoneTLM_InitStruct.Uptime = (*(uint8_t *)data_address) +
((*(uint8_t *)(data_address + 1)) << 8) +
((*(uint8_t *)(data_address + 2)) << 16) +
((*(uint8_t *)(data_address + 3)) << 24);
data_address += 4;
if((*(uint8_t *)data_address) != 0xFF)
{ /* Advertising count downloaded */
EddystoneTLM_InitStruct.AdvertisingCount = (*(uint8_t *)data_address) +
((*(uint8_t *)(data_address + 1)) << 8) +
((*(uint8_t *)(data_address + 2)) << 16) +
((*(uint8_t *)(data_address + 3)) << 24);
}
}
}
}
EddystoneTLM_Init(&EddystoneTLM_InitStruct);
tlm_adv = FALSE;
/* Wait 1s */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC);
}
else
{ /* TLM not present or User Data not downloaded */
EddystoneTLM_Init(&EddystoneTLM_InitStruct);
tlm_adv = FALSE;
/* Wait 1s */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC);
}
#else
/* No OTA */
EddystoneTLM_Init(&EddystoneTLM_InitStruct);
tlm_adv = FALSE;
/* Wait 1s */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC);
#endif
}
else
{ /* Advertising of UUID or URL */
ret = aci_gap_set_non_discoverable();
if (ret != BLE_STATUS_SUCCESS)
{
while(1);
}
#ifdef USE_OTA
data_address += 9; /* 0x8006012 */
if((*(uint8_t *)data_address) == 0x00)
{
/* Eddystone UID */
uint8_t i, NameId[10], BeaconId[6];
EddystoneUID_InitStruct.NamespaceID = NameId;
EddystoneUID_InitStruct.BeaconID = BeaconId;
data_address += 1; /* 0x8006013 */
EddystoneUID_InitStruct.CalibratedTxPower = *(uint8_t *)data_address;
data_address += 1; /* 0x8006014 */
for(i = 0; i < 10; i++)
EddystoneUID_InitStruct.NamespaceID[i] = *(uint8_t *)(data_address + i);
data_address += 10; /* 0x800601E */
for(i = 0; i < 6; i++)
EddystoneUID_InitStruct.BeaconID[i] = *(uint8_t *)(data_address + i);
data_address += 8; /* 0x8006026 */
EddystoneUID_Init(&EddystoneUID_InitStruct);
tlm_adv = TRUE; /* Next TLM advertise */
/* 10s of UID advertise */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC * 10);
}
else if((*(uint8_t *)data_address) == 0x10)
{
/* Eddystone URL */
uint8_t i;
uint8_t Url[100];
EddystoneURL_InitStruct.Url = Url;
EddystoneURL_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
data_address += 1; /* 0x8006013 */
EddystoneURL_InitStruct.CalibratedTxPower = *(uint8_t *)data_address;
data_address += 1; /* 0x8006014 */
EddystoneURL_InitStruct.CalibratedTxPower = *(uint8_t *)data_address;
data_address += 1; /* 0x8006015 */
for(i = 0; i < EddystoneURL_InitStruct.UrlLength - 6; i++)
EddystoneURL_InitStruct.Url[i] = *(uint8_t *)(data_address + i);
EddystoneURL_InitStruct.UrlLength = *(uint8_t *)(OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_LENGTH + 5); /* 0x800600e */
data_address += EddystoneURL_InitStruct.UrlLength - 6; /* 0x8006015 + EddystoneURL_InitStruct.UrlLength - 6 */
EddystoneURL_Init(&EddystoneURL_InitStruct);
tlm_adv = TRUE; /* Next TLM advertise */
/* 10s of URL advertise */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC * 10);
}
else
{
EddystoneURL_Init(&EddystoneURL_InitStruct);
tlm_adv = TRUE;
/* 10s of URL advertise */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC * 10);
}
#else
/* No OTA */
EddystoneURL_Init(&EddystoneURL_InitStruct);
tlm_adv = TRUE;
/* 10s of URL advertise */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC * 10);
#endif
}
}
/* Exported functions --------------------------------------------------------*/
void EddystoneTLM_Process(void)
{
#ifdef USE_OTA
uint32_t data_address = OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_LENGTH; /* 0x8006009 */
uint8_t length = *(uint8_t *)(data_address);
#else
uint8_t UrlScheme = URL_PREFIX;
uint8_t Url[] = PHYSICAL_WEB_URL;
uint8_t NamespaceID[] = { NAMESPACE_ID };
uint8_t BeaconID[] = { BEACON_ID };
EddystoneURL_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
EddystoneURL_InitStruct.CalibratedTxPower = CALIBRATED_TX_POWER_AT_0_M;
EddystoneURL_InitStruct.UrlScheme = UrlScheme;
EddystoneURL_InitStruct.Url = Url;
EddystoneURL_InitStruct.UrlLength = sizeof(Url) - 1;
EddystoneTLM_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
EddystoneTLM_InitStruct.TLM_Version = 0;
EddystoneTLM_InitStruct.BatteryVoltage = 3000;
EddystoneTLM_InitStruct.BeaconTemperature = 10000;
EddystoneTLM_InitStruct.Uptime = 2000000;
EddystoneTLM_InitStruct.AdvertisingCount = 3000000;
EddystoneUID_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
EddystoneUID_InitStruct.CalibratedTxPower = CALIBRATED_TX_POWER_AT_0_M;
EddystoneUID_InitStruct.NamespaceID = NamespaceID;
EddystoneUID_InitStruct.BeaconID = BeaconID;
#endif
HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(TimerTLM_Id), hw_ts_SingleShot, EddystoneTLM);
#ifdef USE_OTA
if(((*(uint8_t *)(OTA_BEACON_DATA_ADDRESS)) != 0xFF) &&
(length != 0xFF))
{
/* Service Data Updated via OTA */
data_address += 9; /* 0x8006012 */
if((*(uint8_t *)data_address) == 0x00)
{
/* Eddystone UID */
uint8_t i, NameId[10], BeaconId[6];
EddystoneUID_InitStruct.NamespaceID = NameId;
EddystoneUID_InitStruct.BeaconID = BeaconId;
data_address += 1; /* 0x8006013 */
EddystoneUID_InitStruct.CalibratedTxPower = *(uint8_t *)data_address;
data_address += 1; /* 0x8006014 */
for(i = 0; i < 10; i++)
EddystoneUID_InitStruct.NamespaceID[i] = *(uint8_t *)(data_address + i);
data_address += 10; /* 0x800601E */
for(i = 0; i < 6; i++)
EddystoneUID_InitStruct.BeaconID[i] = *(uint8_t *)(data_address + i);
data_address += 8; /* 0x8006026 */
EddystoneUID_Init(&EddystoneUID_InitStruct);
tlm_adv = TRUE;
/* 10s of UID advertise */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC * 10);
}
else if((*(uint8_t *)data_address) == 0x10)
{
/* Eddystone URL */
uint8_t i;
uint8_t Url[100];
EddystoneURL_InitStruct.Url = Url;
EddystoneURL_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
data_address += 1; /* 0x8006013 */
EddystoneURL_InitStruct.CalibratedTxPower = *(uint8_t *)data_address;
data_address += 1; /* 0x8006014 */
EddystoneURL_InitStruct.CalibratedTxPower = *(uint8_t *)data_address;
data_address += 1; /* 0x8006015 */
for(i = 0; i < EddystoneURL_InitStruct.UrlLength - 6; i++)
EddystoneURL_InitStruct.Url[i] = *(uint8_t *)(data_address + i);
EddystoneURL_InitStruct.UrlLength = *(uint8_t *)(OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_LENGTH + 5); /* 0x800600e */
data_address += EddystoneURL_InitStruct.UrlLength - 6; /* 0x8006015 + EddystoneURL_InitStruct.UrlLength - 6 */
EddystoneURL_Init(&EddystoneURL_InitStruct);
tlm_adv = TRUE;
/* 10s of URL advertise */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC * 10);
}
}
else
#endif
{
uint8_t UrlScheme = URL_PREFIX;
uint8_t Url[] = PHYSICAL_WEB_URL;
uint8_t NamespaceID[] = { NAMESPACE_ID };
uint8_t BeaconID[] = { BEACON_ID };
EddystoneURL_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
EddystoneURL_InitStruct.CalibratedTxPower = CALIBRATED_TX_POWER_AT_0_M;
EddystoneURL_InitStruct.UrlScheme = UrlScheme;
EddystoneURL_InitStruct.Url = Url;
EddystoneURL_InitStruct.UrlLength = sizeof(Url) - 1;
EddystoneTLM_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
EddystoneTLM_InitStruct.TLM_Version = 0;
EddystoneTLM_InitStruct.BatteryVoltage = 3000;
EddystoneTLM_InitStruct.BeaconTemperature = 10000;
EddystoneTLM_InitStruct.Uptime = 2000000;
EddystoneTLM_InitStruct.AdvertisingCount = 3000000;
EddystoneUID_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
EddystoneUID_InitStruct.CalibratedTxPower = CALIBRATED_TX_POWER_AT_0_M;
EddystoneUID_InitStruct.NamespaceID = NamespaceID;
EddystoneUID_InitStruct.BeaconID = BeaconID;
EddystoneURL_Init(&EddystoneURL_InitStruct);
tlm_adv = TRUE;
/* 10s of URL advertise */
HW_TS_Start(TimerTLM_Id, DEFAULT_BEACON_SEC * 10);
}
}
@@ -1,41 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/eddystone_tlm_service.h
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 EDDYSTONE_TLM_SERVICE_H
#define EDDYSTONE_TLM_SERVICE_H
#ifdef __cplusplus
extern "C"
{
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported Macros -----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
void EddystoneTLM_Process(void);
#ifdef __cplusplus
}
#endif
#endif /* EDDYSTONE_TLM_SERVICE_H */
@@ -1,191 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/eddystone_uid_service.c
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "ble.h"
#include "eddystone_beacon.h"
#include "eddystone_uid_service.h"
/* Exported types ------------------------------------------------------------*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADVERTISING_INTERVAL_INCREMENT (16)
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
tBleStatus EddystoneUID_Init(EddystoneUID_InitTypeDef *EddystoneUID_Init)
{
tBleStatus ret = BLE_STATUS_SUCCESS;
uint16_t AdvertisingInterval = (EddystoneUID_Init->AdvertisingInterval * ADVERTISING_INTERVAL_INCREMENT / 10);
uint8_t service_data[] =
{
23, /*< Length. */
AD_TYPE_SERVICE_DATA, /*< Service Data data type value. */
0xAA, 0xFE, /*< 16-bit Eddystone UUID. */
0x00, /*< UID frame type. */
EddystoneUID_Init->CalibratedTxPower, /*< Ranging data. */
EddystoneUID_Init->NamespaceID[0], /*< 10-byte ID Namespace. */
EddystoneUID_Init->NamespaceID[1],
EddystoneUID_Init->NamespaceID[2],
EddystoneUID_Init->NamespaceID[3],
EddystoneUID_Init->NamespaceID[4],
EddystoneUID_Init->NamespaceID[5],
EddystoneUID_Init->NamespaceID[6],
EddystoneUID_Init->NamespaceID[7],
EddystoneUID_Init->NamespaceID[8],
EddystoneUID_Init->NamespaceID[9],
EddystoneUID_Init->BeaconID[0], /*< 6-byte ID Instance. */
EddystoneUID_Init->BeaconID[1],
EddystoneUID_Init->BeaconID[2],
EddystoneUID_Init->BeaconID[3],
EddystoneUID_Init->BeaconID[4],
EddystoneUID_Init->BeaconID[5],
0x00, /*< Reserved. */
0x00 /*< Reserved. */
};
uint8_t service_uuid_list[] =
{
3, /*< Length. */
AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST, /*< Complete list of 16-bit Service UUIDs data type value. */
0xAA, 0xFE /*< 16-bit Eddystone UUID. */
};
uint8_t flags[] =
{
2, /*< Length. */
AD_TYPE_FLAGS, /*< Flags data type value. */
(FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE | FLAG_BIT_BR_EDR_NOT_SUPPORTED) /*< BLE general discoverable, without BR/EDR support. */
};
/* Disable scan response. */
hci_le_set_scan_response_data(0, NULL);
/* Put the device in a non-connectable mode. */
ret = aci_gap_set_discoverable(ADV_NONCONN_IND, /*< Advertise as non-connectable, undirected. */
AdvertisingInterval, AdvertisingInterval, /*< Set the advertising interval as 700 ms (0.625 us increment). */
GAP_PUBLIC_ADDR, NO_WHITE_LIST_USE, /*< Use the public address, with no white list. */
0, NULL, /*< Do not use a local name. */
0, NULL, /*< Do not include the service UUID list. */
0, 0); /*< Do not set a slave connection interval. */
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Remove the TX power level advertisement (this is done to decrease the packet size). */
ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the service data. */
ret = aci_gap_update_adv_data(sizeof(service_data), service_data);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the service UUID list. */
ret = aci_gap_update_adv_data(sizeof(service_uuid_list), service_uuid_list);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the adverstising flags. */
ret = aci_gap_update_adv_data(sizeof(flags), flags);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
return ret;
}
void EddystoneUID_Process(void)
{
#ifdef USE_OTA
uint32_t data_address = OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_LENGTH; /* 0x8006009 */
if(((*(uint8_t *)(OTA_BEACON_DATA_ADDRESS)) != 0xFF) &&
((*(uint8_t *)(data_address + 9)) == 0x00))
{
/* Eddystone UID beacon User Data download */
uint8_t NamespaceID[10];
uint8_t BeaconID[6];
EddystoneUID_InitTypeDef EddystoneUID_InitStruct;
uint8_t i;
EddystoneUID_InitStruct.NamespaceID = NamespaceID;
EddystoneUID_InitStruct.BeaconID = BeaconID;
EddystoneUID_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
data_address += 5; /* 0x800600E */
EddystoneUID_InitStruct.CalibratedTxPower = *(uint8_t *)(data_address);
data_address += 1; /* 0x800600F */
for(i = 0; i < 10; i++)
EddystoneUID_InitStruct.NamespaceID[i] = *(uint8_t *)(data_address + i);
data_address += 10; /* 0x8006019 */
for(i = 0; i < 6; i++)
EddystoneUID_InitStruct.BeaconID[i] = *(uint8_t *)(data_address + i);
EddystoneUID_Init(&EddystoneUID_InitStruct);
}
else
{
uint8_t NamespaceID[] = { NAMESPACE_ID };
uint8_t BeaconID[] = { BEACON_ID };
EddystoneUID_InitTypeDef EddystoneUID_InitStruct =
{
.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS,
.CalibratedTxPower = CALIBRATED_TX_POWER_AT_0_M,
.NamespaceID = NamespaceID,
.BeaconID = BeaconID
};
EddystoneUID_Init(&EddystoneUID_InitStruct);
}
#else
uint8_t NamespaceID[] = { NAMESPACE_ID };
uint8_t BeaconID[] = { BEACON_ID };
EddystoneUID_InitTypeDef EddystoneUID_InitStruct =
{
.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS,
.CalibratedTxPower = CALIBRATED_TX_POWER_AT_0_M,
.NamespaceID = NamespaceID,
.BeaconID = BeaconID
};
EddystoneUID_Init(&EddystoneUID_InitStruct);
#endif
}
@@ -1,50 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/eddystone_uid_service.h
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 EDDYSTONE_UID_SERVICE_H
#define EDDYSTONE_UID_SERVICE_H
#ifdef __cplusplus
extern "C"
{
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef struct
{
uint16_t AdvertisingInterval;/*!< Specifies the desired advertising interval. */
uint8_t CalibratedTxPower; /*!< Specifies the power at 0m. */
uint8_t * NamespaceID; /*!< Specifies the 10-byte namespace to which the beacon belongs. */
uint8_t * BeaconID; /*!< Specifies the unique 6-byte beacon ID within the specified namespace. */
} EddystoneUID_InitTypeDef;
/* Exported constants --------------------------------------------------------*/
/* Exported Macros -----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
tBleStatus EddystoneUID_Init(EddystoneUID_InitTypeDef *EddystoneUID_Init);
void EddystoneUID_Process(void);
#ifdef __cplusplus
}
#endif
#endif /* EDDYSTONE_UID_SERVICE_H */
@@ -1,195 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/eddystone_url_service.c
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "ble.h"
#include "eddystone_beacon.h"
#include "eddystone_url_service.h"
/* Exported types ------------------------------------------------------------*/
/* Private types -------------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADVERTISING_INTERVAL_INCREMENT (16)
/* Private variables ---------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
tBleStatus EddystoneURL_Init(EddystoneURL_InitTypeDef *EddystoneURL_Init)
{
tBleStatus ret;
uint16_t AdvertisingInterval = (EddystoneURL_Init->AdvertisingInterval * ADVERTISING_INTERVAL_INCREMENT / 10);
uint8_t service_data[24] =
{
6 + EddystoneURL_Init->UrlLength, /*< Length. */
AD_TYPE_SERVICE_DATA, /*< Service Data data type value. */
0xAA, 0xFE, /*< 16-bit Eddystone UUID. */
0x10, /*< URL frame type. */
EddystoneURL_Init->CalibratedTxPower, /*< Ranging data. */
EddystoneURL_Init->UrlScheme, /*< URL Scheme Prefix is http://www. */
0x00, /*< URL */
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
uint8_t service_uuid_list[] =
{
3, /*< Length. */
AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST, /*< Complete list of 16-bit Service UUIDs data type value. */
0xAA, 0xFE /*< 16-bit Eddystone UUID. */
};
uint8_t flags[] =
{
2, /*< Length. */
AD_TYPE_FLAGS, /*< Flags data type value. */
(FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE | FLAG_BIT_BR_EDR_NOT_SUPPORTED) /*< BLE general discoverable, without BR/EDR support. */
};
/* Disable scan response. */
hci_le_set_scan_response_data(0, NULL);
/* Put the device in a non-connectable mode. */
ret = aci_gap_set_discoverable(ADV_NONCONN_IND, /*< Advertise as non-connectable, undirected. */
AdvertisingInterval, AdvertisingInterval, /*< Set the advertising interval as 700 ms (0.625 us increment). */
GAP_PUBLIC_ADDR, NO_WHITE_LIST_USE, /*< Use the public address, with no white list. */
0, NULL, /*< Do not use a local name. */
0, NULL, /*< Do not include the service UUID list. */
0, 0); /*< Do not set a slave connection interval. */
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Remove the TX power level advertisement (this is done to decrease the packet size). */
ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
for (uint8_t i = 0; i < EddystoneURL_Init->UrlLength; ++i)
{
service_data[7 + i] = EddystoneURL_Init->Url[i];
}
/* Update the service data. */
ret = aci_gap_update_adv_data(sizeof(service_data), service_data);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the service UUID list. */
ret = aci_gap_update_adv_data(sizeof(service_uuid_list), service_uuid_list);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the adverstising flags. */
ret = aci_gap_update_adv_data(sizeof(flags), flags);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
return ret;
}
void EddystoneURL_Process(void)
{
#ifdef USE_OTA
uint32_t data_address = OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_LENGTH; /* 0x8006009 */
if(((*(uint8_t *)(OTA_BEACON_DATA_ADDRESS)) != 0xFF) &&
((*(uint8_t *)(data_address + 9)) == 0x10))
{
/* Eddystone URL beacon User Data download */
EddystoneURL_InitTypeDef EddystoneURL_InitStruct;
uint8_t Url[100];
uint8_t i;
EddystoneURL_InitStruct.Url = Url;
EddystoneURL_InitStruct.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS;
data_address += 5; /* 0x800600e */
EddystoneURL_InitStruct.UrlLength = *(uint8_t *)(data_address);
data_address += 5; /* 0x8006013 */
EddystoneURL_InitStruct.CalibratedTxPower = *(uint8_t *)(data_address);
data_address += 1; /* 0x8006014 */
EddystoneURL_InitStruct.UrlScheme = *(uint8_t *)(data_address);
data_address += 1; /* 0x8006015 */
for(i = 0; i < EddystoneURL_InitStruct.UrlLength - 6; i++)
EddystoneURL_InitStruct.Url[i] = *(uint8_t *)(data_address + i);
EddystoneURL_Init(&EddystoneURL_InitStruct);
}
else
{
uint8_t UrlScheme = URL_PREFIX;
uint8_t Url[] = PHYSICAL_WEB_URL;
EddystoneURL_InitTypeDef EddystoneURL_InitStruct =
{
.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS,
.CalibratedTxPower = CALIBRATED_TX_POWER_AT_0_M,
.UrlScheme = UrlScheme,
.Url = Url,
.UrlLength = sizeof(Url) - 1
};
EddystoneURL_Init(&EddystoneURL_InitStruct);
}
#else
uint8_t UrlScheme = URL_PREFIX;
uint8_t Url[] = PHYSICAL_WEB_URL;
EddystoneURL_InitTypeDef EddystoneURL_InitStruct =
{
.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS,
.CalibratedTxPower = CALIBRATED_TX_POWER_AT_0_M,
.UrlScheme = UrlScheme,
.Url = Url,
.UrlLength = sizeof(Url) - 1
};
EddystoneURL_Init(&EddystoneURL_InitStruct);
#endif
}
@@ -1,71 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/eddystone_url_service.h
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 EDDYSTONE_URL_SERVICE_H
#define EDDYSTONE_URL_SERVICE_H
#ifdef __cplusplus
extern "C"
{
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef struct
{
uint16_t AdvertisingInterval;/*!< Specifies the desired advertising interval. */
uint8_t CalibratedTxPower; /*!< Specifies the power at 0m. */
uint8_t UrlScheme; /*!< Specifies the URL Encoded Scheme Prefix. */
uint8_t * Url; /*!< Specifies the Encoded URL (max 17 characters). */
uint8_t UrlLength; /*!< Specifies the length of the Encoded URL (max 17 characters). */
} EddystoneURL_InitTypeDef;
/* Exported constants --------------------------------------------------------*/
#define HTTP_WWW (0x00u)
#define HTTPS_WWW (0x01u)
#define HTTP (0x02u)
#define HTTPS (0x03u)
#define DOT_COM_SLASH (0x00u)
#define DOT_ORG_SLASH (0x01u)
#define DOT_EDU_SLASH (0x02u)
#define DOT_NET_SLASH (0x03u)
#define DOT_INFO_SLASH (0x04u)
#define DOT_BIZ_SLASH (0x05u)
#define DOT_GOV_SLASH (0x06u)
#define DOT_COM (0x07u)
#define DOT_ORG (0x08u)
#define DOT_EDU (0x09u)
#define DOT_NET (0x0Au)
#define DOT_INFO (0x0Bu)
#define DOT_BIZ (0x0Cu)
#define DOT_GOV (0x0Du)
/* Exported Macros -----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
tBleStatus EddystoneURL_Init(EddystoneURL_InitTypeDef *EddystoneURL_Init);
void EddystoneURL_Process(void);
#ifdef __cplusplus
}
#endif
#endif /* EDDYSTONE_URL_SERVICE_H */
-67
View File
@@ -1,67 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/ibeacon.h
* @author MCD Application Team
* @brief Header for ibeacon_application.c module
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 IBEACON_H
#define IBEACON_H
#ifdef __cplusplus
extern "C"
{
#endif
/* Includes ------------------------------------------------------------------*/
#if defined (__CC_ARM) || defined (__ARMCC_VERSION)
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
/* These can't be used after statements in c89. */
#ifdef __COUNTER__
#define STATIC_ASSERT(e,m) \
;enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }
#else
/* This can't be used twice on the same line so ensure if using in headers
* that the headers are not included twice (by wrapping in #ifndef...#endif)
* Note it doesn't cause an issue when used on same line of separate modules
* compiled with gcc -combine -fwhole-program. */
#define static_assert(e,m) \
;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
#endif
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define ADVERTISING_INTERVAL_IN_MS (1000)
#define CALIBRATED_TX_POWER_AT_1_M ((uint8_t) (-63))
#define UUID 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
#define MAJOR_ID 0, 1
#define MINOR_ID 0, 1
#if ((ADVERTISING_INTERVAL_IN_MS <= 0) || (ADVERTISING_INTERVAL_IN_MS > 40959))
#error "Invalid advertising interval! Please select a value between 0 and 40959 ms."
#endif
/* Exported Macros -----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* IBEACON_H */
@@ -1,203 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/ibeacon_service.c
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "ble.h"
#include "ibeacon.h"
#include "ibeacon_service.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef ------------------------------------------------------------*/
typedef struct
{
uint16_t AdvertisingInterval;/*!< Specifies the desired advertising interval. */
uint8_t * UuID; /*!< Specifies the 16-byte UUID to which the beacon belongs. */
uint8_t * MajorID; /*!< Specifies the 2-byte beacon identifying information. */
uint8_t * MinorID; /*!< Specifies the 2-byte beacon identifying information. */
uint8_t CalibratedTxPower; /*!< Specifies the power at 1m. */
} IBeacon_InitTypeDef;
/* 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 ---------------------------------------------------------*/
#define ADVERTISING_INTERVAL_INCREMENT (16)
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Functions Definition ------------------------------------------------------*/
static tBleStatus IBeacon_Init(IBeacon_InitTypeDef *IBeacon_Init)
{
/* USER CODE BEGIN IBeacon_Init_1 */
/* USER CODE END IBeacon_Init_1 */
tBleStatus ret = BLE_STATUS_SUCCESS;
uint16_t AdvertisingInterval = (IBeacon_Init->AdvertisingInterval * ADVERTISING_INTERVAL_INCREMENT / 10);
/* Disable scan response. */
hci_le_set_scan_response_data(0, NULL);
/* Put the device in a non-connectable mode. */
ret = aci_gap_set_discoverable(ADV_NONCONN_IND, /*< Advertise as non-connectable, undirected. */
AdvertisingInterval, AdvertisingInterval, /*< Set the advertising interval as 700 ms (0.625 us increment). */
GAP_PUBLIC_ADDR, NO_WHITE_LIST_USE, /*< Use the public address, with no white list. */
0, NULL, /*< Do not use a local name. */
0, NULL, /*< Do not include the service UUID list. */
0, 0); /*< Do not set a slave connection interval. */
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Remove the TX power level advertisement (this is done to decrease the packet size). */
ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
uint8_t service_data[] =
{
26, /*< Length. */
AD_TYPE_MANUFACTURER_SPECIFIC_DATA, /*< Manufacturer Specific Data data type value. */
0x4C, 0x00, 0x02, 0x15, /*< 32-bit Manufacturer Data. */
IBeacon_Init->UuID[0], /*< 16-byte Proximity UUID. */
IBeacon_Init->UuID[1],
IBeacon_Init->UuID[2],
IBeacon_Init->UuID[3],
IBeacon_Init->UuID[4],
IBeacon_Init->UuID[5],
IBeacon_Init->UuID[6],
IBeacon_Init->UuID[7],
IBeacon_Init->UuID[8],
IBeacon_Init->UuID[9],
IBeacon_Init->UuID[10],
IBeacon_Init->UuID[11],
IBeacon_Init->UuID[12],
IBeacon_Init->UuID[13],
IBeacon_Init->UuID[14],
IBeacon_Init->UuID[15],
IBeacon_Init->MajorID[0], /*< 2-byte Major. */
IBeacon_Init->MajorID[1],
IBeacon_Init->MinorID[0], /*< 2-byte Minor. */
IBeacon_Init->MinorID[1],
IBeacon_Init->CalibratedTxPower, /*< Ranging data. */
};
uint8_t flags[] =
{
2, /*< Length. */
AD_TYPE_FLAGS, /*< Flags data type value. */
(FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE | FLAG_BIT_BR_EDR_NOT_SUPPORTED) /*< BLE general discoverable, without BR/EDR support. */
};
/* Update the service data. */
ret = aci_gap_update_adv_data(sizeof(service_data), service_data);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* Update the adverstising flags. */
ret = aci_gap_update_adv_data(sizeof(flags), flags);
if (ret != BLE_STATUS_SUCCESS)
{
return ret;
}
/* USER CODE BEGIN IBeacon_Init_2 */
/* USER CODE END IBeacon_Init_2 */
return ret;
}
void IBeacon_Process(void)
{
/* USER CODE BEGIN IBeacon_Process_1 */
/* USER CODE END IBeacon_Process_1 */
/* Default ibeacon */
uint8_t UuID[] = { UUID };
uint8_t MajorID[] = { MAJOR_ID };
uint8_t MinorID[] = { MINOR_ID };
IBeacon_InitTypeDef IBeacon_InitStruct =
{
.AdvertisingInterval = ADVERTISING_INTERVAL_IN_MS,
.UuID = UuID,
.MajorID = MajorID,
.MinorID = MinorID,
.CalibratedTxPower = CALIBRATED_TX_POWER_AT_1_M
};
#ifdef USE_OTA
if(((*(uint8_t *)(OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_LENGTH)) == 27) &&
((*(uint8_t *)(OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_DATA)) == 26))
{
uint8_t i;
uint32_t data_address = OTA_BEACON_DATA_ADDRESS + OFFSET_PAYLOAD_DATA + 6;
for(i = 0; i < 16; i++)
IBeacon_InitStruct.UuID[i] = *(uint8_t *)(data_address + i);
data_address += 16;
for(i = 0; i < 2; i++)
IBeacon_InitStruct.MinorID[i] = *(uint8_t *)(data_address + i);
data_address += 2;
for(i = 0; i < 2; i++)
IBeacon_InitStruct.MajorID[i] = *(uint8_t *)(data_address + i);
data_address += 2;
IBeacon_InitStruct.CalibratedTxPower = *(uint8_t *)(data_address);
}
#endif
IBeacon_Init(&IBeacon_InitStruct);
/* USER CODE BEGIN IBeacon_Process_2 */
/* USER CODE END IBeacon_Process_2 */
}
/* USER CODE BEGIN FD */
/* USER CODE END FD */
@@ -1,65 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/ibeacon_service.h
* @author MCD Application Team
* @brief
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 IBEACON_SERVICE_H
#define IBEACON_SERVICE_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 macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
/* USER CODE BEGIN EFP */
void IBeacon_Process(void);
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* IBEACON_SERVICE_H */
@@ -1,133 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file App/tl_dbg_conf.h
* @author MCD Application Team
* @brief Debug configuration file for stm32wpan transport layer interface.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 TL_DBG_CONF_H
#define TL_DBG_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* USER CODE BEGIN Tl_Conf */
/* Includes ------------------------------------------------------------------*/
#include "app_conf.h" /* required as some configuration used in dbg_trace.h are set there */
#include "dbg_trace.h"
#include "hw_if.h"
/**
* Enable or Disable traces
* The raw data output is the hci binary packet format as specified by the BT specification *
*/
#define TL_SHCI_CMD_DBG_EN 0 /* Reports System commands sent to CPU2 and the command response */
#define TL_SHCI_CMD_DBG_RAW_EN 0 /* Reports raw data System commands sent to CPU2 and the command response */
#define TL_SHCI_EVT_DBG_EN 0 /* Reports System Asynchronous Events received from CPU2 */
#define TL_SHCI_EVT_DBG_RAW_EN 0 /* Reports raw data System Asynchronous Events received from CPU2 */
#define TL_HCI_CMD_DBG_EN 0 /* Reports BLE command sent to CPU2 and the command response */
#define TL_HCI_CMD_DBG_RAW_EN 0 /* Reports raw data BLE command sent to CPU2 and the command response */
#define TL_HCI_EVT_DBG_EN 0 /* Reports BLE Asynchronous Events received from CPU2 */
#define TL_HCI_EVT_DBG_RAW_EN 0 /* Reports raw data BLE Asynchronous Events received from CPU2 */
#define TL_MM_DBG_EN 0 /* Reports the information of the buffer released to CPU2 */
/**
* Macro definition
*/
/**
* System Transport Layer
*/
#if (TL_SHCI_CMD_DBG_EN != 0)
#define TL_SHCI_CMD_DBG_MSG PRINT_MESG_DBG
#define TL_SHCI_CMD_DBG_BUF PRINT_LOG_BUFF_DBG
#else
#define TL_SHCI_CMD_DBG_MSG(...)
#define TL_SHCI_CMD_DBG_BUF(...)
#endif
#if (TL_SHCI_CMD_DBG_RAW_EN != 0)
#define TL_SHCI_CMD_DBG_RAW(_PDATA_, _SIZE_) HW_UART_Transmit(hw_uart1, (uint8_t*)_PDATA_, _SIZE_, (~0))
#else
#define TL_SHCI_CMD_DBG_RAW(...)
#endif
#if (TL_SHCI_EVT_DBG_EN != 0)
#define TL_SHCI_EVT_DBG_MSG PRINT_MESG_DBG
#define TL_SHCI_EVT_DBG_BUF PRINT_LOG_BUFF_DBG
#else
#define TL_SHCI_EVT_DBG_MSG(...)
#define TL_SHCI_EVT_DBG_BUF(...)
#endif
#if (TL_SHCI_EVT_DBG_RAW_EN != 0)
#define TL_SHCI_EVT_DBG_RAW(_PDATA_, _SIZE_) HW_UART_Transmit(hw_uart1, (uint8_t*)_PDATA_, _SIZE_, (~0))
#else
#define TL_SHCI_EVT_DBG_RAW(...)
#endif
/**
* BLE Transport Layer
*/
#if (TL_HCI_CMD_DBG_EN != 0)
#define TL_HCI_CMD_DBG_MSG PRINT_MESG_DBG
#define TL_HCI_CMD_DBG_BUF PRINT_LOG_BUFF_DBG
#else
#define TL_HCI_CMD_DBG_MSG(...)
#define TL_HCI_CMD_DBG_BUF(...)
#endif
#if (TL_HCI_CMD_DBG_RAW_EN != 0)
#define TL_HCI_CMD_DBG_RAW(_PDATA_, _SIZE_) HW_UART_Transmit(hw_uart1, (uint8_t*)_PDATA_, _SIZE_, (~0))
#else
#define TL_HCI_CMD_DBG_RAW(...)
#endif
#if (TL_HCI_EVT_DBG_EN != 0)
#define TL_HCI_EVT_DBG_MSG PRINT_MESG_DBG
#define TL_HCI_EVT_DBG_BUF PRINT_LOG_BUFF_DBG
#else
#define TL_HCI_EVT_DBG_MSG(...)
#define TL_HCI_EVT_DBG_BUF(...)
#endif
#if (TL_HCI_EVT_DBG_RAW_EN != 0)
#define TL_HCI_EVT_DBG_RAW(_PDATA_, _SIZE_) HW_UART_Transmit(hw_uart1, (uint8_t*)_PDATA_, _SIZE_, (~0))
#else
#define TL_HCI_EVT_DBG_RAW(...)
#endif
/**
* Memory Manager - Released buffer tracing
*/
#if (TL_MM_DBG_EN != 0)
#define TL_MM_DBG_MSG PRINT_MESG_DBG
#else
#define TL_MM_DBG_MSG(...)
#endif
/* USER CODE END Tl_Conf */
#ifdef __cplusplus
}
#endif
#endif /*TL_DBG_CONF_H */