Trinity Devboard PCB V1.0 Firmware. FreeRTOS is setup and the MCU reads IMU data over SPI fand Magnetometer data over I2C, each with a seperate task. Sensordata is then run though MadgwickAHRS and send over USB as serial packet data to use in trinity visualizer. Bare minimum functionality works and is replicated from the first prototype.
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hci_tl.c
|
||||
* @author MCD Application Team
|
||||
* @brief Function for managing HCI interface.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "ble_common.h"
|
||||
#include "ble_const.h"
|
||||
|
||||
#include "stm_list.h"
|
||||
#include "tl.h"
|
||||
#include "hci_tl.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
HCI_TL_CMD_RESP_RELEASE,
|
||||
HCI_TL_CMD_RESP_WAIT,
|
||||
} HCI_TL_CmdRespStatus_t;
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* The default HCI layer timeout is set to 33s
|
||||
*/
|
||||
#define HCI_TL_DEFAULT_TIMEOUT (33000)
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Public variables ---------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/**
|
||||
* START of Section BLE_DRIVER_CONTEXT
|
||||
*/
|
||||
PLACE_IN_SECTION("BLE_DRIVER_CONTEXT") static volatile uint8_t hci_timer_id;
|
||||
PLACE_IN_SECTION("BLE_DRIVER_CONTEXT") static tListNode HciAsynchEventQueue;
|
||||
PLACE_IN_SECTION("BLE_DRIVER_CONTEXT") static TL_CmdPacket_t *pCmdBuffer;
|
||||
PLACE_IN_SECTION("BLE_DRIVER_CONTEXT") HCI_TL_UserEventFlowStatus_t UserEventFlow;
|
||||
/**
|
||||
* END of Section BLE_DRIVER_CONTEXT
|
||||
*/
|
||||
|
||||
static tHciContext hciContext;
|
||||
static tListNode HciCmdEventQueue;
|
||||
static void (* StatusNotCallBackFunction) (HCI_TL_CmdStatus_t status);
|
||||
static volatile HCI_TL_CmdRespStatus_t CmdRspStatusFlag;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void NotifyCmdStatus(HCI_TL_CmdStatus_t hcicmdstatus);
|
||||
static void SendCmd(uint16_t opcode, uint8_t plen, void *param);
|
||||
static void TlEvtReceived(TL_EvtPacket_t *hcievt);
|
||||
static void TlInit( TL_CmdPacket_t * p_cmdbuffer );
|
||||
|
||||
/* Interface ------- ---------------------------------------------------------*/
|
||||
void hci_init(void(* UserEvtRx)(void* pData), void* pConf)
|
||||
{
|
||||
StatusNotCallBackFunction = ((HCI_TL_HciInitConf_t *)pConf)->StatusNotCallBack;
|
||||
hciContext.UserEvtRx = UserEvtRx;
|
||||
|
||||
hci_register_io_bus (&hciContext.io);
|
||||
|
||||
TlInit((TL_CmdPacket_t *)(((HCI_TL_HciInitConf_t *)pConf)->p_cmdbuffer));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void hci_user_evt_proc(void)
|
||||
{
|
||||
TL_EvtPacket_t *phcievtbuffer;
|
||||
tHCI_UserEvtRxParam UserEvtRxParam;
|
||||
|
||||
/**
|
||||
* Up to release version v1.2.0, a while loop was implemented to read out events from the queue as long as
|
||||
* it is not empty. However, in a bare metal implementation, this leads to calling in a "blocking" mode
|
||||
* hci_user_evt_proc() as long as events are received without giving the opportunity to run other tasks
|
||||
* in the background.
|
||||
* From now, the events are reported one by one. When it is checked there is still an event pending in the queue,
|
||||
* a request to the user is made to call again hci_user_evt_proc().
|
||||
* This gives the opportunity to the application to run other background tasks between each event.
|
||||
*/
|
||||
|
||||
/**
|
||||
* It is more secure to use LST_remove_head()/LST_insert_head() compare to LST_get_next_node()/LST_remove_node()
|
||||
* in case the user overwrite the header where the next/prev pointers are located
|
||||
*/
|
||||
|
||||
if((LST_is_empty(&HciAsynchEventQueue) == FALSE) && (UserEventFlow != HCI_TL_UserEventFlow_Disable))
|
||||
{
|
||||
LST_remove_head ( &HciAsynchEventQueue, (tListNode **)&phcievtbuffer );
|
||||
|
||||
if (hciContext.UserEvtRx != NULL)
|
||||
{
|
||||
UserEvtRxParam.pckt = phcievtbuffer;
|
||||
UserEvtRxParam.status = HCI_TL_UserEventFlow_Enable;
|
||||
hciContext.UserEvtRx((void *)&UserEvtRxParam);
|
||||
UserEventFlow = UserEvtRxParam.status;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserEventFlow = HCI_TL_UserEventFlow_Enable;
|
||||
}
|
||||
|
||||
if(UserEventFlow != HCI_TL_UserEventFlow_Disable)
|
||||
{
|
||||
TL_MM_EvtDone( phcievtbuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* put back the event in the queue
|
||||
*/
|
||||
LST_insert_head ( &HciAsynchEventQueue, (tListNode *)phcievtbuffer );
|
||||
}
|
||||
}
|
||||
|
||||
if((LST_is_empty(&HciAsynchEventQueue) == FALSE) && (UserEventFlow != HCI_TL_UserEventFlow_Disable))
|
||||
{
|
||||
hci_notify_asynch_evt((void*) &HciAsynchEventQueue);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void hci_resume_flow( void )
|
||||
{
|
||||
UserEventFlow = HCI_TL_UserEventFlow_Enable;
|
||||
|
||||
/**
|
||||
* It is better to go through the background process as it is not sure from which context this API may
|
||||
* be called
|
||||
*/
|
||||
hci_notify_asynch_evt((void*) &HciAsynchEventQueue);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int hci_send_req(struct hci_request *p_cmd, uint8_t async)
|
||||
{
|
||||
(void)(async);
|
||||
uint16_t opcode;
|
||||
TL_CcEvt_t *pcommand_complete_event;
|
||||
TL_CsEvt_t *pcommand_status_event;
|
||||
TL_EvtPacket_t *pevtpacket;
|
||||
uint8_t hci_cmd_complete_return_parameters_length;
|
||||
HCI_TL_CmdStatus_t local_cmd_status;
|
||||
|
||||
NotifyCmdStatus(HCI_TL_CmdBusy);
|
||||
local_cmd_status = HCI_TL_CmdBusy;
|
||||
opcode = ((p_cmd->ocf) & 0x03ff) | ((p_cmd->ogf) << 10);
|
||||
|
||||
CmdRspStatusFlag = HCI_TL_CMD_RESP_WAIT;
|
||||
SendCmd(opcode, p_cmd->clen, p_cmd->cparam);
|
||||
|
||||
while(local_cmd_status == HCI_TL_CmdBusy)
|
||||
{
|
||||
hci_cmd_resp_wait(HCI_TL_DEFAULT_TIMEOUT);
|
||||
|
||||
/**
|
||||
* Process Cmd Event
|
||||
*/
|
||||
while(LST_is_empty(&HciCmdEventQueue) == FALSE)
|
||||
{
|
||||
LST_remove_head (&HciCmdEventQueue, (tListNode **)&pevtpacket);
|
||||
|
||||
if(pevtpacket->evtserial.evt.evtcode == TL_BLEEVT_CS_OPCODE)
|
||||
{
|
||||
pcommand_status_event = (TL_CsEvt_t*)pevtpacket->evtserial.evt.payload;
|
||||
if(pcommand_status_event->cmdcode == opcode)
|
||||
{
|
||||
*(uint8_t *)(p_cmd->rparam) = pcommand_status_event->status;
|
||||
}
|
||||
|
||||
if(pcommand_status_event->numcmd != 0)
|
||||
{
|
||||
local_cmd_status = HCI_TL_CmdAvailable;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pcommand_complete_event = (TL_CcEvt_t*)pevtpacket->evtserial.evt.payload;
|
||||
|
||||
if(pcommand_complete_event->cmdcode == opcode)
|
||||
{
|
||||
hci_cmd_complete_return_parameters_length = pevtpacket->evtserial.evt.plen - TL_EVT_HDR_SIZE;
|
||||
p_cmd->rlen = MIN(hci_cmd_complete_return_parameters_length, p_cmd->rlen);
|
||||
memcpy(p_cmd->rparam, pcommand_complete_event->payload, p_cmd->rlen);
|
||||
}
|
||||
|
||||
if(pcommand_complete_event->numcmd != 0)
|
||||
{
|
||||
local_cmd_status = HCI_TL_CmdAvailable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotifyCmdStatus(HCI_TL_CmdAvailable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
static void TlInit( TL_CmdPacket_t * p_cmdbuffer )
|
||||
{
|
||||
TL_BLE_InitConf_t Conf;
|
||||
|
||||
/**
|
||||
* Always initialize the command event queue
|
||||
*/
|
||||
LST_init_head (&HciCmdEventQueue);
|
||||
|
||||
pCmdBuffer = p_cmdbuffer;
|
||||
|
||||
LST_init_head (&HciAsynchEventQueue);
|
||||
|
||||
UserEventFlow = HCI_TL_UserEventFlow_Enable;
|
||||
|
||||
/* Initialize low level driver */
|
||||
if (hciContext.io.Init)
|
||||
{
|
||||
|
||||
Conf.p_cmdbuffer = (uint8_t *)p_cmdbuffer;
|
||||
Conf.IoBusEvtCallBack = TlEvtReceived;
|
||||
hciContext.io.Init(&Conf);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void SendCmd(uint16_t opcode, uint8_t plen, void *param)
|
||||
{
|
||||
pCmdBuffer->cmdserial.cmd.cmdcode = opcode;
|
||||
pCmdBuffer->cmdserial.cmd.plen = plen;
|
||||
memcpy( pCmdBuffer->cmdserial.cmd.payload, param, plen );
|
||||
|
||||
hciContext.io.Send(0,0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void NotifyCmdStatus(HCI_TL_CmdStatus_t hcicmdstatus)
|
||||
{
|
||||
if(hcicmdstatus == HCI_TL_CmdBusy)
|
||||
{
|
||||
if(StatusNotCallBackFunction != 0)
|
||||
{
|
||||
StatusNotCallBackFunction(HCI_TL_CmdBusy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(StatusNotCallBackFunction != 0)
|
||||
{
|
||||
StatusNotCallBackFunction(HCI_TL_CmdAvailable);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void TlEvtReceived(TL_EvtPacket_t *hcievt)
|
||||
{
|
||||
if ( ((hcievt->evtserial.evt.evtcode) == TL_BLEEVT_CS_OPCODE) || ((hcievt->evtserial.evt.evtcode) == TL_BLEEVT_CC_OPCODE ) )
|
||||
{
|
||||
LST_insert_tail(&HciCmdEventQueue, (tListNode *)hcievt);
|
||||
hci_cmd_resp_release(0); /**< Notify the application a full Cmd Event has been received */
|
||||
}
|
||||
else
|
||||
{
|
||||
LST_insert_tail(&HciAsynchEventQueue, (tListNode *)hcievt);
|
||||
hci_notify_asynch_evt((void*) &HciAsynchEventQueue); /**< Notify the application a full HCI event has been received */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Weak implementation ----------------------------------------------------------------*/
|
||||
__WEAK void hci_cmd_resp_wait(uint32_t timeout)
|
||||
{
|
||||
(void)timeout;
|
||||
|
||||
while(CmdRspStatusFlag != HCI_TL_CMD_RESP_RELEASE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__WEAK void hci_cmd_resp_release(uint32_t flag)
|
||||
{
|
||||
(void)flag;
|
||||
|
||||
CmdRspStatusFlag = HCI_TL_CMD_RESP_RELEASE;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hci_tl.h
|
||||
* @author MCD Application Team
|
||||
* @brief Constants and functions for HCI layer. See Bluetooth Core
|
||||
* v 4.0, Vol. 2, Part E.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __HCI_TL_H_
|
||||
#define __HCI_TL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32_wpan_common.h"
|
||||
#include "tl.h"
|
||||
|
||||
/* Exported defines -----------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
HCI_TL_UserEventFlow_Disable,
|
||||
HCI_TL_UserEventFlow_Enable,
|
||||
} HCI_TL_UserEventFlowStatus_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HCI_TL_CmdBusy,
|
||||
HCI_TL_CmdAvailable
|
||||
} HCI_TL_CmdStatus_t;
|
||||
|
||||
/**
|
||||
* @brief Structure used to manage the BUS IO operations.
|
||||
* All the structure fields will point to functions defined at user level.
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int32_t (* Init) (void* pConf); /**< Pointer to HCI TL function for the IO Bus initialization */
|
||||
int32_t (* DeInit) (void); /**< Pointer to HCI TL function for the IO Bus de-initialization */
|
||||
int32_t (* Reset) (void); /**< Pointer to HCI TL function for the IO Bus reset */
|
||||
int32_t (* Receive) (uint8_t*, uint16_t); /**< Pointer to HCI TL function for the IO Bus data reception */
|
||||
int32_t (* Send) (uint8_t*, uint16_t); /**< Pointer to HCI TL function for the IO Bus data transmission */
|
||||
int32_t (* DataAck) (uint8_t*, uint16_t* len); /**< Pointer to HCI TL function for the IO Bus data ack reception */
|
||||
int32_t (* GetTick) (void); /**< Pointer to BSP function for getting the HAL time base timestamp */
|
||||
} tHciIO;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Contain the HCI context
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
tHciIO io; /**< Manage the BUS IO operations */
|
||||
void (* UserEvtRx) (void * pData); /**< ACI events callback function pointer */
|
||||
} tHciContext;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HCI_TL_UserEventFlowStatus_t status;
|
||||
TL_EvtPacket_t *pckt;
|
||||
} tHCI_UserEvtRxParam;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_cmdbuffer;
|
||||
void (* StatusNotCallBack) (HCI_TL_CmdStatus_t status);
|
||||
} HCI_TL_HciInitConf_t;
|
||||
|
||||
/**
|
||||
* @brief Register IO bus services.
|
||||
* @param fops The HCI IO structure managing the IO BUS
|
||||
* @retval None
|
||||
*/
|
||||
void hci_register_io_bus(tHciIO* fops);
|
||||
|
||||
/**
|
||||
* @brief This callback is called from either
|
||||
* - IPCC RX interrupt context
|
||||
* - hci_user_evt_proc() context.
|
||||
* - hci_resume_flow() context
|
||||
* It requests hci_user_evt_proc() to be executed.
|
||||
*
|
||||
* @param pdata Packet or event pointer
|
||||
* @retval None
|
||||
*/
|
||||
void hci_notify_asynch_evt(void* pdata);
|
||||
|
||||
/**
|
||||
* @brief This function resume the User Event Flow which has been stopped on return
|
||||
* from UserEvtRx() when the User Event has not been processed.
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void hci_resume_flow(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called when an ACI/HCI command is sent to the CPU2 and the response is waited.
|
||||
* It is called from the same context the HCI command has been sent.
|
||||
* It shall not return until the command response notified by hci_cmd_resp_release() is received.
|
||||
* A weak implementation is available in hci_tl.c based on polling mechanism
|
||||
* The user may re-implement this function in the application to improve performance :
|
||||
* - It may use UTIL_SEQ_WaitEvt() API when using the Sequencer
|
||||
* - It may use a semaphore when using cmsis_os interface
|
||||
*
|
||||
* @param timeout: Waiting timeout
|
||||
* @retval None
|
||||
*/
|
||||
void hci_cmd_resp_wait(uint32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief This function is called when an ACI/HCI command response is received from the CPU2.
|
||||
* A weak implementation is available in hci_tl.c based on polling mechanism
|
||||
* The user may re-implement this function in the application to improve performance :
|
||||
* - It may use UTIL_SEQ_SetEvt() API when using the Sequencer
|
||||
* - It may use a semaphore when using cmsis_os interface
|
||||
*
|
||||
* @param flag: Release flag
|
||||
* @retval None
|
||||
*/
|
||||
void hci_cmd_resp_release(uint32_t flag);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* END OF SECTION - FUNCTIONS TO BE IMPLEMENTED BY THE APPLICATION
|
||||
*********************************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*********************************************************************************************************************
|
||||
* START OF SECTION - PROCESS TO BE CALLED BY THE SCHEDULER
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This process shall be called by the scheduler each time it is requested with hci_notify_asynch_evt()
|
||||
* This process may send an ACI/HCI command when the svc_ctl.c module is used
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void hci_user_evt_proc(void);
|
||||
|
||||
/**
|
||||
* END OF SECTION - PROCESS TO BE CALLED BY THE SCHEDULER
|
||||
*********************************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*********************************************************************************************************************
|
||||
* START OF SECTION - INTERFACES USED BY THE BLE DRIVER
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the Host Controller Interface.
|
||||
* This function must be called before any data can be received
|
||||
* from BLE controller.
|
||||
*
|
||||
* @param pData: ACI events callback function pointer
|
||||
* This callback is triggered when an user event is received from
|
||||
* the BLE core device.
|
||||
* @param pConf: Configuration structure pointer
|
||||
* @retval None
|
||||
*/
|
||||
void hci_init(void(* UserEvtRx)(void* pData), void* pConf);
|
||||
|
||||
/**
|
||||
* END OF SECTION - INTERFACES USED BY THE BLE DRIVER
|
||||
*********************************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TL_BLE_HCI_H_ */
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hci_tl_if.c
|
||||
* @author MCD Application Team
|
||||
* @brief Transport layer interface to BLE
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "hci_tl.h"
|
||||
#include "tl.h"
|
||||
|
||||
|
||||
void hci_register_io_bus(tHciIO* fops)
|
||||
{
|
||||
/* Register IO bus services */
|
||||
fops->Init = TL_BLE_Init;
|
||||
fops->Send = TL_BLE_SendCmd;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file mbox_def.h
|
||||
* @author MCD Application Team
|
||||
* @brief Mailbox definition
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MBOX_H
|
||||
#define __MBOX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32_wpan_common.h"
|
||||
|
||||
/**
|
||||
* This file shall be identical between the CPU1 and the CPU2
|
||||
*/
|
||||
|
||||
/**
|
||||
*********************************************************************************
|
||||
* TABLES
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Version
|
||||
* [0:3] = Build - 0: Untracked - 15:Released - x: Tracked version
|
||||
* [4:7] = branch - 0: Mass Market - x: ...
|
||||
* [8:15] = Subversion
|
||||
* [16:23] = Version minor
|
||||
* [24:31] = Version major
|
||||
*
|
||||
* Memory Size
|
||||
* [0:7] = Flash ( Number of 4k sector)
|
||||
* [8:15] = Reserved ( Shall be set to 0 - may be used as flash extension )
|
||||
* [16:23] = SRAM2b ( Number of 1k sector)
|
||||
* [24:31] = SRAM2a ( Number of 1k sector)
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint32_t Version;
|
||||
} MB_SafeBootInfoTable_t;
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint32_t Version;
|
||||
uint32_t MemorySize;
|
||||
uint32_t FusInfo;
|
||||
} MB_FusInfoTable_t;
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint32_t Version;
|
||||
uint32_t MemorySize;
|
||||
uint32_t InfoStack;
|
||||
uint32_t Reserved;
|
||||
} MB_WirelessFwInfoTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MB_SafeBootInfoTable_t SafeBootInfoTable;
|
||||
MB_FusInfoTable_t FusInfoTable;
|
||||
MB_WirelessFwInfoTable_t WirelessFwInfoTable;
|
||||
} MB_DeviceInfoTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *pcmd_buffer;
|
||||
uint8_t *pcs_buffer;
|
||||
uint8_t *pevt_queue;
|
||||
uint8_t *phci_acl_data_buffer;
|
||||
} MB_BleTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *notack_buffer;
|
||||
uint8_t *clicmdrsp_buffer;
|
||||
uint8_t *otcmdrsp_buffer;
|
||||
uint8_t *clinot_buffer;
|
||||
} MB_ThreadTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *clicmdrsp_buffer;
|
||||
uint8_t *m0cmd_buffer;
|
||||
} MB_LldTestsTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *cmdrsp_buffer;
|
||||
uint8_t *m0cmd_buffer;
|
||||
} MB_BleLldTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *notifM0toM4_buffer;
|
||||
uint8_t *appliCmdM4toM0_buffer;
|
||||
uint8_t *requestM0toM4_buffer;
|
||||
} MB_ZigbeeTable_t;
|
||||
/**
|
||||
* msg
|
||||
* [0:7] = cmd/evt
|
||||
* [8:31] = Reserved
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *pcmd_buffer;
|
||||
uint8_t *sys_queue;
|
||||
} MB_SysTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *spare_ble_buffer;
|
||||
uint8_t *spare_sys_buffer;
|
||||
uint8_t *blepool;
|
||||
uint32_t blepoolsize;
|
||||
uint8_t *pevt_free_buffer_queue;
|
||||
uint8_t *traces_evt_pool;
|
||||
uint32_t tracespoolsize;
|
||||
} MB_MemManagerTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *traces_queue;
|
||||
} MB_TracesTable_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_cmdrsp_buffer;
|
||||
uint8_t *p_notack_buffer;
|
||||
uint8_t *evt_queue;
|
||||
} MB_Mac_802_15_4_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MB_DeviceInfoTable_t *p_device_info_table;
|
||||
MB_BleTable_t *p_ble_table;
|
||||
MB_ThreadTable_t *p_thread_table;
|
||||
MB_SysTable_t *p_sys_table;
|
||||
MB_MemManagerTable_t *p_mem_manager_table;
|
||||
MB_TracesTable_t *p_traces_table;
|
||||
MB_Mac_802_15_4_t *p_mac_802_15_4_table;
|
||||
MB_ZigbeeTable_t *p_zigbee_table;
|
||||
MB_LldTestsTable_t *p_lld_tests_table;
|
||||
MB_BleLldTable_t *p_ble_lld_table;
|
||||
} MB_RefTable_t;
|
||||
|
||||
/**
|
||||
* This table shall be used only in the case the CPU2 runs the FUS.
|
||||
* It is used by the command SHCI_GetWirelessFwInfo()
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t DeviceInfoTableState;
|
||||
uint8_t Reserved1;
|
||||
uint8_t LastFusActiveState;
|
||||
uint8_t LastWirelessStackState;
|
||||
uint8_t CurrentWirelessStackType;
|
||||
uint32_t SafeBootVersion;
|
||||
uint32_t FusVersion;
|
||||
uint32_t FusMemorySize;
|
||||
uint32_t WirelessStackVersion;
|
||||
uint32_t WirelessStackMemorySize;
|
||||
uint32_t WirelessFirmwareBleInfo;
|
||||
uint32_t WirelessFirmwareThreadInfo;
|
||||
uint32_t Reserved2;
|
||||
uint64_t UID64;
|
||||
uint16_t DeviceId;
|
||||
} MB_FUS_DeviceInfoTable_t ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
*********************************************************************************
|
||||
* IPCC CHANNELS
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
/* CPU1 CPU2
|
||||
* | (SYSTEM) |
|
||||
* |----HW_IPCC_SYSTEM_CMD_RSP_CHANNEL-------------->|
|
||||
* | |
|
||||
* |<---HW_IPCC_SYSTEM_EVENT_CHANNEL-----------------|
|
||||
* | |
|
||||
* | (ZIGBEE) |
|
||||
* |----HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL------------>|
|
||||
* | |
|
||||
* |----HW_IPCC_ZIGBEE_CMD_CLI_CHANNEL-------------->|
|
||||
* | |
|
||||
* |<---HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL-------|
|
||||
* | |
|
||||
* |<---HW_IPCC_ZIGBEE_CLI_NOTIF_ACK_CHANNEL---------|
|
||||
* | |
|
||||
* | (THREAD) |
|
||||
* |----HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL----------->|
|
||||
* | |
|
||||
* |----HW_IPCC_THREAD_CLI_CMD_CHANNEL-------------->|
|
||||
* | |
|
||||
* |<---HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL------|
|
||||
* | |
|
||||
* |<---HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL--|
|
||||
* | |
|
||||
* | (BLE) |
|
||||
* |----HW_IPCC_BLE_CMD_CHANNEL--------------------->|
|
||||
* | |
|
||||
* |----HW_IPCC_HCI_ACL_DATA_CHANNEL---------------->|
|
||||
* | |
|
||||
* |<---HW_IPCC_BLE_EVENT_CHANNEL--------------------|
|
||||
* | |
|
||||
* | (BLE LLD) |
|
||||
* |----HW_IPCC_BLE_LLD_CMD_CHANNEL----------------->|
|
||||
* | |
|
||||
* |<---HW_IPCC_BLE_LLD_RSP_CHANNEL------------------|
|
||||
* | |
|
||||
* |<---HW_IPCC_BLE_LLD_M0_CMD_CHANNEL---------------|
|
||||
* | |
|
||||
* | (MAC) |
|
||||
* |----HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL-------->|
|
||||
* | |
|
||||
* |<---HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL|
|
||||
* | |
|
||||
* | (BUFFER) |
|
||||
* |----HW_IPCC_MM_RELEASE_BUFFER_CHANNE------------>|
|
||||
* | |
|
||||
* | (TRACE) |
|
||||
* |<----HW_IPCC_TRACES_CHANNEL----------------------|
|
||||
* | |
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** CPU1 */
|
||||
#define HW_IPCC_BLE_CMD_CHANNEL LL_IPCC_CHANNEL_1
|
||||
#define HW_IPCC_SYSTEM_CMD_RSP_CHANNEL LL_IPCC_CHANNEL_2
|
||||
#define HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL LL_IPCC_CHANNEL_3
|
||||
#define HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL LL_IPCC_CHANNEL_3
|
||||
#define HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL LL_IPCC_CHANNEL_3
|
||||
#define HW_IPCC_MM_RELEASE_BUFFER_CHANNEL LL_IPCC_CHANNEL_4
|
||||
#define HW_IPCC_THREAD_CLI_CMD_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#define HW_IPCC_LLDTESTS_CLI_CMD_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#define HW_IPCC_BLE_LLD_CLI_CMD_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#define HW_IPCC_BLE_LLD_CMD_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#define HW_IPCC_HCI_ACL_DATA_CHANNEL LL_IPCC_CHANNEL_6
|
||||
|
||||
/** CPU2 */
|
||||
#define HW_IPCC_BLE_EVENT_CHANNEL LL_IPCC_CHANNEL_1
|
||||
#define HW_IPCC_SYSTEM_EVENT_CHANNEL LL_IPCC_CHANNEL_2
|
||||
#define HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL LL_IPCC_CHANNEL_3
|
||||
#define HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL LL_IPCC_CHANNEL_3
|
||||
#define HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL LL_IPCC_CHANNEL_3
|
||||
#define HW_IPCC_LLDTESTS_M0_CMD_CHANNEL LL_IPCC_CHANNEL_3
|
||||
#define HW_IPCC_BLE_LLD_M0_CMD_CHANNEL LL_IPCC_CHANNEL_3
|
||||
#define HW_IPCC_TRACES_CHANNEL LL_IPCC_CHANNEL_4
|
||||
#define HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#define HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#define HW_IPCC_BLE_LLD_CLI_RSP_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#define HW_IPCC_BLE_LLD_RSP_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#define HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL LL_IPCC_CHANNEL_5
|
||||
#endif /*__MBOX_H */
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file shci.c
|
||||
* @author MCD Application Team
|
||||
* @brief System HCI command implementation
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32_wpan_common.h"
|
||||
|
||||
#include "stm_list.h"
|
||||
#include "shci_tl.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
SHCI_TL_CMD_RESP_RELEASE,
|
||||
SHCI_TL_CMD_RESP_WAIT,
|
||||
} SHCI_TL_CmdRespStatus_t;
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/**
|
||||
* The default System HCI layer timeout is set to 33s
|
||||
*/
|
||||
#define SHCI_TL_DEFAULT_TIMEOUT (33000)
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Public variables ---------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/**
|
||||
* START of Section SYSTEM_DRIVER_CONTEXT
|
||||
*/
|
||||
PLACE_IN_SECTION("SYSTEM_DRIVER_CONTEXT") static tListNode SHciAsynchEventQueue;
|
||||
PLACE_IN_SECTION("SYSTEM_DRIVER_CONTEXT") static volatile SHCI_TL_CmdStatus_t SHCICmdStatus;
|
||||
PLACE_IN_SECTION("SYSTEM_DRIVER_CONTEXT") static TL_CmdPacket_t *pCmdBuffer;
|
||||
PLACE_IN_SECTION("SYSTEM_DRIVER_CONTEXT") SHCI_TL_UserEventFlowStatus_t SHCI_TL_UserEventFlow;
|
||||
/**
|
||||
* END of Section SYSTEM_DRIVER_CONTEXT
|
||||
*/
|
||||
|
||||
static tSHciContext shciContext;
|
||||
static void (* StatusNotCallBackFunction) (SHCI_TL_CmdStatus_t status);
|
||||
|
||||
static volatile SHCI_TL_CmdRespStatus_t CmdRspStatusFlag;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void Cmd_SetStatus(SHCI_TL_CmdStatus_t shcicmdstatus);
|
||||
static void TlCmdEvtReceived(TL_EvtPacket_t *shcievt);
|
||||
static void TlUserEvtReceived(TL_EvtPacket_t *shcievt);
|
||||
static void TlInit( TL_CmdPacket_t * p_cmdbuffer );
|
||||
|
||||
/* Interface ------- ---------------------------------------------------------*/
|
||||
void shci_init(void(* UserEvtRx)(void* pData), void* pConf)
|
||||
{
|
||||
StatusNotCallBackFunction = ((SHCI_TL_HciInitConf_t *)pConf)->StatusNotCallBack;
|
||||
shciContext.UserEvtRx = UserEvtRx;
|
||||
|
||||
shci_register_io_bus (&shciContext.io);
|
||||
|
||||
TlInit((TL_CmdPacket_t *)(((SHCI_TL_HciInitConf_t *)pConf)->p_cmdbuffer));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void shci_user_evt_proc(void)
|
||||
{
|
||||
TL_EvtPacket_t *phcievtbuffer;
|
||||
tSHCI_UserEvtRxParam UserEvtRxParam;
|
||||
|
||||
/**
|
||||
* Up to release version v1.2.0, a while loop was implemented to read out events from the queue as long as
|
||||
* it is not empty. However, in a bare metal implementation, this leads to calling in a "blocking" mode
|
||||
* shci_user_evt_proc() as long as events are received without giving the opportunity to run other tasks
|
||||
* in the background.
|
||||
* From now, the events are reported one by one. When it is checked there is still an event pending in the queue,
|
||||
* a request to the user is made to call again shci_user_evt_proc().
|
||||
* This gives the opportunity to the application to run other background tasks between each event.
|
||||
*/
|
||||
|
||||
/**
|
||||
* It is more secure to use LST_remove_head()/LST_insert_head() compare to LST_get_next_node()/LST_remove_node()
|
||||
* in case the user overwrite the header where the next/prev pointers are located
|
||||
*/
|
||||
if((LST_is_empty(&SHciAsynchEventQueue) == FALSE) && (SHCI_TL_UserEventFlow != SHCI_TL_UserEventFlow_Disable))
|
||||
{
|
||||
LST_remove_head ( &SHciAsynchEventQueue, (tListNode **)&phcievtbuffer );
|
||||
|
||||
if (shciContext.UserEvtRx != NULL)
|
||||
{
|
||||
UserEvtRxParam.pckt = phcievtbuffer;
|
||||
UserEvtRxParam.status = SHCI_TL_UserEventFlow_Enable;
|
||||
shciContext.UserEvtRx((void *)&UserEvtRxParam);
|
||||
SHCI_TL_UserEventFlow = UserEvtRxParam.status;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHCI_TL_UserEventFlow = SHCI_TL_UserEventFlow_Enable;
|
||||
}
|
||||
|
||||
if(SHCI_TL_UserEventFlow != SHCI_TL_UserEventFlow_Disable)
|
||||
{
|
||||
TL_MM_EvtDone( phcievtbuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* put back the event in the queue
|
||||
*/
|
||||
LST_insert_head ( &SHciAsynchEventQueue, (tListNode *)phcievtbuffer );
|
||||
}
|
||||
}
|
||||
|
||||
if((LST_is_empty(&SHciAsynchEventQueue) == FALSE) && (SHCI_TL_UserEventFlow != SHCI_TL_UserEventFlow_Disable))
|
||||
{
|
||||
shci_notify_asynch_evt((void*) &SHciAsynchEventQueue);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void shci_resume_flow( void )
|
||||
{
|
||||
SHCI_TL_UserEventFlow = SHCI_TL_UserEventFlow_Enable;
|
||||
|
||||
/**
|
||||
* It is better to go through the background process as it is not sure from which context this API may
|
||||
* be called
|
||||
*/
|
||||
shci_notify_asynch_evt((void*) &SHciAsynchEventQueue);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void shci_send( uint16_t cmd_code, uint8_t len_cmd_payload, uint8_t * p_cmd_payload, TL_EvtPacket_t * p_rsp )
|
||||
{
|
||||
Cmd_SetStatus(SHCI_TL_CmdBusy);
|
||||
|
||||
pCmdBuffer->cmdserial.cmd.cmdcode = cmd_code;
|
||||
pCmdBuffer->cmdserial.cmd.plen = len_cmd_payload;
|
||||
|
||||
memcpy(pCmdBuffer->cmdserial.cmd.payload, p_cmd_payload, len_cmd_payload );
|
||||
CmdRspStatusFlag = SHCI_TL_CMD_RESP_WAIT;
|
||||
shciContext.io.Send(0,0);
|
||||
|
||||
shci_cmd_resp_wait(SHCI_TL_DEFAULT_TIMEOUT);
|
||||
|
||||
/**
|
||||
* The command complete of a system command does not have the header
|
||||
* It starts immediately with the evtserial field
|
||||
*/
|
||||
memcpy( &(p_rsp->evtserial), pCmdBuffer, ((TL_EvtSerial_t*)pCmdBuffer)->evt.plen + TL_EVT_HDR_SIZE );
|
||||
|
||||
Cmd_SetStatus(SHCI_TL_CmdAvailable);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
static void TlInit( TL_CmdPacket_t * p_cmdbuffer )
|
||||
{
|
||||
TL_SYS_InitConf_t Conf;
|
||||
|
||||
pCmdBuffer = p_cmdbuffer;
|
||||
|
||||
LST_init_head (&SHciAsynchEventQueue);
|
||||
|
||||
Cmd_SetStatus(SHCI_TL_CmdAvailable);
|
||||
|
||||
SHCI_TL_UserEventFlow = SHCI_TL_UserEventFlow_Enable;
|
||||
|
||||
/* Initialize low level driver */
|
||||
if (shciContext.io.Init)
|
||||
{
|
||||
|
||||
Conf.p_cmdbuffer = (uint8_t *)p_cmdbuffer;
|
||||
Conf.IoBusCallBackCmdEvt = TlCmdEvtReceived;
|
||||
Conf.IoBusCallBackUserEvt = TlUserEvtReceived;
|
||||
shciContext.io.Init(&Conf);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void Cmd_SetStatus(SHCI_TL_CmdStatus_t shcicmdstatus)
|
||||
{
|
||||
if(shcicmdstatus == SHCI_TL_CmdBusy)
|
||||
{
|
||||
if(StatusNotCallBackFunction != 0)
|
||||
{
|
||||
StatusNotCallBackFunction( SHCI_TL_CmdBusy );
|
||||
}
|
||||
SHCICmdStatus = SHCI_TL_CmdBusy;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHCICmdStatus = SHCI_TL_CmdAvailable;
|
||||
if(StatusNotCallBackFunction != 0)
|
||||
{
|
||||
StatusNotCallBackFunction( SHCI_TL_CmdAvailable );
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void TlCmdEvtReceived(TL_EvtPacket_t *shcievt)
|
||||
{
|
||||
(void)(shcievt);
|
||||
shci_cmd_resp_release(0); /**< Notify the application the Cmd response has been received */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void TlUserEvtReceived(TL_EvtPacket_t *shcievt)
|
||||
{
|
||||
LST_insert_tail(&SHciAsynchEventQueue, (tListNode *)shcievt);
|
||||
shci_notify_asynch_evt((void*) &SHciAsynchEventQueue); /**< Notify the application a full HCI event has been received */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Weak implementation ----------------------------------------------------------------*/
|
||||
__WEAK void shci_cmd_resp_wait(uint32_t timeout)
|
||||
{
|
||||
(void)timeout;
|
||||
|
||||
while(CmdRspStatusFlag != SHCI_TL_CMD_RESP_RELEASE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__WEAK void shci_cmd_resp_release(uint32_t flag)
|
||||
{
|
||||
(void)flag;
|
||||
|
||||
CmdRspStatusFlag = SHCI_TL_CMD_RESP_RELEASE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file shci_tl.h
|
||||
* @author MCD Application Team
|
||||
* @brief System HCI command header for the system channel
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __SHCI_TL_H_
|
||||
#define __SHCI_TL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tl.h"
|
||||
|
||||
/* Exported defines -----------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
SHCI_TL_UserEventFlow_Disable,
|
||||
SHCI_TL_UserEventFlow_Enable,
|
||||
} SHCI_TL_UserEventFlowStatus_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SHCI_TL_CmdBusy,
|
||||
SHCI_TL_CmdAvailable
|
||||
} SHCI_TL_CmdStatus_t;
|
||||
|
||||
/**
|
||||
* @brief Structure used to manage the BUS IO operations.
|
||||
* All the structure fields will point to functions defined at user level.
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int32_t (* Init) (void* pConf); /**< Pointer to SHCI TL function for the IO Bus initialization */
|
||||
int32_t (* DeInit) (void); /**< Pointer to SHCI TL function for the IO Bus de-initialization */
|
||||
int32_t (* Reset) (void); /**< Pointer to SHCI TL function for the IO Bus reset */
|
||||
int32_t (* Receive) (uint8_t*, uint16_t); /**< Pointer to SHCI TL function for the IO Bus data reception */
|
||||
int32_t (* Send) (uint8_t*, uint16_t); /**< Pointer to SHCI TL function for the IO Bus data transmission */
|
||||
int32_t (* DataAck) (uint8_t*, uint16_t* len); /**< Pointer to SHCI TL function for the IO Bus data ack reception */
|
||||
int32_t (* GetTick) (void); /**< Pointer to BSP function for getting the HAL time base timestamp */
|
||||
} tSHciIO;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Contain the SHCI context
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
tSHciIO io; /**< Manage the BUS IO operations */
|
||||
void (* UserEvtRx) (void * pData); /**< User System events callback function pointer */
|
||||
} tSHciContext;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SHCI_TL_UserEventFlowStatus_t status;
|
||||
TL_EvtPacket_t *pckt;
|
||||
} tSHCI_UserEvtRxParam;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_cmdbuffer;
|
||||
void (* StatusNotCallBack) (SHCI_TL_CmdStatus_t status);
|
||||
} SHCI_TL_HciInitConf_t;
|
||||
|
||||
/**
|
||||
* shci_send
|
||||
* @brief Send an System HCI Command
|
||||
*
|
||||
* @param : cmd_code = Opcode of the command
|
||||
* @param : len_cmd_payload = Length of the command payload
|
||||
* @param : p_cmd_payload = Address of the command payload
|
||||
* @param : p_rsp_status = Address of the full buffer holding the command complete event
|
||||
* @retval : None
|
||||
*/
|
||||
void shci_send( uint16_t cmd_code, uint8_t len_cmd_payload, uint8_t * p_cmd_payload, TL_EvtPacket_t * p_rsp_status );
|
||||
|
||||
/**
|
||||
* @brief Register IO bus services.
|
||||
* @param fops The SHCI IO structure managing the IO BUS
|
||||
* @retval None
|
||||
*/
|
||||
void shci_register_io_bus(tSHciIO* fops);
|
||||
|
||||
/**
|
||||
* @brief Interrupt service routine that must be called when the system channel
|
||||
* reports a packet has been received
|
||||
*
|
||||
* @param pdata Packet or event pointer
|
||||
* @retval None
|
||||
*/
|
||||
void shci_notify_asynch_evt(void* pdata);
|
||||
|
||||
/**
|
||||
* @brief This function resume the User Event Flow which has been stopped on return
|
||||
* from UserEvtRx() when the User Event has not been processed.
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void shci_resume_flow(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called when an System HCI Command is sent to the CPU2 and the response is waited.
|
||||
* It is called from the same context the System HCI command has been sent.
|
||||
* It shall not return until the command response notified by shci_cmd_resp_release() is received.
|
||||
* A weak implementation is available in shci_tl.c based on polling mechanism
|
||||
* The user may re-implement this function in the application to improve performance :
|
||||
* - It may use UTIL_SEQ_WaitEvt() API when using the Sequencer
|
||||
* - It may use a semaphore when using cmsis_os interface
|
||||
*
|
||||
* @param timeout: Waiting timeout
|
||||
* @retval None
|
||||
*/
|
||||
void shci_cmd_resp_wait(uint32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief This function is called when an System HCI command is received from the CPU2.
|
||||
* A weak implementation is available in shci_tl.c based on polling mechanism
|
||||
* The user may re-implement this function in the application to improve performance :
|
||||
* - It may use UTIL_SEQ_SetEvt() API when using the Sequencer
|
||||
* - It may use a semaphore when using cmsis_os interface
|
||||
*
|
||||
*
|
||||
* @param flag: Release flag
|
||||
* @retval None
|
||||
*/
|
||||
void shci_cmd_resp_release(uint32_t flag);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This process shall be called each time the shci_notify_asynch_evt notification is received
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void shci_user_evt_proc(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the System Host Controller Interface.
|
||||
* This function must be called before any communication on the System Channel
|
||||
*
|
||||
* @param UserEvtRx: System events callback function pointer
|
||||
* This callback is triggered when an user event is received on
|
||||
* the System Channel from CPU2.
|
||||
* @param pConf: Configuration structure pointer
|
||||
* @retval None
|
||||
*/
|
||||
void shci_init(void(* UserEvtRx)(void* pData), void* pConf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SHCI_TL_H_ */
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file shci_tl_if.c
|
||||
* @author MCD Application Team
|
||||
* @brief Transport layer interface to the system channel
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "shci_tl.h"
|
||||
#include "tl.h"
|
||||
|
||||
|
||||
void shci_register_io_bus(tSHciIO* fops)
|
||||
{
|
||||
/* Register IO bus services */
|
||||
fops->Init = TL_SYS_Init;
|
||||
fops->Send = TL_SYS_SendCmd;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tl.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for tl module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __TL_H
|
||||
#define __TL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32_wpan_common.h"
|
||||
|
||||
/* Exported defines -----------------------------------------------------------*/
|
||||
#define TL_BLECMD_PKT_TYPE ( 0x01 )
|
||||
#define TL_ACL_DATA_PKT_TYPE ( 0x02 )
|
||||
#define TL_BLEEVT_PKT_TYPE ( 0x04 )
|
||||
#define TL_OTCMD_PKT_TYPE ( 0x08 )
|
||||
#define TL_OTRSP_PKT_TYPE ( 0x09 )
|
||||
#define TL_CLICMD_PKT_TYPE ( 0x0A )
|
||||
#define TL_OTNOT_PKT_TYPE ( 0x0C )
|
||||
#define TL_OTACK_PKT_TYPE ( 0x0D )
|
||||
#define TL_CLINOT_PKT_TYPE ( 0x0E )
|
||||
#define TL_CLIACK_PKT_TYPE ( 0x0F )
|
||||
#define TL_SYSCMD_PKT_TYPE ( 0x10 )
|
||||
#define TL_SYSRSP_PKT_TYPE ( 0x11 )
|
||||
#define TL_SYSEVT_PKT_TYPE ( 0x12 )
|
||||
#define TL_CLIRESP_PKT_TYPE ( 0x15 )
|
||||
#define TL_M0CMD_PKT_TYPE ( 0x16 )
|
||||
#define TL_LOCCMD_PKT_TYPE ( 0x20 )
|
||||
#define TL_LOCRSP_PKT_TYPE ( 0x21 )
|
||||
#define TL_TRACES_APP_PKT_TYPE ( 0x40 )
|
||||
#define TL_TRACES_WL_PKT_TYPE ( 0x41 )
|
||||
|
||||
#define TL_CMD_HDR_SIZE (4)
|
||||
#define TL_EVT_HDR_SIZE (3)
|
||||
#define TL_EVT_CS_PAYLOAD_SIZE (4)
|
||||
|
||||
#define TL_BLEEVT_CC_OPCODE (0x0E)
|
||||
#define TL_BLEEVT_CS_OPCODE (0x0F)
|
||||
#define TL_BLEEVT_VS_OPCODE (0xFF)
|
||||
|
||||
#define TL_BLEEVT_CC_PACKET_SIZE (TL_EVT_HDR_SIZE + sizeof(TL_CcEvt_t))
|
||||
#define TL_BLEEVT_CC_BUFFER_SIZE (sizeof(TL_PacketHeader_t) + TL_BLEEVT_CC_PACKET_SIZE)
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**< Packet header */
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint32_t *next;
|
||||
uint32_t *prev;
|
||||
} TL_PacketHeader_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Event type
|
||||
*/
|
||||
|
||||
/**
|
||||
* This the payload of TL_Evt_t for a command status event
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t numcmd;
|
||||
uint16_t cmdcode;
|
||||
} TL_CsEvt_t;
|
||||
|
||||
/**
|
||||
* This the payload of TL_Evt_t for a command complete event, only used a pointer
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t numcmd;
|
||||
uint16_t cmdcode;
|
||||
uint8_t payload[2];
|
||||
} TL_CcEvt_t;
|
||||
|
||||
/**
|
||||
* This the payload of TL_Evt_t for an asynchronous event, only used a pointer
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint16_t subevtcode;
|
||||
uint8_t payload[2];
|
||||
} TL_AsynchEvt_t;
|
||||
|
||||
/**
|
||||
* This the payload of TL_Evt_t, only used a pointer
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t evtcode;
|
||||
uint8_t plen;
|
||||
uint8_t payload[2];
|
||||
} TL_Evt_t;
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t type;
|
||||
TL_Evt_t evt;
|
||||
} TL_EvtSerial_t;
|
||||
|
||||
/**
|
||||
* This format shall be used for all events (asynchronous and command response) reported
|
||||
* by the CPU2 except for the command response of a system command where the header is not there
|
||||
* and the format to be used shall be TL_EvtSerial_t.
|
||||
* Note: Be careful that the asynchronous events reported by the CPU2 on the system channel do
|
||||
* include the header and shall use TL_EvtPacket_t format. Only the command response format on the
|
||||
* system channel is different.
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
TL_PacketHeader_t header;
|
||||
TL_EvtSerial_t evtserial;
|
||||
} TL_EvtPacket_t;
|
||||
|
||||
/*****************************************************************************************
|
||||
* Command type
|
||||
*/
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint16_t cmdcode;
|
||||
uint8_t plen;
|
||||
uint8_t payload[255];
|
||||
} TL_Cmd_t;
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t type;
|
||||
TL_Cmd_t cmd;
|
||||
} TL_CmdSerial_t;
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
TL_PacketHeader_t header;
|
||||
TL_CmdSerial_t cmdserial;
|
||||
} TL_CmdPacket_t;
|
||||
|
||||
/*****************************************************************************************
|
||||
* HCI ACL DATA type
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t type;
|
||||
uint16_t handle;
|
||||
uint16_t length;
|
||||
uint8_t acl_data[1];
|
||||
} TL_AclDataSerial_t;
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
TL_PacketHeader_t header;
|
||||
TL_AclDataSerial_t AclDataSerial;
|
||||
} TL_AclDataPacket_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_BleSpareEvtBuffer;
|
||||
uint8_t *p_SystemSpareEvtBuffer;
|
||||
uint8_t *p_AsynchEvtPool;
|
||||
uint32_t AsynchEvtPoolSize;
|
||||
uint8_t *p_TracesEvtPool;
|
||||
uint32_t TracesEvtPoolSize;
|
||||
} TL_MM_Config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_ThreadOtCmdRspBuffer;
|
||||
uint8_t *p_ThreadCliRspBuffer;
|
||||
uint8_t *p_ThreadNotAckBuffer;
|
||||
uint8_t *p_ThreadCliNotBuffer;
|
||||
} TL_TH_Config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_LldTestsCliCmdRspBuffer;
|
||||
uint8_t *p_LldTestsM0CmdBuffer;
|
||||
} TL_LLD_tests_Config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_BleLldCmdRspBuffer;
|
||||
uint8_t *p_BleLldM0CmdBuffer;
|
||||
} TL_BLE_LLD_Config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_Mac_802_15_4_CmdRspBuffer;
|
||||
uint8_t *p_Mac_802_15_4_NotAckBuffer;
|
||||
} TL_MAC_802_15_4_Config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_ZigbeeOtCmdRspBuffer;
|
||||
uint8_t *p_ZigbeeNotAckBuffer;
|
||||
uint8_t *p_ZigbeeNotifRequestBuffer;
|
||||
} TL_ZIGBEE_Config_t;
|
||||
|
||||
/**
|
||||
* @brief Contain the BLE HCI Init Configuration
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void (* IoBusEvtCallBack) ( TL_EvtPacket_t *phcievt );
|
||||
void (* IoBusAclDataTxAck) ( void );
|
||||
uint8_t *p_cmdbuffer;
|
||||
uint8_t *p_AclDataBuffer;
|
||||
} TL_BLE_InitConf_t;
|
||||
|
||||
/**
|
||||
* @brief Contain the SYSTEM HCI Init Configuration
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void (* IoBusCallBackCmdEvt) (TL_EvtPacket_t *phcievt);
|
||||
void (* IoBusCallBackUserEvt) (TL_EvtPacket_t *phcievt);
|
||||
uint8_t *p_cmdbuffer;
|
||||
} TL_SYS_InitConf_t;
|
||||
|
||||
/*****************************************************************************************
|
||||
* Event type copied from ble_legacy.h
|
||||
*/
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t data[1];
|
||||
} hci_uart_pckt;
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t evt;
|
||||
uint8_t plen;
|
||||
uint8_t data[1];
|
||||
} hci_event_pckt;
|
||||
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint8_t subevent;
|
||||
uint8_t data[1];
|
||||
} evt_le_meta_event;
|
||||
|
||||
/**
|
||||
* Vendor specific event for BLE core.
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
uint16_t ecode; /**< One of the BLE core event codes. */
|
||||
uint8_t data[1];
|
||||
} evt_blecore_aci;
|
||||
|
||||
/* Bluetooth 48 bit address (in little-endian order).
|
||||
*/
|
||||
typedef uint8_t tBDAddr[6];
|
||||
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/******************************************************************************
|
||||
* GENERAL
|
||||
******************************************************************************/
|
||||
void TL_Enable( void );
|
||||
void TL_Init( void );
|
||||
|
||||
/******************************************************************************
|
||||
* BLE
|
||||
******************************************************************************/
|
||||
int32_t TL_BLE_Init( void* pConf );
|
||||
int32_t TL_BLE_SendCmd( uint8_t* buffer, uint16_t size );
|
||||
int32_t TL_BLE_SendAclData( uint8_t* buffer, uint16_t size );
|
||||
|
||||
/******************************************************************************
|
||||
* SYSTEM
|
||||
******************************************************************************/
|
||||
int32_t TL_SYS_Init( void* pConf );
|
||||
int32_t TL_SYS_SendCmd( uint8_t* buffer, uint16_t size );
|
||||
|
||||
/******************************************************************************
|
||||
* THREAD
|
||||
******************************************************************************/
|
||||
void TL_THREAD_Init( TL_TH_Config_t *p_Config );
|
||||
void TL_OT_SendCmd( void );
|
||||
void TL_CLI_SendCmd( void );
|
||||
void TL_OT_CmdEvtReceived( TL_EvtPacket_t * Otbuffer );
|
||||
void TL_THREAD_NotReceived( TL_EvtPacket_t * Notbuffer );
|
||||
void TL_THREAD_SendAck ( void );
|
||||
void TL_THREAD_CliSendAck ( void );
|
||||
void TL_THREAD_CliNotReceived( TL_EvtPacket_t * Notbuffer );
|
||||
|
||||
/******************************************************************************
|
||||
* LLD TESTS
|
||||
******************************************************************************/
|
||||
void TL_LLDTESTS_Init( TL_LLD_tests_Config_t *p_Config );
|
||||
void TL_LLDTESTS_SendCliCmd( void );
|
||||
void TL_LLDTESTS_ReceiveCliRsp( TL_CmdPacket_t * Notbuffer );
|
||||
void TL_LLDTESTS_SendCliRspAck( void );
|
||||
void TL_LLDTESTS_ReceiveM0Cmd( TL_CmdPacket_t * Notbuffer );
|
||||
void TL_LLDTESTS_SendM0CmdAck( void );
|
||||
|
||||
/******************************************************************************
|
||||
* BLE LLD
|
||||
******************************************************************************/
|
||||
void TL_BLE_LLD_Init( TL_BLE_LLD_Config_t *p_Config );
|
||||
void TL_BLE_LLD_SendCliCmd( void );
|
||||
void TL_BLE_LLD_ReceiveCliRsp( TL_CmdPacket_t * Notbuffer );
|
||||
void TL_BLE_LLD_SendCliRspAck( void );
|
||||
void TL_BLE_LLD_ReceiveM0Cmd( TL_CmdPacket_t * Notbuffer );
|
||||
void TL_BLE_LLD_SendM0CmdAck( void );
|
||||
void TL_BLE_LLD_SendCmd( void );
|
||||
void TL_BLE_LLD_ReceiveRsp( TL_CmdPacket_t * Notbuffer );
|
||||
void TL_BLE_LLD_SendRspAck( void );
|
||||
/******************************************************************************
|
||||
* MEMORY MANAGER
|
||||
******************************************************************************/
|
||||
void TL_MM_Init( TL_MM_Config_t *p_Config );
|
||||
void TL_MM_EvtDone( TL_EvtPacket_t * hcievt );
|
||||
|
||||
/******************************************************************************
|
||||
* TRACES
|
||||
******************************************************************************/
|
||||
void TL_TRACES_Init( void );
|
||||
void TL_TRACES_EvtReceived( TL_EvtPacket_t * hcievt );
|
||||
|
||||
/******************************************************************************
|
||||
* MAC 802.15.4
|
||||
******************************************************************************/
|
||||
void TL_MAC_802_15_4_Init( TL_MAC_802_15_4_Config_t *p_Config );
|
||||
void TL_MAC_802_15_4_SendCmd( void );
|
||||
void TL_MAC_802_15_4_CmdEvtReceived( TL_EvtPacket_t * Otbuffer );
|
||||
void TL_MAC_802_15_4_NotReceived( TL_EvtPacket_t * Notbuffer );
|
||||
void TL_MAC_802_15_4_SendAck ( void );
|
||||
|
||||
/******************************************************************************
|
||||
* ZIGBEE
|
||||
******************************************************************************/
|
||||
void TL_ZIGBEE_Init( TL_ZIGBEE_Config_t *p_Config );
|
||||
void TL_ZIGBEE_SendM4RequestToM0( void );
|
||||
void TL_ZIGBEE_SendM4AckToM0Notify ( void );
|
||||
void TL_ZIGBEE_NotReceived( TL_EvtPacket_t * Notbuffer );
|
||||
void TL_ZIGBEE_CmdEvtReceived( TL_EvtPacket_t * Otbuffer );
|
||||
void TL_ZIGBEE_M0RequestReceived(TL_EvtPacket_t * Otbuffer );
|
||||
void TL_ZIGBEE_SendM4AckToM0Request(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*__TL_H */
|
||||
|
||||
@@ -0,0 +1,877 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tl_mbox.c
|
||||
* @author MCD Application Team
|
||||
* @brief Transport layer for the mailbox interface
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32_wpan_common.h"
|
||||
#include "hw.h"
|
||||
|
||||
#include "stm_list.h"
|
||||
#include "tl.h"
|
||||
#include "mbox_def.h"
|
||||
#include "tl_dbg_conf.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
TL_MB_MM_RELEASE_BUFFER,
|
||||
TL_MB_BLE_CMD,
|
||||
TL_MB_BLE_CMD_RSP,
|
||||
TL_MB_ACL_DATA,
|
||||
TL_MB_ACL_DATA_RSP,
|
||||
TL_MB_BLE_ASYNCH_EVT,
|
||||
TL_MB_SYS_CMD,
|
||||
TL_MB_SYS_CMD_RSP,
|
||||
TL_MB_SYS_ASYNCH_EVT,
|
||||
} TL_MB_PacketType_t;
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/**< reference table */
|
||||
PLACE_IN_SECTION("MAPPING_TABLE") static volatile MB_RefTable_t TL_RefTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_DeviceInfoTable_t TL_DeviceInfoTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_BleTable_t TL_BleTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_ThreadTable_t TL_ThreadTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_LldTestsTable_t TL_LldTestsTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_BleLldTable_t TL_BleLldTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_SysTable_t TL_SysTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_MemManagerTable_t TL_MemManagerTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_TracesTable_t TL_TracesTable;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_Mac_802_15_4_t TL_Mac_802_15_4_Table;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static MB_ZigbeeTable_t TL_Zigbee_Table;
|
||||
|
||||
/**< tables */
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static tListNode FreeBufQueue;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static tListNode TracesEvtQueue;
|
||||
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t CsBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + sizeof(TL_CsEvt_t)];
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static tListNode EvtQueue;
|
||||
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static tListNode SystemEvtQueue;
|
||||
|
||||
|
||||
static tListNode LocalFreeBufQueue;
|
||||
static void (* BLE_IoBusEvtCallBackFunction) (TL_EvtPacket_t *phcievt);
|
||||
static void (* BLE_IoBusAclDataTxAck) ( void );
|
||||
static void (* SYS_CMD_IoBusCallBackFunction) (TL_EvtPacket_t *phcievt);
|
||||
static void (* SYS_EVT_IoBusCallBackFunction) (TL_EvtPacket_t *phcievt);
|
||||
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void SendFreeBuf( void );
|
||||
static void OutputDbgTrace(TL_MB_PacketType_t packet_type, uint8_t* buffer);
|
||||
|
||||
/* Public Functions Definition ------------------------------------------------------*/
|
||||
|
||||
/******************************************************************************
|
||||
* GENERAL - refer to AN5289 for functions description.
|
||||
******************************************************************************/
|
||||
void TL_Enable( void )
|
||||
{
|
||||
HW_IPCC_Enable();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void TL_Init( void )
|
||||
{
|
||||
TL_RefTable.p_device_info_table = &TL_DeviceInfoTable;
|
||||
TL_RefTable.p_ble_table = &TL_BleTable;
|
||||
TL_RefTable.p_thread_table = &TL_ThreadTable;
|
||||
TL_RefTable.p_lld_tests_table = &TL_LldTestsTable;
|
||||
TL_RefTable.p_ble_lld_table = &TL_BleLldTable;
|
||||
TL_RefTable.p_sys_table = &TL_SysTable;
|
||||
TL_RefTable.p_mem_manager_table = &TL_MemManagerTable;
|
||||
TL_RefTable.p_traces_table = &TL_TracesTable;
|
||||
TL_RefTable.p_mac_802_15_4_table = &TL_Mac_802_15_4_Table;
|
||||
TL_RefTable.p_zigbee_table = &TL_Zigbee_Table;
|
||||
HW_IPCC_Init();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BLE
|
||||
******************************************************************************/
|
||||
int32_t TL_BLE_Init( void* pConf )
|
||||
{
|
||||
MB_BleTable_t * p_bletable;
|
||||
|
||||
TL_BLE_InitConf_t *pInitHciConf = (TL_BLE_InitConf_t *) pConf;
|
||||
|
||||
LST_init_head (&EvtQueue);
|
||||
|
||||
p_bletable = TL_RefTable.p_ble_table;
|
||||
|
||||
p_bletable->pcmd_buffer = pInitHciConf->p_cmdbuffer;
|
||||
p_bletable->phci_acl_data_buffer = pInitHciConf->p_AclDataBuffer;
|
||||
p_bletable->pcs_buffer = (uint8_t*)CsBuffer;
|
||||
p_bletable->pevt_queue = (uint8_t*)&EvtQueue;
|
||||
|
||||
HW_IPCC_BLE_Init();
|
||||
|
||||
BLE_IoBusEvtCallBackFunction = pInitHciConf->IoBusEvtCallBack;
|
||||
BLE_IoBusAclDataTxAck = pInitHciConf->IoBusAclDataTxAck;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t TL_BLE_SendCmd( uint8_t* buffer, uint16_t size )
|
||||
{
|
||||
(void)(buffer);
|
||||
(void)(size);
|
||||
|
||||
((TL_CmdPacket_t*)(TL_RefTable.p_ble_table->pcmd_buffer))->cmdserial.type = TL_BLECMD_PKT_TYPE;
|
||||
|
||||
OutputDbgTrace(TL_MB_BLE_CMD, TL_RefTable.p_ble_table->pcmd_buffer);
|
||||
|
||||
HW_IPCC_BLE_SendCmd();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HW_IPCC_BLE_RxEvtNot(void)
|
||||
{
|
||||
TL_EvtPacket_t *phcievt;
|
||||
|
||||
while(LST_is_empty(&EvtQueue) == FALSE)
|
||||
{
|
||||
LST_remove_head (&EvtQueue, (tListNode **)&phcievt);
|
||||
|
||||
if ( ((phcievt->evtserial.evt.evtcode) == TL_BLEEVT_CS_OPCODE) || ((phcievt->evtserial.evt.evtcode) == TL_BLEEVT_CC_OPCODE ) )
|
||||
{
|
||||
OutputDbgTrace(TL_MB_BLE_CMD_RSP, (uint8_t*)phcievt);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDbgTrace(TL_MB_BLE_ASYNCH_EVT, (uint8_t*)phcievt);
|
||||
}
|
||||
|
||||
BLE_IoBusEvtCallBackFunction(phcievt);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t TL_BLE_SendAclData( uint8_t* buffer, uint16_t size )
|
||||
{
|
||||
(void)(buffer);
|
||||
(void)(size);
|
||||
|
||||
((TL_AclDataPacket_t *)(TL_RefTable.p_ble_table->phci_acl_data_buffer))->AclDataSerial.type = TL_ACL_DATA_PKT_TYPE;
|
||||
|
||||
OutputDbgTrace(TL_MB_ACL_DATA, TL_RefTable.p_ble_table->phci_acl_data_buffer);
|
||||
|
||||
HW_IPCC_BLE_SendAclData();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HW_IPCC_BLE_AclDataAckNot(void)
|
||||
{
|
||||
OutputDbgTrace(TL_MB_ACL_DATA_RSP, (uint8_t*)NULL);
|
||||
|
||||
BLE_IoBusAclDataTxAck( );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SYSTEM
|
||||
******************************************************************************/
|
||||
int32_t TL_SYS_Init( void* pConf )
|
||||
{
|
||||
MB_SysTable_t * p_systable;
|
||||
|
||||
TL_SYS_InitConf_t *pInitHciConf = (TL_SYS_InitConf_t *) pConf;
|
||||
|
||||
LST_init_head (&SystemEvtQueue);
|
||||
p_systable = TL_RefTable.p_sys_table;
|
||||
p_systable->pcmd_buffer = pInitHciConf->p_cmdbuffer;
|
||||
p_systable->sys_queue = (uint8_t*)&SystemEvtQueue;
|
||||
|
||||
HW_IPCC_SYS_Init();
|
||||
|
||||
SYS_CMD_IoBusCallBackFunction = pInitHciConf->IoBusCallBackCmdEvt;
|
||||
SYS_EVT_IoBusCallBackFunction = pInitHciConf->IoBusCallBackUserEvt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t TL_SYS_SendCmd( uint8_t* buffer, uint16_t size )
|
||||
{
|
||||
(void)(buffer);
|
||||
(void)(size);
|
||||
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_sys_table->pcmd_buffer))->cmdserial.type = TL_SYSCMD_PKT_TYPE;
|
||||
|
||||
OutputDbgTrace(TL_MB_SYS_CMD, TL_RefTable.p_sys_table->pcmd_buffer);
|
||||
|
||||
HW_IPCC_SYS_SendCmd();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HW_IPCC_SYS_CmdEvtNot(void)
|
||||
{
|
||||
OutputDbgTrace(TL_MB_SYS_CMD_RSP, (uint8_t*)(TL_RefTable.p_sys_table->pcmd_buffer) );
|
||||
|
||||
SYS_CMD_IoBusCallBackFunction( (TL_EvtPacket_t*)(TL_RefTable.p_sys_table->pcmd_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_SYS_EvtNot( void )
|
||||
{
|
||||
TL_EvtPacket_t *p_evt;
|
||||
|
||||
while(LST_is_empty(&SystemEvtQueue) == FALSE)
|
||||
{
|
||||
LST_remove_head (&SystemEvtQueue, (tListNode **)&p_evt);
|
||||
|
||||
OutputDbgTrace(TL_MB_SYS_ASYNCH_EVT, (uint8_t*)p_evt );
|
||||
|
||||
SYS_EVT_IoBusCallBackFunction( p_evt );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* THREAD
|
||||
******************************************************************************/
|
||||
#ifdef THREAD_WB
|
||||
void TL_THREAD_Init( TL_TH_Config_t *p_Config )
|
||||
{
|
||||
MB_ThreadTable_t * p_thread_table;
|
||||
|
||||
p_thread_table = TL_RefTable.p_thread_table;
|
||||
|
||||
p_thread_table->clicmdrsp_buffer = p_Config->p_ThreadCliRspBuffer;
|
||||
p_thread_table->otcmdrsp_buffer = p_Config->p_ThreadOtCmdRspBuffer;
|
||||
p_thread_table->notack_buffer = p_Config->p_ThreadNotAckBuffer;
|
||||
p_thread_table->clinot_buffer = p_Config->p_ThreadCliNotBuffer;
|
||||
|
||||
HW_IPCC_THREAD_Init();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_OT_SendCmd( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_thread_table->otcmdrsp_buffer))->cmdserial.type = TL_OTCMD_PKT_TYPE;
|
||||
|
||||
HW_IPCC_OT_SendCmd();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_CLI_SendCmd( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_thread_table->clicmdrsp_buffer))->cmdserial.type = TL_CLICMD_PKT_TYPE;
|
||||
|
||||
HW_IPCC_CLI_SendCmd();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_THREAD_SendAck ( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_thread_table->notack_buffer))->cmdserial.type = TL_OTACK_PKT_TYPE;
|
||||
|
||||
HW_IPCC_THREAD_SendAck();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_THREAD_CliSendAck ( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_thread_table->notack_buffer))->cmdserial.type = TL_OTACK_PKT_TYPE;
|
||||
|
||||
HW_IPCC_THREAD_CliSendAck();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_OT_CmdEvtNot(void)
|
||||
{
|
||||
TL_OT_CmdEvtReceived( (TL_EvtPacket_t*)(TL_RefTable.p_thread_table->otcmdrsp_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_THREAD_EvtNot( void )
|
||||
{
|
||||
TL_THREAD_NotReceived( (TL_EvtPacket_t*)(TL_RefTable.p_thread_table->notack_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_THREAD_CliEvtNot( void )
|
||||
{
|
||||
TL_THREAD_CliNotReceived( (TL_EvtPacket_t*)(TL_RefTable.p_thread_table->clinot_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__WEAK void TL_OT_CmdEvtReceived( TL_EvtPacket_t * Otbuffer ){};
|
||||
__WEAK void TL_THREAD_NotReceived( TL_EvtPacket_t * Notbuffer ){};
|
||||
__WEAK void TL_THREAD_CliNotReceived( TL_EvtPacket_t * Notbuffer ){};
|
||||
|
||||
#endif /* THREAD_WB */
|
||||
|
||||
/******************************************************************************
|
||||
* LLD TESTS
|
||||
******************************************************************************/
|
||||
#ifdef LLD_TESTS_WB
|
||||
void TL_LLDTESTS_Init( TL_LLD_tests_Config_t *p_Config )
|
||||
{
|
||||
MB_LldTestsTable_t * p_lld_tests_table;
|
||||
|
||||
p_lld_tests_table = TL_RefTable.p_lld_tests_table;
|
||||
p_lld_tests_table->clicmdrsp_buffer = p_Config->p_LldTestsCliCmdRspBuffer;
|
||||
p_lld_tests_table->m0cmd_buffer = p_Config->p_LldTestsM0CmdBuffer;
|
||||
HW_IPCC_LLDTESTS_Init();
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_LLDTESTS_SendCliCmd( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_lld_tests_table->clicmdrsp_buffer))->cmdserial.type = TL_CLICMD_PKT_TYPE;
|
||||
HW_IPCC_LLDTESTS_SendCliCmd();
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_LLDTESTS_ReceiveCliRsp( void )
|
||||
{
|
||||
TL_LLDTESTS_ReceiveCliRsp( (TL_CmdPacket_t*)(TL_RefTable.p_lld_tests_table->clicmdrsp_buffer) );
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_LLDTESTS_SendCliRspAck( void )
|
||||
{
|
||||
HW_IPCC_LLDTESTS_SendCliRspAck();
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_LLDTESTS_ReceiveM0Cmd( void )
|
||||
{
|
||||
TL_LLDTESTS_ReceiveM0Cmd( (TL_CmdPacket_t*)(TL_RefTable.p_lld_tests_table->m0cmd_buffer) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void TL_LLDTESTS_SendM0CmdAck( void )
|
||||
{
|
||||
HW_IPCC_LLDTESTS_SendM0CmdAck();
|
||||
return;
|
||||
}
|
||||
|
||||
__WEAK void TL_LLDTESTS_ReceiveCliRsp( TL_CmdPacket_t * Notbuffer ){};
|
||||
__WEAK void TL_LLDTESTS_ReceiveM0Cmd( TL_CmdPacket_t * Notbuffer ){};
|
||||
#endif /* LLD_TESTS_WB */
|
||||
|
||||
/******************************************************************************
|
||||
* BLE LLD
|
||||
******************************************************************************/
|
||||
#ifdef BLE_LLD_WB
|
||||
void TL_BLE_LLD_Init( TL_BLE_LLD_Config_t *p_Config )
|
||||
{
|
||||
MB_BleLldTable_t * p_ble_lld_table;
|
||||
|
||||
p_ble_lld_table = TL_RefTable.p_ble_lld_table;
|
||||
p_ble_lld_table->cmdrsp_buffer = p_Config->p_BleLldCmdRspBuffer;
|
||||
p_ble_lld_table->m0cmd_buffer = p_Config->p_BleLldM0CmdBuffer;
|
||||
HW_IPCC_BLE_LLD_Init();
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_BLE_LLD_SendCliCmd( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_ble_lld_table->cmdrsp_buffer))->cmdserial.type = TL_CLICMD_PKT_TYPE;
|
||||
HW_IPCC_BLE_LLD_SendCliCmd();
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_BLE_LLD_ReceiveCliRsp( void )
|
||||
{
|
||||
TL_BLE_LLD_ReceiveCliRsp( (TL_CmdPacket_t*)(TL_RefTable.p_ble_lld_table->cmdrsp_buffer) );
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_BLE_LLD_SendCliRspAck( void )
|
||||
{
|
||||
HW_IPCC_BLE_LLD_SendCliRspAck();
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_BLE_LLD_ReceiveM0Cmd( void )
|
||||
{
|
||||
TL_BLE_LLD_ReceiveM0Cmd( (TL_CmdPacket_t*)(TL_RefTable.p_ble_lld_table->m0cmd_buffer) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void TL_BLE_LLD_SendM0CmdAck( void )
|
||||
{
|
||||
HW_IPCC_BLE_LLD_SendM0CmdAck();
|
||||
return;
|
||||
}
|
||||
|
||||
__WEAK void TL_BLE_LLD_ReceiveCliRsp( TL_CmdPacket_t * Notbuffer ){};
|
||||
__WEAK void TL_BLE_LLD_ReceiveM0Cmd( TL_CmdPacket_t * Notbuffer ){};
|
||||
|
||||
/* Transparent Mode */
|
||||
void TL_BLE_LLD_SendCmd( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_ble_lld_table->cmdrsp_buffer))->cmdserial.type = TL_CLICMD_PKT_TYPE;
|
||||
HW_IPCC_BLE_LLD_SendCmd();
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_BLE_LLD_ReceiveRsp( void )
|
||||
{
|
||||
TL_BLE_LLD_ReceiveRsp( (TL_CmdPacket_t*)(TL_RefTable.p_ble_lld_table->cmdrsp_buffer) );
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_BLE_LLD_SendRspAck( void )
|
||||
{
|
||||
HW_IPCC_BLE_LLD_SendRspAck();
|
||||
return;
|
||||
}
|
||||
#endif /* BLE_LLD_WB */
|
||||
|
||||
#ifdef MAC_802_15_4_WB
|
||||
/******************************************************************************
|
||||
* MAC 802.15.4
|
||||
******************************************************************************/
|
||||
void TL_MAC_802_15_4_Init( TL_MAC_802_15_4_Config_t *p_Config )
|
||||
{
|
||||
MB_Mac_802_15_4_t * p_mac_802_15_4_table;
|
||||
|
||||
p_mac_802_15_4_table = TL_RefTable.p_mac_802_15_4_table;
|
||||
|
||||
p_mac_802_15_4_table->p_cmdrsp_buffer = p_Config->p_Mac_802_15_4_CmdRspBuffer;
|
||||
p_mac_802_15_4_table->p_notack_buffer = p_Config->p_Mac_802_15_4_NotAckBuffer;
|
||||
|
||||
HW_IPCC_MAC_802_15_4_Init();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_MAC_802_15_4_SendCmd( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_mac_802_15_4_table->p_cmdrsp_buffer))->cmdserial.type = TL_OTCMD_PKT_TYPE;
|
||||
|
||||
HW_IPCC_MAC_802_15_4_SendCmd();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_MAC_802_15_4_SendAck ( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_mac_802_15_4_table->p_notack_buffer))->cmdserial.type = TL_OTACK_PKT_TYPE;
|
||||
|
||||
HW_IPCC_MAC_802_15_4_SendAck();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_MAC_802_15_4_CmdEvtNot(void)
|
||||
{
|
||||
TL_MAC_802_15_4_CmdEvtReceived( (TL_EvtPacket_t*)(TL_RefTable.p_mac_802_15_4_table->p_cmdrsp_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_MAC_802_15_4_EvtNot( void )
|
||||
{
|
||||
TL_MAC_802_15_4_NotReceived( (TL_EvtPacket_t*)(TL_RefTable.p_mac_802_15_4_table->p_notack_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__WEAK void TL_MAC_802_15_4_CmdEvtReceived( TL_EvtPacket_t * Otbuffer ){};
|
||||
__WEAK void TL_MAC_802_15_4_NotReceived( TL_EvtPacket_t * Notbuffer ){};
|
||||
#endif
|
||||
|
||||
#ifdef ZIGBEE_WB
|
||||
/******************************************************************************
|
||||
* ZIGBEE
|
||||
******************************************************************************/
|
||||
void TL_ZIGBEE_Init( TL_ZIGBEE_Config_t *p_Config )
|
||||
{
|
||||
MB_ZigbeeTable_t * p_zigbee_table;
|
||||
|
||||
p_zigbee_table = TL_RefTable.p_zigbee_table;
|
||||
p_zigbee_table->appliCmdM4toM0_buffer = p_Config->p_ZigbeeOtCmdRspBuffer;
|
||||
p_zigbee_table->notifM0toM4_buffer = p_Config->p_ZigbeeNotAckBuffer;
|
||||
p_zigbee_table->requestM0toM4_buffer = p_Config->p_ZigbeeNotifRequestBuffer;
|
||||
|
||||
HW_IPCC_ZIGBEE_Init();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Zigbee M4 to M0 Request */
|
||||
void TL_ZIGBEE_SendM4RequestToM0( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_zigbee_table->appliCmdM4toM0_buffer))->cmdserial.type = TL_OTCMD_PKT_TYPE;
|
||||
|
||||
HW_IPCC_ZIGBEE_SendM4RequestToM0();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Used to receive an ACK from the M0 */
|
||||
void HW_IPCC_ZIGBEE_RecvAppliAckFromM0(void)
|
||||
{
|
||||
TL_ZIGBEE_CmdEvtReceived( (TL_EvtPacket_t*)(TL_RefTable.p_zigbee_table->appliCmdM4toM0_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Zigbee notification from M0 to M4 */
|
||||
void HW_IPCC_ZIGBEE_RecvM0NotifyToM4( void )
|
||||
{
|
||||
TL_ZIGBEE_NotReceived( (TL_EvtPacket_t*)(TL_RefTable.p_zigbee_table->notifM0toM4_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send an ACK to the M0 for a Notification */
|
||||
void TL_ZIGBEE_SendM4AckToM0Notify ( void )
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_zigbee_table->notifM0toM4_buffer))->cmdserial.type = TL_OTACK_PKT_TYPE;
|
||||
|
||||
HW_IPCC_ZIGBEE_SendM4AckToM0Notify();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Zigbee M0 to M4 Request */
|
||||
void HW_IPCC_ZIGBEE_RecvM0RequestToM4( void )
|
||||
{
|
||||
TL_ZIGBEE_M0RequestReceived( (TL_EvtPacket_t*)(TL_RefTable.p_zigbee_table->requestM0toM4_buffer) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send an ACK to the M0 for a Request */
|
||||
void TL_ZIGBEE_SendM4AckToM0Request(void)
|
||||
{
|
||||
((TL_CmdPacket_t *)(TL_RefTable.p_zigbee_table->requestM0toM4_buffer))->cmdserial.type = TL_OTACK_PKT_TYPE;
|
||||
|
||||
HW_IPCC_ZIGBEE_SendM4AckToM0Request();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
__WEAK void TL_ZIGBEE_CmdEvtReceived( TL_EvtPacket_t * Otbuffer ){};
|
||||
__WEAK void TL_ZIGBEE_NotReceived( TL_EvtPacket_t * Notbuffer ){};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* MEMORY MANAGER
|
||||
******************************************************************************/
|
||||
void TL_MM_Init( TL_MM_Config_t *p_Config )
|
||||
{
|
||||
static MB_MemManagerTable_t * p_mem_manager_table;
|
||||
|
||||
LST_init_head (&FreeBufQueue);
|
||||
LST_init_head (&LocalFreeBufQueue);
|
||||
|
||||
p_mem_manager_table = TL_RefTable.p_mem_manager_table;
|
||||
|
||||
p_mem_manager_table->blepool = p_Config->p_AsynchEvtPool;
|
||||
p_mem_manager_table->blepoolsize = p_Config->AsynchEvtPoolSize;
|
||||
p_mem_manager_table->pevt_free_buffer_queue = (uint8_t*)&FreeBufQueue;
|
||||
p_mem_manager_table->spare_ble_buffer = p_Config->p_BleSpareEvtBuffer;
|
||||
p_mem_manager_table->spare_sys_buffer = p_Config->p_SystemSpareEvtBuffer;
|
||||
p_mem_manager_table->traces_evt_pool = p_Config->p_TracesEvtPool;
|
||||
p_mem_manager_table->tracespoolsize = p_Config->TracesEvtPoolSize;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TL_MM_EvtDone(TL_EvtPacket_t * phcievt)
|
||||
{
|
||||
LST_insert_tail(&LocalFreeBufQueue, (tListNode *)phcievt);
|
||||
|
||||
OutputDbgTrace(TL_MB_MM_RELEASE_BUFFER, (uint8_t*)phcievt);
|
||||
|
||||
HW_IPCC_MM_SendFreeBuf( SendFreeBuf );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void SendFreeBuf( void )
|
||||
{
|
||||
tListNode *p_node;
|
||||
|
||||
while ( FALSE == LST_is_empty (&LocalFreeBufQueue) )
|
||||
{
|
||||
LST_remove_head( &LocalFreeBufQueue, (tListNode **)&p_node );
|
||||
LST_insert_tail( (tListNode*)(TL_RefTable.p_mem_manager_table->pevt_free_buffer_queue), p_node );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* TRACES
|
||||
******************************************************************************/
|
||||
void TL_TRACES_Init( void )
|
||||
{
|
||||
LST_init_head (&TracesEvtQueue);
|
||||
|
||||
TL_RefTable.p_traces_table->traces_queue = (uint8_t*)&TracesEvtQueue;
|
||||
|
||||
HW_IPCC_TRACES_Init();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_IPCC_TRACES_EvtNot(void)
|
||||
{
|
||||
TL_EvtPacket_t *phcievt;
|
||||
|
||||
while(LST_is_empty(&TracesEvtQueue) == FALSE)
|
||||
{
|
||||
LST_remove_head (&TracesEvtQueue, (tListNode **)&phcievt);
|
||||
TL_TRACES_EvtReceived( phcievt );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__WEAK void TL_TRACES_EvtReceived( TL_EvtPacket_t * hcievt )
|
||||
{
|
||||
(void)(hcievt);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DEBUG INFORMATION
|
||||
******************************************************************************/
|
||||
static void OutputDbgTrace(TL_MB_PacketType_t packet_type, uint8_t* buffer)
|
||||
{
|
||||
TL_EvtPacket_t *p_evt_packet;
|
||||
TL_CmdPacket_t *p_cmd_packet;
|
||||
TL_AclDataPacket_t *p_acldata_packet;
|
||||
TL_EvtSerial_t *p_cmd_rsp_packet;
|
||||
|
||||
switch(packet_type)
|
||||
{
|
||||
case TL_MB_MM_RELEASE_BUFFER:
|
||||
p_evt_packet = (TL_EvtPacket_t*)buffer;
|
||||
switch(p_evt_packet->evtserial.evt.evtcode)
|
||||
{
|
||||
case TL_BLEEVT_CS_OPCODE:
|
||||
TL_MM_DBG_MSG("mm evt released: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
TL_MM_DBG_MSG(" cmd opcode: 0x%04X", ((TL_CsEvt_t*)(p_evt_packet->evtserial.evt.payload))->cmdcode);
|
||||
TL_MM_DBG_MSG(" buffer addr: 0x%08X", p_evt_packet);
|
||||
break;
|
||||
|
||||
case TL_BLEEVT_CC_OPCODE:
|
||||
TL_MM_DBG_MSG("mm evt released: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
TL_MM_DBG_MSG(" cmd opcode: 0x%04X", ((TL_CcEvt_t*)(p_evt_packet->evtserial.evt.payload))->cmdcode);
|
||||
TL_MM_DBG_MSG(" buffer addr: 0x%08X", p_evt_packet);
|
||||
break;
|
||||
|
||||
case TL_BLEEVT_VS_OPCODE:
|
||||
TL_MM_DBG_MSG("mm evt released: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
TL_MM_DBG_MSG(" subevtcode: 0x%04X", ((TL_AsynchEvt_t*)(p_evt_packet->evtserial.evt.payload))->subevtcode);
|
||||
TL_MM_DBG_MSG(" buffer addr: 0x%08X", p_evt_packet);
|
||||
break;
|
||||
|
||||
default:
|
||||
TL_MM_DBG_MSG("mm evt released: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
TL_MM_DBG_MSG(" buffer addr: 0x%08X", p_evt_packet);
|
||||
break;
|
||||
}
|
||||
|
||||
TL_MM_DBG_MSG("\r\n");
|
||||
break;
|
||||
|
||||
case TL_MB_BLE_CMD:
|
||||
p_cmd_packet = (TL_CmdPacket_t*)buffer;
|
||||
TL_HCI_CMD_DBG_MSG("ble cmd: 0x%04X", p_cmd_packet->cmdserial.cmd.cmdcode);
|
||||
if(p_cmd_packet->cmdserial.cmd.plen != 0)
|
||||
{
|
||||
TL_HCI_CMD_DBG_MSG(" payload:");
|
||||
TL_HCI_CMD_DBG_BUF(p_cmd_packet->cmdserial.cmd.payload, p_cmd_packet->cmdserial.cmd.plen, "");
|
||||
}
|
||||
TL_HCI_CMD_DBG_MSG("\r\n");
|
||||
|
||||
TL_HCI_CMD_DBG_RAW(&p_cmd_packet->cmdserial, p_cmd_packet->cmdserial.cmd.plen+TL_CMD_HDR_SIZE);
|
||||
break;
|
||||
|
||||
case TL_MB_ACL_DATA:
|
||||
(void)p_acldata_packet;
|
||||
p_acldata_packet = (TL_AclDataPacket_t*)buffer;
|
||||
TL_HCI_CMD_DBG_MSG("acl_data: 0x%02X", p_acldata_packet->AclDataSerial.type);
|
||||
TL_HCI_CMD_DBG_MSG("acl_data: 0x%04X", p_acldata_packet->AclDataSerial.handle);
|
||||
TL_HCI_CMD_DBG_MSG("acl_data: 0x%04X", p_acldata_packet->AclDataSerial.length);
|
||||
/*if(p_acldata_packet->AclDataSerial.length != 0)
|
||||
{
|
||||
TL_HCI_CMD_DBG_MSG(" payload:");
|
||||
TL_HCI_CMD_DBG_BUF(p_acldata_packet->AclDataSerial.acl_data, p_acldata_packet->AclDataSerial.length, "");
|
||||
}*/
|
||||
TL_HCI_CMD_DBG_MSG("\r\n");
|
||||
/*TL_HCI_CMD_DBG_RAW(&p_acldata_packet->AclDataSerial, p_acldata_packet->AclDataSerial.length+TL_CMD_HDR_SIZE);*/
|
||||
break;
|
||||
|
||||
case TL_MB_ACL_DATA_RSP:
|
||||
TL_HCI_CMD_DBG_MSG(" ACL Data Tx Ack received");
|
||||
TL_HCI_CMD_DBG_MSG("\r\n");
|
||||
break;
|
||||
|
||||
case TL_MB_BLE_CMD_RSP:
|
||||
p_evt_packet = (TL_EvtPacket_t*)buffer;
|
||||
switch(p_evt_packet->evtserial.evt.evtcode)
|
||||
{
|
||||
case TL_BLEEVT_CS_OPCODE:
|
||||
TL_HCI_CMD_DBG_MSG("ble rsp: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
TL_HCI_CMD_DBG_MSG(" cmd opcode: 0x%04X", ((TL_CsEvt_t*)(p_evt_packet->evtserial.evt.payload))->cmdcode);
|
||||
TL_HCI_CMD_DBG_MSG(" numhci: 0x%02X", ((TL_CsEvt_t*)(p_evt_packet->evtserial.evt.payload))->numcmd);
|
||||
TL_HCI_CMD_DBG_MSG(" status: 0x%02X", ((TL_CsEvt_t*)(p_evt_packet->evtserial.evt.payload))->status);
|
||||
break;
|
||||
|
||||
case TL_BLEEVT_CC_OPCODE:
|
||||
TL_HCI_CMD_DBG_MSG("ble rsp: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
TL_HCI_CMD_DBG_MSG(" cmd opcode: 0x%04X", ((TL_CcEvt_t*)(p_evt_packet->evtserial.evt.payload))->cmdcode);
|
||||
TL_HCI_CMD_DBG_MSG(" numhci: 0x%02X", ((TL_CcEvt_t*)(p_evt_packet->evtserial.evt.payload))->numcmd);
|
||||
TL_HCI_CMD_DBG_MSG(" status: 0x%02X", ((TL_CcEvt_t*)(p_evt_packet->evtserial.evt.payload))->payload[0]);
|
||||
if((p_evt_packet->evtserial.evt.plen-4) != 0)
|
||||
{
|
||||
TL_HCI_CMD_DBG_MSG(" payload:");
|
||||
TL_HCI_CMD_DBG_BUF(&((TL_CcEvt_t*)(p_evt_packet->evtserial.evt.payload))->payload[1], p_evt_packet->evtserial.evt.plen-4, "");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
TL_HCI_CMD_DBG_MSG("unknown ble rsp received: %02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
break;
|
||||
}
|
||||
|
||||
TL_HCI_CMD_DBG_MSG("\r\n");
|
||||
|
||||
TL_HCI_CMD_DBG_RAW(&p_evt_packet->evtserial, p_evt_packet->evtserial.evt.plen+TL_EVT_HDR_SIZE);
|
||||
break;
|
||||
|
||||
case TL_MB_BLE_ASYNCH_EVT:
|
||||
p_evt_packet = (TL_EvtPacket_t*)buffer;
|
||||
if(p_evt_packet->evtserial.evt.evtcode != TL_BLEEVT_VS_OPCODE)
|
||||
{
|
||||
TL_HCI_EVT_DBG_MSG("ble evt: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
if((p_evt_packet->evtserial.evt.plen) != 0)
|
||||
{
|
||||
TL_HCI_EVT_DBG_MSG(" payload:");
|
||||
TL_HCI_EVT_DBG_BUF(p_evt_packet->evtserial.evt.payload, p_evt_packet->evtserial.evt.plen, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TL_HCI_EVT_DBG_MSG("ble evt: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
TL_HCI_EVT_DBG_MSG(" subevtcode: 0x%04X", ((TL_AsynchEvt_t*)(p_evt_packet->evtserial.evt.payload))->subevtcode);
|
||||
if((p_evt_packet->evtserial.evt.plen-2) != 0)
|
||||
{
|
||||
TL_HCI_EVT_DBG_MSG(" payload:");
|
||||
TL_HCI_EVT_DBG_BUF(((TL_AsynchEvt_t*)(p_evt_packet->evtserial.evt.payload))->payload, p_evt_packet->evtserial.evt.plen-2, "");
|
||||
}
|
||||
}
|
||||
|
||||
TL_HCI_EVT_DBG_MSG("\r\n");
|
||||
|
||||
TL_HCI_EVT_DBG_RAW(&p_evt_packet->evtserial, p_evt_packet->evtserial.evt.plen+TL_EVT_HDR_SIZE);
|
||||
break;
|
||||
|
||||
case TL_MB_SYS_CMD:
|
||||
p_cmd_packet = (TL_CmdPacket_t*)buffer;
|
||||
|
||||
TL_SHCI_CMD_DBG_MSG("sys cmd: 0x%04X", p_cmd_packet->cmdserial.cmd.cmdcode);
|
||||
|
||||
if(p_cmd_packet->cmdserial.cmd.plen != 0)
|
||||
{
|
||||
TL_SHCI_CMD_DBG_MSG(" payload:");
|
||||
TL_SHCI_CMD_DBG_BUF(p_cmd_packet->cmdserial.cmd.payload, p_cmd_packet->cmdserial.cmd.plen, "");
|
||||
}
|
||||
TL_SHCI_CMD_DBG_MSG("\r\n");
|
||||
|
||||
TL_SHCI_CMD_DBG_RAW(&p_cmd_packet->cmdserial, p_cmd_packet->cmdserial.cmd.plen+TL_CMD_HDR_SIZE);
|
||||
break;
|
||||
|
||||
case TL_MB_SYS_CMD_RSP:
|
||||
p_cmd_rsp_packet = (TL_EvtSerial_t*)buffer;
|
||||
switch(p_cmd_rsp_packet->evt.evtcode)
|
||||
{
|
||||
case TL_BLEEVT_CC_OPCODE:
|
||||
TL_SHCI_CMD_DBG_MSG("sys rsp: 0x%02X", p_cmd_rsp_packet->evt.evtcode);
|
||||
TL_SHCI_CMD_DBG_MSG(" cmd opcode: 0x%02X", ((TL_CcEvt_t*)(p_cmd_rsp_packet->evt.payload))->cmdcode);
|
||||
TL_SHCI_CMD_DBG_MSG(" status: 0x%02X", ((TL_CcEvt_t*)(p_cmd_rsp_packet->evt.payload))->payload[0]);
|
||||
if((p_cmd_rsp_packet->evt.plen-4) != 0)
|
||||
{
|
||||
TL_SHCI_CMD_DBG_MSG(" payload:");
|
||||
TL_SHCI_CMD_DBG_BUF(&((TL_CcEvt_t*)(p_cmd_rsp_packet->evt.payload))->payload[1], p_cmd_rsp_packet->evt.plen-4, "");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
TL_SHCI_CMD_DBG_MSG("unknown sys rsp received: %02X", p_cmd_rsp_packet->evt.evtcode);
|
||||
break;
|
||||
}
|
||||
|
||||
TL_SHCI_CMD_DBG_MSG("\r\n");
|
||||
|
||||
TL_SHCI_CMD_DBG_RAW(&p_cmd_rsp_packet->evt, p_cmd_rsp_packet->evt.plen+TL_EVT_HDR_SIZE);
|
||||
break;
|
||||
|
||||
case TL_MB_SYS_ASYNCH_EVT:
|
||||
p_evt_packet = (TL_EvtPacket_t*)buffer;
|
||||
if(p_evt_packet->evtserial.evt.evtcode != TL_BLEEVT_VS_OPCODE)
|
||||
{
|
||||
TL_SHCI_EVT_DBG_MSG("unknown sys evt received: %02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
TL_SHCI_EVT_DBG_MSG("sys evt: 0x%02X", p_evt_packet->evtserial.evt.evtcode);
|
||||
TL_SHCI_EVT_DBG_MSG(" subevtcode: 0x%04X", ((TL_AsynchEvt_t*)(p_evt_packet->evtserial.evt.payload))->subevtcode);
|
||||
if((p_evt_packet->evtserial.evt.plen-2) != 0)
|
||||
{
|
||||
TL_SHCI_EVT_DBG_MSG(" payload:");
|
||||
TL_SHCI_EVT_DBG_BUF(((TL_AsynchEvt_t*)(p_evt_packet->evtserial.evt.payload))->payload, p_evt_packet->evtserial.evt.plen-2, "");
|
||||
}
|
||||
}
|
||||
|
||||
TL_SHCI_EVT_DBG_MSG("\r\n");
|
||||
|
||||
TL_SHCI_EVT_DBG_RAW(&p_evt_packet->evtserial, p_evt_packet->evtserial.evt.plen+TL_EVT_HDR_SIZE);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user