/** ****************************************************************************** * File Name : app_entry.c * Description : Entry application source file for STM32WPAN Middleware. ****************************************************************************** * @attention * *

© Copyright (c) 2020 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license * SLA0044, the "License"; You may not use this file except in compliance with * the License. You may obtain a copy of the License at: * www.st.com/SLA0044 * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "app_common.h" #include "main.h" #include "app_entry.h" #include "app_zigbee.h" #include "app_conf.h" #include "hw_conf.h" #include "stm32_seq.h" #include "stm_logging.h" #include "shci_tl.h" #include "stm32_lpm.h" #include "dbg_trace.h" #include "shci.h" #if (CFG_USB_INTERFACE_ENABLE != 0) #include "vcp.h" #include "vcp_conf.h" #endif /* (CFG_USB_INTERFACE_ENABLE != 0) */ /* Private includes -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/ extern RTC_HandleTypeDef hrtc; /* Private defines -----------------------------------------------------------*/ #define POOL_SIZE (CFG_TL_EVT_QUEUE_LENGTH * 4U * DIVC((sizeof(TL_PacketHeader_t) + TL_EVENT_FRAME_SIZE), 4U)) /* 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]; #if (CFG_USB_INTERFACE_ENABLE != 0) static uint8_t VcpTxBuffer[MAX_DBG_TRACE_MSG_SIZE]; /* Transmit buffer over USB */ #endif /* Global function prototypes -----------------------------------------------*/ size_t __write(int handle, const unsigned char *buf, size_t bufSize); /* Private functions prototypes-----------------------------------------------*/ static void SystemPower_Config(void); static void Init_Debug(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); static void APPE_SysEvtError(SCHI_SystemErrCode_t ErrorCode); #if (CFG_HW_LPUART1_ENABLED == 1) extern void MX_LPUART1_UART_Init(void); #endif #if (CFG_HW_USART1_ENABLED == 1) extern void MX_USART1_UART_Init(void); #endif /* USER CODE BEGIN PFP */ static void Led_Init(void); static void Button_Init(void); /* Section specific to button management using UART */ static void RxUART_Init(void); static void RxCpltCallback(void); static void UartCmdExecute(void); #define C_SIZE_CMD_STRING 256U #define RX_BUFFER_SIZE 8U static uint8_t aRxBuffer[RX_BUFFER_SIZE]; static uint8_t CommandString[C_SIZE_CMD_STRING]; static uint16_t indexReceiveChar = 0; EXTI_HandleTypeDef exti_handle; /* USER CODE END PFP */ /* Functions Definition ------------------------------------------------------*/ void APPE_Init( void ) { SystemPower_Config(); /**< Configure the system Power Mode */ HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */ Init_Debug(); /** * The Standby mode should not be entered before the initialization is over * The default state of the Low Power Manager is to allow the Standby Mode so an request is needed here */ UTIL_LPM_SetOffMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE); Led_Init(); Button_Init(); RxUART_Init(); 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 Zigbee Stack * This system event is received with APPE_SysUserEvtRx() */ return; } /************************************************************* * * LOCAL FUNCTIONS * *************************************************************/ static void Init_Debug( void ) { #if (CFG_DEBUGGER_SUPPORTED == 1) /** * Keep debugger enabled while in any low power mode */ HAL_DBGMCU_EnableDBGSleepMode(); /***************** ENABLE DEBUGGER *************************************/ LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); LL_C2_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); #else GPIO_InitTypeDef gpio_config = {0}; gpio_config.Pull = GPIO_NOPULL; gpio_config.Mode = GPIO_MODE_ANALOG; gpio_config.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13; __HAL_RCC_GPIOA_CLK_ENABLE(); HAL_GPIO_Init(GPIOA, &gpio_config); __HAL_RCC_GPIOA_CLK_DISABLE(); gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_3; __HAL_RCC_GPIOB_CLK_ENABLE(); HAL_GPIO_Init(GPIOB, &gpio_config); __HAL_RCC_GPIOB_CLK_DISABLE(); HAL_DBGMCU_DisableDBGSleepMode(); HAL_DBGMCU_DisableDBGStopMode(); HAL_DBGMCU_DisableDBGStandbyMode(); #endif /* (CFG_DEBUGGER_SUPPORTED == 1) */ #if(CFG_DEBUG_TRACE != 0) DbgTraceInit(); #endif 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 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(); /**< System channel initialization */ UTIL_SEQ_RegTask( 1<< CFG_TASK_SYSTEM_HCI_ASYNCH_EVT, UTIL_SEQ_RFU, shci_user_evt_proc ); 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 = 0; 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; } static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status) { UNUSED(status); return; } /** * @brief Trap a notification coming from the M0 firmware * @param pPayload : payload associated to the notification * * @retval None */ /** * 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; p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload); switch(p_sys_event->subevtcode) { case SHCI_SUB_EVT_CODE_READY: APPE_SysEvtReadyProcessing(); break; case SHCI_SUB_EVT_ERROR_NOTIF: APPE_SysEvtError((SCHI_SystemErrCode_t) (p_sys_event->payload[0])); 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( SCHI_SystemErrCode_t ErrorCode) { switch (ErrorCode) { case ERR_ZIGBEE_UNKNOWN_CMD: APP_DBG("** ERR_ZIGBEE : UNKNOWN_CMD \n"); break; default: APP_DBG("** ERR_ZIGBEE : ErroCode=%d \n", ErrorCode); break; } return; } static void APPE_SysEvtReadyProcessing( void ) { /* Traces channel initialization */ TL_TRACES_Init(); APP_ZIGBEE_Init(); UTIL_LPM_SetOffMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE); return; } /* USER CODE BEGIN FD_LOCAL_FUNCTIONS */ static void Led_Init( void ) { #if (CFG_LED_SUPPORTED == 1U) /** * Leds Initialization */ BSP_LED_Init(LED_BLUE); BSP_LED_Init(LED_GREEN); BSP_LED_Init(LED_RED); #endif return; } static void Button_Init( void ) { #if (CFG_BUTTON_SUPPORTED == 1U) /** * Button Initialization */ BSP_PB_Init(BUTTON_SW1, BUTTON_MODE_EXTI); #endif return; } /************************************************************* * * WRAP FUNCTIONS * *************************************************************/ void UTIL_SEQ_Idle( void ) { #if ( CFG_LPM_SUPPORTED == 1) UTIL_LPM_EnterLowPower( ); #endif return; } /** * @brief This function is called by the scheduler each time an event * is pending. * * @param evt_waited_bm : Event pending. * @retval None */ void UTIL_SEQ_EvtIdle( UTIL_SEQ_bm_t task_id_bm, UTIL_SEQ_bm_t evt_waited_bm ) { switch (evt_waited_bm) { case EVENT_ACK_FROM_M0_EVT: /* Run only the task CFG_TASK_REQUEST_FROM_M0_TO_M4 to process * direct requests from the M0 (e.g. ZbMalloc), but no stack notifications * until we're done the request to the M0. */ UTIL_SEQ_Run((1U << CFG_TASK_REQUEST_FROM_M0_TO_M4)); break; case EVENT_SYNCHRO_BYPASS_IDLE: UTIL_SEQ_SetEvt(EVENT_SYNCHRO_BYPASS_IDLE); /* Process notifications and requests from the M0 */ UTIL_SEQ_Run((1U << CFG_TASK_NOTIFY_FROM_M0_TO_M4) | (1U << CFG_TASK_REQUEST_FROM_M0_TO_M4)); break; default: /* default case */ UTIL_SEQ_Run( UTIL_SEQ_DEFAULT ); break; } } void shci_notify_asynch_evt(void* pdata) { UNUSED(pdata); UTIL_SEQ_SetTask(1U << CFG_TASK_SYSTEM_HCI_ASYNCH_EVT, CFG_SCH_PRIO_0); return; } void shci_cmd_resp_release(uint32_t flag) { UNUSED(flag); UTIL_SEQ_SetEvt(1U << CFG_EVT_SYSTEM_HCI_CMD_EVT_RESP); return; } void shci_cmd_resp_wait(uint32_t timeout) { UNUSED(timeout); UTIL_SEQ_WaitEvt(1U << CFG_EVT_SYSTEM_HCI_CMD_EVT_RESP); return; } /* Received trace buffer from M0 */ void TL_TRACES_EvtReceived( TL_EvtPacket_t * hcievt ) { #if(CFG_DEBUG_TRACE != 0) /* Call write/print function using DMA from dbg_trace */ /* - Cast to TL_AsynchEvt_t* to get "real" payload (without Sub Evt code 2bytes), - (-2) to size to remove Sub Evt Code */ DbgTraceWrite(1U, (const unsigned char *) ((TL_AsynchEvt_t *)(hcievt->evtserial.evt.payload))->payload, hcievt->evtserial.evt.plen - 2U); #endif /* CFG_DEBUG_TRACE */ /* Release buffer */ TL_MM_EvtDone( hcievt ); } /** * @brief Initialisation of the trace mechanism * @param None * @retval None */ #if(CFG_DEBUG_TRACE != 0) void DbgOutputInit( void ) { #if (CFG_USB_INTERFACE_ENABLE == 0) MX_USART1_UART_Init(); #else VCP_Init( &VcpTxBuffer[0], 0 ); #endif return; } /** * @brief Management of the traces * @param p_data : data * @param size : size * @param call-back : * @retval None */ void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) ) { #if (CFG_USB_INTERFACE_ENABLE == 0) HW_UART_Transmit_DMA(CFG_DEBUG_TRACE_UART, p_data, size, cb); #else VCP_SendData ( p_data , size , cb ); #endif return; } #endif /* USER CODE BEGIN FD_WRAP_FUNCTIONS */ /** * @brief This function manage the Push button action * @param GPIO_Pin : GPIO pin which has been activated * @retval None */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { switch (GPIO_Pin) { case BUTTON_SW1_PIN: break; default: break; } } static void RxUART_Init(void) { HW_UART_Receive_IT(CFG_DEBUG_TRACE_UART, aRxBuffer, 1U, RxCpltCallback); } static void RxCpltCallback(void) { /* Filling buffer and wait for '\r' char */ if (indexReceiveChar < C_SIZE_CMD_STRING) { if (aRxBuffer[0] == '\r') { APP_DBG("received %s", CommandString); UartCmdExecute(); /* Clear receive buffer and character counter*/ indexReceiveChar = 0; memset(CommandString, 0, C_SIZE_CMD_STRING); } else { CommandString[indexReceiveChar++] = aRxBuffer[0]; } } /* Once a character has been sent, put back the device in reception mode */ HW_UART_Receive_IT(CFG_DEBUG_TRACE_UART, aRxBuffer, 1U, RxCpltCallback); } static void UartCmdExecute(void) { /* Parse received CommandString */ if(strcmp((char const*)CommandString, "SW1") == 0) { APP_DBG("SW1 OK"); exti_handle.Line = EXTI_LINE_10; HAL_EXTI_GenerateSWI(&exti_handle); } else { APP_DBG("NOT RECOGNIZED COMMAND : %s", CommandString); } } /* USER CODE END FD_WRAP_FUNCTIONS */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/