Import Mbed OS hard-float snapshot

This commit is contained in:
Beslan
2026-06-01 20:15:04 +03:00
commit d3738e2f89
16278 changed files with 10628036 additions and 0 deletions

View File

@@ -0,0 +1,947 @@
/*
* Copyright (c) 2019 ARM Limited
* Copyright (c) 2019 STMicroelectronics
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "ble/common/ble/blecommon.h"
#include "BLEInstanceBase.h"
#include "CordioHCIDriver.h"
#include "CordioHCITransportDriver.h"
#include "mbed.h"
#include "hci_api.h"
#include "hci_cmd.h"
#include "hci_core.h"
#include "dm_api.h"
#include "bstream.h"
#include "hci_mbed_os_adaptation.h"
#include "mbed_trace.h"
/* STM32WB include files */
#include "stm32wbxx_ll_ipcc.h"
#include "stm32wbxx_ll_system.h"
#include "tl.h"
#include "shci.h"
#include "shci_tl.h"
#include "hw.h"
#include "app_conf.h"
#include "otp.h"
/* mbed trace feature is supported */
/* ex in mbed_app.json */
/* "mbed-trace.enable": "1" */
#define TRACE_GROUP "BLWB"
/******************************************************************************
* BLE config parameters
******************************************************************************/
/* Defined from WB Cube reference SW */
#define CFG_TLBLE_EVT_QUEUE_LENGTH 5
#define CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE 255 /**< Set to 255 with the memory manager and the mailbox */
#define TL_BLE_EVENT_FRAME_SIZE ( TL_EVT_HDR_SIZE + CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE )
#define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH*4*DIVC(( sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE ), 4))
#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */
#define CONFIG_DATA_PUBADDR_LEN (6)
/* HCI related defines */
#define HCI_RESET_RAND_CNT 4
#define VENDOR_SPECIFIC_EVENT 0xFF
#define ACI_HAL_SET_TX_POWER_LEVEL 0xFC0F
#define ACI_WRITE_CONFIG_DATA_OPCODE 0xFC0C
#define ACI_READ_CONFIG_DATA_OPCODE 0xFC0D
#define MAX_HCI_ACL_PACKET_SIZE (sizeof(TL_PacketHeader_t) + 5 + 251)
#define MAX_HACI_EVT_SIZE (255+5)
/* mbed_trace: debug traces (tr_debug) can be disabled here with no change in mbed_app.json */
// #undef TRACE_LEVEL_DEBUG
// #define TRACE_LEVEL_DEBUG 0
/* tr_debug : add data content in console print */
#define PRINT_HCI_DATA 0
/******************************************************************************
* BLE config parameters
******************************************************************************/
static void evt_received(TL_EvtPacket_t *hcievt);
static void syscmd_status_not(SHCI_TL_CmdStatus_t status);
static void sysevt_received(void *pdata);
static void acl_data_ack(void);
static bool acl_data_wait(void);
static void init_debug(void);
static bool get_bd_address(uint8_t *bd_addr);
static bool sysevt_wait(void);
static bool sysevt_check(void);
extern int BLE_inited;
namespace ble {
namespace vendor {
namespace stm32wb {
/**
* stm32wb HCI driver implementation
* @see CordioHCIDriver
*/
class HCIDriver : public CordioHCIDriver {
public:
/**
* Construction of the HCIDriver.
* @param transport: Transport of the HCI commands.
* @param rst: Name of the reset pin
*/
HCIDriver(
CordioHCITransportDriver &transport_driver
) : CordioHCIDriver(transport_driver) { }
virtual buf_pool_desc_t get_buffer_pool_description();
/**
* @see CordioHCIDriver::do_initialize
*/
virtual void do_initialize()
{
// Nothig needed, init is only at transpot layer level
}
/**
* @see CordioHCIDriver::do_terminate
*/
virtual void do_terminate()
{
// Nothig needed, init is only at transpot layer level
}
/**
* @see CordioHCIDriver::start_reset_sequence
*/
virtual void start_reset_sequence()
{
/* send an HCI Reset command to start the sequence */
HciResetCmd();
}
static uint8_t convert_db_to_tx_power_index(int8_t level_db) {
const int8_t conversion[] = {
-40, -21, -20, -19,
-18, -16, -15, -14,
-13, -12, -11, -10,
-9, -8, -7, -6,
-5, -4, -3, -2,
-1, -1, -1, -1,
0, 0, 1, 2,
3, 4, 5, 6
};
uint8_t index;
for (index = 0; index < sizeof(conversion); ++index) {
if (level_db <= conversion[index]) {
break;
}
}
return index;
}
virtual ble_error_t set_tx_power(int8_t level_db) {
uint8_t buf[2];
buf[0] = 0x1; // Enable high power mode - deprecated and ignored on STM32WB
buf[1] = convert_db_to_tx_power_index(level_db);
HciVendorSpecificCmd(ACI_HAL_SET_TX_POWER_LEVEL, 2, buf);
return BLE_ERROR_NONE;
}
/**
* @see CordioHCIDriver::handle_reset_sequence
*/
virtual void handle_reset_sequence(uint8_t *pMsg)
{
uint16_t opcode;
static uint8_t randCnt;
/* if event is a command complete event */
if (*pMsg == HCI_CMD_CMPL_EVT) {
tr_debug("Command Complete Event Command");
#if (PRINT_HCI_DATA)
for (uint8_t i = 0; i < 20; i++) {
tr_debug(" %02X", *((uint8_t *)pMsg + i));
}
#endif
/* parse parameters */
tr_debug(" HCI_EVT_HDR_LEN=%d", HCI_EVT_HDR_LEN);
pMsg += HCI_EVT_HDR_LEN;
pMsg++; /* skip num packets */
BSTREAM_TO_UINT16(opcode, pMsg);
pMsg++; /* skip status */
/* decode opcode */
tr_debug(" opcode = %#06x", opcode);
switch (opcode) {
case HCI_OPCODE_RESET:
/* initialize rand command count */
randCnt = 0;
tr_info("WB Reset Received");
/* Once reset complete evet is received we need
* to send a few more commands:
* Tx power and set bd addr
*/
if (get_bd_address(bd_addr)) {
aciWriteConfigData(CONFIG_DATA_PUBADDR_OFFSET, bd_addr);
tr_info("Setting Bdaddr: %02x:%02x:%02x:%02x:%02x:%02x",
bd_addr[0],
bd_addr[1],
bd_addr[2],
bd_addr[3],
bd_addr[4],
bd_addr[5]);
} else {
tr_info("could not find BDaddr");
/* Skip to next step */
set_tx_power(MBED_CONF_CORDIO_PREFERRED_TX_POWER);
}
break;
case ACI_WRITE_CONFIG_DATA_OPCODE:
tr_debug("Bluetooth Device address set");
/* set the event mask to control which events are generated by the
* controller for the host */
set_tx_power(MBED_CONF_CORDIO_PREFERRED_TX_POWER);
break;
case ACI_HAL_SET_TX_POWER_LEVEL:
tr_debug("Tx Power Level set");
//signal_reset_sequence_done();
HciSetEventMaskCmd((uint8_t *) hciEventMask);
break;
case HCI_OPCODE_SET_EVENT_MASK:
// set the event mask to control which LE events are generated by
// the controller for the host
HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask);
break;
case HCI_OPCODE_LE_SET_EVENT_MASK:
/* below command is not supported */
#if COMMAND_NOT_SUPPORTED_SKIP_STEP
// set the event mask to control which events are generated by the
// controller for the host (2nd page of flags )
HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2);
break;
case HCI_OPCODE_SET_EVENT_MASK_PAGE2:
#endif
// Ask the Bluetooth address of the controller
HciReadBdAddrCmd();
break;
case HCI_OPCODE_READ_BD_ADDR:
// Store the Bluetooth address in the stack runtime parameter
BdaCpy(hciCoreCb.bdAddr, pMsg);
// Read the size of the buffer of the controller
HciLeReadBufSizeCmd();
break;
case HCI_OPCODE_LE_READ_BUF_SIZE:
// Store the buffer parameters in the stack runtime parameters
BSTREAM_TO_UINT16(hciCoreCb.bufSize, pMsg);
BSTREAM_TO_UINT8(hciCoreCb.numBufs, pMsg);
/* initialize ACL buffer accounting */
hciCoreCb.availBufs = hciCoreCb.numBufs;
// read the states and state combinations supported by the link
// layer of the controller
HciLeReadSupStatesCmd();
break;
case HCI_OPCODE_LE_READ_SUP_STATES:
// store supported state and combination in the runtime parameters
// of the stack
memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN);
// read the total of whitelist entries that can be stored in the
// controller.
HciLeReadWhiteListSizeCmd();
break;
case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE:
// store the number of whitelist entries in the stack runtime
// parameters
BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg);
// Read the LE features supported by the controller
HciLeReadLocalSupFeatCmd();
break;
case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT:
// Store the set of LE features supported by the controller
BSTREAM_TO_UINT16(hciCoreCb.leSupFeat, pMsg);
// read the total number of address translation entries which can be
// stored in the controller resolving list.
hciCoreReadResolvingListSize();
break;
case HCI_OPCODE_LE_READ_RES_LIST_SIZE:
// store the number of address translation entries in the stack
// runtime parameter
BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg);
// read the Controller's maximum supported payload octets and packet
// duration times for transmission and reception
hciCoreReadMaxDataLen();
break;
case HCI_OPCODE_LE_READ_MAX_DATA_LEN: {
// store payload definition in the runtime stack parameters.
uint16_t maxTxOctets;
uint16_t maxTxTime;
BSTREAM_TO_UINT16(maxTxOctets, pMsg);
BSTREAM_TO_UINT16(maxTxTime, pMsg);
/* use Controller's maximum supported payload octets and packet duration times
* for transmission as Host's suggested values for maximum transmission number
* of payload octets and maximum packet transmission time for new connections.
*/
HciLeWriteDefDataLen(maxTxOctets, maxTxTime);
}
break;
case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN:
if (hciCoreCb.extResetSeq) {
HciReadLocalVerInfoCmd();
} else {
/* initialize extended parameters */
hciCoreCb.maxAdvDataLen = 0;
hciCoreCb.numSupAdvSets = 0;
hciCoreCb.perAdvListSize = 0;
/* send next command in sequence */
HciLeRandCmd();
}
break;
case HCI_OPCODE_READ_LOCAL_VER_INFO:
case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN:
case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS:
case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE:
// handle extended command
if (hciCoreCb.extResetSeq) {
/* send next extended command in sequence */
(*hciCoreCb.extResetSeq)(pMsg, opcode);
}
break;
case HCI_OPCODE_LE_RAND:
/* check if need to send second rand command */
if (randCnt < (HCI_RESET_RAND_CNT - 1)) {
randCnt++;
HciLeRandCmd();
} else {
uint8_t addr[6] = { 0 };
memcpy(addr, pMsg, sizeof(addr));
DM_RAND_ADDR_SET(addr, DM_RAND_ADDR_STATIC);
// note: will invoke set rand address
set_random_static_address(addr);
}
break;
case HCI_OPCODE_LE_SET_RAND_ADDR:
/* send next command in sequence */
signal_reset_sequence_done();
break;
default:
tr_info("Complete Event in reset seq with unknown opcode =0x%4X", opcode);
break;
}
} else if (*pMsg == HCI_CMD_STATUS_EVT) {
uint8_t status;
/* get status */
/* parse parameters */
pMsg += HCI_EVT_HDR_LEN;
status = *pMsg;
pMsg++;
pMsg++; /* skip num packets */
BSTREAM_TO_UINT16(opcode, pMsg);
tr_info("Command Status event, status:%d, opcode=0x%4X", status, opcode);
} else {
/**
* vendor specific event
*/
if (pMsg[0] == VENDOR_SPECIFIC_EVENT) {
/* parse parameters */
pMsg += HCI_EVT_HDR_LEN;
BSTREAM_TO_UINT16(opcode, pMsg);
tr_debug("Vendor specific event, opcode=0x%4X", opcode);
} else {
tr_info("Unknown event %d!", pMsg[0]);
}
}
}
private:
uint8_t bd_addr[6];
void aciReadConfigParameter(uint8_t offset)
{
uint8_t *pBuf = hciCmdAlloc(ACI_READ_CONFIG_DATA_OPCODE, 1);
if (!pBuf) {
return;
}
pBuf[3] = offset;
hciCmdSend(pBuf);
}
template<size_t N>
void aciWriteConfigData(uint8_t offset, uint8_t (&buf)[N])
{
uint8_t *pBuf = hciCmdAlloc(ACI_WRITE_CONFIG_DATA_OPCODE, 2 + N);
if (!pBuf) {
return;
}
pBuf[3] = offset;
pBuf[4] = N;
memcpy(pBuf + 5, buf, N);
hciCmdSend(pBuf);
}
void hciCoreReadResolvingListSize(void)
{
/* if LL Privacy is supported by Controller and included */
if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_PRIVACY) &&
(hciLeSupFeatCfg & HCI_LE_SUP_FEAT_PRIVACY)) {
/* send next command in sequence */
HciLeReadResolvingListSize();
} else {
hciCoreCb.resListSize = 0;
/* send next command in sequence */
hciCoreReadMaxDataLen();
}
}
void hciCoreReadMaxDataLen(void)
{
/* if LE Data Packet Length Extensions is supported by Controller and included */
if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_DATA_LEN_EXT) &&
(hciLeSupFeatCfg & HCI_LE_SUP_FEAT_DATA_LEN_EXT)) {
/* send next command in sequence */
HciLeReadMaxDataLen();
} else {
/* send next command in sequence */
HciLeRandCmd();
}
}
};
ble::buf_pool_desc_t ble::vendor::stm32wb::HCIDriver::get_buffer_pool_description()
{
// Use default buffer pool
return ble::CordioHCIDriver::get_default_buffer_pool_description();
}
class TransportDriver : public CordioHCITransportDriver {
public:
TransportDriver(TL_CmdPacket_t *BleCmdBuffer, TL_CmdPacket_t *SystemCmdBuffer, uint8_t *EvtPool, uint8_t *SystemSpareEvtBuffer, uint8_t *BleSpareEvtBuffer, uint8_t *HciAclDataBuffer)
{
bleCmdBuf = BleCmdBuffer;
sysCmdBuf = SystemCmdBuffer;
evtPool = EvtPool;
sysSpareEvtBuf = SystemSpareEvtBuffer;
bleSpareEvtBuf = BleSpareEvtBuffer;
aclDataBuffer = HciAclDataBuffer;
}
virtual ~TransportDriver() { }
/**
* @see CordioHCITransportDriver::initialize
*/
virtual void initialize()
{
/* Check whether M0 sub-system was started already by
* checking if the system event was already received
* before. If it was not, then go thru all init. */
if (!sysevt_check()) {
init_debug();
stm32wb_reset();
transport_init();
WirelessFwInfo_t wireless_info_instance;
WirelessFwInfo_t *p_wireless_info = &wireless_info_instance;
if (SHCI_GetWirelessFwInfo(p_wireless_info) != SHCI_Success) {
tr_info("SHCI_GetWirelessFwInfo error");
} else {
tr_info("WIRELESS COPROCESSOR FW VERSION ID = %d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, p_wireless_info->VersionSub);
tr_info("WIRELESS COPROCESSOR FW STACK TYPE = %d", p_wireless_info->StackType);
}
}
}
/**
* @see CordioHCITransportDriver::terminate
*/
virtual void terminate() { }
/**
* @see CordioHCITransportDriver::write
*/
virtual uint16_t write(uint8_t type, uint16_t len, uint8_t *pData)
{
return mbox_write(type, len, pData);
}
private:
void transport_init(void)
{
TL_MM_Config_t tl_mm_config;
TL_BLE_InitConf_t tl_ble_Config;
/* STM32WB offers a System Channel HCI interface for
offering system services, with proprietary commands.
System Channel must be used as well for starting up
BLE service so we need to initialize it. */
SHCI_TL_HciInitConf_t shci_init_config;
/**< Reference table initialization */
TL_Init();
/**< System channel initialization */
shci_init_config.p_cmdbuffer = (uint8_t *)sysCmdBuf;
shci_init_config.StatusNotCallBack = syscmd_status_not;
shci_init(sysevt_received, (void *) &shci_init_config);
/**< Memory Manager channel initialization */
tl_mm_config.p_BleSpareEvtBuffer = bleSpareEvtBuf;
tl_mm_config.p_SystemSpareEvtBuffer = sysSpareEvtBuf;
tl_mm_config.p_AsynchEvtPool = evtPool;
tl_mm_config.AsynchEvtPoolSize = POOL_SIZE;
TL_MM_Init(&tl_mm_config);
TL_Enable();
/* At this stage, we'll need to wait for ready event,
* passed thru TL_SYS_EvtReceived */
if (!sysevt_wait()) {
tr_info("ERROR booting WB controler");
return;
}
// TO DO : check if we need to disable LPM
// requires to import as well all lpm driver
tl_ble_Config.p_AclDataBuffer = aclDataBuffer;
tl_ble_Config.IoBusAclDataTxAck = acl_data_ack;
tl_ble_Config.p_cmdbuffer = (uint8_t *)bleCmdBuf;
tl_ble_Config.IoBusEvtCallBack = evt_received;
TL_BLE_Init(&tl_ble_Config);
/* Now start BLE service on firmware side, using Vendor specific
* command on the System Channe
*/
stm32wb_start_ble();
}
uint16_t mbox_write(uint8_t type, uint16_t len, uint8_t *pData)
{
// Note: Until enum is avalable
// type 01 Command
// type 02 ACL DATA
// type 03 SCO Voice (not supported)
// type 04 event - uplink (not suported)
tr_debug("mbox_write type:%d, len:%d", type, len);
/* TO DO : MANAGE ACL DATA CASE in separate buffer */
switch (type) {
case 1://BLE command
bleCmdBuf->cmdserial.type = type; // for now this param is overwritten in TL_BLE_SendCmd
memcpy((void *) &bleCmdBuf->cmdserial.cmd, pData, len);
/* We're tracing here the command, after copy in shared mem but before
* * M0 trigger. */
tr_info("TX>> BLE CMD");
/* Trace the buffer including Type (+1 on lngth) */
tr_debug(" Type %#x", bleCmdBuf->cmdserial.type);
tr_debug(" Cmd %#x", bleCmdBuf->cmdserial.cmd.cmdcode);
tr_debug(" Len %#x", bleCmdBuf->cmdserial.cmd.plen);
#if (PRINT_HCI_DATA)
for (uint8_t i = 0; i < bleCmdBuf->cmdserial.cmd.plen; i++) {
tr_debug(" %02X", *(((uint8_t *)&bleCmdBuf->cmdserial.cmd.payload) + i));
}
#endif
TL_BLE_SendCmd(NULL, 0); // unused parameters for now
break;
case 2://ACL DATA
if (!acl_data_wait()) {
tr_info("ERROR: previous ACL message not ACK'd");
/* return number of bytes sent, 0 in this error case */
return 0;
}
TL_AclDataSerial_t *aclDataSerial = (TL_AclDataSerial_t *)(aclDataBuffer + sizeof(TL_PacketHeader_t));
aclDataSerial->type = type; // for now this param is overwritten in TL_BLE_SendCmd
memcpy(aclDataBuffer + + sizeof(TL_PacketHeader_t) + sizeof(type), pData, len);
TL_BLE_SendAclData(NULL, 0); // unused parameters for now
tr_info("TX>> BLE ACL");
#if (PRINT_HCI_DATA)
for (uint8_t i = 0; i < len + 1 + 8; i++) {
tr_debug(" %02x", *(((uint8_t *) aclDataBuffer) + i));
}
#endif
break;
}
return len;
}
void stm32wb_reset(void)
{
// Reset IPCC
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC);
LL_C1_IPCC_ClearFlag_CHx(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_ClearFlag_CHx(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C1_IPCC_DisableTransmitChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_DisableTransmitChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C1_IPCC_DisableReceiveChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_DisableReceiveChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
/* Set IPCC default IRQ handlers */
NVIC_SetVector(IPCC_C1_TX_IRQn, (uint32_t)HW_IPCC_Tx_Handler);
NVIC_SetVector(IPCC_C1_RX_IRQn, (uint32_t)HW_IPCC_Rx_Handler);
return;
} // stm32wb_reset
void stm32wb_start_ble(void)
{
SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = {
0, 0, 0, /**< Header unused */
0, /** pBleBufferAddress not used */
0, /** BleBufferSize not used */
CFG_BLE_NUM_GATT_ATTRIBUTES,
CFG_BLE_NUM_GATT_SERVICES,
CFG_BLE_ATT_VALUE_ARRAY_SIZE,
CFG_BLE_NUM_LINK,
CFG_BLE_DATA_LENGTH_EXTENSION,
CFG_BLE_PREPARE_WRITE_LIST_SIZE,
CFG_BLE_MBLOCK_COUNT,
CFG_BLE_MAX_ATT_MTU,
CFG_BLE_SLAVE_SCA,
CFG_BLE_MASTER_SCA,
CFG_BLE_LSE_SOURCE,
CFG_BLE_MAX_CONN_EVENT_LENGTH,
CFG_BLE_HSE_STARTUP_TIME,
CFG_BLE_VITERBI_MODE,
CFG_BLE_LL_ONLY,
0 /** TODO Should be read from HW */
};
/**
* Starts the BLE Stack on CPU2
*/
SHCI_C2_BLE_Init(&ble_init_cmd_packet);
/* Used in flash_api.c */
BLE_inited = 1;
}
TL_CmdPacket_t *bleCmdBuf;
TL_CmdPacket_t *sysCmdBuf;
uint8_t *evtPool;
uint8_t *sysSpareEvtBuf;
uint8_t *aclDataBuffer;
uint8_t *bleSpareEvtBuf;
}; // class TransportDriver
} // namespace stm32wb
} // namespace vendor
} // namespace ble
/* There must be only 1 instance of the Transport Driver in STM32WB
* and the command buffers needs to be located in correct memory areas
*/
/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer;
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t HciAclDataBuffer[MAX_HCI_ACL_PACKET_SIZE];
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t EvtPool[POOL_SIZE];
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer;
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t BleSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
/**
* Cordio HCI driver factory
*/
ble::CordioHCIDriver &ble_cordio_get_hci_driver()
{
static ble::vendor::stm32wb::TransportDriver transport_driver(
&BleCmdBuffer,
&SystemCmdBuffer,
EvtPool,
SystemSpareEvtBuffer,
BleSpareEvtBuffer,
HciAclDataBuffer
);
static ble::vendor::stm32wb::HCIDriver hci_driver(
transport_driver /* other hci driver parameters */
);
return hci_driver;
}
static void evt_received(TL_EvtPacket_t *hcievt)
{
uint16_t len = 0;
// We need to memcpy the data before passing to higher layers.
switch (hcievt->evtserial.type) {
case TL_BLEEVT_PKT_TYPE:
len = hcievt->evtserial.evt.plen + TL_EVT_HDR_SIZE;
ble::vendor::stm32wb::TransportDriver::on_data_received((uint8_t *)&hcievt->evtserial, len);
break;
case TL_ACL_DATA_PKT_TYPE: {
TL_AclDataSerial_t *acl = &(((TL_AclDataPacket_t *)hcievt)->AclDataSerial);
len = acl->length + 5;
ble::vendor::stm32wb::TransportDriver::on_data_received((uint8_t *)acl, len);
}
break;
default:
// should not happen - let's block to check
tr_error("BLE TL evt_received, wrong type:%d", hcievt->evtserial.type);
break;
}
/* In case Event belongs to the Evt Pool we need to inform */
if (((uint8_t *)hcievt >= EvtPool) && ((uint8_t *)hcievt < (EvtPool + POOL_SIZE))) {
/* Free the message from shared memory */
TL_MM_EvtDone(hcievt);
}
}
/**
* TL Mailbox synchronisation means
*/
/* Using Semaphore to implemented blocking cmd/resp on system channel */
static rtos::Semaphore sys_event_sem(0, 1);
static rtos::Semaphore sys_resp_sem(0, 1);
static rtos::Semaphore acl_ack_sem(1, 1);
static void acl_data_ack(void)
{
/**
* The current implementation assumes the tackGUI will not send a new HCI ACL DATA packet before this ack is received
* ( which means the CPU2 has handled the previous packet )
* In order to implement a secure mechanism, it is required either
* - a flow control with the stack
* - a local pool of buffer to store packets received from the stack
*/
acl_ack_sem.release();
return;
}
static bool acl_data_wait(void)
{
/* Wait 10 sec for previous ACL command to be ack'ed by Low Layers
* before sending the next one */
if (!acl_ack_sem.try_acquire_for(10000)) {
return false;
} else {
return true;
}
}
/* WEAK callbacks from the BLE TL driver - will be called under Interrupt */
static void sysevt_received(void *pdata)
{
/* For now only READY event is received, so we know this is it */
sys_event_sem.release();
/* But later on ... we'll have to parse the answer */
return;
}
/* returns true if ssyevt was received, false otherwise */
static bool sysevt_wait(void)
{
/* Wait for 10sec max - if not return an error */
if (!sys_event_sem.try_acquire_for(10000)) {
return false;
} else {
/* release immmediately, now that M0 runs */
sys_event_sem.release();
return true;
}
}
/* returns true if ssyevt was already received, which means M0 core is
* already up and running */
static bool sysevt_check(void)
{
/* Check if system is UP and runing already */
if (!sys_event_sem.try_acquire_for(10)) {
return false;
} else {
/* release immmediately as M0 already runs */
sys_event_sem.release();
return true;
}
}
static void syscmd_status_not(SHCI_TL_CmdStatus_t status)
{
tr_debug("syscmd_status_not, status:%d", status);
return;
}
void shci_notify_asynch_evt(void *pdata)
{
/* Need to parse data in future version */
shci_user_evt_proc();
return;
}
void shci_cmd_resp_release(uint32_t flag)
{
sys_resp_sem.release();
return;
}
void shci_cmd_resp_wait(uint32_t timeout)
{
/* TO DO: manage timeouts if we can return an error */
if (!sys_resp_sem.try_acquire_for(timeout)) {
tr_error("shci_cmd_resp_wait timed out");
}
}
void shci_register_io_bus(tSHciIO *fops)
{
/* Register IO bus services */
fops->Init = TL_SYS_Init;
fops->Send = TL_SYS_SendCmd;
}
/**
* Few utilities functions
*/
static void init_debug(void)
{
/* In case of MBED debug profile, configure debugger support */
#if (defined(MBED_DEBUG) || (CFG_DEBUGGER_SUPPORTED == 1))
tr_info("init_debug ENABLED");
/**
* Keep debugger enabled while in any low power mode
*/
HAL_DBGMCU_EnableDBGSleepMode();
HAL_DBGMCU_EnableDBGStopMode();
HAL_DBGMCU_EnableDBGStandbyMode();
/***************** ENABLE DEBUGGER *************************************/
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
LL_C2_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
#else
tr_info("init_debug DISABLED");
GPIO_InitTypeDef gpio_config = {0};
gpio_config.Pull = GPIO_NOPULL;
gpio_config.Mode = GPIO_MODE_ANALOG;
gpio_config.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13;
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA, &gpio_config);
gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_3;
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_Init(GPIOB, &gpio_config);
HAL_DBGMCU_DisableDBGSleepMode();
HAL_DBGMCU_DisableDBGStopMode();
HAL_DBGMCU_DisableDBGStandbyMode();
#endif /* (CFG_DEBUGGER_SUPPORTED == 1) */
return;
}
/* This function fills in a BD address table */
bool get_bd_address(uint8_t *bd_addr)
{
uint8_t *otp_addr;
uint32_t udn;
uint32_t company_id;
uint32_t device_id;
bool bd_found;
udn = LL_FLASH_GetUDN();
if (udn != 0xFFFFFFFF) {
tr_info("Found Unique Device Number: %#06x", udn);
company_id = LL_FLASH_GetSTCompanyID();
device_id = LL_FLASH_GetDeviceID();
bd_addr[0] = (uint8_t)(udn & 0x000000FF);
bd_addr[1] = (uint8_t)((udn & 0x0000FF00) >> 8);
bd_addr[2] = (uint8_t)((udn & 0x00FF0000) >> 16);
bd_addr[3] = (uint8_t)device_id;
bd_addr[4] = (uint8_t)(company_id & 0x000000FF);
bd_addr[5] = (uint8_t)((company_id & 0x0000FF00) >> 8);
bd_found = true;
} else {
otp_addr = OTP_Read(0);
if (otp_addr) {
memcpy(bd_addr, ((OTP_ID0_t *)otp_addr)->bd_address, CONFIG_DATA_PUBADDR_LEN);
bd_found = false;
} else {
tr_debug("Cannot find Bluetooth Device ADDRESS to program - will leave hw default");
bd_found = true;
}
}
return bd_found;
}

