diff options
Diffstat (limited to 'Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Pressbutton/STM32_WPAN/App/app_ble_lld.c')
-rw-r--r-- | Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Pressbutton/STM32_WPAN/App/app_ble_lld.c | 261 |
1 files changed, 153 insertions, 108 deletions
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Pressbutton/STM32_WPAN/App/app_ble_lld.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Pressbutton/STM32_WPAN/App/app_ble_lld.c index 2f6812ebb..ea1573ea1 100644 --- a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Pressbutton/STM32_WPAN/App/app_ble_lld.c +++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Pressbutton/STM32_WPAN/App/app_ble_lld.c @@ -1,7 +1,7 @@ /** ****************************************************************************** * File Name : app_ble_lld.c - * Description : PRESSBUTTON BLE LLD Application. + * Description : application utilities. ****************************************************************************** * @attention * @@ -16,8 +16,15 @@ ****************************************************************************** */ +/** + * This file provides low level utilities for application: + * - IPCC for communication with radio MCU + * - UART management + * - error handling + */ + /* Includes ------------------------------------------------------------------*/ -#include <stdio.h> +#include <stdbool.h> #include "app_common.h" #include "utilities_common.h" #include "app_entry.h" @@ -28,9 +35,9 @@ #include "stm32_lpm.h" #include "stm32_seq.h" #include "gpio_lld.h" +#include "stm_queue.h" #include "ble_lld.h" #include "app_ble_lld.h" -#include "ring_buffer.h" /* Private includes ----------------------------------------------------------*/ @@ -57,16 +64,33 @@ typedef enum /* Private function prototypes -----------------------------------------------*/ static void uartTxSendChunk(void); +static void uartRxCpltCallback(void); +static void m0CmdProcess(void); /* Private variables ---------------------------------------------------------*/ -BUF_ALLOC(uartTxBufMem, TX_BUFFER_SIZE); -static Buffer *uartTxBuf = (Buffer *)&uartTxBufMem; +static queue_t uartTxBuf; +static uint8_t uartTxBufData[TX_BUFFER_SIZE]; + static bool txBusy = false; +static char uartRxBuf; +static void(*uartRxUserCb)(char); + +// IPCC configuration PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_BLE_LLD_Config_t BleLldConfigBuffer; + +// Shared memory used by IPCC to send/receive messages to/from M0 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t BleLldM0CmdPacket; PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t BleLldCmdRspPacket; +/* Shared memory used to send/receive data and parameters to/from M0 because + IPCC messages have a limited size */ +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static msg_BLE_LLD_t bleparam_BLE_LLD_Packet; + +// Shared buffers for packet transmission and reception, separate buffers are needed because radio +PLACE_IN_SECTION("MB_MEM2") static ipBLE_lld_txrxdata_Type txBuffer; +PLACE_IN_SECTION("MB_MEM2") static ipBLE_lld_txrxdata_Type rxBuffer; + /* Functions Definition ------------------------------------------------------*/ @@ -82,35 +106,38 @@ void APP_BLE_LLD_Init(void) BleLldConfigBuffer.p_BleLldM0CmdBuffer = (uint8_t*)&BleLldM0CmdPacket; TL_BLE_LLD_Init(&BleLldConfigBuffer); - /* Configure UART for receiving CLI command from PC and sending CLI response or notifications to PC */ - APP_BLE_LLD_Init_UART_CLI(); + APP_BLE_LLD_Init_UART(); - /* Send LLD tests CLI start information to CLI UART */ - logUart("================================"); -#ifdef STM32WB35xx - logUart("Little DORY RF BLE LLD"); -#else - logUart("DORY RF BLE LLD"); -#endif - logUart("================================"); + /* Send LLD tests start information to UART */ + uartWrite(""); + uartWrite("================================"); + uartWrite("RF BLE LLD"); + uartWrite("================================"); #if (CFG_DEBUGGER_SUPPORTED == 0U) - logUart("Debugger de-activated"); + uartWrite("Debugger de-activated"); #endif #if (( CFG_DEBUG_TRACE_FULL == 0 ) && ( CFG_DEBUG_TRACE_LIGHT == 0 )) - logUart("Trace is de-activated"); + uartWrite("Trace is de-activated"); #endif - PRINT_MESG_DBG("Test appli initialized on M4, waiting for M0 initialization"); + APP_DBG("Test appli initialized on M4, waiting for M0 initialization"); - /* Send CLI start cmd to M0 (with device and revision ID as parameters */ - memcpy(¶m[0], &devId, 4 ); - memcpy(¶m[4], &revId, 4 ); - LldTestsInitStatus = SHCI_C2_BLE_LLD_Init(8, param); + /* Send start cmd to M0 (with device and revision ID as parameters */ + memcpy(¶m[0], &devId, sizeof(devId)); + memcpy(¶m[4], &revId, sizeof(revId)); + LldTestsInitStatus = SHCI_C2_BLE_LLD_Init(sizeof(param), param); if(LldTestsInitStatus != SHCI_Success){ - PRINT_MESG_DBG("!! ERROR during M0 init !!"); + APP_DBG("!! ERROR during M0 init !!"); }else{ - PRINT_MESG_DBG("M0 initialized"); + APP_DBG("M0 initialized"); } + + UTIL_SEQ_RegTask( 1<<CFG_TASK_CMD_FROM_M0_TO_M4, UTIL_SEQ_RFU, m0CmdProcess); + + BLE_LLD_PRX_Init(&bleparam_BLE_LLD_Packet.params, + &txBuffer, + &rxBuffer, + APP_BLE_LLD_SendCmdM0); } /** @@ -130,7 +157,7 @@ void APP_BLE_LLD_Error(uint32_t ErrId, uint32_t ErrCode) case ERR_BLE_LLD_CHECK_WIRELESS: msg = "ERROR: ERR_BLE_LLD_CHECK_WIRELESS "; break; default: msg = "ERROR Unknown "; break; } - PRINT_MESG_DBG("**** Fatal error = %s (Err = %d)", msg, ErrCode); + APP_DBG("**** Fatal error = %s (Err = %d)", msg, ErrCode); while(true) { BSP_LED_Toggle(LED1); @@ -152,35 +179,27 @@ void CheckWirelessFirmwareInfo(void) { WirelessFwInfo_t wireless_info_instance; WirelessFwInfo_t* p_wireless_info = &wireless_info_instance; - if (SHCI_GetWirelessFwInfo(p_wireless_info) != SHCI_Success) + if (SHCI_GetWirelessFwInfo(p_wireless_info) != SHCI_Success) { APP_BLE_LLD_Error(ERR_BLE_LLD_CHECK_WIRELESS, 0); } else { - PRINT_MESG_DBG("**********************************************************"); - PRINT_MESG_DBG("Loaded M0 TEST FW info:"); + APP_DBG("**********************************************************"); + APP_DBG("Loaded M0 TEST FW info:"); switch(p_wireless_info->StackType) { - case INFO_STACK_TYPE_802154_LLD_TESTS : - PRINT_MESG_DBG(" M0 FW Type: 802.15.4 and radio LLDs tests"); - break; - - case INFO_STACK_TYPE_802154_PHY_VALID : - PRINT_MESG_DBG(" M0 FW Type: 802.15.4 and radio PHY validation"); - break; - case INFO_STACK_TYPE_BLE_PHY_VALID : - PRINT_MESG_DBG(" M0 FW Type: BLE and radio PHY validation"); + APP_DBG(" M0 FW Type: BLE and radio PHY validation"); break; - + default : + APP_DBG(" ERROR: incompatible firmware"); APP_BLE_LLD_Error(ERR_BLE_LLD_CHECK_WIRELESS, 0); - PRINT_MESG_DBG(" M0 FW Type: Unknown !!"); break; } - PRINT_MESG_DBG(" M0 FW VERSION: v%d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, p_wireless_info->VersionSub); - PRINT_MESG_DBG("**********************************************************"); + APP_DBG(" M0 FW VERSION: v%d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, p_wireless_info->VersionSub); + APP_DBG("**********************************************************"); } } @@ -196,32 +215,58 @@ void CheckWirelessFirmwareInfo(void) * *************************************************************/ /** - * @brief Perform initialization of CLI UART interface. + * @brief Perform initialization of UART. * @param None * @retval None */ -void APP_BLE_LLD_Init_UART_CLI(void) +void APP_BLE_LLD_Init_UART(void) { -#if (CFG_HW_USART1_ENABLED == 1) - MX_USART1_UART_Init(); +#ifdef CFG_UART + MX_UART_Init(CFG_UART); #endif - bufInit(uartTxBuf, TX_BUFFER_SIZE); + + CircularQueue_Init(&uartTxBuf, + uartTxBufData, + sizeof(uartTxBufData), + sizeof(char), + CIRCULAR_QUEUE_NO_FLAG); txBusy = false; } /** - * @brief Perform de-initialization of CLI UART interface. + * @brief Perform de-initialization of UART. * @param None * @retval None */ -void APP_BLE_LLD_DeInit_UART_CLI(void) +void APP_BLE_LLD_DeInit_UART(void) { -#if (CFG_HW_USART1_ENABLED == 1) - MX_USART1_UART_DeInit(); +#ifdef CFG_UART + MX_UART_Deinit(CFG_UART); #endif } -void logUart(const char *format, ...) +static void uartRxStart(void) +{ + if (HW_UART_Receive_IT(CFG_UART, (uint8_t *)&uartRxBuf, 1, uartRxCpltCallback) != hw_uart_ok){ + APP_DBG("ERROR returned by HW_UART_Receive_IT()"); + } +} + +void APP_BLE_LLD_uartRxStart(void(*callback)(char)) +{ + uartRxUserCb = callback; + uartRxStart(); +} + +static void uartRxCpltCallback(void) +{ + // No need to buffer uartRxBuf since the callback is called by value + uartRxUserCb(uartRxBuf); + // Since UART is in full duplex, receive can be always active without blocking send + uartRxStart(); +} + +void uartWrite(const char *format, ...) { char out[UART_BUFFER_SIZE]; int nbChar; @@ -237,13 +282,16 @@ void logUart(const char *format, ...) }else{ strcat(out, UART_LINE_END); } - logUartRaw(out); + uartWriteRaw(out); } -void logUartRaw(const char *str) +void uartWriteRaw(const char *str) { CRITICAL_BEGIN(); - bufPutString(uartTxBuf, str); + while (*str != '\0'){ + CircularQueue_Add(&uartTxBuf, (uint8_t *)str, 0, 1); + str++; + } if (! txBusy){ uartTxSendChunk(); } @@ -255,89 +303,86 @@ void logUartRaw(const char *str) // loop on itself via the UART callback static void uartTxSendChunk(void){ static char hwBuf[UART_TX_CHUNK_SIZE]; - uint32_t count; - count = bufGetMultiChar(uartTxBuf, hwBuf, UART_TX_CHUNK_SIZE); + char *charPtr; + uint32_t count = 0; + + while ((charPtr = (char *)CircularQueue_Remove(&uartTxBuf, NULL)) != NULL){ + hwBuf[count] = *charPtr; + count++; + if (count >= UART_TX_CHUNK_SIZE){ + break; + } + } if (count != 0){ txBusy = true; - if (HW_UART_Transmit_IT(CFG_CLI_UART, (uint8_t *)hwBuf, count, uartTxSendChunk) != hw_uart_ok){ - PRINT_MESG_DBG("!! HAL_UART_Transmit_IT error on M4"); + if (HW_UART_Transmit_IT(CFG_UART, (uint8_t *)hwBuf, count, uartTxSendChunk) != hw_uart_ok){ + APP_DBG("ERROR returned by HW_UART_Transmit_IT()"); } }else{ txBusy = false; } } -/** - * @brief This function is called when notification on TL Channel from M0+ is received. - * - * @param Notbuffer : a pointer to TL_CmdPacket_t - * @return None - */ -void TL_BLE_LLD_ReceiveRsp( TL_CmdPacket_t * Notbuffer ) +static void m0CmdProcess(void) { - uint8_t l_size = Notbuffer->cmdserial.cmd.plen; - char *sourceBuf = (char *)Notbuffer->cmdserial.cmd.payload; - - if (l_size > 0) - { - if (strcmp(sourceBuf, "Resp_End") == 0) - { - /* This is an answer to indicate that command has been completed */ - UTIL_SEQ_SetEvt(1U << CFG_EVT_RECEIVE_RSPACKEVT); - } - else - { - /* This is just a trace from M0, write to UART */ - logUartRaw(sourceBuf); - } - } - else - { - PRINT_MESG_DBG("!! Empty M0 CLI response received by M4 !!"); - } - TL_BLE_LLD_SendRspAck(); + BLE_LLD_PRX_EventProcessTask(); } /** - * @brief This function is called when notification on TL Channel from M0+ is received. + * @brief Processes an event from radio CPU * * @param cmdBuffer : a pointer to TL_CmdPacket_t * @return None */ void TL_BLE_LLD_ReceiveM0Cmd( TL_CmdPacket_t * cmdBuffer ) { - uint8_t bufferSize = cmdBuffer->cmdserial.cmd.plen; - char * bufferAddr = (char *)cmdBuffer->cmdserial.cmd.payload; - - if (bufferSize > 0) { - if (BLE_LLD_PRX_ReplyInterDispatch(bufferAddr)) { - UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0); - }else{ - PRINT_MESG_DBG((char *)"!! Unknown M0 command received by M4 !!"); - } - }else{ - PRINT_MESG_DBG((char *)"!! Empty M0 command received by M4 !!"); - } + BLE_LLD_PRX_EventProcessInter((radioEventType)cmdBuffer->cmdserial.cmd.cmdcode); + UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0); TL_BLE_LLD_SendM0CmdAck(); } /** - * @brief This function is called to Send Command to M0 + * @brief Sends a command to radio CPU + * + * Waits for reply from radio CPU before returning (synchronous calls). * * @param[in] command BLE command already packed (by LLD) */ -void APP_BLE_LLD_SendCmdM0(void *command) +uint8_t APP_BLE_LLD_SendCmdM0(BLE_LLD_Code_t bleCmd) { - bleCmdIndirect_t *cmdIndirect = (bleCmdIndirect_t *)BleLldCmdRspPacket.cmdserial.cmd.payload; - cmdIndirect->command = command; - cmdIndirect->length = 5; - - BleLldCmdRspPacket.cmdserial.cmd.plen = sizeof(bleCmdIndirect_t); - BleLldCmdRspPacket.cmdserial.cmd.cmdcode = 0x0; - + BleLldCmdRspPacket.cmdserial.cmd.cmdcode = bleCmd; + payload_BLE_LLD_t *payload = (payload_BLE_LLD_t *)&BleLldCmdRspPacket.cmdserial.cmd.payload; + payload->msg = &bleparam_BLE_LLD_Packet; UTIL_SEQ_ClrEvt(1U << CFG_EVT_RECEIVE_RSPACKEVT); TL_BLE_LLD_SendCmd(); UTIL_SEQ_WaitEvt(1U << CFG_EVT_RECEIVE_RSPACKEVT); + + return bleparam_BLE_LLD_Packet.returnValue; +} + +/** + * @brief Processes a reply (to a command) from radio CPU + * + * Unlocks task waiting in APP_BLE_LLD_SendCmdM0(), this is used to make LLD + * API calls synchronous. + * + * @param Notbuffer : a pointer to TL_CmdPacket_t + * @return None + */ +void TL_BLE_LLD_ReceiveRsp( TL_CmdPacket_t * Notbuffer ) +{ + switch (Notbuffer->cmdserial.cmd.cmdcode){ + case BLE_LLD_RSP_END: + UTIL_SEQ_SetEvt(1U << CFG_EVT_RECEIVE_RSPACKEVT); + break; + default: + APP_DBG("WARNING: unknown response received %d", Notbuffer->cmdserial.cmd.cmdcode); + } + + /* This is just a trace from M0, write to UART */ + //uartWriteRaw(sourceBuf); + + TL_BLE_LLD_SendRspAck(); } /* USER CODE END FD_WRAP_FUNCTIONS */ |