Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Flipper-Zero/STM32CubeWB.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Projects/P-NUCLEO-WB55.Nucleo/Applications/LLD_BLE/LLD_BLE_Proximity/STM32_WPAN/App/app_lld_ble.c')
-rw-r--r--Projects/P-NUCLEO-WB55.Nucleo/Applications/LLD_BLE/LLD_BLE_Proximity/STM32_WPAN/App/app_lld_ble.c1805
1 files changed, 1805 insertions, 0 deletions
diff --git a/Projects/P-NUCLEO-WB55.Nucleo/Applications/LLD_BLE/LLD_BLE_Proximity/STM32_WPAN/App/app_lld_ble.c b/Projects/P-NUCLEO-WB55.Nucleo/Applications/LLD_BLE/LLD_BLE_Proximity/STM32_WPAN/App/app_lld_ble.c
new file mode 100644
index 000000000..dbb1d17b4
--- /dev/null
+++ b/Projects/P-NUCLEO-WB55.Nucleo/Applications/LLD_BLE/LLD_BLE_Proximity/STM32_WPAN/App/app_lld_ble.c
@@ -0,0 +1,1805 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : app_lld_ble.c
+ * Description : PROXIMITY LLD BLE Application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "app_common.h"
+#include "utilities_common.h"
+#include "app_entry.h"
+#include "dbg_trace.h"
+#include "lld_ble.h"
+#include "app_lld_ble.h"
+#include "tl.h"
+#include "shci.h"
+#include "stm_logging.h"
+#include "stm32_lpm.h"
+#include "stm32_seq.h"
+#include "gpio_lld.h"
+
+/* Private includes -----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+typedef enum
+{
+ CMD_FROM_M0_STOP0_ON = 0,
+ CMD_FROM_M0_STOP1_ON = 1,
+ CMD_FROM_M0_STOP2_ON = 2,
+ CMD_FROM_M0_STOP_OFF = 3,
+ CMD_FROM_M0_GO_IN_WFI = 4,
+ CMD_FROM_M0_GO_DIRECTLY_IN_WFI = 5,
+ CMD_FROM_M0_USE_MSI = 6,
+ CMD_FROM_M0_USE_MSI_PLL = 7,
+ CMD_FROM_M0_USE_HSE = 8,
+ CMD_FROM_M0_USE_HSE_PLL = 9,
+ CMD_FROM_M0_EXT_PA_EN = 10,
+ CMD_FROM_M0_EXT_PA_DIS = 11,
+ CMD_FROM_M0_RADIO_STOP = 12,
+ CMD_FROM_M0_RADIO_END = 13,
+ CMD_FROM_M0_RADIO_RXACK = 14,
+ CMD_FROM_M0_RADIO_RXOK = 15,
+ CMD_FROM_M0_RADIO_RXACKEND = 16,
+ CMD_FROM_M0_RADIO_RXOKEND = 17,
+} cmdFromM0_t;
+
+enum
+{
+ CHAR_CTRLC = 3,
+ CHAR_ESC = 27,
+ CHAR_DEL = 127
+};
+
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private defines -----------------------------------------------------------*/
+#define RX_BUFFER_SIZE 258
+#define CMD_HISTORY_LENGTH 10
+#define CLI_BUFFER_SIZE 30
+#define TX_BUFFER_SIZE 268
+#define CMD_BUFFER_SIZE 8
+
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macros ------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private function prototypes -----------------------------------------------*/
+static void CheckWirelessFirmwareInfo(void);
+static void LldBleTraceError(const char * pMess, uint32_t ErrCode);
+
+static void SendM0CmdAckToM0(void);
+static void SendCmdToM0(void);
+static void SendRspAckToM0(void);
+
+static void uartRxCpltCallback(void);
+static void uartRxItProcess(void);
+static void uartRxBufferProcessMode(uint8_t uartRxCmdEnable);
+static void uartRxBufferProcess(void);
+static void uartClearChars(int nbChar);
+
+static void uartTxBufferAdd(const char * str);
+static void uartTxItProcess(void);
+static void uartTxCpltCallback(void);
+
+static void m0RadioProcess(void);
+static void m0CmdProcess(void);
+static void m0CmdStopRequired(uint32_t stopRequired);
+static void m4ConfigBeforeStop(void);
+static void m4ConfigAfterStop(void);
+
+static void Appli_ProcessMode(void);
+static void Appli_RegTask(void);
+static void Appli_Init(void);
+static void Appli_uartRxBufferPrint(void);
+
+void Appli_m0RadioProcess_RadioStop(void);
+void Appli_m0RadioProcess_RadioEnd(void);
+void Appli_m0RadioProcess_RxAck(void);
+void Appli_m0RadioProcess_RxOk(void);
+void Appli_m0RadioProcess_RxAckEnd(void);
+void Appli_m0RadioProcess_RxOkEnd(void);
+
+void Appli_m0CmdProcess_RadioStop(void);
+void Appli_m0CmdProcess_RadioEnd(void);
+void Appli_m0CmdProcess_RxAck(void);
+void Appli_m0CmdProcess_RxOk(void);
+void Appli_m0CmdProcess_RxAckEnd(void);
+void Appli_m0CmdProcess_RxOkEnd(void);
+
+/* USER CODE BEGIN PFP */
+void BUTTON_SW1_BLE_Init(void);
+void BUTTON_SW2_StartPacket(void);
+void BUTTON_SW3_StopPacket(void);
+void m4CmdPacketStacking (void);
+void m4CmdPacketStackProcess (void);
+/* USER CODE END PFP */
+
+/* debug function prototypes */
+uint32_t Debug_Start_timer(void);
+uint32_t Debug_Stop_timer(void);
+
+/* Private variables -----------------------------------------------*/
+static cmdFromM0_t m0Cmd = CMD_FROM_M0_STOP_OFF;
+
+static uint8_t txBusy;
+static uint8_t rxCmdAllowed = 0;
+static uint8_t txBuffer_Tab[TX_BUFFER_SIZE];
+static uint32_t txBuffer_wrPtr;
+static uint32_t txBuffer_rdPtr;
+static uint8_t *pTxBuff_currentWr;
+static uint8_t rxBuffer_Tab[RX_BUFFER_SIZE];
+static uint32_t rxBuffer_wrPtr;
+static uint32_t rxBuffer_rdPtr;
+static uint8_t currentCommand[CMD_BUFFER_SIZE];
+static uint32_t currentCommandPos;
+static uint8_t commandHistory[CMD_HISTORY_LENGTH][RX_BUFFER_SIZE];
+static int commandHistoryIdx;
+static int commandHistoryIdxSav;
+static uint32_t txtCommandPos;
+static uint8_t txtCommand[TX_BUFFER_SIZE];
+static char cliPrompt[CLI_BUFFER_SIZE] = "Unknown M0 appli > ";
+static uint8_t uartRxCmd = 0;
+static uint32_t delayBeforeSleepOnM4 = 100000;
+static uint8_t uartLastChar;
+static uint8_t uartPayload[RX_BUFFER_SIZE];
+
+/* used with lld_ble */
+extern uint8_t *txBuffer_Ptr;
+uint8_t *rxBuffer_Ptr[8];
+uint32_t *rxStatus_Ptr[8];
+uint32_t *rxTimeStamp_Ptr[8];
+int *rxRSSI_Ptr[8];
+
+PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_LLD_BLE_Config_t LldBleConfigBuffer;
+PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t LldBleM0CmdPacket;
+PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t LldBleCmdRspPacket;
+PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t currentCommand[CMD_BUFFER_SIZE];
+PLACE_IN_SECTION("MB_MEM2") ALIGN(4) param_hal_BLE_t bleparam_hal_BLE_Packet;
+
+/* debug */
+#define LLD_BLE_DEBUG
+PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint32_t debug_timer[4];
+uint32_t start_timer;
+uint32_t stop_timer;
+extern TIM_HandleTypeDef htim2;
+
+/* USER CODE BEGIN PV */
+/* Parameters */
+uint8_t init_done =0;
+uint8_t use_hal = 0;
+
+uint32_t proxID = 0x752D5525; // 25 transitions 0xC0
+
+uint8_t proxChannel = 13;
+uint8_t proxPower = 5;
+uint32_t proxWakeup = 1535;
+uint32_t proxReceive = 65535;
+uint32_t proxReceiveAck = 576;
+uint32_t proxtime=1234;
+
+/* data buffer Tab to send TX */
+uint8_t proxtxBufferTab[258] ={0x80,0x18,
+0x73,0x65,0x70,0x68,0x26,0x48,0x6F,0x73,0x26,0x48,0x6F,0x73,
+0x73,0x65,0x70,0x68,0x26,0x48,0x6F,0x73,0x26,0x48,0x6F,0x73,
+};
+uint8_t* proxtxBuffer = proxtxBufferTab;
+
+/* data buffer ACK Tab to send TX ACK after RX */
+uint8_t proxAcktxBufferTab[258] ={0x60,0x18,
+0x4a,0x75,0x6c,0x69,0x65,0x6e,0x2b,0x4d,0x61,0x72,0x69,0x6e,
+0x4a,0x75,0x6c,0x69,0x65,0x6e,0x2b,0x4d,0x61,0x72,0x69,0x6e,
+};
+uint8_t* proxAcktxBuffer = proxAcktxBufferTab;
+
+/* data buffer Tab to receive RX (Not empty)*/
+uint8_t proxrxBufferTab[258]={0x77,0x00,
+0xAB,0xBA,0x67,0x76,0x55,0x55,0x4E,0xE4,0x9B,0xB9,0xAB,0xBA,
+};
+uint8_t* proxrxBuffer = proxrxBufferTab;
+
+/* data buffer ACK Tab to receive RX ACK after TX */
+uint8_t proxAckrxBufferTab[258]={0x33,0x00,
+0x3E,0xE3,0x28,0x82,0x64,0x46,0xC1,0x1C,0x78,0x87,0xDC,0xCD,
+};
+uint8_t* proxAckrxBuffer= proxAckrxBufferTab;
+
+/* Routines */
+/* dataRoutine enum for LL and HAL dataRoutine() */
+dataCase_t dataRoutineDone_hal_BLE = dataCase_Custom0;
+dataCase_t dataRoutineTx_hal_BLE = dataCase_Custom1;
+dataCase_t dataRoutineRx_hal_BLE = dataCase_Custom2;
+dataCase_t dataRoutineStop_hal_BLE = dataCase_Custom3;
+
+/* dataRoutine enum for LL dataRoutine() */
+dataCase_t dataRoutine_LL_TxAck = dataCase_Custom4;
+dataCase_t dataRoutine_LL_RxAck = dataCase_Custom5;
+dataCase_t dataRoutine_Action = dataCase_Custom6;
+
+/* dataRoutine enum for HAL dataRoutine() */
+dataCase_t dataRoutine_HAL_Tx = dataCase_Custom4;
+dataCase_t dataRoutine_HAL_TxAck = dataCase_Custom5;
+dataCase_t dataRoutine_HAL_Rx = dataCase_Custom6;
+dataCase_t dataRoutine_HAL_RxAck = dataCase_Custom7;
+
+/* Routines options */
+uint32_t proxPacketNumber = 100; // NB of Successif PACKET using LL Send or Receive
+uint8_t proxPacketStopRx = 1; // Stop after RX
+
+ActionPacket proxPacket[8];
+Led_TypeDef LED_TXRX=LED_BLUE;
+uint32_t proxSTDEVICEUDN[6];
+uint8_t Packet_ID[8][24];
+uint8_t Local_ID[24];
+uint8_t Recorded_ID=0;
+uint8_t init_ID = 0 ;
+uint8_t Stack_Packet=0;
+uint8_t Packet_Ptr[8][26];
+
+/* Hot config */
+uint32_t LLD_BLE_hot_ana_config_table[BLE_HOT_ANA_CONFIG_TABLE_LENGTH/4];
+
+/* Variable used with m0RadioProcess/m0CmdProcess */
+static uint8_t radioPacketNb=0;
+/* USER CODE END PV */
+
+/* Functions Definition ------------------------------------------------------*/
+void APP_LLD_BLE_Init( void )
+{
+ uint32_t devId = HAL_GetDEVID();
+ uint32_t revId = HAL_GetREVID();
+ uint8_t param[8];
+ char traceBuff[50];
+
+ SHCI_CmdStatus_t LldTestsInitStatus;
+
+ /* Check the compatibility with the Coprocessor Wireless Firmware loaded */
+ CheckWirelessFirmwareInfo();
+
+ /**
+ * Do not allow standby in the application
+ */
+ UTIL_LPM_SetOffMode(1 << CFG_LPM_APP_LLD_BLE, UTIL_LPM_DISABLE);
+
+ /* No need to activate the System low power mode as it is managed by the low-power test itself */
+ UTIL_LPM_SetStopMode(1 << CFG_LPM_APP_LLD_BLE, UTIL_LPM_DISABLE );
+
+ /* Init config buffer and call TL_LLD_BLE_Init */
+ APP_LLD_BLE_Init_TL();
+
+ /* Create a task to send CLI commands to M0 via IPCC */
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_SEND_TO_M0, UTIL_SEQ_RFU, SendCmdToM0);
+
+ /* Create a task to process data received from UART and create CLI commands */
+ Appli_ProcessMode();
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_PROCESS_UART_RX_BUFFER, UTIL_SEQ_RFU, uartRxBufferProcess);
+
+ /* Create tasks to process interrupt from/to UART to avoid locking UART during IT processing */
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_PROCESS_UART_RX_IT, UTIL_SEQ_RFU, uartRxItProcess);
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_PROCESS_UART_TX_IT, UTIL_SEQ_RFU, uartTxItProcess);
+
+ /* Create a task to manage commands from M0 */
+ UTIL_SEQ_RegTask( 1<< CFG_TASK_CMD_FROM_M0_TO_M4, UTIL_SEQ_RFU, m0CmdProcess);
+
+ /* Create Task for Appli */
+ Appli_RegTask();
+
+ /* Configure UART for receiving CLI command from PC and sending CLI response or notifications to PC */
+ txBusy = 0;
+ rxCmdAllowed = 0;
+ txBuffer_Tab[TX_BUFFER_SIZE-1] = 0;
+ txBuffer_wrPtr = 0;
+ txBuffer_rdPtr = 0;
+ rxBuffer_wrPtr = 0;
+ rxBuffer_rdPtr = 0;
+ currentCommandPos = 0;
+ commandHistoryIdx = 0;
+ commandHistoryIdxSav = 0;
+ APP_LLD_BLE_Init_UART_CLI();
+
+ /* Send LLD tests CLI start information to CLI UART */
+ uartTxBufferAdd("\r\n\n================================\r\n");
+#ifdef STM32WB35xx
+ sprintf(traceBuff, "= Little DORY");
+#else
+ sprintf(traceBuff, "= DORY");
+#endif
+ sprintf(traceBuff, "%s RF LLD BLE \r\n", traceBuff );
+ uartTxBufferAdd(traceBuff);
+ uartTxBufferAdd("================================\r\n");
+#if (CFG_FULL_LOW_POWER == 1U)
+ uartTxBufferAdd("Low-power mode is activated\r\n");
+#endif
+#if (CFG_DEBUGGER_SUPPORTED == 0U)
+ uartTxBufferAdd("Debugger de-activated\r\n");
+#endif
+#if (( CFG_DEBUG_TRACE_FULL == 0 ) && ( CFG_DEBUG_TRACE_LIGHT == 0 ))
+ uartTxBufferAdd("Trace is de-activated\r\n");
+#endif
+
+#if 0
+ APP_DBG("EXTI status");
+ sprintf(traceBuff, " IMR1 0x%08X IMR2 0x%08X", EXTI->IMR1, EXTI->IMR2);
+ APP_DBG(traceBuff);
+ sprintf(traceBuff, " EMR1 0x%08X EMR2 0x%08X", EXTI->EMR1, EXTI->EMR2);
+ APP_DBG(traceBuff);
+ sprintf(traceBuff, "C2IMR1 0x%08X C2IMR2 0x%08X", EXTI->C2IMR1, EXTI->C2IMR2);
+ APP_DBG(traceBuff);
+ sprintf(traceBuff, "C2EMR1 0x%08X C2EMR2 0x%08X", EXTI->C2EMR1, EXTI->C2EMR2);
+ APP_DBG(traceBuff);
+#endif
+
+#if 0
+ // Read the RCC_CR register
+ APP_DBG( "RCC_CR (0x%08X) = 0x%08X", (uint32_t)&(RCC->CR), RCC->CR);
+ // RCC CFGR register
+ APP_DBG( "RCC_CFGR (0x%08X) = 0x%08X", (uint32_t)&(RCC->CFGR), RCC->CFGR);
+ // PLL_CFG register
+ APP_DBG( "RCC_PLLCFGR (0x%08X) = 0x%08X", (uint32_t)&(RCC->PLLCFGR), RCC->PLLCFGR);
+#endif
+
+ /* Indicate end of M4 initialization */
+ APP_DBG("Test appli initialized on M4, wait for M0 initialization");
+
+ /* Send CLI start cmd to M0 (with device and revision ID as parameters */
+ memcpy(&param[0], &devId, 4 );
+ memcpy(&param[4], &revId, 4 );
+ LldTestsInitStatus = SHCI_C2_LLD_BLE_Init(8, param);
+ if(LldTestsInitStatus != SHCI_Success)
+ APP_DBG((char *)"!! ERROR during M0 init !!");
+
+ /* M0 init done, send first command to have M0 code info and thus, a first prompt will be printed automatically */
+ /* Do not accept new command from UART until this one is managed */
+ rxCmdAllowed = 0;
+ currentCommandPos = 5;
+ currentCommand[0] = HAL_BLE_UNUSED_CMDCODE ;/* HAL_BLE_INIT_CMDCODE cmdcode */
+ currentCommand[1] = 'i';
+ currentCommand[2] = 'n';
+ currentCommand[3] = 'f';
+ currentCommand[4] = 'o';
+ currentCommand[5] = 0;
+ /* Set corresponding task to send this command to M0 */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_SEND_TO_M0, CFG_SCH_PRIO_0);
+
+ /* Activate UART RX buffer processing task to allow USER command comming from UART */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_PROCESS_UART_RX_BUFFER, CFG_SCH_PRIO_0);
+
+ Appli_Init();
+
+}
+
+/**
+ * @brief Trace the error or the warning reported.
+ * @param ErrId :
+ * @param ErrCode
+ * @retval None
+ */
+void APP_LLD_BLE_Error(uint32_t ErrId, uint32_t ErrCode)
+{
+ switch(ErrId)
+ {
+ case ERR_LLD_BLE_SET_STATE_CB :
+ LldBleTraceError("ERROR : ERR_LLD_BLE_SET_STATE_CB ",ErrCode);
+ break;
+
+ case ERR_LLD_BLE_ERASE_PERSISTENT_INFO :
+ LldBleTraceError("ERROR : ERR_LLDT_BLE_ERASE_PERSISTENT_INFO ",ErrCode);
+ break;
+
+ case ERR_LLD_BLE_CHECK_WIRELESS :
+ LldBleTraceError("ERROR : ERR_LLD_BLE_CHECK_WIRELESS ",ErrCode);
+ break;
+
+ default :
+ LldBleTraceError("ERROR Unknown ", 0);
+ break;
+ }
+}
+
+
+/*************************************************************
+ *
+ * LOCAL FUNCTIONS
+ *
+ *************************************************************/
+/**
+ * @brief Warn the user that an error has occurred.In this case,
+ * the LEDs on the Board will start blinking.
+ *
+ * @param pMess : Message associated to the error.
+ * @param ErrCode: Error code associated to the module (OpenThread or other module if any)
+ * @retval None
+ */
+static void LldBleTraceError(const char * pMess, uint32_t ErrCode)
+{
+ APP_DBG("**** Fatal error = %s (Err = %d)", pMess, ErrCode);
+ while(1U == 1U)
+ {
+ BSP_LED_Toggle(LED1);
+ HAL_Delay(500U);
+ BSP_LED_Toggle(LED2);
+ HAL_Delay(500U);
+ BSP_LED_Toggle(LED3);
+ HAL_Delay(500U);
+ }
+}
+
+/**
+ * @brief Check if the Coprocessor Wireless Firmware loaded supports Thread
+ * and display associated informations
+ * @param None
+ * @retval None
+ */
+static void CheckWirelessFirmwareInfo(void)
+{
+ WirelessFwInfo_t wireless_info_instance;
+ WirelessFwInfo_t* p_wireless_info = &wireless_info_instance;
+ char m0FwType[50] = "M0 FW Type : Unknown !! ";
+
+ if (SHCI_GetWirelessFwInfo(p_wireless_info) != SHCI_Success)
+ {
+ APP_LLD_BLE_Error((uint32_t)ERR_LLD_BLE_CHECK_WIRELESS, 0);
+ }
+ else
+ {
+ APP_DBG("**********************************************************");
+ APP_DBG("Loaded M0 TEST FW info :");
+ switch(p_wireless_info->StackType)
+ {
+ case INFO_STACK_TYPE_802154_LLD_TESTS :
+ sprintf(m0FwType, " M0 FW Type : 802.15.4 and radio LLDs tests");
+ sprintf(cliPrompt, "802.15.4 TESTS > ");
+ break;
+
+ case INFO_STACK_TYPE_802154_PHY_VALID :
+ sprintf(m0FwType, " M0 FW Type : 802.15.4 and radio PHY validation");
+ sprintf(cliPrompt, "802.15.4 valid cli > ");
+ break;
+
+ case INFO_STACK_TYPE_BLE_PHY_VALID :
+ sprintf(m0FwType, " M0 FW Type : BLE and radio PHY validation");
+ sprintf(cliPrompt, "BLE valid cli > ");
+ break;
+
+ default :
+ /* FW not supported */
+ APP_LLD_BLE_Error((uint32_t)ERR_LLD_BLE_CHECK_WIRELESS, 0);
+ break;
+ }
+ APP_DBG(m0FwType);
+
+ /* Print version */
+ APP_DBG(" M0 FW VERSION = v%d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, p_wireless_info->VersionSub);
+
+ APP_DBG("**********************************************************");
+ }
+}
+
+/*************************************************************
+ *
+ * WRAP FUNCTIONS
+ *
+ *************************************************************/
+/**
+ * @brief Perform initialization of CLI UART interface.
+ * @param None
+ * @retval None
+ */
+void APP_LLD_BLE_Init_UART_CLI(void)
+{
+#if (CFG_HW_USART1_ENABLED == 1)
+ MX_USART1_UART_Init();
+
+ /* Put the UART device in reception mode and wait for interrupt */
+ if (HW_UART_Receive_IT(CFG_CLI_UART, &rxBuffer_Tab[rxBuffer_wrPtr], 1, uartRxCpltCallback) != hw_uart_ok)
+ APP_DBG((char *)"!! HAL_UART_Receive_IT error on M4 in APP_LLD_BLE_Init_UART_CLI !!");
+#endif
+}
+
+/**
+ * @brief Perform de-initialization of CLI UART interface.
+ * @param None
+ * @retval None
+ */
+void APP_LLD_BLE_DeInit_UART_CLI(void)
+{
+#if (CFG_HW_USART1_ENABLED == 1)
+ MX_USART1_UART_DeInit();
+#endif
+}
+
+static void uartRxCpltCallback(void)
+{
+ /* This callback is called :
+ - during RX isr (huart->RxISR)
+ - after bytes copy in buffer specified in last call to HW_UART_Receive_IT()
+ - when number of bytes specified in last call to HW_UART_Receive_IT() is acheived */
+
+ /* Prepare buffer to receive next character */
+ if ( rxCmdAllowed ) {
+ /* Increment read pointer index and manage buffer rollover */
+ rxBuffer_wrPtr++;
+ if(rxBuffer_wrPtr >= RX_BUFFER_SIZE)
+ rxBuffer_wrPtr = 0;
+ }
+
+ /* Re-put UART device in reception mode (not during IT to avoid locking the device while perhaps in transmit phase) */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_PROCESS_UART_RX_IT, CFG_SCH_PRIO_0);
+}
+
+static void uartRxItProcess(void)
+{
+ /* Put the UART device in reception mode and wait for interrupt */
+ if (HW_UART_Receive_IT(CFG_CLI_UART, &rxBuffer_Tab[rxBuffer_wrPtr], 1, uartRxCpltCallback) != hw_uart_ok)
+ APP_DBG((char *)"!! HAL_UART_Receive_IT error on M4 in uartRxItProcess !!");
+}
+
+static void uartClearChars(int nbChar)
+{
+ char clearCmd[2];
+
+ clearCmd[0] = CHAR_DEL;
+ clearCmd[1] = 0;
+ for (int i = 0; i < nbChar; i++) {
+ uartTxBufferAdd(clearCmd);
+ }
+}
+
+static void uartRxBufferProcessMode(uint8_t uartRxCmdEnable) /* 1 for Cmd ; 0 for Print */
+{
+ uartRxCmd=uartRxCmdEnable;
+}
+
+static void uartRxBufferProcess( void )
+{
+ char last_char[2];
+ static int8_t escape = -1;
+ static uint8_t escape_seq[3] = {0};
+
+ /* Ensure that last_char buffer contains a string with the char and a \0 (usefull to send echo or CHAR_DEL to UART) */
+ last_char[1] = 0;
+
+ if(uartRxCmd) {
+ /* Interpret and Command the character reception from UART */
+ while (rxBuffer_rdPtr != rxBuffer_wrPtr ) {
+ last_char[0] = rxBuffer_Tab[rxBuffer_rdPtr];
+ if( escape >= 0 ) {
+ escape_seq[escape++] = last_char[0];
+ if ( escape == 2 ) {
+ if ( strcmp((char*)escape_seq, "[A") == 0 ) { // UP
+ uartClearChars(currentCommandPos);
+ commandHistoryIdx = (commandHistoryIdx > 0) ? (commandHistoryIdx - 1) : (CMD_HISTORY_LENGTH - 1);
+ strcpy((char*)currentCommand,(char*)commandHistory[commandHistoryIdx]);
+ currentCommandPos = strlen((char*)currentCommand);
+ uartTxBufferAdd((char*)currentCommand);
+ }
+ if ( strcmp((char*)escape_seq, "[B") == 0 ) { // DOWN
+ uartClearChars(currentCommandPos);
+ commandHistoryIdx = (commandHistoryIdx < (CMD_HISTORY_LENGTH - 1)) ? (commandHistoryIdx + 1) : 0;
+ strcpy((char*)currentCommand,(char*)commandHistory[commandHistoryIdx]);
+ currentCommandPos = strlen((char*)currentCommand);
+ uartTxBufferAdd((char*)currentCommand);
+ }
+ escape = -1;
+ }
+ }
+ else if ( last_char[0] == CHAR_DEL ) {
+ if ( currentCommandPos > 0 ) {
+ currentCommandPos--;
+ uartTxBufferAdd(last_char);
+ }
+ }
+ else if ( last_char[0] == CHAR_ESC ) {
+ escape = 0;
+ }
+ else if ( last_char[0] == CHAR_CTRLC ) {
+ /* Just send a new prompt to wait for a new command */
+ currentCommandPos = 0;
+ uartTxBufferAdd("\r\n");
+ uartTxBufferAdd(cliPrompt);
+ }
+ else if ( ( last_char[0] == '\r' ) || ( last_char[0] == '\n' )) {
+ if (currentCommandPos == 0) {
+ /* User just typed 'enter' without any command, so, just send a new prompt to wait for a new command */
+ uartTxBufferAdd("\r\n");
+ uartTxBufferAdd(cliPrompt);
+ } else {
+ /* Do not accept new command from UART until this one is managed */
+ rxCmdAllowed = 0;
+
+ /* Put a end of line in UART TX buffer to have the echo sent */
+ uartTxBufferAdd("\r\n");
+
+ /* Copy the current command in history buffer before to send it to M0 */
+ memcpy(commandHistory[commandHistoryIdxSav],currentCommand,currentCommandPos);
+ /* add a \0 to avoid reseting end of command history buffer */
+ commandHistory[commandHistoryIdxSav][currentCommandPos] = 0;
+ commandHistoryIdxSav = (commandHistoryIdxSav+1) % CMD_HISTORY_LENGTH;
+ commandHistoryIdx = commandHistoryIdxSav;
+
+ /* UART task scheduling to send it to M0 */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_SEND_TO_M0, CFG_SCH_PRIO_0);
+ }
+ }
+ else {
+ /* Put the char in UART TX buffer to have the echo sent */
+ uartTxBufferAdd(last_char);
+ /* Put the char in the current command buffer */
+ currentCommand[currentCommandPos++] = last_char[0];
+ }
+
+ /* Increment read pointer index and manage buffer rollover */
+ rxBuffer_rdPtr++;
+ if(rxBuffer_rdPtr >= RX_BUFFER_SIZE)
+ rxBuffer_rdPtr = 0;
+ }
+ } else {
+ /* Interpret and Print the character reception from UART */
+ while (rxBuffer_rdPtr != rxBuffer_wrPtr ) {
+ last_char[0] = rxBuffer_Tab[rxBuffer_rdPtr];
+ if( escape >= 0 ) {
+ escape_seq[escape++] = last_char[0];
+ if ( escape == 2 ) {
+ if ( strcmp((char*)escape_seq, "[A") == 0 ) { // UP
+ uartClearChars(txtCommandPos);
+ commandHistoryIdx = (commandHistoryIdx > 0) ? (commandHistoryIdx - 1) : (CMD_HISTORY_LENGTH - 1);
+ strcpy((char*)txtCommand,(char*)commandHistory[commandHistoryIdx]);
+ txtCommandPos = strlen((char*)txtCommand);
+ uartTxBufferAdd((char*)txtCommand);
+ }
+ if ( strcmp((char*)escape_seq, "[B") == 0 ) { // DOWN
+ uartClearChars(txtCommandPos);
+ commandHistoryIdx = (commandHistoryIdx < (CMD_HISTORY_LENGTH - 1)) ? (commandHistoryIdx + 1) : 0;
+ strcpy((char*)txtCommand,(char*)commandHistory[commandHistoryIdx]);
+ txtCommandPos = strlen((char*)txtCommand);
+ uartTxBufferAdd((char*)txtCommand);
+ }
+ escape = -1;
+ }
+ }
+ else if ( last_char[0] == CHAR_DEL ) {
+ if ( txtCommandPos > 0 ) {
+ txtCommandPos--;
+ uartTxBufferAdd(last_char);
+ }
+ }
+ else if ( last_char[0] == CHAR_ESC ) {
+ escape = 0;
+ }
+ else if ( last_char[0] == CHAR_CTRLC ) {
+ /* Just send a new prompt to wait for a new command */
+ txtCommandPos = 0;
+ uartTxBufferAdd("\r\n");
+ uartTxBufferAdd(cliPrompt);
+ }
+ else if ( ( last_char[0] == '\r' ) || ( last_char[0] == '\n' )) {
+ if (txtCommandPos == 0) {
+ /* User just typed 'enter' without any command, so, just send a new prompt to wait for a new command */
+ uartTxBufferAdd("\r\n");
+ uartTxBufferAdd(cliPrompt);
+ uartLastChar=0;
+
+ } else {
+ /* Do not accept new command from UART until this one is managed */
+ rxCmdAllowed = 0;
+
+ /* Put a end of line in UART TX buffer to have the echo sent */
+ uartTxBufferAdd("\r\n");
+
+ /* Copy the current command in history buffer before to send it to M0 */
+ memcpy(commandHistory[commandHistoryIdxSav],txtCommand,txtCommandPos);
+ /* add a \0 to avoid reseting end of command history buffer */
+ commandHistory[commandHistoryIdxSav][txtCommandPos] = 0;
+ commandHistoryIdxSav = (commandHistoryIdxSav+1) % CMD_HISTORY_LENGTH;
+ commandHistoryIdx = commandHistoryIdxSav;
+
+ /* UART task scheduling to send it to M0 */
+ /* Send Packet with UART Char as Payload */
+ uartPayload[0]= 0xAA; // Appli Header
+ uartPayload[1]= txtCommandPos; // Appli Length
+ memcpy(&uartPayload[2],txtCommand,txtCommandPos);
+ txtCommandPos=0;
+ Appli_uartRxBufferPrint();
+ uartLastChar=1;
+
+ }
+ }
+ else {
+ /* Put the char in UART TX buffer to have the echo sent */
+ uartTxBufferAdd(last_char);
+ /* Put the char in the current command buffer */
+ txtCommand[txtCommandPos++] = last_char[0];
+ }
+
+ /* Increment read pointer index and manage buffer rollover */
+ rxBuffer_rdPtr++;
+ if(rxBuffer_rdPtr >= RX_BUFFER_SIZE)
+ rxBuffer_rdPtr = 0;
+ }
+ }
+
+ /* Re-activate UART RX buffer processing task */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_PROCESS_UART_RX_BUFFER, CFG_SCH_PRIO_0);
+}
+
+uint32_t txBufferFullCount;
+static void uartTxBufferAdd(const char * str)
+{
+ uint16_t bytesToWrite = strlen(str);
+ uint32_t txBufferFull = 0;
+
+ if (bytesToWrite) {
+ CRITICAL_BEGIN();
+ {
+ uint16_t remainingBytesToWrite = bytesToWrite;
+ uint32_t currentWrPtr = txBuffer_wrPtr;
+ uint8_t * currentWrAddr = &txBuffer_Tab[txBuffer_wrPtr];
+
+ while ((remainingBytesToWrite > 0) && (txBufferFull == 0)) {
+ if ((txBuffer_rdPtr == (currentWrPtr + 1)) || ((txBuffer_rdPtr == 0) && (currentWrPtr == (TX_BUFFER_SIZE - 1)))) {
+ /* If there is not enougth place (i.e. write pointer is just behind read pointer in the circular buffer),
+ buffer is full, so do not consider new string */
+ /* !! No trace here as it is under CRITICAL section */
+ txBufferFull = 1;
+ } else {
+ *currentWrAddr = str[bytesToWrite - remainingBytesToWrite];
+ remainingBytesToWrite--;
+
+ /* Increment write pointer index and manage buffer rollover */
+ currentWrPtr++;
+ if(currentWrPtr >= TX_BUFFER_SIZE)
+ currentWrPtr = 0;
+ currentWrAddr = &txBuffer_Tab[currentWrPtr];
+ }
+ }
+
+ if (txBufferFull == 0) {
+ txBuffer_wrPtr = currentWrPtr;
+ }
+ }
+ CRITICAL_END();
+
+ if (txBufferFull == 0) {
+ if (txBusy == 0) {
+ txBusy = 1;
+ uartTxCpltCallback();
+ }
+ } else {
+ txBufferFullCount++;
+ APP_DBG((char *)"!! TX buffer full : %u", txBufferFullCount);
+ }
+ }
+}
+
+static void uartTxCpltCallback(void)
+{
+ /* Prepare buffer to receive next character */
+ if ( txBuffer_rdPtr != txBuffer_wrPtr ) {
+ /* Re-put UART device in reception mode (not during IT to avoid locking the device while perhaps in transmit phase) */
+ pTxBuff_currentWr = &txBuffer_Tab[txBuffer_rdPtr];
+ UTIL_SEQ_SetTask(1U << CFG_TASK_PROCESS_UART_TX_IT, CFG_SCH_PRIO_0);
+
+ /* Increment write pointer index and manage buffer rollover */
+ txBuffer_rdPtr++;
+ if(txBuffer_rdPtr >= TX_BUFFER_SIZE)
+ txBuffer_rdPtr = 0;
+ } else {
+ txBusy = 0;
+ }
+}
+
+static void uartTxItProcess(void)
+{
+ /* Put the UART device in transmission mode and wait for interrupts :
+ - 1 to write the data in TDR register
+ - 1 when char is sent
+ - 1 to indicate end of transmit if several chars are to be transmitted */
+ if (HW_UART_Transmit_IT(CFG_CLI_UART, pTxBuff_currentWr, 1, uartTxCpltCallback) != hw_uart_ok)
+ APP_DBG((char *)"!! HAL_UART_Transmit_IT error on M4 in uart TX callback !!");
+}
+
+/**
+ * @brief Process sends CLI command to M0.
+ * @param None
+ * @retval None
+ */
+static void SendCmdToM0(void)
+{
+ memset(LldBleCmdRspPacket.cmdserial.cmd.payload, 0x0U, 255U);
+ *(uint32_t *)LldBleCmdRspPacket.cmdserial.cmd.payload = (uint32_t)currentCommand;
+ *(uint32_t *)&LldBleCmdRspPacket.cmdserial.cmd.payload[4] = currentCommandPos;
+ LldBleCmdRspPacket.cmdserial.cmd.plen = 8;
+ LldBleCmdRspPacket.cmdserial.cmd.cmdcode = 0x0;
+
+ TL_LLD_BLE_SendCmd();
+}
+
+/**
+ * @brief Perform initialization of TL for LLD tests.
+ * @param None
+ * @retval None
+ */
+void APP_LLD_BLE_Init_TL(void)
+{
+ LldBleConfigBuffer.p_LldBleCmdRspBuffer = (uint8_t*)&LldBleCmdRspPacket;
+ LldBleConfigBuffer.p_LldBleM0CmdBuffer = (uint8_t*)&LldBleM0CmdPacket;
+
+ TL_LLD_BLE_Init( &LldBleConfigBuffer );
+}
+
+static void m0RadioProcess(void)
+{
+ switch (m0Cmd) {
+ case CMD_FROM_M0_RADIO_STOP :
+ Appli_m0RadioProcess_RadioStop();
+ break;
+
+ case CMD_FROM_M0_RADIO_END :
+ Appli_m0RadioProcess_RadioEnd();
+ break;
+
+ case CMD_FROM_M0_RADIO_RXACK :
+ Appli_m0RadioProcess_RxAck();
+ break;
+
+ case CMD_FROM_M0_RADIO_RXOK :
+ Appli_m0RadioProcess_RxOk();
+ break;
+
+ case CMD_FROM_M0_RADIO_RXACKEND :
+ Appli_m0RadioProcess_RxAckEnd();
+ break;
+
+ case CMD_FROM_M0_RADIO_RXOKEND :
+ Appli_m0RadioProcess_RxOkEnd();
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void m0CmdProcess(void)
+{
+ switch (m0Cmd) {
+
+ case CMD_FROM_M0_RADIO_STOP :
+ Appli_m0CmdProcess_RadioStop();
+ break;
+
+ case CMD_FROM_M0_RADIO_END :
+ Appli_m0CmdProcess_RadioEnd();
+ break;
+
+ case CMD_FROM_M0_RADIO_RXACK :
+ Appli_m0CmdProcess_RxAck();
+ break;
+
+ case CMD_FROM_M0_RADIO_RXOK :
+ Appli_m0CmdProcess_RxOk();
+ break;
+
+ case CMD_FROM_M0_RADIO_RXACKEND :
+ Appli_m0CmdProcess_RxAckEnd();
+ break;
+
+ case CMD_FROM_M0_RADIO_RXOKEND :
+ Appli_m0CmdProcess_RxOkEnd();
+ break;
+
+ case CMD_FROM_M0_STOP0_ON :
+ m0CmdStopRequired(0);
+ break;
+
+ case CMD_FROM_M0_STOP1_ON :
+ m0CmdStopRequired(1);
+ break;
+
+ case CMD_FROM_M0_STOP2_ON :
+ m0CmdStopRequired(2);
+ break;
+
+ case CMD_FROM_M0_STOP_OFF :
+ // Nothing done here as the goal of this command is just to have an IPCC interrupt
+ // that will make the M4 going out of STOP or WFI
+ break;
+
+ case CMD_FROM_M0_GO_IN_WFI :
+ m0CmdStopRequired(3);
+ break;
+
+ case CMD_FROM_M0_GO_DIRECTLY_IN_WFI :
+ m0CmdStopRequired(4);
+ break;
+
+ case CMD_FROM_M0_USE_MSI :
+ SystemClock_Config_MSI(0);
+ break;
+
+ case CMD_FROM_M0_USE_MSI_PLL :
+ SystemClock_Config_MSI(1);
+ break;
+
+ case CMD_FROM_M0_USE_HSE :
+ SystemClock_Config_HSE(0);
+ break;
+
+ case CMD_FROM_M0_USE_HSE_PLL :
+ SystemClock_Config_HSE(1);
+ break;
+
+#if (CFG_HW_EXTPA_ENABLED == 1)
+ case CMD_FROM_M0_EXT_PA_EN :
+ gpio_lld_extPa_init();
+ // Indicate to M0 which GPIO must be managed
+ SHCI_C2_ExtpaConfig((uint32_t)GPIO_EXT_PA_EN_PORT, GPIO_EXT_PA_EN_PIN, EXT_PA_ENABLED_HIGH, EXT_PA_ENABLED);
+ break;
+
+ case CMD_FROM_M0_EXT_PA_DIS :
+ gpio_lld_extPa_deInit();
+ SHCI_C2_ExtpaConfig((uint32_t)GPIO_EXT_PA_EN_PORT, GPIO_EXT_PA_EN_PIN, EXT_PA_ENABLED_HIGH, EXT_PA_DISABLED);
+ break;
+#endif
+
+ default:
+ break;
+ }
+}
+
+static void m4ConfigBeforeStop(void)
+{
+ // Clear C1 Stop flag if any remaining
+ LL_PWR_ClearFlag_C1STOP_C1STB();
+}
+
+static void m4ConfigAfterStop(void)
+{
+ // Clear C1 Stop flag
+ LL_PWR_ClearFlag_C1STOP_C1STB();
+}
+
+static void m0CmdStopRequired(uint32_t stopRequired)
+{
+ switch (stopRequired) {
+ case 0:
+ // flush IPC and trace before sleeping. Let time to M0 to set RF in sleep and to be in STOP if needed
+ us_delay(delayBeforeSleepOnM4);
+
+ // Stop UART and its GPIOs to reduce power consumption
+ APP_LLD_BLE_DeInit_UART_CLI();
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ MX_LPUART1_UART_DeInit();
+#endif
+
+ // trial for no IT (ex RF) at low speed
+ CRITICAL_BEGIN();
+
+ // Prepare system to be stopped
+ m4ConfigBeforeStop();
+
+ // Enter selected STOP mode
+ HAL_PWREx_EnterSTOP0Mode(PWR_STOPENTRY_WFI);
+
+ // Restart system
+ m4ConfigAfterStop();
+
+ // Restart UART before to go out of critical area to not have to send trace from M0 before to restart it
+ APP_LLD_BLE_Init_UART_CLI();
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ MX_LPUART1_UART_Init();
+#endif
+
+ // trial for no IT (ex RF) at low speed
+ CRITICAL_END();
+
+ APP_DBG("M4 back from STOP0");
+ break;
+
+ case 1:
+ // flush IPC and trace before sleeping. Let time to M0 to set RF in sleep and to be in STOP if needed
+ us_delay(delayBeforeSleepOnM4);
+
+ // Stop UART and its GPIOs to reduce power consumption
+ APP_LLD_BLE_DeInit_UART_CLI();
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ MX_LPUART1_UART_DeInit();
+#endif
+
+ // trial for no IT (ex RF) at low speed
+ CRITICAL_BEGIN();
+
+ // Prepare system to be stopped
+ m4ConfigBeforeStop();
+
+ // Enter selected STOP mode
+ HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
+
+ // Restart system
+ m4ConfigAfterStop();
+
+ // Restart UART before to go out of critical area to not have to send trace from M0 before to restart it
+ APP_LLD_BLE_Init_UART_CLI();
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ MX_LPUART1_UART_Init();
+#endif
+
+ // trial for no IT (ex RF) at low speed
+ CRITICAL_END();
+
+ APP_DBG("M4 back from STOP1");
+ break;
+
+ case 2:
+ // flush IPC and trace before sleeping. Let time to M0 to set RF in sleep and to be in STOP if needed
+ us_delay(delayBeforeSleepOnM4);
+
+ // Stop UART and its GPIOs to reduce power consumption
+ APP_LLD_BLE_DeInit_UART_CLI();
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ MX_LPUART1_UART_DeInit();
+#endif
+
+ // trial for no IT (ex RF) at low speed
+ CRITICAL_BEGIN();
+
+ // Prepare system to be stopped
+ m4ConfigBeforeStop();
+
+ // Enter selected STOP mode
+ HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
+
+ // Restart system
+ m4ConfigAfterStop();
+
+ // Restart UART before to go out of critical area to not have to send trace from M0 before to restart it
+ APP_LLD_BLE_Init_UART_CLI();
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ MX_LPUART1_UART_Init();
+#endif
+
+ // trial for no IT (ex RF) at low speed
+ CRITICAL_END();
+
+ APP_DBG("M4 back from STOP2");
+ break;
+
+ case 3:
+ // flush IPC and trace before sleeping. Let time to M0 to set RF in sleep and to be in STOP if needed
+ us_delay(delayBeforeSleepOnM4);
+
+ // Stop UART and its GPIOs to reduce power consumption
+ APP_LLD_BLE_DeInit_UART_CLI();
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ MX_LPUART1_UART_DeInit();
+#endif
+
+ // trial for no IT (ex RF) at low speed
+ CRITICAL_BEGIN();
+
+ __WFI();
+ // Restart UART before to go out of critical area to not have to send trace from M0 before to restart it
+ APP_LLD_BLE_Init_UART_CLI();
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ MX_LPUART1_UART_Init();
+#endif
+
+ // trial for no IT (ex RF) at low speed
+ CRITICAL_END();
+
+ APP_DBG("M4 back from WFI");
+ break;
+
+ case 4:
+ // Put M4 in WFI without delay :
+ // - In some cases, it is recomanded to limit the M4 activity to avoid Flash access which can slow down the M0 which share it with M4
+ // - But, be carrefull as WFI can be blocking as there is no more interrupts
+ // - As example, if not used, SF timer test is failed.
+ __WFI();
+ APP_DBG("M4 back from WFI (without delay)");
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Send Ack to M0 CLI Response channel.
+ * @param None
+ * @retval None
+ */
+static void SendRspAckToM0(void)
+{
+ /* Notify M0 that CLI notification has been taken into account */
+ TL_LLD_BLE_SendRspAck();
+}
+
+/**
+ * @brief This function is called when notification on CLI TL Channel from M0+ is received.
+ *
+ * @param Notbuffer : a pointer to TL_CmdPacket_t
+ * @return None
+ */
+void TL_LLD_BLE_ReceiveRsp( TL_CmdPacket_t * Notbuffer )
+{
+
+ uint8_t l_size = Notbuffer->cmdserial.cmd.plen;
+ char * sourceBuf = (char *)Notbuffer->cmdserial.cmd.payload;
+
+ if (l_size > 0)
+ {
+ if (strncmp(sourceBuf, "Resp_End", 9) == 0)
+ {
+ /* This is an answer to indicate that the CLI command has been completed */
+ UTIL_SEQ_SetEvt(1U << CFG_EVT_RECEIVE_RSPACKEVT);
+
+ /* Write a promp to UART and allow to receive a new command */
+ //sprintf(cliPrompt, "LLD BLE > ");
+ //uartTxBufferAdd("\r\n");
+ //uartTxBufferAdd(cliPrompt);
+
+ currentCommandPos = 0;
+ rxCmdAllowed = 1;
+ }
+ else
+ {
+ /* This is just a trace from M0, write to CLI UART buffer */
+ uartTxBufferAdd(sourceBuf);
+ }
+ }
+ else
+ {
+ APP_DBG((char *)"!! Empty M0 CLI response received by M4 !!");
+ }
+ SendRspAckToM0();
+}
+
+/**
+ * @brief Send Ack to M0 CLI Response channel.
+ * @param None
+ * @retval None
+ */
+static void SendM0CmdAckToM0(void)
+{
+ /* Notify M0 that CLI notification has been taken into account */
+ TL_LLD_BLE_SendM0CmdAck();
+}
+
+/**
+ * @brief This function is called when notification on CLI TL Channel from M0+ is received.
+ *
+ * @param Notbuffer : a pointer to TL_CmdPacket_t
+ * @return None
+ */
+void TL_LLD_BLE_ReceiveM0Cmd( TL_CmdPacket_t * cmdBuffer )
+{
+ //TL_CmdPacket_t* l_CliBuffer = (TL_CmdPacket_t*)Notbuffer;
+ uint8_t bufferSize = cmdBuffer->cmdserial.cmd.plen;
+ char * bufferAddr = (char *)cmdBuffer->cmdserial.cmd.payload;
+ //uint32_t length = *(uint32_t *)&l_CliBuffer->cmdserial.cmd.payload[4];
+
+ if (bufferSize > 0)
+ {
+ if (strncmp(bufferAddr, "Radio_Stop", 10) == 0)
+ {
+ m0Cmd = CMD_FROM_M0_RADIO_STOP;
+
+ /* Action under IT */
+ m0RadioProcess();
+
+ /* Action under Sequencer */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+
+ }
+ else if (strncmp(bufferAddr, "Radio_End", 9) == 0)
+ {
+ m0Cmd = CMD_FROM_M0_RADIO_END;
+
+ /* Action under IT */
+ m0RadioProcess();
+
+ /* Action under Sequencer */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+
+ }
+ else if (strncmp(bufferAddr, "Radio_RxAckEnd", 14) == 0)
+ {
+ m0Cmd = CMD_FROM_M0_RADIO_RXACKEND;
+
+ /* Action under IT */
+ m0RadioProcess();
+
+ /* Action under Sequencer */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+
+ }
+ else if (strncmp(bufferAddr, "Radio_RxOkEnd", 13) == 0)
+ {
+ m0Cmd = CMD_FROM_M0_RADIO_RXOKEND;
+
+ /* Action under IT */
+ m0RadioProcess();
+
+ /* Action under Sequencer */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+
+ }
+ else if (strncmp(bufferAddr, "Radio_RxAck", 11) == 0)
+ {
+ m0Cmd = CMD_FROM_M0_RADIO_RXACK;
+
+ /* Action under IT */
+ m0RadioProcess();
+
+ /* Action under Sequencer */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+
+ }
+ else if (strncmp(bufferAddr, "Radio_RxOk", 10) == 0)
+ {
+ m0Cmd = CMD_FROM_M0_RADIO_RXOK;
+
+ /* Action under IT */
+ m0RadioProcess();
+
+ /* Action under Sequencer */
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+
+ }
+ else if (strncmp(bufferAddr, "stop0_on", 8) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_STOP0_ON;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "stop1_on", 8) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_STOP1_ON;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "stop2_on", 8) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_STOP2_ON;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "stop_off", 8) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_STOP_OFF;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "go_in_wfi", 9) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_GO_IN_WFI;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "go_directly_in_wfi", 18) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_GO_DIRECTLY_IN_WFI;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "use_msi_no_pll", 14) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_USE_MSI;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "use_msi_pll", 11) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_USE_MSI_PLL;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "use_hse_no_pll", 14) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_USE_HSE;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "use_hse_pll", 11) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_USE_HSE_PLL;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "ext_pa_enable", 13) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_EXT_PA_EN;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else if (strncmp(bufferAddr, "ext_pa_disable", 14) == 0)
+ {
+ // Save the command
+ m0Cmd = CMD_FROM_M0_EXT_PA_DIS;
+ // Set the task to process the command
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_FROM_M0_TO_M4, CFG_SCH_PRIO_0);
+ }
+ else
+ {
+ APP_DBG((char *)"!! Unknown M0 command received by M4 !!");
+ }
+ }
+ else
+ {
+ APP_DBG((char *)"!! Empty M0 command received by M4 !!");
+ }
+ SendM0CmdAckToM0();
+}
+
+/**
+ * @brief This function is called to Send Command to M0, Every lld_ble API call this function
+ *
+ * @param currentCmd : a value of the lld_ble API
+ * @param currentPt : a pointer to param_hal_BLE_t
+ * @return M0 return value
+ */
+uint8_t APP_LLD_BLE_SendCmdM0(uint8_t currentCmd , uint32_t* currentPt)
+{
+ /* M0 init done, send first command to have M0 code info and thus, a first prompt will be printed automatically */
+ /* Do not accept new command from UART until this one is managed */
+ rxCmdAllowed = 0;
+ currentCommandPos = 5;
+ currentCommand[0] = currentCmd ;
+ currentCommand[1] = (uint8_t)((((uint32_t)(currentPt)) >> 0) & 0xFF);
+ currentCommand[2] = (uint8_t)((((uint32_t)(currentPt)) >> 8) & 0xFF);
+ currentCommand[3] = (uint8_t)((((uint32_t)(currentPt)) >> 16) & 0xFF);
+ currentCommand[4] = (uint8_t)((((uint32_t)(currentPt)) >> 24) & 0xFF);
+
+ currentCommand[5] = 0;
+
+ /* Set corresponding task to send this command to M0 */
+ //UTIL_SEQ_SetTask(1U << CFG_TASK_SEND_TO_M0, CFG_SCH_PRIO_0);
+ UTIL_SEQ_ClrEvt(1U << CFG_EVT_RECEIVE_RSPACKEVT);
+ SendCmdToM0();
+
+ UTIL_SEQ_WaitEvt(1U << CFG_EVT_RECEIVE_RSPACKEVT);
+
+ /* Activate UART RX buffer processing task to allow USER command comming from UART */
+ //UTIL_SEQ_SetTask(1U << CFG_TASK_PROCESS_UART_RX_BUFFER, CFG_SCH_PRIO_0);
+ return(((param_hal_BLE_t*)(currentPt))->return_value);
+
+}
+
+/**
+ * @brief As the default systick is not used, declare here, at least, an empty function to
+ * over-write the default one as it declared as WEAK in HAL.
+ */
+void HAL_Delay(__IO uint32_t Delay)
+{
+ us_delay(Delay*1000);
+ return;
+}
+
+/* USER CODE BEGIN FD */
+/* Appli common functions */
+void Appli_ProcessMode(void)
+{
+ uartRxBufferProcessMode(1); /* cmd mode */
+}
+
+void Appli_RegTask(void)
+{
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_HAL_BLE_INIT , UTIL_SEQ_RFU, BUTTON_SW1_BLE_Init);
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_HAL_BLE_SENDPACKET , UTIL_SEQ_RFU, BUTTON_SW2_StartPacket);
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_HAL_BLE_RECEIVEPACKET , UTIL_SEQ_RFU, BUTTON_SW3_StopPacket);
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_CMD_M4_PACKET_STACKING, UTIL_SEQ_RFU, m4CmdPacketStacking);
+ UTIL_SEQ_RegTask( 1<<CFG_TASK_CMD_M4_PACKET_STACK_PROCESS, UTIL_SEQ_RFU, m4CmdPacketStackProcess);
+}
+
+void Appli_Init(void)
+{
+ proxSTDEVICEUDN[0]=LL_FLASH_GetUDN();
+ proxSTDEVICEUDN[1]=(LL_FLASH_GetSTCompanyID() << 8)| LL_FLASH_GetDeviceID();
+ proxSTDEVICEUDN[2]=HAL_GetDEVID();
+ proxSTDEVICEUDN[3]=HAL_GetUIDw0();
+ proxSTDEVICEUDN[4]=HAL_GetUIDw1();
+ proxSTDEVICEUDN[5]=HAL_GetUIDw2();
+
+ uint8_t i = 0;
+ for (i=0; i<(6*4);i++)
+ {
+ proxtxBufferTab[i+2]=(uint8_t)(proxSTDEVICEUDN[i/4]>>((i%4)*8) & 0xFF);
+ proxAcktxBufferTab[i+2]=~proxtxBufferTab[i+2];
+ }
+}
+
+void Appli_uartRxBufferPrint(void)
+{
+ sprintf(cliPrompt, "LLD BLE > ");
+ uartTxBufferAdd(cliPrompt);
+}
+
+/* Appli radio functions */
+void Appli_m0RadioProcess_RadioStop(void)
+{
+ /* copy status from M0 BLE Radio */
+ radioPacketNb=bleparam_hal_BLE_Packet.txrxBuffer.rxBuffer[257];
+ *rxStatus_Ptr[radioPacketNb]=bleparam_hal_BLE_Packet.status; // status
+}
+
+void Appli_m0RadioProcess_RadioEnd(void)
+{
+ /* copy status from M0 BLE Radio */
+ radioPacketNb=bleparam_hal_BLE_Packet.txrxBuffer.rxBuffer[257];
+ *rxStatus_Ptr[radioPacketNb]=bleparam_hal_BLE_Packet.status; // status
+ UTIL_SEQ_PauseTask(1U <<CFG_TASK_CMD_M4_PACKET_STACK_PROCESS);
+}
+
+void Appli_m0RadioProcess_RxAck(void)
+{
+ /* copy status from M0 BLE Radio */
+ radioPacketNb=bleparam_hal_BLE_Packet.txrxBuffer.rxBuffer[257];
+ *rxStatus_Ptr[radioPacketNb]=bleparam_hal_BLE_Packet.status; // status
+}
+
+void Appli_m0RadioProcess_RxOk(void)
+{
+ /* copy status from M0 BLE Radio */
+ radioPacketNb=bleparam_hal_BLE_Packet.txrxBuffer.rxBuffer[257];
+ *rxStatus_Ptr[radioPacketNb]=bleparam_hal_BLE_Packet.status; // status
+ *rxTimeStamp_Ptr[radioPacketNb]=bleparam_hal_BLE_Packet.timestamp_receive; // timestamp_receive
+ *rxRSSI_Ptr[radioPacketNb]=bleparam_hal_BLE_Packet.rssi; // rssi
+ /* copy payload from M0 BLE Radio */
+ memcpy(rxBuffer_Ptr[radioPacketNb],(bleparam_hal_BLE_Packet.txrxBuffer.rxBuffer),258);
+ UTIL_SEQ_PauseTask(1U <<CFG_TASK_CMD_M4_PACKET_STACK_PROCESS);
+}
+
+void Appli_m0RadioProcess_RxAckEnd(void)
+{
+ /* copy status from M0 BLE Radio */
+ radioPacketNb=bleparam_hal_BLE_Packet.txrxBuffer.rxBuffer[257];
+ *rxStatus_Ptr[radioPacketNb]=bleparam_hal_BLE_Packet.status; // status
+}
+
+void Appli_m0RadioProcess_RxOkEnd(void)
+{
+ /* copy status from M0 BLE Radio */
+ radioPacketNb=bleparam_hal_BLE_Packet.txrxBuffer.rxBuffer[257];
+ *rxStatus_Ptr[radioPacketNb]=bleparam_hal_BLE_Packet.status; // status
+}
+
+
+void Appli_m0CmdProcess_RadioStop(void)
+{
+ HAL_TIM_Base_Stop_IT(&htim2);
+
+ uint8_t j;
+ extern uint8_t Packet_ID[8][24];
+ extern uint8_t Local_ID[24];
+ extern uint8_t Recorded_ID;
+
+ sprintf(cliPrompt, "\r\nLocal ID > ");
+ for (j=0 ; j<2; j++) //24
+ {
+ sprintf(cliPrompt, "%s %2x ",cliPrompt, Local_ID[j]); // Record ID from Stack_Packet
+ }
+
+ while(Recorded_ID)
+ {
+ sprintf(cliPrompt, "%s\r\nRadio Get ID %d> " ,cliPrompt ,Recorded_ID);
+ for (j=0 ; j<2; j++) //24
+ {
+ sprintf(cliPrompt, "%s %2x ",cliPrompt, Packet_ID[Recorded_ID-1][j]); // Record ID from Stack_Packet
+ }
+ Recorded_ID--;
+ }
+ uartTxBufferAdd(cliPrompt);
+}
+
+void Appli_m0CmdProcess_RadioEnd(void)
+{
+ UTIL_SEQ_SetTask(1U <<CFG_TASK_CMD_M4_PACKET_STACKING , CFG_SCH_PRIO_0);
+ if(uartLastChar) uartLastChar=0;
+}
+
+void Appli_m0CmdProcess_RxAck(void)
+{
+}
+
+void Appli_m0CmdProcess_RxOk(void)
+{
+ UTIL_SEQ_SetTask(1U <<CFG_TASK_CMD_M4_PACKET_STACKING , CFG_SCH_PRIO_0);
+}
+
+void Appli_m0CmdProcess_RxAckEnd(void)
+{
+}
+
+void Appli_m0CmdProcess_RxOkEnd(void)
+{
+}
+
+/* Appli custom functions */
+void BUTTON_SW1_BLE_Init(void)
+{
+ #ifdef LLD_BLE_DEBUG
+ bleparam_hal_BLE_Packet.InfoTime=(uint32_t)debug_timer;
+ #endif
+ LLD_BLE_Init(HS_STARTUP_TIME, 1, LLD_BLE_hot_ana_config_table, ENABLE); // lecozj ENABLE for whitening
+ UTIL_SEQ_SetTask(1U << CFG_TASK_CMD_M4_PACKET_STACKING, CFG_SCH_PRIO_0);
+
+ BSP_LED_On(LED_BLUE);
+
+}
+
+
+// ___________________________
+// | _____ |
+// | true |---=>|2:TX |__|
+// | _____ | | |_____| _____
+// |=>|0:RX |___| |_____________|1:RX |
+// | |_____|___ _____________|_____|<=-|
+// | | | _____ _____ |
+// | false |---=>|3:TX |--=>|4:RX |___|
+// | |_____| |_____|___
+// |_______________________________________|
+//
+void BUTTON_SW2_StartPacket(void)
+{
+ LED_TXRX=LED_GREEN;
+
+ LLD_BLE_GetStatus(&proxtime);
+
+ uint8_t map[5]= {0xFF,0xFF,0xFF,0xFF,0xFF};
+ LLD_BLE_SetChannelMap(STATE_MACHINE_3, &map[0]);
+ LLD_BLE_SetChannel(STATE_MACHINE_3, proxChannel, 0);
+ LLD_BLE_SetTxAttributes(STATE_MACHINE_3, proxID, 0x555555,0);
+ LLD_BLE_SetTx_Rx_Phy(STATE_MACHINE_3, TX_PHY_2MBPS, RX_PHY_2MBPS);
+ LLD_BLE_SetTxPower(proxPower);
+ LLD_BLE_SetBackToBackTime(BACK2BACK_TIME);
+
+ //uint8_t map[5]= {0xBB,0xFF,0xFF,0xFF,0xBB};
+ LLD_BLE_SetChannelMap(STATE_MACHINE_0, &map[0]);
+ LLD_BLE_SetChannel(STATE_MACHINE_0,(proxChannel+2),0);
+ LLD_BLE_SetTxAttributes(STATE_MACHINE_0, ~proxID, 0x555555,0);
+ LLD_BLE_SetTx_Rx_Phy(STATE_MACHINE_0, TX_PHY_2MBPS, RX_PHY_2MBPS);
+ LLD_BLE_SetBackToBackTime(BACK2BACK_TIME);
+
+
+ proxPacket[APACKET_0].StateMachineNo = STATE_MACHINE_0; // First RX
+ proxPacket[APACKET_0].ActionTag = PLL_TRIG | TIMER_WAKEUP | RELATIVE;
+ proxPacket[APACKET_0].WakeupTime = proxWakeup;
+ proxPacket[APACKET_0].ReceiveWindowLength = proxReceive;
+ proxPacket[APACKET_0].data = proxrxBuffer;
+ proxPacket[APACKET_0].next_true = APACKET_2; // Ack
+ proxPacket[APACKET_0].next_false = APACKET_3;
+ proxPacket[APACKET_0].condRoutine = condCase_Rx;
+ proxPacket[APACKET_0].dataRoutine = dataRoutine_Action;
+ proxPacket[APACKET_0].actionPacketNb = APACKET_0;
+ LLD_BLE_SetReservedArea(&proxPacket[APACKET_0]);
+
+ proxPacket[APACKET_1].StateMachineNo = STATE_MACHINE_0; // Second RX
+ proxPacket[APACKET_1].ActionTag = PLL_TRIG | TIMER_WAKEUP | RELATIVE;
+ proxPacket[APACKET_1].WakeupTime = 4*proxReceive;
+ proxPacket[APACKET_1].ReceiveWindowLength = proxReceive;
+ proxPacket[APACKET_1].data = proxrxBuffer;
+ proxPacket[APACKET_1].next_true = APACKET_2; // back to RX
+ proxPacket[APACKET_1].next_false = APACKET_3;
+ proxPacket[APACKET_1].condRoutine = condCase_Rx;
+ proxPacket[APACKET_1].dataRoutine = dataRoutine_Action;
+ proxPacket[APACKET_1].actionPacketNb = APACKET_1;
+ LLD_BLE_SetReservedArea(&proxPacket[APACKET_1]);
+
+ proxPacket[APACKET_2].StateMachineNo = STATE_MACHINE_3; // TX Ack State Machine of ACK
+ proxPacket[APACKET_2].ActionTag = TXRX ;
+ proxPacket[APACKET_2].WakeupTime = proxWakeup;
+ proxPacket[APACKET_2].ReceiveWindowLength = 0; /* does not affect for Tx */
+ proxPacket[APACKET_2].data = proxAcktxBuffer;
+ proxPacket[APACKET_2].next_true = APACKET_0;
+ proxPacket[APACKET_2].next_false = APACKET_NULL;
+ proxPacket[APACKET_2].condRoutine = condCase_Done;
+ proxPacket[APACKET_2].dataRoutine = dataRoutineDone_hal_BLE; // return TRUE
+ proxPacket[APACKET_2].actionPacketNb = APACKET_2;
+ LLD_BLE_SetReservedArea(&proxPacket[APACKET_2]);
+
+ proxPacket[APACKET_3].StateMachineNo = STATE_MACHINE_0;
+ proxPacket[APACKET_3].ActionTag = TXRX ;
+ proxPacket[APACKET_3].WakeupTime = proxWakeup;
+ proxPacket[APACKET_3].ReceiveWindowLength = 0 ; /* does not affect for Tx */
+ proxPacket[APACKET_3].data = proxtxBuffer;
+ proxPacket[APACKET_3].next_true = APACKET_4; // Ack
+ proxPacket[APACKET_3].next_false = APACKET_NULL;
+ proxPacket[APACKET_3].condRoutine = condCase_Done;
+ proxPacket[APACKET_3].dataRoutine = dataRoutine_Action;
+ proxPacket[APACKET_3].actionPacketNb = APACKET_3;
+ LLD_BLE_SetReservedArea(&proxPacket[APACKET_3]);
+
+ proxPacket[APACKET_4].StateMachineNo = STATE_MACHINE_3; // RX Ack State Machine of ACK
+ proxPacket[APACKET_4].ActionTag = 0;
+ proxPacket[APACKET_4].WakeupTime = proxWakeup;
+ proxPacket[APACKET_4].ReceiveWindowLength = proxReceiveAck;
+ proxPacket[APACKET_4].data = proxAckrxBuffer;
+ proxPacket[APACKET_4].next_true = APACKET_1; // Ack
+ proxPacket[APACKET_4].next_false = APACKET_0;
+ proxPacket[APACKET_4].condRoutine = condCase_Rx;
+ proxPacket[APACKET_4].dataRoutine = dataRoutineDone_hal_BLE;
+ proxPacket[APACKET_4].actionPacketNb = APACKET_4;
+ LLD_BLE_SetReservedArea(&proxPacket[APACKET_4]);
+
+ APP_LLD_BLE_SetdataRoutineOption(proxPacketNumber,proxPacketStopRx);
+ #ifdef LLD_BLE_DEBUG
+ start_timer=Debug_Start_timer();
+ #endif
+ LLD_BLE_MakeActionPacketPending(&proxPacket[APACKET_0]);
+ #ifdef LLD_BLE_DEBUG
+ stop_timer=Debug_Stop_timer();
+ #endif
+ BSP_LED_On(LED_TXRX);
+
+}
+
+void BUTTON_SW3_StopPacket(void)
+{
+ LED_TXRX=LED_GREEN;
+ //LLD_BLE_StopActivity();
+ proxPacket[APACKET_1].next_true = APACKET_NULL;
+ proxPacket[APACKET_3].next_true = APACKET_NULL;
+ LLD_BLE_SetReservedArea(&proxPacket[APACKET_1]);
+ LLD_BLE_SetReservedArea(&proxPacket[APACKET_3]);
+
+ BSP_LED_Off(LED_TXRX);
+}
+
+void m4CmdPacketStacking(void) // CFG_TASK_CMD_M4_PACKET_STACKING
+{
+ uint8_t i=0;
+ for (i=0 ; i<8 ; i++) // parsed all the actionPacket and keep packet with data not empty
+ {
+ if ((proxPacket[i].status & BIT_TX_MODE)==0 && (proxPacket[i].status & IRQ_RCV_OK)!=0)
+ {
+ if( ((proxPacket[i].rssi)+80) > 0)
+ {
+ // SEMA start
+ memcpy(Packet_Ptr[Stack_Packet++],proxPacket[i].data,26);
+ proxPacket[i].status=0;
+ // SEMA end
+ }
+ } else if ((proxPacket[i].status & BIT_TX_MODE)!=0) {
+ proxPacket[i].WakeupTime = (proxPacket[i].WakeupTime == proxWakeup)? ((__HAL_TIM_GET_COUNTER(&htim2)%3)*proxReceive+proxReceive): proxWakeup;
+ //LLD_BLE_SetReservedArea(&proxPacket[i]);
+ proxPacket[i].status=0;
+ }
+ }
+ //UTIL_SEQ_PauseTask(CFG_TASK_CMD_M4_PACKET_STACKING);
+ UTIL_SEQ_ResumeTask(1U <<CFG_TASK_CMD_M4_PACKET_STACK_PROCESS);
+ UTIL_SEQ_SetTask(1U <<CFG_TASK_CMD_M4_PACKET_STACK_PROCESS , CFG_SCH_PRIO_0);
+
+
+}
+
+void m4CmdPacketStackProcess(void) // CFG_TASK_CMD_M4_PACKET_STACK_PROCESS
+{
+ uint8_t i=0, j=0;
+ if(init_ID++==0) memcpy(Local_ID,(uint8_t*)proxSTDEVICEUDN,24); // init [0] with local ID
+
+ if (Stack_Packet>0)
+ {
+ if (Recorded_ID<8) /* write max of 8 ID*/
+ {
+ for (j=0 ; j<24; j++)
+ {
+ Packet_ID[Recorded_ID][j]=Packet_Ptr[Stack_Packet-1][j+2] ; // Record ID from Stack_Packet
+ }
+ Stack_Packet--;
+ if (Recorded_ID==0)
+ {
+ Recorded_ID++; // no compare We keep first
+ } else {
+ uint8_t comp_ID = 0 ;
+ for (i=0 ; i<Recorded_ID; i++) /* compare */
+ {
+ comp_ID = 0 ;
+ for (j=0 ; j<24; j++)
+ {
+ if (Packet_ID[i][j]==Packet_ID[Recorded_ID][j])
+ {
+ comp_ID++ ;
+ continue; // continue to compare
+ } else {
+ break; // go to next comparison as it is different
+ }
+ }
+ if (comp_ID==24) break; // We already have this ID as all the 24 bytes are similar
+ }
+ if (comp_ID!=24)
+ {
+ Recorded_ID++; // We do not removed we keep this ID
+ }
+ }
+ }
+ UTIL_SEQ_SetTask(1U <<CFG_TASK_CMD_M4_PACKET_STACK_PROCESS , CFG_SCH_PRIO_0);
+ }
+}
+/* USER CODE END FD */
+
+/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
+void Appli_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+ switch (GPIO_Pin)
+ {
+ case BUTTON_SW1_PIN:
+ UTIL_SEQ_SetTask(1U << CFG_TASK_HAL_BLE_INIT, CFG_SCH_PRIO_0);
+ break;
+
+ case BUTTON_SW2_PIN:
+ UTIL_SEQ_SetTask(1U << CFG_TASK_HAL_BLE_SENDPACKET, CFG_SCH_PRIO_0);
+ break;
+
+ case BUTTON_SW3_PIN:
+ UTIL_SEQ_SetTask(1U << CFG_TASK_HAL_BLE_RECEIVEPACKET, CFG_SCH_PRIO_0);
+ break;
+
+ default:
+ break;
+
+ }
+ return;
+}
+void Appli_TIM_IC_CaptureCallback(void)
+{
+}
+
+void Appli_TIM_PeriodElapsedCallback(void)
+{
+}
+/* USER CODE END FD_WRAP_FUNCTIONS */
+
+/* debug */
+uint32_t Debug_Start_timer(void)
+{
+ debug_timer[0]=__HAL_TIM_GET_COUNTER(&htim2);
+ if(!debug_timer[2])
+ {
+ return 0;
+ } else
+ {
+ return(debug_timer[0]-debug_timer[2]);
+ }
+}
+uint32_t Debug_Stop_timer(void)
+{
+ debug_timer[1]=__HAL_TIM_GET_COUNTER(&htim2);
+ return(debug_timer[1]-debug_timer[0]);
+}
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \ No newline at end of file