View File

@@ -0,0 +1,258 @@
/**
******************************************************************************
* @file mbox_def.h
* @author MCD Application Team
* @brief Mailbox definition
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* 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;
} 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_LldBleTable_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_LldBleTable_t *p_lld_ble_table;
} MB_RefTable_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--------------------|
* | |
* | (LLD BLE) |
* |----HW_IPCC_LLD_BLE_CMD_CHANNEL----------------->|
* | |
* |<---HW_IPCC_LLD_BLE_RSP_CHANNEL------------------|
* | |
* |<---HW_IPCC_LLD_BLE_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_LLD_BLE_CLI_CMD_CHANNEL LL_IPCC_CHANNEL_5
#define HW_IPCC_LLD_BLE_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_LLD_BLE_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_LLD_BLE_CLI_RSP_CHANNEL LL_IPCC_CHANNEL_5
#define HW_IPCC_LLD_BLE_RSP_CHANNEL LL_IPCC_CHANNEL_5
#define HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL LL_IPCC_CHANNEL_5
#endif /*__MBOX_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,590 @@
/**
******************************************************************************
* @file shci.c
* @author MCD Application Team
* @brief HCI command for the system channel
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32_wpan_common.h"
#include "shci_tl.h"
#include "shci.h"
#include "stm32wbxx.h"
/* Private typedef -----------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Global variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Local Functions Definition ------------------------------------------------------*/
/* Public Functions Definition ------------------------------------------------------*/
/**
* C2 COMMAND
* These commands are sent to the CPU2
*/
uint8_t SHCI_C2_FUS_GetState( SHCI_FUS_GetState_ErrorCode_t *p_error_code )
{
/**
* A command status event + payload has the same size than the expected command complete
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE + 1];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_FUS_GET_STATE,
0,
0,
p_rsp );
if(p_error_code != 0)
{
*p_error_code = (SHCI_FUS_GetState_ErrorCode_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[1]);
}
return (((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FUS_FwUpgrade( uint32_t fw_src_add, uint32_t fw_dest_add )
{
/**
* TL_BLEEVT_CS_BUFFER_SIZE is 15 bytes so it is large enough to hold the 8 bytes of command parameters
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
uint32_t *p_cmd;
uint8_t cmd_length;
p_cmd = (uint32_t*)local_buffer;
cmd_length = 0;
if(fw_src_add != 0)
{
*p_cmd = fw_src_add;
cmd_length += 4;
}
if(fw_dest_add != 0)
{
*(p_cmd+1) = fw_dest_add;
cmd_length += 4;
}
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_FUS_FW_UPGRADE,
cmd_length,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FUS_FwDelete( void )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_FUS_FW_DELETE,
0,
0,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FUS_UpdateAuthKey( SHCI_C2_FUS_UpdateAuthKey_Cmd_Param_t *pParam )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_FUS_UPDATE_AUTH_KEY,
sizeof( SHCI_C2_FUS_UpdateAuthKey_Cmd_Param_t ),
(uint8_t*)pParam,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FUS_LockAuthKey( void )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_FUS_LOCK_AUTH_KEY,
0,
0,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FUS_StoreUsrKey( SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t *pParam, uint8_t *p_key_index )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE + 1];
TL_EvtPacket_t * p_rsp;
uint8_t local_payload_len;
if(pParam->KeyType == KEYTYPE_ENCRYPTED)
{
/**
* When the key is encrypted, the 12 bytes IV Key is included in the payload as well
* The IV key is always 12 bytes
*/
local_payload_len = pParam->KeySize + 2 + 12;
}
else
{
local_payload_len = pParam->KeySize + 2;
}
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_FUS_STORE_USR_KEY,
local_payload_len ,
(uint8_t*)pParam,
p_rsp );
*p_key_index = (((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[1]);
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FUS_LoadUsrKey( uint8_t key_index )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
local_buffer[0] = key_index;
shci_send( SHCI_OPCODE_C2_FUS_LOAD_USR_KEY,
1,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FUS_StartWs( void )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_FUS_START_WS,
0,
0,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FUS_LockUsrKey( uint8_t key_index )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
local_buffer[0] = key_index;
shci_send( SHCI_OPCODE_C2_FUS_LOCK_USR_KEY,
1,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_BLE_Init( SHCI_C2_Ble_Init_Cmd_Packet_t *pCmdPacket )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_BLE_INIT,
sizeof( SHCI_C2_Ble_Init_Cmd_Param_t ),
(uint8_t*)&pCmdPacket->Param,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_THREAD_Init( void )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_THREAD_INIT,
0,
0,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_LLDTESTS_Init( uint8_t param_size, uint8_t * p_param )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_LLD_TESTS_INIT,
param_size,
p_param,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_LLD_BLE_Init( uint8_t param_size, uint8_t * p_param )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_LLD_TESTS_INIT,
param_size,
p_param,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_ZIGBEE_Init( void )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_ZIGBEE_INIT,
0,
0,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_DEBUG_Init( SHCI_C2_DEBUG_Init_Cmd_Packet_t *pCmdPacket )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_DEBUG_INIT,
sizeof( SHCI_C2_DEBUG_init_Cmd_Param_t ),
(uint8_t*)&pCmdPacket->Param,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FLASH_EraseActivity( SHCI_EraseActivity_t erase_activity )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
local_buffer[0] = erase_activity;
shci_send( SHCI_OPCODE_C2_FLASH_ERASE_ACTIVITY,
1,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_CONCURRENT_SetMode( SHCI_C2_CONCURRENT_Mode_Param_t Mode )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
local_buffer[0] = Mode;
shci_send( SHCI_OPCODE_C2_CONCURRENT_SET_MODE,
1,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FLASH_StoreData( SHCI_C2_FLASH_Ip_t Ip )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
local_buffer[0] = Ip;
shci_send( SHCI_OPCODE_C2_FLASH_STORE_DATA,
1,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_FLASH_EraseData( SHCI_C2_FLASH_Ip_t Ip )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
local_buffer[0] = Ip;
shci_send( SHCI_OPCODE_C2_FLASH_ERASE_DATA,
1,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_RADIO_AllowLowPower( SHCI_C2_FLASH_Ip_t Ip,uint8_t FlagRadioLowPowerOn)
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
local_buffer[0] = Ip;
local_buffer[1] = FlagRadioLowPowerOn;
shci_send( SHCI_OPCODE_C2_RADIO_ALLOW_LOW_POWER,
2,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_MAC_802_15_4_Init( void )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_MAC_802_15_4_INIT,
0,
0,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_Reinit( void )
{
/**
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
shci_send( SHCI_OPCODE_C2_REINIT,
0,
0,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_ExtpaConfig(uint32_t gpio_port, uint16_t gpio_pin_number, uint8_t gpio_polarity, uint8_t gpio_status)
{
/**
* TL_BLEEVT_CS_BUFFER_SIZE is 15 bytes so it is large enough to hold the 8 bytes of command parameters
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
((SHCI_C2_EXTPA_CONFIG_Cmd_Param_t*)local_buffer)->gpio_port = gpio_port;
((SHCI_C2_EXTPA_CONFIG_Cmd_Param_t*)local_buffer)->gpio_pin_number = gpio_pin_number;
((SHCI_C2_EXTPA_CONFIG_Cmd_Param_t*)local_buffer)->gpio_polarity = gpio_polarity;
((SHCI_C2_EXTPA_CONFIG_Cmd_Param_t*)local_buffer)->gpio_status = gpio_status;
shci_send( SHCI_OPCODE_C2_EXTPA_CONFIG,
8,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
SHCI_CmdStatus_t SHCI_C2_SetFlashActivityControl(SHCI_C2_SET_FLASH_ACTIVITY_CONTROL_Source_t Source)
{
/**
* TL_BLEEVT_CS_BUFFER_SIZE is 15 bytes so it is large enough to hold the 1 byte of command parameter
* Buffer is large enough to hold command complete without payload
*/
uint8_t local_buffer[TL_BLEEVT_CS_BUFFER_SIZE];
TL_EvtPacket_t * p_rsp;
p_rsp = (TL_EvtPacket_t *)local_buffer;
local_buffer[0] = (uint8_t)Source;
shci_send( SHCI_OPCODE_C2_SET_FLASH_ACTIVITY_CONTROL,
1,
local_buffer,
p_rsp );
return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
}
/**
* Local System COMMAND
* These commands are NOT sent to the CPU2
*/
SHCI_CmdStatus_t SHCI_GetWirelessFwInfo( WirelessFwInfo_t* pWirelessInfo )
{
uint32_t ipccdba = 0;
MB_RefTable_t * p_RefTable = NULL;
uint32_t version = 0;
uint32_t memorySize = 0;
uint32_t infoStack = 0;
ipccdba = READ_BIT( FLASH->IPCCBR, FLASH_IPCCBR_IPCCDBA );
p_RefTable = (MB_RefTable_t*)((ipccdba<<2) + SRAM2A_BASE);
/**
* Retrieve the WirelessFwInfoTable
* This table is stored in RAM at startup during the TL (transport layer) initialization
*/
version = p_RefTable->p_device_info_table->WirelessFwInfoTable.Version;
pWirelessInfo->VersionMajor = ((version & INFO_VERSION_MAJOR_MASK) >> INFO_VERSION_MAJOR_OFFSET);
pWirelessInfo->VersionMinor = ((version & INFO_VERSION_MINOR_MASK) >> INFO_VERSION_MINOR_OFFSET);
pWirelessInfo->VersionSub = ((version & INFO_VERSION_SUB_MASK) >> INFO_VERSION_SUB_OFFSET);
pWirelessInfo->VersionBranch = ((version & INFO_VERSION_BRANCH_MASK) >> INFO_VERSION_BRANCH_OFFSET);
pWirelessInfo->VersionReleaseType = ((version & INFO_VERSION_TYPE_MASK) >> INFO_VERSION_TYPE_OFFSET);
memorySize = p_RefTable->p_device_info_table->WirelessFwInfoTable.MemorySize;
pWirelessInfo->MemorySizeSram2B = ((memorySize & INFO_SIZE_SRAM2B_MASK) >> INFO_SIZE_SRAM2B_OFFSET);
pWirelessInfo->MemorySizeSram2A = ((memorySize & INFO_SIZE_SRAM2A_MASK) >> INFO_SIZE_SRAM2A_OFFSET);
pWirelessInfo->MemorySizeSram1 = ((memorySize & INFO_SIZE_SRAM1_MASK) >> INFO_SIZE_SRAM1_OFFSET);
pWirelessInfo->MemorySizeFlash = ((memorySize & INFO_SIZE_FLASH_MASK) >> INFO_SIZE_FLASH_OFFSET);
infoStack = p_RefTable->p_device_info_table->WirelessFwInfoTable.InfoStack;
pWirelessInfo->StackType = ((infoStack & INFO_STACK_TYPE_MASK) >> INFO_STACK_TYPE_OFFSET);
/**
* Retrieve the FusInfoTable
* This table is stored in RAM at startup during the TL (transport layer) initialization
*/
version = p_RefTable->p_device_info_table->FusInfoTable.Version;
pWirelessInfo->FusVersionMajor = ((version & INFO_VERSION_MAJOR_MASK) >> INFO_VERSION_MAJOR_OFFSET);
pWirelessInfo->FusVersionMinor = ((version & INFO_VERSION_MINOR_MASK) >> INFO_VERSION_MINOR_OFFSET);
pWirelessInfo->FusVersionSub = ((version & INFO_VERSION_SUB_MASK) >> INFO_VERSION_SUB_OFFSET);
memorySize = p_RefTable->p_device_info_table->FusInfoTable.MemorySize;
pWirelessInfo->FusMemorySizeSram2B = ((memorySize & INFO_SIZE_SRAM2B_MASK) >> INFO_SIZE_SRAM2B_OFFSET);
pWirelessInfo->FusMemorySizeSram2A = ((memorySize & INFO_SIZE_SRAM2A_MASK) >> INFO_SIZE_SRAM2A_OFFSET);
pWirelessInfo->FusMemorySizeFlash = ((memorySize & INFO_SIZE_FLASH_MASK) >> INFO_SIZE_FLASH_OFFSET);
return (SHCI_Success);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,771 @@
/**
******************************************************************************
* @file shci.h
* @author MCD Application Team
* @brief HCI command for the system channel
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SHCI_H
#define __SHCI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "mbox_def.h" /* Requested to expose the MB_WirelessFwInfoTable_t structure */
/* Exported types ------------------------------------------------------------*/
/* SYSTEM EVENT */
typedef enum
{
WIRELESS_FW_RUNNING = 0x00,
RSS_FW_RUNNING = 0x01,
} SHCI_SysEvt_Ready_Rsp_t;
/* ERROR CODES
*
* These error codes are detected on M0 side and are send back to the M4 via a system
* notification message. It is up to the application running on M4 to manage these errors
*
* These errors can be generated by all layers (low level driver, stack, framework infrastructure, etc..)
*/
typedef enum
{
ERR_BLE_INIT = 0,
ERR_THREAD_LLD_FATAL_ERROR = 125, /* The LLD driver used on 802_15_4 detected a fatal error */
ERR_THREAD_UNKNOWN_CMD = 126, /* The command send by the M4 to control the Thread stack is unknown */
ERR_ZIGBEE_UNKNOWN_CMD = 200, /* The command send by the M4 to control the Zigbee stack is unknown */
} SCHI_SystemErrCode_t;
#define SHCI_EVTCODE ( 0xFF )
#define SHCI_SUB_EVT_CODE_BASE ( 0x9200 )
/**
* THE ORDER SHALL NOT BE CHANGED TO GUARANTEE COMPATIBILITY WITH THE CPU1 DEFINITION
*/
typedef enum
{
SHCI_SUB_EVT_CODE_READY = SHCI_SUB_EVT_CODE_BASE,
SHCI_SUB_EVT_ERROR_NOTIF,
} SHCI_SUB_EVT_CODE_t;
typedef PACKED_STRUCT{
SHCI_SysEvt_Ready_Rsp_t sysevt_ready_rsp;
} SHCI_C2_Ready_Evt_t;
typedef PACKED_STRUCT{
SCHI_SystemErrCode_t errorCode;
} SHCI_C2_ErrorNotif_Evt_t;
/* SYSTEM COMMAND */
typedef PACKED_STRUCT
{
uint32_t MetaData[3];
} SHCI_Header_t;
typedef enum
{
SHCI_Success = 0x00,
SHCI_UNKNOWN_CMD = 0x01,
SHCI_ERR_UNSUPPORTED_FEATURE = 0x11,
SHCI_ERR_INVALID_HCI_CMD_PARAMS = 0x12,
SHCI_FUS_CMD_NOT_SUPPORTED = 0xFF,
} SHCI_CmdStatus_t;
typedef enum
{
SHCI_8BITS = 0x01,
SHCI_16BITS = 0x02,
SHCI_32BITS = 0x04,
} SHCI_Busw_t;
#define SHCI_OGF ( 0x3F )
#define SHCI_OCF_BASE ( 0x50 )
/**
* THE ORDER SHALL NOT BE CHANGED TO GUARANTEE COMPATIBILITY WITH THE CPU2 DEFINITION
*/
typedef enum
{
SHCI_OCF_C2_RESERVED1 = SHCI_OCF_BASE,
SHCI_OCF_C2_RESERVED2,
SHCI_OCF_C2_FUS_GET_STATE,
SHCI_OCF_C2_FUS_RESERVED1,
SHCI_OCF_C2_FUS_FW_UPGRADE,
SHCI_OCF_C2_FUS_FW_DELETE,
SHCI_OCF_C2_FUS_UPDATE_AUTH_KEY,
SHCI_OCF_C2_FUS_LOCK_AUTH_KEY,
SHCI_OCF_C2_FUS_STORE_USR_KEY,
SHCI_OCF_C2_FUS_LOAD_USR_KEY,
SHCI_OCF_C2_FUS_START_WS,
SHCI_OCF_C2_FUS_RESERVED2,
SHCI_OCF_C2_FUS_RESERVED3,
SHCI_OCF_C2_FUS_LOCK_USR_KEY,
SHCI_OCF_C2_FUS_RESERVED5,
SHCI_OCF_C2_FUS_RESERVED6,
SHCI_OCF_C2_FUS_RESERVED7,
SHCI_OCF_C2_FUS_RESERVED8,
SHCI_OCF_C2_FUS_RESERVED9,
SHCI_OCF_C2_FUS_RESERVED10,
SHCI_OCF_C2_FUS_RESERVED11,
SHCI_OCF_C2_FUS_RESERVED12,
SHCI_OCF_C2_BLE_INIT,
SHCI_OCF_C2_THREAD_INIT,
SHCI_OCF_C2_DEBUG_INIT,
SHCI_OCF_C2_FLASH_ERASE_ACTIVITY,
SHCI_OCF_C2_CONCURRENT_SET_MODE,
SHCI_OCF_C2_FLASH_STORE_DATA,
SHCI_OCF_C2_FLASH_ERASE_DATA,
SHCI_OCF_C2_RADIO_ALLOW_LOW_POWER,
SHCI_OCF_C2_MAC_802_15_4_INIT,
SHCI_OCF_C2_REINIT,
SHCI_OCF_C2_ZIGBEE_INIT,
SHCI_OCF_C2_LLD_TESTS_INIT,
SHCI_OCF_C2_EXTPA_CONFIG,
SHCI_OCF_C2_SET_FLASH_ACTIVITY_CONTROL,
SHCI_OCF_C2_LLD_BLE_INIT
} SHCI_OCF_t;
#define SHCI_OPCODE_C2_FUS_GET_STATE (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_GET_STATE)
/** No command parameters */
/** Response parameters*/
typedef enum
{
FUS_STATE_NO_ERROR = 0x00,
FUS_STATE_IMG_NOT_FOUND = 0x01,
FUS_STATE_IMG_CORRUPT = 0x02,
FUS_STATE_IMG_NOT_AUTHENTIC = 0x03,
FUS_STATE_IMG_NOT_ENOUGH_SPACE = 0x04,
FUS_STATE_ERR_UNKNOWN = 0xFF,
} SHCI_FUS_GetState_ErrorCode_t;
#define SHCI_OPCODE_C2_FUS_RESERVED1 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED1)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_FW_UPGRADE (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_FW_UPGRADE)
/** No structure for command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_FW_DELETE (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_FW_DELETE)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_UPDATE_AUTH_KEY (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_UPDATE_AUTH_KEY)
typedef PACKED_STRUCT{
uint8_t KeySize;
uint8_t KeyData[64];
} SHCI_C2_FUS_UpdateAuthKey_Cmd_Param_t;
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_LOCK_AUTH_KEY (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_LOCK_AUTH_KEY)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_STORE_USR_KEY (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_STORE_USR_KEY)
/** Command parameters */
/* List of supported key type */
enum
{
KEYTYPE_NONE = 0x00,
KEYTYPE_SIMPLE = 0x01,
KEYTYPE_MASTER = 0x02,
KEYTYPE_ENCRYPTED = 0x03,
};
/* List of supported key size */
enum
{
KEYSIZE_16 = 16,
KEYSIZE_32 = 32,
};
typedef PACKED_STRUCT{
uint8_t KeyType;
uint8_t KeySize;
uint8_t KeyData[32 + 12];
} SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t;
/** Response parameters*/
/** It responds a 1 byte value holding the index given for the stored key */
#define SHCI_OPCODE_C2_FUS_LOAD_USR_KEY (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_LOAD_USR_KEY)
/** Command parameters */
/** 1 byte holding the key index value */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_START_WS (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_START_WS)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED2 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED2)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED3 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED3)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_LOCK_USR_KEY (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_LOCK_USR_KEY)
/** Command parameters */
/** 1 byte holding the key index value */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED5 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED5)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED6 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED6)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED7 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED7)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED8 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED8)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED9 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED9)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED10 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED10)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED11 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED11)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_FUS_RESERVED12 (( SHCI_OGF << 10) + SHCI_OCF_C2_FUS_RESERVED12)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_BLE_INIT (( SHCI_OGF << 10) + SHCI_OCF_C2_BLE_INIT)
/** THE ORDER SHALL NOT BE CHANGED */
typedef PACKED_STRUCT{
uint8_t* pBleBufferAddress; /**< NOT USED CURRENTLY */
uint32_t BleBufferSize; /**< Size of the Buffer allocated in pBleBufferAddress */
uint16_t NumAttrRecord;
uint16_t NumAttrServ;
uint16_t AttrValueArrSize;
uint8_t NumOfLinks;
uint8_t ExtendedPacketLengthEnable;
uint8_t PrWriteListSize;
uint8_t MblockCount;
uint16_t AttMtu;
uint16_t SlaveSca;
uint8_t MasterSca;
uint8_t LsSource;
uint32_t MaxConnEventLength;
uint16_t HsStartupTime;
uint8_t ViterbiEnable;
uint8_t LlOnly;
uint8_t HwVersion;
} SHCI_C2_Ble_Init_Cmd_Param_t;
typedef PACKED_STRUCT{
SHCI_Header_t Header; /** Does not need to be initialized by the user */
SHCI_C2_Ble_Init_Cmd_Param_t Param;
} SHCI_C2_Ble_Init_Cmd_Packet_t;
/** No response parameters*/
#define SHCI_OPCODE_C2_THREAD_INIT (( SHCI_OGF << 10) + SHCI_OCF_C2_THREAD_INIT)
/** No command parameters */
/** No response parameters*/
#define SHCI_OPCODE_C2_DEBUG_INIT (( SHCI_OGF << 10) + SHCI_OCF_C2_DEBUG_INIT)
/** Command parameters */
typedef PACKED_STRUCT
{
uint8_t thread_config;
uint8_t ble_config;
uint8_t mac_802_15_4_config;
uint8_t zigbee_config;
} SHCI_C2_DEBUG_TracesConfig_t;
typedef PACKED_STRUCT
{
uint8_t ble_dtb_cfg;
uint8_t reserved[3];
} SHCI_C2_DEBUG_GeneralConfig_t;
typedef PACKED_STRUCT{
uint8_t *pGpioConfig;
uint8_t *pTracesConfig;
uint8_t *pGeneralConfig;
uint8_t GpioConfigSize;
uint8_t TracesConfigSize;
uint8_t GeneralConfigSize;
} SHCI_C2_DEBUG_init_Cmd_Param_t;
typedef PACKED_STRUCT{
SHCI_Header_t Header; /** Does not need to be initialized by the user */
SHCI_C2_DEBUG_init_Cmd_Param_t Param;
} SHCI_C2_DEBUG_Init_Cmd_Packet_t;
/** No response parameters*/
#define SHCI_OPCODE_C2_FLASH_ERASE_ACTIVITY (( SHCI_OGF << 10) + SHCI_OCF_C2_FLASH_ERASE_ACTIVITY)
/** Command parameters */
typedef enum
{
ERASE_ACTIVITY_OFF = 0x00,
ERASE_ACTIVITY_ON = 0x01,
} SHCI_EraseActivity_t;
/** No response parameters*/
#define SHCI_OPCODE_C2_CONCURRENT_SET_MODE (( SHCI_OGF << 10) + SHCI_OCF_C2_CONCURRENT_SET_MODE)
/** command parameters */
typedef enum
{
BLE_ENABLE,
THREAD_ENABLE,
ZIGBEE_ENABLE,
} SHCI_C2_CONCURRENT_Mode_Param_t;
/** No response parameters*/
#define SHCI_OPCODE_C2_FLASH_STORE_DATA (( SHCI_OGF << 10) + SHCI_OCF_C2_FLASH_STORE_DATA)
#define SHCI_OPCODE_C2_FLASH_ERASE_DATA (( SHCI_OGF << 10) + SHCI_OCF_C2_FLASH_ERASE_DATA)
/** command parameters */
typedef enum
{
BLE_IP,
THREAD_IP,
ZIGBEE_IP,
} SHCI_C2_FLASH_Ip_t;
/** No response parameters*/
#define SHCI_OPCODE_C2_RADIO_ALLOW_LOW_POWER (( SHCI_OGF << 10) + SHCI_OCF_C2_RADIO_ALLOW_LOW_POWER)
#define SHCI_OPCODE_C2_MAC_802_15_4_INIT (( SHCI_OGF << 10) + SHCI_OCF_C2_MAC_802_15_4_INIT)
#define SHCI_OPCODE_C2_REINIT (( SHCI_OGF << 10) + SHCI_OCF_C2_REINIT)
#define SHCI_OPCODE_C2_ZIGBEE_INIT (( SHCI_OGF << 10) + SHCI_OCF_C2_ZIGBEE_INIT)
#define SHCI_OPCODE_C2_LLD_TESTS_INIT (( SHCI_OGF << 10) + SHCI_OCF_C2_LLD_TESTS_INIT)
#define SHCI_OPCODE_C2_LLD_BLE_INIT (( SHCI_OGF << 10) + SHCI_OCF_C2_LLD_BLE_INIT)
#define SHCI_OPCODE_C2_EXTPA_CONFIG (( SHCI_OGF << 10) + SHCI_OCF_C2_EXTPA_CONFIG)
/** Command parameters */
enum
{
EXT_PA_ENABLED_LOW,
EXT_PA_ENABLED_HIGH,
}/* gpio_polarity */;
enum
{
EXT_PA_DISABLED,
EXT_PA_ENABLED,
}/* gpio_status */;
typedef PACKED_STRUCT{
uint32_t gpio_port;
uint16_t gpio_pin_number;
uint8_t gpio_polarity;
uint8_t gpio_status;
} SHCI_C2_EXTPA_CONFIG_Cmd_Param_t;
/** No response parameters*/
#define SHCI_OPCODE_C2_SET_FLASH_ACTIVITY_CONTROL (( SHCI_OGF << 10) + SHCI_OCF_C2_SET_FLASH_ACTIVITY_CONTROL)
/** Command parameters */
typedef enum
{
FLASH_ACTIVITY_CONTROL_PES,
FLASH_ACTIVITY_CONTROL_SEM7,
}SHCI_C2_SET_FLASH_ACTIVITY_CONTROL_Source_t;
/** No response parameters*/
/* Exported type --------------------------------------------------------*/
typedef MB_WirelessFwInfoTable_t SHCI_WirelessFwInfoTable_t;
/*
* At startup, the informations relative to the wireless binary are stored in RAM trough a structure defined by
* SHCI_WirelessFwInfoTable_t.This structure contains 4 fields (Version,MemorySize, Stack_info and a reserved part)
* each of those coded on 32 bits as shown on the table below:
*
*
* |7 |6 |5 |4 |3 |2 |1 |0 |7 |6 |5 |4 |3 |2 |1 |0 |7 |6 |5 |4 |3 |2 |1 |0 |7 |6 |5 |4 |3 |2 |1 |0 |
* -------------------------------------------------------------------------------------------------
* Version | Major version | Minor version | Sub version | Branch |Releas Type|
* -------------------------------------------------------------------------------------------------
* MemorySize | SRAM2B (kB) | SRAM2A (kB) | SRAM1 (kB) | FLASH (4kb) |
* -------------------------------------------------------------------------------------------------
* Info stack | Reserved | Reserved | Reserved | Type (MAC,Thread,BLE) |
* -------------------------------------------------------------------------------------------------
* Reserved | Reserved | Reserved | Reserved | Reserved |
* -------------------------------------------------------------------------------------------------
*
*/
/* Field Version */
#define INFO_VERSION_MAJOR_OFFSET 24
#define INFO_VERSION_MAJOR_MASK 0xff000000
#define INFO_VERSION_MINOR_OFFSET 16
#define INFO_VERSION_MINOR_MASK 0x00ff0000
#define INFO_VERSION_SUB_OFFSET 8
#define INFO_VERSION_SUB_MASK 0x0000ff00
#define INFO_VERSION_BRANCH_OFFSET 4
#define INFO_VERSION_BRANCH_MASK 0x0000000f0
#define INFO_VERSION_TYPE_OFFSET 0
#define INFO_VERSION_TYPE_MASK 0x00000000f
#define INFO_VERSION_TYPE_RELEASE 1
/* Field Memory */
#define INFO_SIZE_SRAM2B_OFFSET 24
#define INFO_SIZE_SRAM2B_MASK 0xff000000
#define INFO_SIZE_SRAM2A_OFFSET 16
#define INFO_SIZE_SRAM2A_MASK 0x00ff0000
#define INFO_SIZE_SRAM1_OFFSET 8
#define INFO_SIZE_SRAM1_MASK 0x0000ff00
#define INFO_SIZE_FLASH_OFFSET 0
#define INFO_SIZE_FLASH_MASK 0x000000ff
/* Field stack information */
#define INFO_STACK_TYPE_OFFSET 0
#define INFO_STACK_TYPE_MASK 0x000000ff
#define INFO_STACK_TYPE_NONE 0
#define INFO_STACK_TYPE_BLE_STANDARD 0x01
#define INFO_STACK_TYPE_BLE_HCI 0x02
#define INFO_STACK_TYPE_BLE_LIGHT 0x03
#define INFO_STACK_TYPE_THREAD_FTD 0x10
#define INFO_STACK_TYPE_THREAD_MTD 0x11
#define INFO_STACK_TYPE_ZIGBEE_FFD 0x30
#define INFO_STACK_TYPE_ZIGBEE_RFD 0x31
#define INFO_STACK_TYPE_MAC 0x40
#define INFO_STACK_TYPE_BLE_THREAD_FTD_STATIC 0x50
#define INFO_STACK_TYPE_802154_LLD_TESTS 0x60
#define INFO_STACK_TYPE_802154_PHY_VALID 0x61
#define INFO_STACK_TYPE_BLE_PHY_VALID 0x62
#define INFO_STACK_TYPE_BLE_LLD_TESTS 0x63
#define INFO_STACK_TYPE_BLE_RLV 0x64
#define INFO_STACK_TYPE_802154_RLV 0x65
#define INFO_STACK_TYPE_BLE_ZIGBEE_FFD_STATIC 0x70
typedef struct {
/**
* Wireless Info
*/
uint8_t VersionMajor;
uint8_t VersionMinor;
uint8_t VersionSub;
uint8_t VersionBranch;
uint8_t VersionReleaseType;
uint8_t MemorySizeSram2B; /*< Multiple of 1K */
uint8_t MemorySizeSram2A; /*< Multiple of 1K */
uint8_t MemorySizeSram1; /*< Multiple of 1K */
uint8_t MemorySizeFlash; /*< Multiple of 4K */
uint8_t StackType;
/**
* Fus Info
*/
uint8_t FusVersionMajor;
uint8_t FusVersionMinor;
uint8_t FusVersionSub;
uint8_t FusMemorySizeSram2B; /*< Multiple of 1K */
uint8_t FusMemorySizeSram2A; /*< Multiple of 1K */
uint8_t FusMemorySizeFlash; /*< Multiple of 4K */
}WirelessFwInfo_t;
/* Exported functions ------------------------------------------------------- */
/**
* For all SHCI_C2_FUS_xxx() command:
* When the wireless FW is running on the CPU2, the command returns SHCI_FUS_CMD_NOT_SUPPORTED
* When any FUS command is sent after the SHCI_FUS_CMD_NOT_SUPPORTED has been received,
* the CPU2 switches on the RSS ( This reboots automatically the device )
*/
/**
* SHCI_C2_FUS_GetState
* @brief Read the FUS State
* If the user is not interested by the Error code response, a null value may
* be passed as parameter
*
* @param p_rsp : return the error code when the FUS State Value = 0xFF
* @retval FUS State Values
*/
uint8_t SHCI_C2_FUS_GetState( SHCI_FUS_GetState_ErrorCode_t *p_rsp );
/**
* SHCI_C2_FUS_FwUpgrade
* @brief Request the FUS to install the CPU2 firmware update
*
* @param fw_src_add: Address of the firmware image location
* @param fw_dest_add: Address of the firmware destination
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FUS_FwUpgrade( uint32_t fw_src_add, uint32_t fw_dest_add );
/**
* SHCI_C2_FUS_FwDelete
* @brief Delete the wireless stack on CPU2
*
* @param None
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FUS_FwDelete( void );
/**
* SHCI_C2_FUS_UpdateAuthKey
* @brief Request the FUS to update the authentication key
*
* @param pCmdPacket
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FUS_UpdateAuthKey( SHCI_C2_FUS_UpdateAuthKey_Cmd_Param_t *pParam );
/**
* SHCI_C2_FUS_LockAuthKey
* @brief Request the FUS to prevent any future update of the authentication key
*
* @param None
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FUS_LockAuthKey( void );
/**
* SHCI_C2_FUS_StoreUsrKey
* @brief Request the FUS to store the user key
*
* @param pParam : command parameter
* @param p_key_index : Index allocated by the FUS to the stored key
*
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FUS_StoreUsrKey( SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t *pParam, uint8_t *p_key_index );
/**
* SHCI_C2_FUS_LoadUsrKey
* @brief Request the FUS to load the user key into the AES
*
* @param key_index : index of the user key to load in AES1
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FUS_LoadUsrKey( uint8_t key_index );
/**
* SHCI_C2_FUS_StartWs
* @brief Request the FUS to reboot on the wireless stack
*
* @param None
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FUS_StartWs( void );
/**
* SHCI_C2_FUS_LockUsrKey
* @brief Request the FUS to lock the user key so that it cannot be updated later on
*
* @param key_index : index of the user key to lock
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FUS_LockUsrKey( uint8_t key_index );
/**
* SHCI_C2_BLE_Init
* @brief Provides parameters and starts the BLE Stack
*
* @param pCmdPacket : Parameters to be provided to the BLE Stack
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_BLE_Init( SHCI_C2_Ble_Init_Cmd_Packet_t *pCmdPacket );
/**
* SHCI_C2_THREAD_Init
* @brief Starts the THREAD Stack
*
* @param None
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_THREAD_Init( void );
/**
* SHCI_C2_LLDTESTS_Init
* @brief Starts the LLD tests CLI
*
* @param param_size : Nb of bytes
* @param p_param : pointeur with data to give from M4 to M0
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_LLDTESTS_Init( uint8_t param_size, uint8_t * p_param );
/**
* SHCI_C2_LLD_BLE_Init
* @brief Starts the LLD tests CLI
*
* @param param_size : Nb of bytes
* @param p_param : pointeur with data to give from M4 to M0
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_LLD_BLE_Init( uint8_t param_size, uint8_t * p_param );
/**
* SHCI_C2_ZIGBEE_Init
* @brief Starts the Zigbee Stack
*
* @param None
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_ZIGBEE_Init( void );
/**
* SHCI_C2_DEBUG_Init
* @brief Starts the Traces
*
* @param None
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_DEBUG_Init( SHCI_C2_DEBUG_Init_Cmd_Packet_t *pCmdPacket );
/**
* SHCI_C2_FLASH_EraseActivity
* @brief Provides the information of the start and the end of a flash erase window on the CPU1
*
* @param erase_activity: Start/End of erase activity
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FLASH_EraseActivity( SHCI_EraseActivity_t erase_activity );
/**
* SHCI_C2_CONCURRENT_SetMode
* @brief Enable/Disable Thread on CPU2 (M0+)
*
* @param Mode: BLE or Thread enable flag
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_CONCURRENT_SetMode( SHCI_C2_CONCURRENT_Mode_Param_t Mode );
/**
* SHCI_C2_FLASH_StoreData
* @brief Store Data in Flash
*
* @param Ip: BLE or THREAD
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FLASH_StoreData( SHCI_C2_FLASH_Ip_t Ip );
/**
* SHCI_C2_FLASH_EraseData
* @brief Erase Data in Flash
*
* @param Ip: BLE or THREAD
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_FLASH_EraseData( SHCI_C2_FLASH_Ip_t Ip );
/**
* SHCI_C2_RADIO_AllowLowPower
* @brief Allow or forbid IP_radio (802_15_4 or BLE) to enter in low power mode.
*
* @param Ip: BLE or 802_15_5
* @param FlagRadioLowPowerOn: True or false
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_RADIO_AllowLowPower( SHCI_C2_FLASH_Ip_t Ip,uint8_t FlagRadioLowPowerOn);
/**
* SHCI_C2_MAC_802_15_4_Init
* @brief Starts the MAC 802.15.4 on M0
*
* @param None
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_MAC_802_15_4_Init( void );
/**
* SHCI_GetWirelessFwInfo
* @brief This function read back the informations relative to the wireless binary loaded.
* Refer yourself to SHCI_WirelessFwInfoTable_t structure to get the significance
* of the different parameters returned.
* @param pWirelessInfo : Pointer to WirelessFwInfo_t.
*
* @retval SHCI_Success
*/
SHCI_CmdStatus_t SHCI_GetWirelessFwInfo( WirelessFwInfo_t* pWirelessInfo );
/**
* SHCI_C2_Reinit
* @brief This is required to allow the CPU1 to fake a set C2BOOT when it has already been set.
* In order to fake a C2BOOT, the CPU1 shall :
* - Send SHCI_C2_Reinit()
* - call SEV instruction
* WARNING:
* This function is intended to be used by the SBSFU
*
* @param None
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_Reinit( void );
/**
* SHCI_C2_ExtpaConfig
* @brief Send the Ext PA configuration
* When the CPU2 receives the command, it controls the Ext PA as requested by the configuration
* This configures only which IO is used to enable/disable the ExtPA and the associated polarity
* This command has no effect on the other IO that is used to control the mode of the Ext PA (Rx/Tx)
*
* @param gpio_port: GPIOx where x can be (A..F) to select the GPIO peripheral for STM32WBxx family
* @param gpio_pin_number: This parameter can be one of GPIO_PIN_x (= LL_GPIO_PIN_x) where x can be (0..15).
* @param gpio_polarity: This parameter can be either
* - EXT_PA_ENABLED_LOW: ExtPA is enabled when GPIO is low
* - EXT_PA_ENABLED_HIGH: ExtPA is enabled when GPIO is high
* @param gpio_status: This parameter can be either
* - EXT_PA_DISABLED: Stop driving the ExtPA
* - EXT_PA_ENABLED: Drive the ExtPA according to radio activity
* (ON before the Event and OFF at the end of the event)
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_ExtpaConfig(uint32_t gpio_port, uint16_t gpio_pin_number, uint8_t gpio_polarity, uint8_t gpio_status);
/**
* SHCI_C2_SetFlashActivityControl
* @brief Set the mechanism to be used on CPU2 to prevent the CPU1 to either write or erase in flash
*
* @param Source: It can be one of the following list
* - FLASH_ACTIVITY_CONTROL_PES : The CPU2 set the PES bit to prevent the CPU1 to either read or write in flash
* - FLASH_ACTIVITY_CONTROL_SEM7 : The CPU2 gets the semaphore 7 to prevent the CPU1 to either read or write in flash.
* This requires the CPU1 to first get semaphore 7 before erasing or writing the flash.
*
* @retval Status
*/
SHCI_CmdStatus_t SHCI_C2_SetFlashActivityControl(SHCI_C2_SET_FLASH_ACTIVITY_CONTROL_Source_t Source);
#ifdef __cplusplus
}
#endif
#endif /*__SHCI_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,353 @@
/**
******************************************************************************
* @file shci.c
* @author MCD Application Team
* @brief System HCI command implementation
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32_wpan_common.h"
#include "stm_list.h"
#include "shci_tl.h"
#include "mbed_toolchain.h"
/**
* These traces are not yet supported in an usual way in the delivery package
* They can enabled by adding the definition of TL_SHCI_CMD_DBG_EN and/or TL_SHCI_EVT_DBG_EN in the preprocessor option in the IDE
*/
#if ( (TL_SHCI_CMD_DBG_EN != 0) || (TL_SHCI_EVT_DBG_EN != 0) )
#include "app_conf.h"
#include "dbg_trace.h"
#endif
#if (TL_SHCI_CMD_DBG_EN != 0)
#define TL_SHCI_CMD_DBG_MSG PRINT_MESG_DBG
#define TL_SHCI_CMD_DBG_BUF PRINT_LOG_BUFF_DBG
#else
#define TL_SHCI_CMD_DBG_MSG(...)
#define TL_SHCI_CMD_DBG_BUF(...)
#endif
#if (TL_SHCI_EVT_DBG_EN != 0)
#define TL_SHCI_EVT_DBG_MSG PRINT_MESG_DBG
#define TL_SHCI_EVT_DBG_BUF PRINT_LOG_BUFF_DBG
#else
#define TL_SHCI_EVT_DBG_MSG(...)
#define TL_SHCI_EVT_DBG_BUF(...)
#endif
/* 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 );
static void OutputCmdTrace(TL_CmdPacket_t *pCmdBuffer);
static void OutputRspTrace(TL_EvtPacket_t *p_rsp);
static void OutputEvtTrace(TL_EvtPacket_t *phcievtbuffer);
/* 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 );
OutputEvtTrace(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 );
OutputCmdTrace(pCmdBuffer);
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 );
OutputRspTrace(p_rsp);
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;
}
static void OutputCmdTrace(TL_CmdPacket_t *pCmdBuffer)
{
TL_SHCI_CMD_DBG_MSG("sys cmd: 0x%04X", pCmdBuffer->cmdserial.cmd.cmdcode);
if(pCmdBuffer->cmdserial.cmd.plen != 0)
{
TL_SHCI_CMD_DBG_MSG(" payload:");
TL_SHCI_CMD_DBG_BUF(pCmdBuffer->cmdserial.cmd.payload, pCmdBuffer->cmdserial.cmd.plen, "");
}
TL_SHCI_CMD_DBG_MSG("\r\n");
return;
}
static void OutputRspTrace(TL_EvtPacket_t *p_rsp)
{
switch(p_rsp->evtserial.evt.evtcode)
{
case TL_BLEEVT_CC_OPCODE:
TL_SHCI_CMD_DBG_MSG("sys rsp: 0x%02X", p_rsp->evtserial.evt.evtcode);
TL_SHCI_CMD_DBG_MSG(" cmd opcode: 0x%02X", ((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->cmdcode);
TL_SHCI_CMD_DBG_MSG(" status: 0x%02X", ((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
if((p_rsp->evtserial.evt.plen-4) != 0)
{
TL_SHCI_CMD_DBG_MSG(" payload:");
TL_SHCI_CMD_DBG_BUF(&((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[1], p_rsp->evtserial.evt.plen-4, "");
}
break;
default:
TL_SHCI_CMD_DBG_MSG("unknown sys rsp received: %02X", p_rsp->evtserial.evt.evtcode);
break;
}
TL_SHCI_CMD_DBG_MSG("\r\n");
return;
}
static void OutputEvtTrace(TL_EvtPacket_t *phcievtbuffer)
{
if(phcievtbuffer->evtserial.evt.evtcode != TL_BLEEVT_VS_OPCODE)
{
TL_SHCI_EVT_DBG_MSG("unknown sys evt received: %02X", phcievtbuffer->evtserial.evt.evtcode);
}
else
{
TL_SHCI_EVT_DBG_MSG("sys evt: 0x%02X", phcievtbuffer->evtserial.evt.evtcode);
TL_SHCI_EVT_DBG_MSG(" subevtcode: 0x%04X", ((TL_AsynchEvt_t*)(phcievtbuffer->evtserial.evt.payload))->subevtcode);
if((phcievtbuffer->evtserial.evt.plen-2) != 0)
{
TL_SHCI_EVT_DBG_MSG(" payload:");
TL_SHCI_EVT_DBG_BUF(((TL_AsynchEvt_t*)(phcievtbuffer->evtserial.evt.payload))->payload, phcievtbuffer->evtserial.evt.plen-2, "");
}
}
TL_SHCI_EVT_DBG_MSG("\r\n");
return;
}
/* Weak implementation ----------------------------------------------------------------*/
MBED_WEAK void shci_cmd_resp_wait(uint32_t timeout)
{
(void)timeout;
CmdRspStatusFlag = SHCI_TL_CMD_RESP_WAIT;
while(CmdRspStatusFlag != SHCI_TL_CMD_RESP_RELEASE);
return;
}
MBED_WEAK void shci_cmd_resp_release(uint32_t flag)
{
(void)flag;
CmdRspStatusFlag = SHCI_TL_CMD_RESP_RELEASE;
return;
}

