627 lines
18 KiB
C
627 lines
18 KiB
C
/* USER CODE BEGIN Header */
|
|||
|
|
/**
|
||
|
|
******************************************************************************
|
||
|
|
* @file app_entry.c
|
||
|
|
* @author MCD Application Team
|
||
|
|
* @brief Entry point of the 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 "app_common.h"
|
||
|
|
#include "main.h"
|
||
|
|
#include "app_entry.h"
|
||
|
|
#include "ble.h"
|
||
|
|
#include "tl.h"
|
||
|
|
#include "cmsis_os.h"
|
||
|
|
#include "shci_tl.h"
|
||
|
|
#include "stm32_lpm.h"
|
||
|
|
#include "app_debug.h"
|
||
|
|
#include "dbg_trace.h"
|
||
|
|
#include "shci.h"
|
||
|
|
#include "otp.h"
|
||
|
|
|
||
|
|
/* Private includes -----------------------------------------------------------*/
|
||
|
|
/* USER CODE BEGIN Includes */
|
||
|
|
|
||
|
|
/* USER CODE END Includes */
|
||
|
|
|
||
|
|
/* Private typedef -----------------------------------------------------------*/
|
||
|
|
extern RTC_HandleTypeDef hrtc;
|
||
|
|
|
||
|
|
/* USER CODE BEGIN PTD */
|
||
|
|
|
||
|
|
/* USER CODE END PTD */
|
||
|
|
|
||
|
|
/* Private defines -----------------------------------------------------------*/
|
||
|
|
#define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH*4U*DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4U))
|
||
|
|
|
||
|
|
/* USER CODE BEGIN PD */
|
||
|
|
|
||
|
|
/* USER CODE END PD */
|
||
|
|
|
||
|
|
/* Private macros ------------------------------------------------------------*/
|
||
|
|
/* USER CODE BEGIN PM */
|
||
|
|
|
||
|
|
/* USER CODE END PM */
|
||
|
|
|
||
|
|
/* Private variables ---------------------------------------------------------*/
|
||
|
|
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t EvtPool[POOL_SIZE];
|
||
|
|
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer;
|
||
|
|
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];
|
||
|
|
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t BleSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
|
||
|
|
|
||
|
|
/* USER CODE BEGIN PV */
|
||
|
|
|
||
|
|
/* USER CODE END PV */
|
||
|
|
|
||
|
|
/* Global variables ----------------------------------------------------------*/
|
||
|
|
osMutexId_t MtxShciId;
|
||
|
|
osSemaphoreId_t SemShciId;
|
||
|
|
osThreadId_t ShciUserEvtProcessId;
|
||
|
|
|
||
|
|
const osThreadAttr_t ShciUserEvtProcess_attr = {
|
||
|
|
.name = CFG_SHCI_USER_EVT_PROCESS_NAME,
|
||
|
|
.attr_bits = CFG_SHCI_USER_EVT_PROCESS_ATTR_BITS,
|
||
|
|
.cb_mem = CFG_SHCI_USER_EVT_PROCESS_CB_MEM,
|
||
|
|
.cb_size = CFG_SHCI_USER_EVT_PROCESS_CB_SIZE,
|
||
|
|
.stack_mem = CFG_SHCI_USER_EVT_PROCESS_STACK_MEM,
|
||
|
|
.priority = CFG_SHCI_USER_EVT_PROCESS_PRIORITY,
|
||
|
|
.stack_size = CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE
|
||
|
|
};
|
||
|
|
|
||
|
|
/* Private functions prototypes-----------------------------------------------*/
|
||
|
|
static void ShciUserEvtProcess(void *argument);
|
||
|
|
static void Config_HSE(void);
|
||
|
|
static void Reset_Device(void);
|
||
|
|
#if (CFG_HW_RESET_BY_FW == 1)
|
||
|
|
static void Reset_IPCC(void);
|
||
|
|
static void Reset_BackupDomain(void);
|
||
|
|
#endif /* CFG_HW_RESET_BY_FW == 1*/
|
||
|
|
static void System_Init(void);
|
||
|
|
static void SystemPower_Config(void);
|
||
|
|
static void appe_Tl_Init(void);
|
||
|
|
static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status);
|
||
|
|
static void APPE_SysUserEvtRx(void * pPayload);
|
||
|
|
static void APPE_SysEvtReadyProcessing(void * pPayload);
|
||
|
|
static void APPE_SysEvtError(void * pPayload);
|
||
|
|
static void Init_Rtc(void);
|
||
|
|
__WEAK void APP_BLE_Init(void);
|
||
|
|
|
||
|
|
/* USER CODE BEGIN PFP */
|
||
|
|
|
||
|
|
/* USER CODE END PFP */
|
||
|
|
|
||
|
|
/* Functions Definition ------------------------------------------------------*/
|
||
|
|
void MX_APPE_Config(void)
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* The OPTVERR flag is wrongly set at power on
|
||
|
|
* It shall be cleared before using any HAL_FLASH_xxx() api
|
||
|
|
*/
|
||
|
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Reset some configurations so that the system behave in the same way
|
||
|
|
* when either out of nReset or Power On
|
||
|
|
*/
|
||
|
|
Reset_Device();
|
||
|
|
|
||
|
|
/* Configure HSE Tuning */
|
||
|
|
Config_HSE();
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void MX_APPE_Init(void)
|
||
|
|
{
|
||
|
|
System_Init(); /**< System initialization */
|
||
|
|
|
||
|
|
SystemPower_Config(); /**< Configure the system Power Mode */
|
||
|
|
|
||
|
|
HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */
|
||
|
|
|
||
|
|
/* USER CODE BEGIN APPE_Init_1 */
|
||
|
|
|
||
|
|
/* USER CODE END APPE_Init_1 */
|
||
|
|
appe_Tl_Init(); /* Initialize all transport layers */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* From now, the application is waiting for the ready event (VS_HCI_C2_Ready)
|
||
|
|
* received on the system channel before starting the Stack
|
||
|
|
* This system event is received with APPE_SysUserEvtRx()
|
||
|
|
*/
|
||
|
|
/* USER CODE BEGIN APPE_Init_2 */
|
||
|
|
|
||
|
|
/* USER CODE END APPE_Init_2 */
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Init_Smps(void)
|
||
|
|
{
|
||
|
|
#if (CFG_USE_SMPS != 0)
|
||
|
|
/**
|
||
|
|
* Configure and enable SMPS
|
||
|
|
*
|
||
|
|
* The SMPS configuration is not yet supported by CubeMx
|
||
|
|
* when SMPS output voltage is set to 1.4V, the RF output power is limited to 3.7dBm
|
||
|
|
* the SMPS output voltage shall be increased for higher RF output power
|
||
|
|
*/
|
||
|
|
LL_PWR_SMPS_SetStartupCurrent(LL_PWR_SMPS_STARTUP_CURRENT_80MA);
|
||
|
|
LL_PWR_SMPS_SetOutputVoltageLevel(LL_PWR_SMPS_OUTPUT_VOLTAGE_1V40);
|
||
|
|
LL_PWR_SMPS_Enable();
|
||
|
|
#endif /* CFG_USE_SMPS != 0 */
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Init_Exti(void)
|
||
|
|
{
|
||
|
|
/* Enable IPCC(36), HSEM(38) wakeup interrupts on CPU1 */
|
||
|
|
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_36 | LL_EXTI_LINE_38);
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* USER CODE BEGIN FD */
|
||
|
|
|
||
|
|
/* USER CODE END FD */
|
||
|
|
|
||
|
|
/*************************************************************
|
||
|
|
*
|
||
|
|
* LOCAL FUNCTIONS
|
||
|
|
*
|
||
|
|
*************************************************************/
|
||
|
|
static void Reset_Device(void)
|
||
|
|
{
|
||
|
|
#if (CFG_HW_RESET_BY_FW == 1)
|
||
|
|
Reset_BackupDomain();
|
||
|
|
|
||
|
|
Reset_IPCC();
|
||
|
|
#endif /* CFG_HW_RESET_BY_FW == 1 */
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if (CFG_HW_RESET_BY_FW == 1)
|
||
|
|
static void Reset_BackupDomain(void)
|
||
|
|
{
|
||
|
|
if ((LL_RCC_IsActiveFlag_PINRST() != FALSE) && (LL_RCC_IsActiveFlag_SFTRST() == FALSE))
|
||
|
|
{
|
||
|
|
HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Write twice the value to flush the APB-AHB bridge
|
||
|
|
* This bit shall be written in the register before writing the next one
|
||
|
|
*/
|
||
|
|
HAL_PWR_EnableBkUpAccess();
|
||
|
|
|
||
|
|
__HAL_RCC_BACKUPRESET_FORCE();
|
||
|
|
__HAL_RCC_BACKUPRESET_RELEASE();
|
||
|
|
}
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void Reset_IPCC(void)
|
||
|
|
{
|
||
|
|
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC);
|
||
|
|
|
||
|
|
LL_C1_IPCC_ClearFlag_CHx(
|
||
|
|
IPCC,
|
||
|
|
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
|
||
|
|
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
|
||
|
|
|
||
|
|
LL_C2_IPCC_ClearFlag_CHx(
|
||
|
|
IPCC,
|
||
|
|
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
|
||
|
|
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
|
||
|
|
|
||
|
|
LL_C1_IPCC_DisableTransmitChannel(
|
||
|
|
IPCC,
|
||
|
|
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
|
||
|
|
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
|
||
|
|
|
||
|
|
LL_C2_IPCC_DisableTransmitChannel(
|
||
|
|
IPCC,
|
||
|
|
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
|
||
|
|
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
|
||
|
|
|
||
|
|
LL_C1_IPCC_DisableReceiveChannel(
|
||
|
|
IPCC,
|
||
|
|
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
|
||
|
|
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
|
||
|
|
|
||
|
|
LL_C2_IPCC_DisableReceiveChannel(
|
||
|
|
IPCC,
|
||
|
|
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
|
||
|
|
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
#endif /* CFG_HW_RESET_BY_FW == 1 */
|
||
|
|
|
||
|
|
static void Config_HSE(void)
|
||
|
|
{
|
||
|
|
OTP_ID0_t * p_otp;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Read HSE_Tuning from OTP
|
||
|
|
*/
|
||
|
|
p_otp = (OTP_ID0_t *) OTP_Read(0);
|
||
|
|
if (p_otp)
|
||
|
|
{
|
||
|
|
LL_RCC_HSE_SetCapacitorTuning(p_otp->hse_tuning);
|
||
|
|
}
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void System_Init(void)
|
||
|
|
{
|
||
|
|
Init_Smps();
|
||
|
|
|
||
|
|
Init_Exti();
|
||
|
|
|
||
|
|
Init_Rtc();
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void Init_Rtc(void)
|
||
|
|
{
|
||
|
|
/* Disable RTC registers write protection */
|
||
|
|
LL_RTC_DisableWriteProtection(RTC);
|
||
|
|
|
||
|
|
LL_RTC_WAKEUP_SetClock(RTC, CFG_RTC_WUCKSEL_DIVIDER);
|
||
|
|
|
||
|
|
/* Enable RTC registers write protection */
|
||
|
|
LL_RTC_EnableWriteProtection(RTC);
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Configure the system for power optimization
|
||
|
|
*
|
||
|
|
* @note This API configures the system to be ready for low power mode
|
||
|
|
*
|
||
|
|
* @param None
|
||
|
|
* @retval None
|
||
|
|
*/
|
||
|
|
static void SystemPower_Config(void)
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* Select HSI as system clock source after Wake Up from Stop mode
|
||
|
|
*/
|
||
|
|
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
|
||
|
|
|
||
|
|
/* Initialize low power manager */
|
||
|
|
UTIL_LPM_Init();
|
||
|
|
/* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */
|
||
|
|
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
|
||
|
|
|
||
|
|
#if (CFG_USB_INTERFACE_ENABLE != 0)
|
||
|
|
/**
|
||
|
|
* Enable USB power
|
||
|
|
*/
|
||
|
|
HAL_PWREx_EnableVddUSB();
|
||
|
|
#endif /* CFG_USB_INTERFACE_ENABLE != 0 */
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void appe_Tl_Init(void)
|
||
|
|
{
|
||
|
|
TL_MM_Config_t tl_mm_config;
|
||
|
|
SHCI_TL_HciInitConf_t SHci_Tl_Init_Conf;
|
||
|
|
/**< Reference table initialization */
|
||
|
|
TL_Init();
|
||
|
|
|
||
|
|
MtxShciId = osMutexNew(NULL);
|
||
|
|
SemShciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */
|
||
|
|
|
||
|
|
/** FreeRTOS system task creation */
|
||
|
|
ShciUserEvtProcessId = osThreadNew(ShciUserEvtProcess, NULL, &ShciUserEvtProcess_attr);
|
||
|
|
|
||
|
|
/**< System channel initialization */
|
||
|
|
SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&SystemCmdBuffer;
|
||
|
|
SHci_Tl_Init_Conf.StatusNotCallBack = APPE_SysStatusNot;
|
||
|
|
shci_init(APPE_SysUserEvtRx, (void*) &SHci_Tl_Init_Conf);
|
||
|
|
|
||
|
|
/**< Memory Manager channel initialization */
|
||
|
|
tl_mm_config.p_BleSpareEvtBuffer = BleSpareEvtBuffer;
|
||
|
|
tl_mm_config.p_SystemSpareEvtBuffer = SystemSpareEvtBuffer;
|
||
|
|
tl_mm_config.p_AsynchEvtPool = EvtPool;
|
||
|
|
tl_mm_config.AsynchEvtPoolSize = POOL_SIZE;
|
||
|
|
TL_MM_Init(&tl_mm_config);
|
||
|
|
|
||
|
|
TL_Enable();
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
__WEAK void APP_BLE_Init(void)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status)
|
||
|
|
{
|
||
|
|
switch (status)
|
||
|
|
{
|
||
|
|
case SHCI_TL_CmdBusy:
|
||
|
|
osMutexAcquire(MtxShciId, osWaitForever);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case SHCI_TL_CmdAvailable:
|
||
|
|
osMutexRelease(MtxShciId);
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The type of the payload for a system user event is tSHCI_UserEvtRxParam
|
||
|
|
* When the system event is both :
|
||
|
|
* - a ready event (subevtcode = SHCI_SUB_EVT_CODE_READY)
|
||
|
|
* - reported by the FUS (sysevt_ready_rsp == FUS_FW_RUNNING)
|
||
|
|
* The buffer shall not be released
|
||
|
|
* (eg ((tSHCI_UserEvtRxParam*)pPayload)->status shall be set to SHCI_TL_UserEventFlow_Disable)
|
||
|
|
* When the status is not filled, the buffer is released by default
|
||
|
|
*/
|
||
|
|
static void APPE_SysUserEvtRx(void * pPayload)
|
||
|
|
{
|
||
|
|
TL_AsynchEvt_t *p_sys_event;
|
||
|
|
WirelessFwInfo_t WirelessInfo;
|
||
|
|
|
||
|
|
p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
|
||
|
|
|
||
|
|
switch(p_sys_event->subevtcode)
|
||
|
|
{
|
||
|
|
case SHCI_SUB_EVT_CODE_READY:
|
||
|
|
/* Read the firmware version of both the wireless firmware and the FUS */
|
||
|
|
SHCI_GetWirelessFwInfo(&WirelessInfo);
|
||
|
|
APP_DBG_MSG("Wireless Firmware version %d.%d.%d\n", WirelessInfo.VersionMajor, WirelessInfo.VersionMinor, WirelessInfo.VersionSub);
|
||
|
|
APP_DBG_MSG("Wireless Firmware build %d\n", WirelessInfo.VersionReleaseType);
|
||
|
|
APP_DBG_MSG("FUS version %d.%d.%d\n", WirelessInfo.FusVersionMajor, WirelessInfo.FusVersionMinor, WirelessInfo.FusVersionSub);
|
||
|
|
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_CODE_READY\n\r");
|
||
|
|
APPE_SysEvtReadyProcessing(pPayload);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case SHCI_SUB_EVT_ERROR_NOTIF:
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_ERROR_NOTIF \n\r");
|
||
|
|
APPE_SysEvtError(pPayload);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case SHCI_SUB_EVT_BLE_NVM_RAM_UPDATE:
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_BLE_NVM_RAM_UPDATE -- BLE NVM RAM HAS BEEN UPDATED BY CPU2 \n");
|
||
|
|
APP_DBG_MSG(" - StartAddress = %lx , Size = %ld\n",
|
||
|
|
((SHCI_C2_BleNvmRamUpdate_Evt_t*)p_sys_event->payload)->StartAddress,
|
||
|
|
((SHCI_C2_BleNvmRamUpdate_Evt_t*)p_sys_event->payload)->Size);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case SHCI_SUB_EVT_NVM_START_WRITE:
|
||
|
|
APP_DBG_MSG("==>> SHCI_SUB_EVT_NVM_START_WRITE : NumberOfWords = %ld\n",
|
||
|
|
((SHCI_C2_NvmStartWrite_Evt_t*)p_sys_event->payload)->NumberOfWords);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case SHCI_SUB_EVT_NVM_END_WRITE:
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_NVM_END_WRITE\n\r");
|
||
|
|
break;
|
||
|
|
|
||
|
|
case SHCI_SUB_EVT_NVM_START_ERASE:
|
||
|
|
APP_DBG_MSG("==>>SHCI_SUB_EVT_NVM_START_ERASE : NumberOfSectors = %ld\n",
|
||
|
|
((SHCI_C2_NvmStartErase_Evt_t*)p_sys_event->payload)->NumberOfSectors);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case SHCI_SUB_EVT_NVM_END_ERASE:
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_NVM_END_ERASE\n\r");
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Notify a system error coming from the M0 firmware
|
||
|
|
* @param ErrorCode : errorCode detected by the M0 firmware
|
||
|
|
*
|
||
|
|
* @retval None
|
||
|
|
*/
|
||
|
|
static void APPE_SysEvtError(void * pPayload)
|
||
|
|
{
|
||
|
|
TL_AsynchEvt_t *p_sys_event;
|
||
|
|
SCHI_SystemErrCode_t *p_sys_error_code;
|
||
|
|
|
||
|
|
p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
|
||
|
|
p_sys_error_code = (SCHI_SystemErrCode_t*) p_sys_event->payload;
|
||
|
|
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_ERROR_NOTIF WITH REASON %x \n\r",(*p_sys_error_code));
|
||
|
|
|
||
|
|
if ((*p_sys_error_code) == ERR_BLE_INIT)
|
||
|
|
{
|
||
|
|
/* Error during BLE stack initialization */
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_ERROR_NOTIF WITH REASON - ERR_BLE_INIT \n");
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_ERROR_NOTIF WITH REASON - BLE ERROR \n");
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void APPE_SysEvtReadyProcessing(void * pPayload)
|
||
|
|
{
|
||
|
|
TL_AsynchEvt_t *p_sys_event;
|
||
|
|
SHCI_C2_Ready_Evt_t *p_sys_ready_event;
|
||
|
|
|
||
|
|
SHCI_C2_CONFIG_Cmd_Param_t config_param = {0};
|
||
|
|
uint32_t RevisionID=0;
|
||
|
|
uint32_t DeviceID=0;
|
||
|
|
|
||
|
|
p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
|
||
|
|
p_sys_ready_event = (SHCI_C2_Ready_Evt_t*) p_sys_event->payload;
|
||
|
|
|
||
|
|
if (p_sys_ready_event->sysevt_ready_rsp == WIRELESS_FW_RUNNING)
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* The wireless firmware is running on the CPU2
|
||
|
|
*/
|
||
|
|
APP_DBG_MSG(">>== WIRELESS_FW_RUNNING \n");
|
||
|
|
|
||
|
|
/* Traces channel initialization */
|
||
|
|
APPD_EnableCPU2();
|
||
|
|
|
||
|
|
/* Enable all events Notification */
|
||
|
|
config_param.PayloadCmdSize = SHCI_C2_CONFIG_PAYLOAD_CMD_SIZE;
|
||
|
|
config_param.EvtMask1 = SHCI_C2_CONFIG_EVTMASK1_BIT0_ERROR_NOTIF_ENABLE
|
||
|
|
+ SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE
|
||
|
|
+ SHCI_C2_CONFIG_EVTMASK1_BIT2_THREAD_NVM_RAM_UPDATE_ENABLE
|
||
|
|
+ SHCI_C2_CONFIG_EVTMASK1_BIT3_NVM_START_WRITE_ENABLE
|
||
|
|
+ SHCI_C2_CONFIG_EVTMASK1_BIT4_NVM_END_WRITE_ENABLE
|
||
|
|
+ SHCI_C2_CONFIG_EVTMASK1_BIT5_NVM_START_ERASE_ENABLE
|
||
|
|
+ SHCI_C2_CONFIG_EVTMASK1_BIT6_NVM_END_ERASE_ENABLE;
|
||
|
|
|
||
|
|
/* Read revision identifier */
|
||
|
|
/**
|
||
|
|
* @brief Return the device revision identifier
|
||
|
|
* @note This field indicates the revision of the device.
|
||
|
|
* @rmtoll DBGMCU_IDCODE REV_ID LL_DBGMCU_GetRevisionID
|
||
|
|
* @retval Values between Min_Data=0x00 and Max_Data=0xFFFF
|
||
|
|
*/
|
||
|
|
RevisionID = LL_DBGMCU_GetRevisionID();
|
||
|
|
|
||
|
|
APP_DBG_MSG(">>== DBGMCU_GetRevisionID= %lx \n\r", RevisionID);
|
||
|
|
|
||
|
|
config_param.RevisionID = (uint16_t)RevisionID;
|
||
|
|
|
||
|
|
DeviceID = LL_DBGMCU_GetDeviceID();
|
||
|
|
APP_DBG_MSG(">>== DBGMCU_GetDeviceID= %lx \n\r", DeviceID);
|
||
|
|
config_param.DeviceID = (uint16_t)DeviceID;
|
||
|
|
(void)SHCI_C2_Config(&config_param);
|
||
|
|
|
||
|
|
APP_BLE_Init();
|
||
|
|
UTIL_LPM_SetOffMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE);
|
||
|
|
}
|
||
|
|
else if (p_sys_ready_event->sysevt_ready_rsp == FUS_FW_RUNNING)
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* The FUS firmware is running on the CPU2
|
||
|
|
* In the scope of this application, there should be no case when we get here
|
||
|
|
*/
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_CODE_READY - FUS_FW_RUNNING \n\r");
|
||
|
|
|
||
|
|
/* The packet shall not be released as this is not supported by the FUS */
|
||
|
|
((tSHCI_UserEvtRxParam*)pPayload)->status = SHCI_TL_UserEventFlow_Disable;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
APP_DBG_MSG(">>== SHCI_SUB_EVT_CODE_READY - UNEXPECTED CASE \n\r");
|
||
|
|
}
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************************
|
||
|
|
*
|
||
|
|
* FREERTOS WRAPPER FUNCTIONS
|
||
|
|
*
|
||
|
|
*************************************************************/
|
||
|
|
static void ShciUserEvtProcess(void *argument)
|
||
|
|
{
|
||
|
|
UNUSED(argument);
|
||
|
|
for(;;)
|
||
|
|
{
|
||
|
|
/* USER CODE BEGIN SHCI_USER_EVT_PROCESS_1 */
|
||
|
|
|
||
|
|
/* USER CODE END SHCI_USER_EVT_PROCESS_1 */
|
||
|
|
osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever);
|
||
|
|
shci_user_evt_proc();
|
||
|
|
/* USER CODE BEGIN SHCI_USER_EVT_PROCESS_2 */
|
||
|
|
|
||
|
|
/* USER CODE END SHCI_USER_EVT_PROCESS_2 */
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */
|
||
|
|
|
||
|
|
/* USER CODE END FD_LOCAL_FUNCTIONS */
|
||
|
|
|
||
|
|
/*************************************************************
|
||
|
|
*
|
||
|
|
* WRAP FUNCTIONS
|
||
|
|
*
|
||
|
|
*************************************************************/
|
||
|
|
void HAL_Delay(uint32_t Delay)
|
||
|
|
{
|
||
|
|
uint32_t tickstart = HAL_GetTick();
|
||
|
|
uint32_t wait = Delay;
|
||
|
|
|
||
|
|
/* Add a freq to guarantee minimum wait */
|
||
|
|
if (wait < HAL_MAX_DELAY)
|
||
|
|
{
|
||
|
|
wait += HAL_GetTickFreq();
|
||
|
|
}
|
||
|
|
|
||
|
|
while ((HAL_GetTick() - tickstart) < wait)
|
||
|
|
{
|
||
|
|
/************************************************************************************
|
||
|
|
* ENTER SLEEP MODE
|
||
|
|
***********************************************************************************/
|
||
|
|
LL_LPM_EnableSleep(); /**< Clear SLEEPDEEP bit of Cortex System Control Register */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This option is used to ensure that store operations are completed
|
||
|
|
*/
|
||
|
|
#if defined (__CC_ARM) || defined (__ARMCC_VERSION)
|
||
|
|
__force_stores();
|
||
|
|
#endif /* __ARMCC_VERSION */
|
||
|
|
|
||
|
|
__WFI();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void shci_notify_asynch_evt(void* pdata)
|
||
|
|
{
|
||
|
|
UNUSED(pdata);
|
||
|
|
osThreadFlagsSet(ShciUserEvtProcessId, 1);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void shci_cmd_resp_release(uint32_t flag)
|
||
|
|
{
|
||
|
|
UNUSED(flag);
|
||
|
|
osSemaphoreRelease(SemShciId);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void shci_cmd_resp_wait(uint32_t timeout)
|
||
|
|
{
|
||
|
|
UNUSED(timeout);
|
||
|
|
osSemaphoreAcquire(SemShciId, osWaitForever);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
|
||
|
|
|
||
|
|
/* USER CODE END FD_WRAP_FUNCTIONS */
|