View File

@@ -0,0 +1,175 @@
/**
******************************************************************************
* @file shci_tl.h
* @author MCD Application Team
* @brief System HCI command header for the system channel
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
#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 pData: 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_ */

View File

@@ -0,0 +1,155 @@
/**
******************************************************************************
* @file stm32_wpan_common.h
* @author MCD Application Team
* @brief Common file to utilities
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_WPAN_COMMON_H
#define __STM32_WPAN_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/* -------------------------------- *
* Basic definitions *
* -------------------------------- */
#undef NULL
#define NULL 0U
#undef FALSE
#define FALSE 0U
#undef TRUE
#define TRUE (!0U)
/* -------------------------------- *
* Critical Section definition *
* -------------------------------- */
#undef BACKUP_PRIMASK
#define BACKUP_PRIMASK() uint32_t primask_bit= __get_PRIMASK()
#undef DISABLE_IRQ
#define DISABLE_IRQ() __disable_irq()
#undef RESTORE_PRIMASK
#define RESTORE_PRIMASK() __set_PRIMASK(primask_bit)
/* -------------------------------- *
* Macro delimiters *
* -------------------------------- */
#undef M_BEGIN
#define M_BEGIN do {
#undef M_END
#define M_END } while(0)
/* -------------------------------- *
* Some useful macro definitions *
* -------------------------------- */
#undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#undef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#undef MODINC
#define MODINC( a, m ) M_BEGIN (a)++; if ((a)>=(m)) (a)=0; M_END
#undef MODDEC
#define MODDEC( a, m ) M_BEGIN if ((a)==0) (a)=(m); (a)--; M_END
#undef MODADD
#define MODADD( a, b, m ) M_BEGIN (a)+=(b); if ((a)>=(m)) (a)-=(m); M_END
#undef MODSUB
#define MODSUB( a, b, m ) MODADD( a, (m)-(b), m )
#undef ALIGN
#ifdef WIN32
#define ALIGN(n)
#else
#define ALIGN(n) __attribute__((aligned(n)))
#endif
#undef PAUSE
#define PAUSE( t ) M_BEGIN \
volatile int _i; \
for ( _i = t; _i > 0; _i -- ); \
M_END
#undef DIVF
#define DIVF( x, y ) ((x)/(y))
#undef DIVC
#define DIVC( x, y ) (((x)+(y)-1)/(y))
#undef DIVR
#define DIVR( x, y ) (((x)+((y)/2))/(y))
#undef SHRR
#define SHRR( x, n ) ((((x)>>((n)-1))+1)>>1)
#undef BITN
#define BITN( w, n ) (((w)[(n)/32] >> ((n)%32)) & 1)
#undef BITNSET
#define BITNSET( w, n, b ) M_BEGIN (w)[(n)/32] |= ((U32)(b))<<((n)%32); M_END
/* -------------------------------- *
* Section attribute *
* -------------------------------- */
#undef PLACE_IN_SECTION
#define PLACE_IN_SECTION( __x__ ) __attribute__((section (__x__)))
/* ----------------------------------- *
* Packed usage (compiler dependent) *
* ----------------------------------- */
#undef PACKED__
#undef PACKED_STRUCT
#if defined ( __CC_ARM )
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050U)
#define PACKED__ __attribute__((packed))
#define PACKED_STRUCT struct PACKED__
#else
#define PACKED__(TYPE) __packed TYPE
#define PACKED_STRUCT PACKED__(struct)
#endif
#elif defined ( __GNUC__ )
#define PACKED__ __attribute__((packed))
#define PACKED_STRUCT struct PACKED__
#elif defined (__ICCARM__)
#define PACKED_STRUCT __packed struct
#elif
#define PACKED_STRUCT __packed struct
#endif
#ifdef __cplusplus
}
#endif
#endif /*__STM32_WPAN_COMMON_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,208 @@
/**
******************************************************************************
* @file stm_list.c
* @author MCD Application Team
* @brief TCircular Linked List Implementation.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/******************************************************************************
* Include Files
******************************************************************************/
#include "utilities_common.h"
#include "stm_list.h"
/******************************************************************************
* Function Definitions
******************************************************************************/
void LST_init_head (tListNode * listHead)
{
listHead->next = listHead;
listHead->prev = listHead;
}
uint8_t LST_is_empty (tListNode * listHead)
{
uint32_t primask_bit;
uint8_t return_value;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
if(listHead->next == listHead)
{
return_value = TRUE;
}
else
{
return_value = FALSE;
}
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
return return_value;
}
void LST_insert_head (tListNode * listHead, tListNode * node)
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
node->next = listHead->next;
node->prev = listHead;
listHead->next = node;
(node->next)->prev = node;
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}
void LST_insert_tail (tListNode * listHead, tListNode * node)
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
node->next = listHead;
node->prev = listHead->prev;
listHead->prev = node;
(node->prev)->next = node;
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}
void LST_remove_node (tListNode * node)
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
(node->prev)->next = node->next;
(node->next)->prev = node->prev;
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}
void LST_remove_head (tListNode * listHead, tListNode ** node )
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
*node = listHead->next;
LST_remove_node (listHead->next);
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}
void LST_remove_tail (tListNode * listHead, tListNode ** node )
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
*node = listHead->prev;
LST_remove_node (listHead->prev);
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}
void LST_insert_node_after (tListNode * node, tListNode * ref_node)
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
node->next = ref_node->next;
node->prev = ref_node;
ref_node->next = node;
(node->next)->prev = node;
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}
void LST_insert_node_before (tListNode * node, tListNode * ref_node)
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
node->next = ref_node;
node->prev = ref_node->prev;
ref_node->prev = node;
(node->prev)->next = node;
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}
int LST_get_size (tListNode * listHead)
{
int size = 0;
tListNode * temp;
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
temp = listHead->next;
while (temp != listHead)
{
size++;
temp = temp->next;
}
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
return (size);
}
void LST_get_next_node (tListNode * ref_node, tListNode ** node)
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
*node = ref_node->next;
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}
void LST_get_prev_node (tListNode * ref_node, tListNode ** node)
{
uint32_t primask_bit;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
*node = ref_node->prev;
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
}

View File

@@ -0,0 +1,55 @@
/**
******************************************************************************
* @file stm_list.h
* @author MCD Application Team
* @brief Header file for linked list library.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
#ifndef _STM_LIST_H_
#define _STM_LIST_H_
/* Includes ------------------------------------------------------------------*/
typedef struct _tListNode {
struct _tListNode * next;
struct _tListNode * prev;
} tListNode;
void LST_init_head (tListNode * listHead);
uint8_t LST_is_empty (tListNode * listHead);
void LST_insert_head (tListNode * listHead, tListNode * node);
void LST_insert_tail (tListNode * listHead, tListNode * node);
void LST_remove_node (tListNode * node);
void LST_remove_head (tListNode * listHead, tListNode ** node );
void LST_remove_tail (tListNode * listHead, tListNode ** node );
void LST_insert_node_after (tListNode * node, tListNode * ref_node);
void LST_insert_node_before (tListNode * node, tListNode * ref_node);
int LST_get_size (tListNode * listHead);
void LST_get_next_node (tListNode * ref_node, tListNode ** node);
void LST_get_prev_node (tListNode * ref_node, tListNode ** node);
#endif /* _STM_LIST_H_ */

View File

@@ -0,0 +1,334 @@
/**
******************************************************************************
* @file tl.h
* @author MCD Application Team
* @brief Header for tl module
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* 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_CS_PACKET_SIZE (TL_EVT_HDR_SIZE + sizeof(TL_CsEvt_t))
#define TL_BLEEVT_CS_BUFFER_SIZE (sizeof(TL_PacketHeader_t) + TL_BLEEVT_CS_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
*/
typedef PACKED_STRUCT
{
uint8_t numcmd;
uint16_t cmdcode;
uint8_t payload[1];
} TL_CcEvt_t;
/**
* This the payload of TL_Evt_t for an asynchronous event
*/
typedef PACKED_STRUCT
{
uint16_t subevtcode;
uint8_t payload[1];
} TL_AsynchEvt_t;
typedef PACKED_STRUCT
{
uint8_t evtcode;
uint8_t plen;
uint8_t payload[1];
} 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;
} TL_TH_Config_t;
typedef struct
{
uint8_t *p_LldTestsCliCmdRspBuffer;
uint8_t *p_LldTestsM0CmdBuffer;
} TL_LLD_tests_Config_t;
typedef struct
{
uint8_t *p_LldBleCmdRspBuffer;
uint8_t *p_LldBleM0CmdBuffer;
} TL_LLD_BLE_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;
/* 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 );
/******************************************************************************
* LLD BLE
******************************************************************************/
void TL_LLD_BLE_Init( TL_LLD_BLE_Config_t *p_Config );
void TL_LLD_BLE_SendCliCmd( void );
void TL_LLD_BLE_ReceiveCliRsp( TL_CmdPacket_t * Notbuffer );
void TL_LLD_BLE_SendCliRspAck( void );
void TL_LLD_BLE_ReceiveM0Cmd( TL_CmdPacket_t * Notbuffer );
void TL_LLD_BLE_SendM0CmdAck( void );
void TL_LLD_BLE_SendCmd( void );
void TL_LLD_BLE_ReceiveRsp( TL_CmdPacket_t * Notbuffer );
void TL_LLD_BLE_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 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,688 @@
/**
******************************************************************************
* @file tl_mbox.c
* @author MCD Application Team
* @brief Transport layer for the mailbox interface
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32_wpan_common.h"
#include "hw.h"
#include "mbed_toolchain.h"
#include "stm_list.h"
#include "tl.h"
#include "mbox_def.h"
/**
* These traces are not yet supported in an usual way in the delivery package
* They can enabled by adding the definition of TL_MM_DBG_EN in the preprocessor option in the IDE
*/
#if(TL_MM_DBG_EN != 0)
#include "app_conf.h"
#include "dbg_trace.h"
#endif
#if (TL_MM_DBG_EN != 0)
#define TL_MM_DBG__MSG PRINT_MESG_DBG
#else
#define TL_MM_DBG__MSG(...)
#endif
/* Private typedef -----------------------------------------------------------*/
/* 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_LldBleTable_t TL_LldBleTable;
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_MEM2") ALIGN(4) static tListNode EvtQueue;
PLACE_IN_SECTION("MB_MEM2") 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 OutputMemReleaseTrace(TL_EvtPacket_t * phcievt);
/* Public Functions Definition ------------------------------------------------------*/
/******************************************************************************
* GENERAL
******************************************************************************/
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_lld_ble_table = &TL_LldBleTable;
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;
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);
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;
HW_IPCC_BLE_SendAclData();
return 0;
}
void HW_IPCC_BLE_AclDataAckNot(void)
{
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;
HW_IPCC_SYS_SendCmd();
return 0;
}
void HW_IPCC_SYS_CmdEvtNot(void)
{
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);
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;
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->clicmdrsp_buffer) );
return;
}
MBED_WEAK void TL_OT_CmdEvtReceived( TL_EvtPacket_t * Otbuffer ){};
MBED_WEAK void TL_THREAD_NotReceived( TL_EvtPacket_t * Notbuffer ){};
MBED_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;
}
MBED_WEAK void TL_LLDTESTS_ReceiveCliRsp( TL_CmdPacket_t * Notbuffer ){};
MBED_WEAK void TL_LLDTESTS_ReceiveM0Cmd( TL_CmdPacket_t * Notbuffer ){};
#endif /* LLD_TESTS_WB */
/******************************************************************************
* LLD BLE
******************************************************************************/
#ifdef LLD_BLE_WB
void TL_LLD_BLE_Init( TL_LLD_BLE_Config_t *p_Config )
{
MB_LldBleTable_t * p_lld_ble_table;
p_lld_ble_table = TL_RefTable.p_lld_ble_table;
p_lld_ble_table->cmdrsp_buffer = p_Config->p_LldBleCmdRspBuffer;
p_lld_ble_table->m0cmd_buffer = p_Config->p_LldBleM0CmdBuffer;
HW_IPCC_LLD_BLE_Init();
return;
}
void TL_LLD_BLE_SendCliCmd( void )
{
((TL_CmdPacket_t *)(TL_RefTable.p_lld_ble_table->cmdrsp_buffer))->cmdserial.type = TL_CLICMD_PKT_TYPE;
HW_IPCC_LLD_BLE_SendCliCmd();
return;
}
void HW_IPCC_LLD_BLE_ReceiveCliRsp( void )
{
TL_LLD_BLE_ReceiveCliRsp( (TL_CmdPacket_t*)(TL_RefTable.p_lld_ble_table->cmdrsp_buffer) );
return;
}
void TL_LLD_BLE_SendCliRspAck( void )
{
HW_IPCC_LLD_BLE_SendCliRspAck();
return;
}
void HW_IPCC_LLD_BLE_ReceiveM0Cmd( void )
{
TL_LLD_BLE_ReceiveM0Cmd( (TL_CmdPacket_t*)(TL_RefTable.p_lld_ble_table->m0cmd_buffer) );
return;
}
void TL_LLD_BLE_SendM0CmdAck( void )
{
HW_IPCC_LLD_BLE_SendM0CmdAck();
return;
}
MBED_WEAK void TL_LLD_BLE_ReceiveCliRsp( TL_CmdPacket_t * Notbuffer ){};
MBED_WEAK void TL_LLD_BLE_ReceiveM0Cmd( TL_CmdPacket_t * Notbuffer ){};
/* Transparent Mode */
void TL_LLD_BLE_SendCmd( void )
{
((TL_CmdPacket_t *)(TL_RefTable.p_lld_ble_table->cmdrsp_buffer))->cmdserial.type = TL_CLICMD_PKT_TYPE;
HW_IPCC_LLD_BLE_SendCmd();
return;
}
void HW_IPCC_LLD_BLE_ReceiveRsp( void )
{
TL_LLD_BLE_ReceiveRsp( (TL_CmdPacket_t*)(TL_RefTable.p_lld_ble_table->cmdrsp_buffer) );
return;
}
void TL_LLD_BLE_SendRspAck( void )
{
HW_IPCC_LLD_BLE_SendRspAck();
return;
}
#endif /* LLD_BLE_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;
}
MBED_WEAK void TL_MAC_802_15_4_CmdEvtReceived( TL_EvtPacket_t * Otbuffer ){};
MBED_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;
}
MBED_WEAK void TL_ZIGBEE_CmdEvtReceived( TL_EvtPacket_t * Otbuffer ){};
MBED_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);
OutputMemReleaseTrace(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;
}
static void OutputMemReleaseTrace(TL_EvtPacket_t * phcievt)
{
switch(phcievt->evtserial.evt.evtcode)
{
case TL_BLEEVT_CS_OPCODE:
TL_MM_DBG__MSG("mm evt released: 0x%02X", phcievt->evtserial.evt.evtcode);
TL_MM_DBG__MSG(" cmd opcode: 0x%04X", ((TL_CsEvt_t*)(phcievt->evtserial.evt.payload))->cmdcode);
TL_MM_DBG__MSG(" buffer addr: 0x%08X", phcievt);
break;
case TL_BLEEVT_CC_OPCODE:
TL_MM_DBG__MSG("mm evt released: 0x%02X", phcievt->evtserial.evt.evtcode);
TL_MM_DBG__MSG(" cmd opcode: 0x%04X", ((TL_CcEvt_t*)(phcievt->evtserial.evt.payload))->cmdcode);
TL_MM_DBG__MSG(" buffer addr: 0x%08X", phcievt);
break;
case TL_BLEEVT_VS_OPCODE:
TL_MM_DBG__MSG("mm evt released: 0x%02X", phcievt->evtserial.evt.evtcode);
TL_MM_DBG__MSG(" subevtcode: 0x%04X", ((TL_AsynchEvt_t*)(phcievt->evtserial.evt.payload))->subevtcode);
TL_MM_DBG__MSG(" buffer addr: 0x%08X", phcievt);
break;
default:
TL_MM_DBG__MSG("mm evt released: 0x%02X", phcievt->evtserial.evt.evtcode);
TL_MM_DBG__MSG(" buffer addr: 0x%08X", phcievt);
break;
}
TL_MM_DBG__MSG("\r\n");
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;
}
MBED_WEAK void TL_TRACES_EvtReceived( TL_EvtPacket_t * hcievt )
{
(void)(hcievt);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,524 @@
/**
******************************************************************************
* File Name : Target/hw_ipcc.c
* Description : Hardware IPCC source file for STM32WPAN Middleware.
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "mbox_def.h"
#include "stm32wbxx_ll_ipcc.h" // MBED
/* Global variables ---------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
#define HW_IPCC_TX_PENDING( channel ) ( !(LL_C1_IPCC_IsActiveFlag_CHx( IPCC, channel )) ) && (((~(IPCC->C1MR)) & (channel << 16U)))
#define HW_IPCC_RX_PENDING( channel ) (LL_C2_IPCC_IsActiveFlag_CHx( IPCC, channel )) && (((~(IPCC->C1MR)) & (channel << 0U)))
/* Private macros ------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static void (*FreeBufCb)( void );
/* Private function prototypes -----------------------------------------------*/
static void HW_IPCC_BLE_EvtHandler( void );
static void HW_IPCC_BLE_AclDataEvtHandler( void );
static void HW_IPCC_MM_FreeBufHandler( void );
static void HW_IPCC_SYS_CmdEvtHandler( void );
static void HW_IPCC_SYS_EvtHandler( void );
static void HW_IPCC_TRACES_EvtHandler( void );
#ifdef THREAD_WB
static void HW_IPCC_OT_CmdEvtHandler( void );
static void HW_IPCC_THREAD_NotEvtHandler( void );
static void HW_IPCC_THREAD_CliNotEvtHandler( void );
#endif
#ifdef MAC_802_15_4_WB
static void HW_IPCC_MAC_802_15_4_CmdEvtHandler( void );
static void HW_IPCC_MAC_802_15_4_NotEvtHandler( void );
#endif
#ifdef ZIGBEE_WB
static void HW_IPCC_ZIGBEE_CmdEvtHandler( void );
static void HW_IPCC_ZIGBEE_StackNotifEvtHandler( void );
static void HW_IPCC_ZIGBEE_CliNotifEvtHandler( void );
#endif
/* Public function definition -----------------------------------------------*/
/******************************************************************************
* INTERRUPT HANDLER
******************************************************************************/
void HW_IPCC_Rx_Handler( void )
{
if (HW_IPCC_RX_PENDING( HW_IPCC_SYSTEM_EVENT_CHANNEL ))
{
HW_IPCC_SYS_EvtHandler();
}
#ifdef MAC_802_15_4_WB
else if (HW_IPCC_RX_PENDING( HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL ))
{
HW_IPCC_MAC_802_15_4_NotEvtHandler();
}
#endif /* MAC_802_15_4_WB */
#ifdef THREAD_WB
else if (HW_IPCC_RX_PENDING( HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL ))
{
HW_IPCC_THREAD_NotEvtHandler();
}
else if (HW_IPCC_RX_PENDING( HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL ))
{
HW_IPCC_THREAD_CliNotEvtHandler();
}
#endif /* THREAD_WB */
#ifdef ZIGBEE_WB
else if (HW_IPCC_RX_PENDING( HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL ))
{
HW_IPCC_ZIGBEE_StackNotifEvtHandler();
}
else if (HW_IPCC_RX_PENDING( HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL ))
{
HW_IPCC_ZIGBEE_CliNotifEvtHandler();
}
#endif /* ZIGBEE_WB */
else if (HW_IPCC_RX_PENDING( HW_IPCC_BLE_EVENT_CHANNEL ))
{
HW_IPCC_BLE_EvtHandler();
}
else if (HW_IPCC_RX_PENDING( HW_IPCC_TRACES_CHANNEL ))
{
HW_IPCC_TRACES_EvtHandler();
}
return;
}
void HW_IPCC_Tx_Handler( void )
{
if (HW_IPCC_TX_PENDING( HW_IPCC_SYSTEM_CMD_RSP_CHANNEL ))
{
HW_IPCC_SYS_CmdEvtHandler();
}
#ifdef MAC_802_15_4_WB
else if (HW_IPCC_TX_PENDING( HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL ))
{
HW_IPCC_MAC_802_15_4_CmdEvtHandler();
}
#endif /* MAC_802_15_4_WB */
#ifdef THREAD_WB
else if (HW_IPCC_TX_PENDING( HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL ))
{
HW_IPCC_OT_CmdEvtHandler();
}
#endif /* THREAD_WB */
#ifdef ZIGBEE_WB
if (HW_IPCC_TX_PENDING( HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL ))
{
HW_IPCC_ZIGBEE_CmdEvtHandler();
}
#endif /* ZIGBEE_WB */
else if (HW_IPCC_TX_PENDING( HW_IPCC_SYSTEM_CMD_RSP_CHANNEL ))
{
HW_IPCC_SYS_CmdEvtHandler();
}
else if (HW_IPCC_TX_PENDING( HW_IPCC_MM_RELEASE_BUFFER_CHANNEL ))
{
HW_IPCC_MM_FreeBufHandler();
}
else if (HW_IPCC_TX_PENDING( HW_IPCC_HCI_ACL_DATA_CHANNEL ))
{
HW_IPCC_BLE_AclDataEvtHandler();
}
return;
}
/******************************************************************************
* GENERAL
******************************************************************************/
void HW_IPCC_Enable( void )
{
/**
* When the device is out of standby, it is required to use the EXTI mechanism to wakeup CPU2
*/
LL_C2_EXTI_EnableEvent_32_63( LL_EXTI_LINE_41 );
LL_EXTI_EnableRisingTrig_32_63( LL_EXTI_LINE_41 );
/**
* In case the SBSFU is implemented, it may have already set the C2BOOT bit to startup the CPU2.
* In that case, to keep the mechanism transparent to the user application, it shall call the system command
* SHCI_C2_Reinit( ) before jumping to the application.
* When the CPU2 receives that command, it waits for its event input to be set to restart the CPU2 firmware.
* This is required because once C2BOOT has been set once, a clear/set on C2BOOT has no effect.
* When SHCI_C2_Reinit( ) is not called, generating an event to the CPU2 does not have any effect
* So, by default, the application shall both set the event flag and set the C2BOOT bit.
*/
__SEV( ); /* Set the internal event flag and send an event to the CPU2 */
__WFE( ); /* Clear the internal event flag */
LL_PWR_EnableBootC2( );
return;
}
void HW_IPCC_Init( void )
{
LL_AHB3_GRP1_EnableClock( LL_AHB3_GRP1_PERIPH_IPCC );
LL_C1_IPCC_EnableIT_RXO( IPCC );
LL_C1_IPCC_EnableIT_TXF( IPCC );
HAL_NVIC_EnableIRQ(IPCC_C1_RX_IRQn);
HAL_NVIC_EnableIRQ(IPCC_C1_TX_IRQn);
return;
}
/******************************************************************************
* BLE
******************************************************************************/
void HW_IPCC_BLE_Init( void )
{
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_BLE_EVENT_CHANNEL );
return;
}
void HW_IPCC_BLE_SendCmd( void )
{
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_BLE_CMD_CHANNEL );
return;
}
static void HW_IPCC_BLE_EvtHandler( void )
{
HW_IPCC_BLE_RxEvtNot();
LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_BLE_EVENT_CHANNEL );
return;
}
void HW_IPCC_BLE_SendAclData( void )
{
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL );
LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL );
return;
}
static void HW_IPCC_BLE_AclDataEvtHandler( void )
{
LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL );
HW_IPCC_BLE_AclDataAckNot();
return;
}
__weak void HW_IPCC_BLE_AclDataAckNot( void ){};
__weak void HW_IPCC_BLE_RxEvtNot( void ){};
/******************************************************************************
* SYSTEM
******************************************************************************/
void HW_IPCC_SYS_Init( void )
{
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_SYSTEM_EVENT_CHANNEL );
return;
}
void HW_IPCC_SYS_SendCmd( void )
{
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL );
LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL );
return;
}
static void HW_IPCC_SYS_CmdEvtHandler( void )
{
LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL );
HW_IPCC_SYS_CmdEvtNot();
return;
}
static void HW_IPCC_SYS_EvtHandler( void )
{
HW_IPCC_SYS_EvtNot();
LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_SYSTEM_EVENT_CHANNEL );
return;
}
__weak void HW_IPCC_SYS_CmdEvtNot( void ){};
__weak void HW_IPCC_SYS_EvtNot( void ){};
/******************************************************************************
* MAC 802.15.4
******************************************************************************/
#ifdef MAC_802_15_4_WB
void HW_IPCC_MAC_802_15_4_Init( void )
{
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL );
return;
}
void HW_IPCC_MAC_802_15_4_SendCmd( void )
{
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL );
LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL );
return;
}
void HW_IPCC_MAC_802_15_4_SendAck( void )
{
LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL );
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL );
return;
}
static void HW_IPCC_MAC_802_15_4_CmdEvtHandler( void )
{
LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL );
HW_IPCC_MAC_802_15_4_CmdEvtNot();
return;
}
static void HW_IPCC_MAC_802_15_4_NotEvtHandler( void )
{
LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL );
HW_IPCC_MAC_802_15_4_EvtNot();
return;
}
__weak void HW_IPCC_MAC_802_15_4_CmdEvtNot( void ){};
__weak void HW_IPCC_MAC_802_15_4_EvtNot( void ){};
#endif
/******************************************************************************
* THREAD
******************************************************************************/
#ifdef THREAD_WB
void HW_IPCC_THREAD_Init( void )
{
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL );
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL );
return;
}
void HW_IPCC_OT_SendCmd( void )
{
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL );
LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL );
return;
}
void HW_IPCC_CLI_SendCmd( void )
{
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_THREAD_CLI_CMD_CHANNEL );
return;
}
void HW_IPCC_THREAD_SendAck( void )
{
LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL );
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL );
return;
}
void HW_IPCC_THREAD_CliSendAck( void )
{
LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL );
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL );
return;
}
static void HW_IPCC_OT_CmdEvtHandler( void )
{
LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL );
HW_IPCC_OT_CmdEvtNot();
return;
}
static void HW_IPCC_THREAD_NotEvtHandler( void )
{
LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL );
HW_IPCC_THREAD_EvtNot();
return;
}
static void HW_IPCC_THREAD_CliNotEvtHandler( void )
{
LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL );
HW_IPCC_THREAD_CliEvtNot();
return;
}
__weak void HW_IPCC_OT_CmdEvtNot( void ){};
__weak void HW_IPCC_CLI_CmdEvtNot( void ){};
__weak void HW_IPCC_THREAD_EvtNot( void ){};
#endif /* THREAD_WB */
/******************************************************************************
* ZIGBEE
******************************************************************************/
#ifdef ZIGBEE_WB
void HW_IPCC_ZIGBEE_Init( void )
{
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL );
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL );
return;
}
void HW_IPCC_ZIGBEE_SendAppliCmd( void )
{
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL );
LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL );
return;
}
void HW_IPCC_ZIGBEE_SendCliCmd( void )
{
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_THREAD_CLI_CMD_CHANNEL );
return;
}
void HW_IPCC_ZIGBEE_SendAppliCmdAck( void )
{
LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL );
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL );
return;
}
void HW_IPCC_ZIGBEE_SendCliCmdAck( void )
{
LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL );
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL );
return;
}
static void HW_IPCC_ZIGBEE_CmdEvtHandler( void )
{
LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL );
HW_IPCC_ZIGBEE_AppliCmdNotification();
return;
}
static void HW_IPCC_ZIGBEE_StackNotifEvtHandler( void )
{
LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL );
HW_IPCC_ZIGBEE_AppliAsyncEvtNotification();
return;
}
static void HW_IPCC_ZIGBEE_CliNotifEvtHandler( void )
{
LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL );
HW_IPCC_ZIGBEE_CliEvtNotification();
return;
}
__weak void HW_IPCC_ZIGBEE_AppliCmdNotification( void ){};
__weak void HW_IPCC_ZIGBEE_AppliAsyncEvtNotification( void ){};
__weak void HW_IPCC_ZIGBEE_CliEvtNotification( void ){};
#endif /* ZIGBEE_WB */
/******************************************************************************
* MEMORY MANAGER
******************************************************************************/
void HW_IPCC_MM_SendFreeBuf( void (*cb)( void ) )
{
if ( LL_C1_IPCC_IsActiveFlag_CHx( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL ) )
{
FreeBufCb = cb;
LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL );
}
else
{
cb();
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL );
}
return;
}
static void HW_IPCC_MM_FreeBufHandler( void )
{
LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL );
FreeBufCb();
LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL );
return;
}
/******************************************************************************
* TRACES
******************************************************************************/
void HW_IPCC_TRACES_Init( void )
{
LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_TRACES_CHANNEL );
return;
}
static void HW_IPCC_TRACES_EvtHandler( void )
{
HW_IPCC_TRACES_EvtNot();
LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_TRACES_CHANNEL );
return;
}
__weak void HW_IPCC_TRACES_EvtNot( void ){};
/******************* (C) COPYRIGHT 2019 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,3 @@
{
"name": "cordio-stm32wb"
}