1004 lines
40 KiB
C
1004 lines
40 KiB
C
//*****************************************************************************
|
|
//
|
|
//! @file am_hal_ble.h
|
|
//!
|
|
//! @brief HAL functions for the BLE interface.
|
|
//!
|
|
//! @addtogroup
|
|
//! @ingroup
|
|
//! @{
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Copyright (c) 2020, Ambiq Micro
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are met:
|
|
//
|
|
// 1. Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the name of the copyright holder nor the names of its
|
|
// contributors may be used to endorse or promote products derived from this
|
|
// software without specific prior written permission.
|
|
//
|
|
// Third party software included in this distribution is subject to the
|
|
// additional license terms as defined in the /docs/licenses directory.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
#ifndef AM_HAL_BLE_H
|
|
#define AM_HAL_BLE_H
|
|
|
|
#include "am_hal_global.h"
|
|
#include "am_hal_status.h"
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// CMSIS-style macro for handling a variable BLEIF module number.
|
|
//
|
|
#define BLEIFn(n) ((BLEIF_Type*)(BLEIF_BASE + (n * (BLEIF_BASE - BLEIF_BASE))))
|
|
//*****************************************************************************
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// BLE-specific status values.
|
|
//
|
|
//*****************************************************************************
|
|
typedef enum
|
|
{
|
|
//
|
|
// This error occurs when an HCI read or write function is called while
|
|
// another HCI communication function is already in progress.
|
|
//
|
|
AM_HAL_BLE_STATUS_BUS_BUSY = AM_HAL_STATUS_MODULE_SPECIFIC_START,
|
|
|
|
//
|
|
// This error happens when the MCU tries to execute an HCI read, but the
|
|
// BLE core hasn't asserted the BLEIRQ line. Try waiting for a BLEIRQ
|
|
// interrupt, or polling the BLECIRQ bit in the BSTATUS register before
|
|
// calling an HCI read function.
|
|
//
|
|
AM_HAL_BLE_STATUS_IRQ_LOW,
|
|
|
|
//
|
|
// This error means that the MCU tried to execute an HCI write, but the BLE
|
|
// core didn't assert its SPI_STATUS signal within the allotted timeout.
|
|
// This might mean that there has been some error inside the BLE core. This
|
|
// may require a reboot of the BLE core.
|
|
//
|
|
AM_HAL_BLE_STATUS_SPI_NOT_READY,
|
|
|
|
//
|
|
// This error means we were trying to write, but the BLE core has requested
|
|
// a READ instead. We will need to perform a read before we can retry this
|
|
// write.
|
|
//
|
|
AM_HAL_BLE_REQUESTING_READ,
|
|
|
|
//
|
|
// We are expecting an HCI response to a packet we just sent, but the BLE
|
|
// core isn't asserting BLEIRQ. Its software may have crashed, and it may
|
|
// need to restart.
|
|
//
|
|
AM_HAL_BLE_NO_HCI_RESPONSE,
|
|
|
|
//
|
|
// Any of these errors indicate a problem with the BLE hardware that
|
|
// requires a complete restart.
|
|
//
|
|
AM_HAL_BLE_FEATURE_DISABLED,
|
|
AM_HAL_BLE_SHUTDOWN_FAILED,
|
|
AM_HAL_BLE_REGULATOR_FAILED,
|
|
AM_HAL_BLE_POWERUP_INCOMPLETE,
|
|
AM_HAL_BLE_HCI_PACKET_INCOMPLETE,
|
|
AM_HAL_BLE_FIFO_ERROR,
|
|
AM_HAL_BLE_32K_CLOCK_UNSTABLE,
|
|
}
|
|
am_ble_status_e;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// BLE power modes.
|
|
//
|
|
//*****************************************************************************
|
|
typedef enum
|
|
{
|
|
AM_HAL_BLE_POWER_ACTIVE,
|
|
AM_HAL_BLE_POWER_OFF,
|
|
}
|
|
am_hal_ble_power_state_e;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// BLE SPI Clock settings.
|
|
//
|
|
//*****************************************************************************
|
|
typedef enum
|
|
{
|
|
AM_HAL_BLE_HCI_CLK_DIV2 = BLEIF_CLKCFG_FSEL_HFRC_DIV2,
|
|
AM_HAL_BLE_HCI_CLK_DIV4 = BLEIF_CLKCFG_FSEL_HFRC_DIV4,
|
|
AM_HAL_BLE_HCI_CLK_DIV8 = BLEIF_CLKCFG_FSEL_HFRC_DIV8,
|
|
AM_HAL_BLE_HCI_CLK_DIV16 = BLEIF_CLKCFG_FSEL_HFRC_DIV16,
|
|
AM_HAL_BLE_HCI_CLK_DIV32 = BLEIF_CLKCFG_FSEL_HFRC_DIV32,
|
|
AM_HAL_BLE_HCI_CLK_DIV64 = BLEIF_CLKCFG_FSEL_HFRC_DIV8,
|
|
}
|
|
am_hal_ble_hci_clock_e;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// BLE Core Clock settings.
|
|
//
|
|
//*****************************************************************************
|
|
typedef enum
|
|
{
|
|
AM_HAL_BLE_CORE_MCU_CLK = 0x02,
|
|
AM_HAL_BLE_CORE_INTERNAL_CLK = 0x00,
|
|
}
|
|
am_hal_ble_core_clock_e;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Interrupts.
|
|
//
|
|
//*****************************************************************************
|
|
// The B2M_STATE went into the shutdown state
|
|
#define AM_BLEIF_INT_B2MSHUTDN AM_REG_BLEIF_INTEN_B2MSHUTDN_M
|
|
// The B2M_STATE went into the active state
|
|
#define AM_BLEIF_INT_B2MACTIVE AM_REG_BLEIF_INTEN_B2MACTIVE_M
|
|
// The B2M_STATE went into the sleep state
|
|
#define AM_BLEIF_INT_B2MSLEEP AM_REG_BLEIF_INTEN_B2MSLEEP_M
|
|
// command queue received and error
|
|
#define AM_BLEIF_INT_CQERR AM_REG_BLEIF_INTEN_CQERR_M
|
|
// CQ write operation performed a register write with the register address bit
|
|
// 0 set to 1. The low address bits in the CQ address fields are unused and
|
|
// bit 0 can be used to trigger an interrupt to indicate when this register
|
|
// write is performed by the CQ operation.
|
|
#define AM_BLEIF_INT_CQUPD AM_REG_BLEIF_INTEN_CQUPD_M
|
|
// The command queue is waiting interrupt
|
|
#define AM_BLEIF_INT_CQPAUSED AM_REG_BLEIF_INTEN_CQPAUSED_M
|
|
// DMA Error
|
|
#define AM_BLEIF_INT_DERR AM_REG_BLEIF_INTEN_DERR_M
|
|
// DMA Complete
|
|
#define AM_BLEIF_INT_DCMP AM_REG_BLEIF_INTEN_DCMP_M
|
|
// THis is the BLE Core IRQ signal
|
|
#define AM_BLEIF_INT_BLECIRQ AM_REG_BLEIF_INTEN_BLECIRQ_M
|
|
// This is the illegal command interrupt.
|
|
#define AM_BLEIF_INT_ICMD AM_REG_BLEIF_INTEN_ICMD_M
|
|
// This is the illegal FIFO access interrupt.
|
|
#define AM_BLEIF_INT_IACC AM_REG_BLEIF_INTEN_IACC_M
|
|
// Any change in the B2M_STATE signal from the BLE Core will set this interrupt
|
|
#define AM_BLEIF_INT_B2MST AM_REG_BLEIF_INTEN_B2MST_M
|
|
// This is the Write FIFO Overflow interrupt.
|
|
#define AM_BLEIF_INT_FOVFL AM_REG_BLEIF_INTEN_FOVFL_M
|
|
// This is the Read FIFO Underflow interrupt.
|
|
#define AM_BLEIF_INT_FUNDFL AM_REG_BLEIF_INTEN_FUNDFL_M
|
|
// This is the FIFO Threshold interrupt.
|
|
#define AM_BLEIF_INT_THR AM_REG_BLEIF_INTEN_THR_M
|
|
// This is the Command Complete interrupt.
|
|
#define AM_BLEIF_INT_CMDCMP AM_REG_BLEIF_INTEN_CMDCMP_M
|
|
|
|
#define AM_HAL_BLE_INT_B2MSHUTDN BLEIF_INTEN_B2MSHUTDN_Msk // The B2M_STATE went into the shutdown state
|
|
#define AM_HAL_BLE_INT_B2MACTIVE BLEIF_INTEN_B2MACTIVE_Msk // The B2M_STATE went into the active state
|
|
#define AM_HAL_BLE_INT_B2MSLEEP BLEIF_INTEN_B2MSLEEP_Msk // The B2M_STATE went into the sleep state
|
|
#define AM_HAL_BLE_INT_CQERR BLEIF_INTEN_CQERR_Msk // command queue received and error
|
|
|
|
// CQ write operation performed a register write with the register address bit
|
|
// 0 set to 1. The low address bits in the CQ address fields are unused and
|
|
// bit 0 can be used to trigger an interrupt to indicate when this register
|
|
// write is performed by the CQ operation.
|
|
#define AM_HAL_BLE_INT_CQUPD BLEIF_INTEN_CQUPD_Msk
|
|
|
|
#define AM_HAL_BLE_INT_CQPAUSED BLEIF_INTEN_CQPAUSED_Msk // The command queue is waiting interrupt
|
|
#define AM_HAL_BLE_INT_DERR BLEIF_INTEN_DERR_Msk // DMA Error
|
|
#define AM_HAL_BLE_INT_DCMP BLEIF_INTEN_DCMP_Msk // DMA Complete
|
|
#define AM_HAL_BLE_INT_BLECSSTAT BLEIF_INTEN_BLECSSTAT_Msk // This is the BLE Core SPI STATUS signal.
|
|
#define AM_HAL_BLE_INT_BLECIRQ BLEIF_INTEN_BLECIRQ_Msk // This is the BLE Core IRQ signal
|
|
#define AM_HAL_BLE_INT_ICMD BLEIF_INTEN_ICMD_Msk // This is the illegal command interrupt.
|
|
#define AM_HAL_BLE_INT_IACC BLEIF_INTEN_IACC_Msk // This is the illegal FIFO access interrupt.
|
|
#define AM_HAL_BLE_INT_B2MST BLEIF_INTEN_B2MST_Msk // Any change in the B2M_STATE signal from the BLE Core will set this interrupt
|
|
#define AM_HAL_BLE_INT_FOVFL BLEIF_INTEN_FOVFL_Msk // This is the Write FIFO Overflow interrupt.
|
|
#define AM_HAL_BLE_INT_FUNDFL BLEIF_INTEN_FUNDFL_Msk // This is the Read FIFO Underflow interrupt.
|
|
#define AM_HAL_BLE_INT_THR BLEIF_INTEN_THR_Msk // This is the FIFO Threshold interrupt.
|
|
#define AM_HAL_BLE_INT_CMDCMP BLEIF_INTEN_CMDCMP_Msk // This is the Command Complete interrupt.
|
|
|
|
#define AM_HAL_BLE_INT_BLECSSTATN BLEIF_INTSTAT_B2MSHUTDN_Msk
|
|
#define AM_HAL_BLE_INT_BLECIRQN BLEIF_INTSTAT_B2MACTIVE_Msk
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Type definitions.
|
|
//
|
|
//*****************************************************************************
|
|
#define am_hal_ble_buffer(A) \
|
|
union \
|
|
{ \
|
|
uint32_t words[(A + 3) >> 2]; \
|
|
uint8_t bytes[A]; \
|
|
}
|
|
|
|
// Function pointer for non-blocking ble read callbacks.
|
|
typedef void (*am_hal_ble_transfer_complete_cb_t)(uint8_t *pui8Data, uint32_t ui32Length, void *pvContext);
|
|
|
|
//
|
|
// Patch container
|
|
//
|
|
typedef struct
|
|
{
|
|
uint32_t ui32Type;
|
|
uint32_t ui32Length;
|
|
uint32_t ui32CRC;
|
|
const uint32_t *pui32Data;
|
|
}
|
|
am_hal_ble_patch_t;
|
|
|
|
//
|
|
// Configuration structure for the BLE module.
|
|
//
|
|
typedef struct
|
|
{
|
|
// HCI interface options.
|
|
uint32_t ui32SpiClkCfg; // Configure the HCI interface clock.
|
|
uint32_t ui32ReadThreshold; // Internal HCI READ FIFO size
|
|
uint32_t ui32WriteThreshold; // Internal HCI WRITE FIFO size.
|
|
|
|
// BLE options.
|
|
uint32_t ui32BleClockConfig; // Configure the BLE core clock.
|
|
uint32_t ui32ClockDrift; // Set the expected BLE clock drift.
|
|
uint32_t ui32SleepClockDrift; // Set the expected sleep clock accuracy.
|
|
bool bAgcEnabled; // Enable/Disable AGC
|
|
bool bSleepEnabled; // Enable/Disable Sleep Algorithm
|
|
|
|
// Patches
|
|
bool bUseDefaultPatches; // Apply the default patches?
|
|
}
|
|
am_hal_ble_config_t;
|
|
|
|
//
|
|
// Default options for the BLE module.
|
|
//
|
|
extern const am_hal_ble_config_t am_hal_ble_default_config;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Structure for sending SPI commands.
|
|
//
|
|
//*****************************************************************************
|
|
typedef struct
|
|
{
|
|
uint32_t *pui32Data;
|
|
uint8_t pui8Offset[3];
|
|
uint8_t ui8OffsetLen;
|
|
uint16_t ui16Length;
|
|
uint8_t ui8Command;
|
|
uint8_t ui8RepeatCount;
|
|
bool bContinue;
|
|
am_hal_ble_transfer_complete_cb_t pfnTransferCompleteCB;
|
|
void *pvContext;
|
|
}
|
|
am_hal_ble_transfer_t;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Vendor Specific commands.
|
|
//
|
|
// Note: Lengths are reported as "4 + <parameter length>". Each vendor-specific
|
|
// header is 4 bytes long. This definition allows the macro version of the
|
|
// length to be used in all BLE APIs.
|
|
//
|
|
//*****************************************************************************
|
|
#define AM_HAL_BLE_SET_BD_ADDR_OPCODE 0xFC32
|
|
#define AM_HAL_BLE_SET_BD_ADDR_LENGTH (4 + 6)
|
|
|
|
#define AM_HAL_BLE_SET_TX_POWER_OPCODE 0xFC3B
|
|
#define AM_HAL_BLE_SET_TX_POWER_LENGTH (4 + 3)
|
|
|
|
#define AM_HAL_BLE_READ_VERSIONS_OPCODE 0xFD01
|
|
#define AM_HAL_BLE_READ_VERSIONS_LENGTH (4 + 0)
|
|
|
|
#define AM_HAL_BLE_PLF_REGISTER_READ_OPCODE 0xFD02
|
|
#define AM_HAL_BLE_PLF_REGISTER_READ_LENGTH (4 + 4)
|
|
|
|
#define AM_HAL_BLE_PLF_REGISTER_WRITE_OPCODE 0xFD03
|
|
#define AM_HAL_BLE_PLF_REGISTER_WRITE_LENGTH (4 + 8)
|
|
|
|
#define AM_HAL_BLE_GET_RSSI_OPCODE 0x1405
|
|
#define AM_HAL_BLE_GET_RSSI_LENGTH (4 + 0)
|
|
|
|
#define AM_HAL_BLE_SET_SLEEP_OPCODE 0xFD09
|
|
#define AM_HAL_BLE_SET_SLEEP_LENGTH (4 + 0)
|
|
|
|
#define AM_HAL_BLE_SPI_SENDFRAME_OPCODE 0xFD04
|
|
#define AM_HAL_BLE_SPI_SENDFRAME_LENGTH (4 + 1)
|
|
|
|
#define AM_HAL_BLE_SET_BD_ADDR_CMD(...) {0x01, 0x32, 0xFC, 0x06, __VA_ARGS__}
|
|
#define AM_HAL_BLE_SET_TX_POWER_CMD(...) {0x01, 0x3B, 0xFC, 0x03, __VA_ARGS__}
|
|
#define AM_HAL_BLE_SET_READ_VERSIONS_CMD() {0x01, 0x01, 0xFD, 0x00}
|
|
#define AM_HAL_BLE_PLF_REGISTER_READ_CMD(...) {0x01, 0x02, 0xFD, 0x04, __VA_ARGS__}
|
|
#define AM_HAL_BLE_PLF_REGISTER_WRITE_CMD(...) {0x01, 0x03, 0xFD, 0x08, __VA_ARGS__}
|
|
#define AM_HAL_BLE_GET_RSSI_CMD() {0x01, 0x05, 0x14, 0x00}
|
|
#define AM_HAL_BLE_SET_SLEEP_CMD() {0x01, 0x09, 0xFD, 0x00}
|
|
#define AM_HAL_BLE_SPI_SENDFRAME_CMD(...) {0x01, 0x04, 0xFD, 0x01, __VA_ARGS__}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// State variables for the BLE module.
|
|
//
|
|
//*****************************************************************************
|
|
typedef struct
|
|
{
|
|
// Handle validation prefix.
|
|
am_hal_handle_prefix_t prefix;
|
|
|
|
// Which BLE module instance is this?
|
|
uint32_t ui32Module;
|
|
|
|
// Apply the default patches during the "boot" function?
|
|
bool bUseDefaultPatches;
|
|
|
|
// What was the last command that we started?
|
|
am_hal_ble_transfer_t sCurrentTransfer;
|
|
|
|
// If a write is interrupted by a read, we have to save the write
|
|
// transaction to execute later. That saved write goes here.
|
|
am_hal_ble_transfer_t sSavedTransfer;
|
|
|
|
// How far along are we?
|
|
uint32_t ui32TransferIndex;
|
|
|
|
// Has this radio already been patched?
|
|
bool bPatchComplete;
|
|
|
|
// Are we in the middle of a continue packet?
|
|
bool bContinuePacket;
|
|
|
|
// Was our last operation to send a TX packet? If we have two TX packets in
|
|
// a row, we need special handling to get the timing right.
|
|
bool bLastPacketWasTX;
|
|
|
|
// Do we have a saved packet?
|
|
bool bSavedPacket;
|
|
|
|
// Is the bus already in use?
|
|
bool bBusy;
|
|
|
|
// Has the last command completed?
|
|
bool bCmdComplete;
|
|
|
|
// Has the last DMA action completed?
|
|
bool bDmaComplete;
|
|
|
|
// Has the BLE core's flow control signal been reset?
|
|
bool bFlowControlComplete;
|
|
}
|
|
am_hal_ble_state_t;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// SPI command macros.
|
|
//
|
|
//*****************************************************************************
|
|
#define AM_HAL_BLE_WRITE 1
|
|
#define AM_HAL_BLE_READ 2
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// HCI packet types.
|
|
//
|
|
//*****************************************************************************
|
|
#define AM_HAL_BLE_RAW 0x0
|
|
#define AM_HAL_BLE_CMD 0x1
|
|
#define AM_HAL_BLE_ACL 0x2
|
|
#define AM_HAL_BLE_EVT 0x4
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// External function declarations.
|
|
//
|
|
//*****************************************************************************
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Basics
|
|
//
|
|
// Initialization, enable/disable, and general configuration.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Initialize the internal state variables for the BLE module.
|
|
//!
|
|
//! @param ui32Module - Which BLE module to use.
|
|
//! @param ppHandle - Pointer to a handle variable to be initialized.
|
|
//!
|
|
//! This function initializes the internal state variables associated with a
|
|
//! particular BLE module and yields a handle that may be used to perform
|
|
//! additional operations with that BLE module.
|
|
//!
|
|
//! This function must be called before any other BLE module operation.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_initialize(uint32_t ui32Module, void **ppHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief De-initialize the internal state variables for the BLE module.
|
|
//!
|
|
//! @param pHandle - Handle variable to be de-initialized.
|
|
//!
|
|
//! This function invalidates a previously initialized BLE module handle and
|
|
//! deletes the contents of the internal state variables associated with it.
|
|
//! This could be used in situations where the caller wants to prevent future
|
|
//! function calls to a particular BLE module.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_deinitialize(void *pHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Configure a BLE module.
|
|
//!
|
|
//! @param pHandle - Handle for the BLE module.
|
|
//! @param psConfig - Pointer to a BLE configuration structure.
|
|
//!
|
|
//! This routine performs the necessary configuration steps to prepare the
|
|
//! physical BLE interface for operation. This function should be called after
|
|
//! \e am_hal_ble_enable() and before any other BLE operation. The \e psConfig
|
|
//! parameter may be used to set a specific interface clock frequency or modify
|
|
//! the FIFO read and write thresholds, but most users will get the best
|
|
//! results from the default settings stored in the global configuration
|
|
//! structure \e am_hal_ble_default_config.
|
|
//!
|
|
//! @note This function will only work if the BLE module has previously been
|
|
//! enabled.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_config(void *pHandle, const am_hal_ble_config_t *psConfig);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Enable the BLE module.
|
|
//!
|
|
//! @param pHandle - Handle for the BLE module.
|
|
//! @param ui32PowerState - Determines whether BLE is powered on or off.
|
|
//!
|
|
//! Performs the power-up or power-down sequence for the BLE module referred to
|
|
//! be \e pHandle. This should be called after am_hal_ble_initialize(), but
|
|
//! before am_hal_ble_config().
|
|
//!
|
|
//! The ui32PowerState variable must be set to either AM_HAL_BLE_POWER_ACTIVE
|
|
//! or AM_HAL_BLE_POWER_OFF.
|
|
//!
|
|
//! After this function is called, the BLE core will be in its startup or
|
|
//! "patching" mode.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t am_hal_ble_power_control(void *pHandle, uint32_t ui32PowerState);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Boot the BLE module
|
|
//!
|
|
//! @param pHandle - Handle for the BLE module.
|
|
//!
|
|
//! This function performs the complete patching process for the BLE core and
|
|
//! returns with the BLE core in HCI mode. If you ask for the default patches
|
|
//! your am_hal_ble_config_t structure, then this is the last function you need
|
|
//! to call on startup. You don't need to call any of the patching functions.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_boot(void *pHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Patching functions.
|
|
//
|
|
// The following functions allow the caller to apply "patches" to the BLE core
|
|
// during its startup phase. These are pre-made configuration files that change
|
|
// the operation parameters of the BLE radio. If you have received a patch file
|
|
// from the manufacturer, you may use the \e am_hal_ble_patch_apply() function
|
|
// during startup to apply these settings to the BLE core. Otherwise, you may
|
|
// skip this step by calling the \e am_hal_ble_patch_complete() function.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Apply a patch to the BLE core.
|
|
//!
|
|
//! @param pHandle Handle for the BLE module.
|
|
//! @param psPatch Pointer to a structure describing the patch.
|
|
//!
|
|
//! The BLE core is an independent processor that executes code from an
|
|
//! on-board ROM. Its behavior can be altered through "patches" which are
|
|
//! binary snippets of code that may be loaded at startup to overlay or replace
|
|
//! sections of the original ROM (for instance, to modify trim settings). This
|
|
//! function allows the caller to apply one of these patches.
|
|
//!
|
|
//! Patches must be applied after the BLE module is enabled and configured, but
|
|
//! before standard HCI operation begins. This is the only time where the BLE
|
|
//! core is able to accept patch files.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_patch_apply(void *pHandle, am_hal_ble_patch_t *psPatch);
|
|
|
|
extern uint32_t am_hal_ble_default_copy_patch_apply(void *pHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Apply the default manufacturer patch to the BLE core.
|
|
//!
|
|
//! @param pHandle Handle for the BLE module.
|
|
//! @param psPatch Pointer to a structure describing the patch.
|
|
//!
|
|
//! The BLE core is an independent processor that executes code from an
|
|
//! on-board ROM. Its behavior can be altered through "patches" which are
|
|
//! binary snippets of code that may be loaded at startup to overlay or replace
|
|
//! sections of the original ROM (for instance, to modify trim settings). This
|
|
//! function allows the caller to apply one of these patches.
|
|
//!
|
|
//! Patches must be applied after the BLE module is enabled and configured, but
|
|
//! before standard HCI operation begins. This is the only time where the BLE
|
|
//! core is able to accept patch files.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_default_patch_apply(void *pHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Complete the patching phase.
|
|
//!
|
|
//! @param pHandle Handle for the BLE module.
|
|
//!
|
|
//! After the BLE core is enabled and configured, it enters a "patching mode"
|
|
//! where it can accept patches from the main CPU. Once all patches have been
|
|
//! applied using the \e am_hal_ble_patch_apply() function. The application
|
|
//! must call this function to command the BLE core to switch to standard HCI
|
|
//! mode.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_patch_complete(void *pHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Manually enable/disable transmitter
|
|
// set ui8TxCtrl as 1 to manually enale transmitter, 0 back to default
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_transmitter_control(void *pHandle, uint8_t ui8TxCtrl);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Manually enable/disable transmitter to output carrier signal
|
|
// set ui8TxChannel as 0 to 0x27 for each transmit channel, 0xFF back to normal modulate mode
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_transmitter_control_ex(void *pHandle, uint8_t ui8TxChannel);
|
|
//*****************************************************************************
|
|
//
|
|
// Manually set modulation characteristic
|
|
// based on the tested values at customer side.
|
|
// manually set frequency offset for 10101010 or 01010101 pattern
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_transmitter_modex_set(void *pHandle, uint8_t ui8ModFrqOffset);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Performs a blocking read or write to the BLE core.
|
|
//!
|
|
//! @param pHandle - Handle for the BLE module.
|
|
//! @param psTransfer - Structure describing the transaction to execute.
|
|
//!
|
|
//! Send or receive data from the
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_blocking_transfer(void *pHandle, am_hal_ble_transfer_t *psTransfer);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Complete the patching phase.
|
|
//!
|
|
//! @param pHandle Handle for the BLE module.
|
|
//!
|
|
//! After the BLE core is enabled and configured, it enters a "patching mode"
|
|
//! where it can accept patches from the main CPU. Once all patches have been
|
|
//! applied using the \e am_hal_ble_patch_apply() function. The application
|
|
//! must call this function to command the BLE core to switch to standard HCI
|
|
//! mode.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_nonblocking_transfer(void *pHandle, am_hal_ble_transfer_t *psTransfer);
|
|
|
|
// High-level HCI APIs
|
|
extern uint32_t am_hal_ble_vs_command_build(uint32_t *pui32Command,
|
|
uint32_t ui32OpCode,
|
|
uint32_t ui32TotalLength,
|
|
uint8_t *pui8Parameters);
|
|
|
|
extern uint32_t am_hal_ble_blocking_hci_read(void *pHandle,
|
|
uint32_t *pui32Data,
|
|
uint32_t *pui32BytesReceived);
|
|
|
|
extern uint32_t am_hal_ble_blocking_hci_write(void *pHandle,
|
|
uint8_t ui8Type,
|
|
uint32_t *pui32Data,
|
|
uint32_t ui32NumBytes);
|
|
|
|
extern uint32_t am_hal_ble_nonblocking_hci_read(void *pHandle,
|
|
uint32_t *pui32Data,
|
|
am_hal_ble_transfer_complete_cb_t pfnCallback,
|
|
void *pvContext);
|
|
|
|
extern uint32_t am_hal_ble_nonblocking_hci_write(void *pHandle,
|
|
uint8_t ui8Type,
|
|
uint32_t *pui32Data,
|
|
uint32_t ui32NumBytes,
|
|
am_hal_ble_transfer_complete_cb_t pfnCallback,
|
|
void *pvContext);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Set one of the trim values for the BLE core.
|
|
//!
|
|
//! @param pHandle is the BLE module handle
|
|
//! @param ui32BleCoreAddress is the target address for the trim value.
|
|
//! @param ui32TrimValue is the trim value to write to the BLE core.
|
|
//!
|
|
//! This function takes a BLE core trim value from the MCU memory and writes it
|
|
//! to a trim register in the BLE core.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_trim_set(void *pHandle, uint32_t ui32BleCoreAddress,
|
|
uint32_t ui32TrimValue, uint32_t ui32TrimMask);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Sets the default trim values for the BLE core.
|
|
//!
|
|
//! @param pHandle is the BLE module handle
|
|
//!
|
|
//! This function reads the default trim values for the BLE core from
|
|
//! non-volatile memory, and writes them to the BLE core registers.
|
|
//! Specifically, this function adjusts the BLE core bandgap voltage, bandgap
|
|
//! current, and memory-retention LDO voltage based on chip-specific,
|
|
//! manufacturer-determined settings.
|
|
//!
|
|
//! For best performance and power consumption, this function should be called
|
|
//! after the patching process is complete, but before normal HCI operation
|
|
//! begins.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_default_trim_set(void *pHandle);
|
|
|
|
uint32_t am_hal_ble_default_trim_set_ramcode(void *pHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Change the TX power setting.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param ui32TxPower is the desired power setting.
|
|
//! 0x03->-20dBm 0x04->-10dBm 0x05->-5dBm 0x08->0dBm 0x0F->4dBm
|
|
//!
|
|
//! This function sends a vendor-specific command to change the TX power level
|
|
//! setting for the BLE core.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_tx_power_set(void *pHandle, uint8_t ui32TxPower);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Generate continuously moderated signal for SRRC/CE test.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param enable, true for enabling continous signal, false for disable
|
|
//!
|
|
//! This function programs an internal register to control transmit mode in
|
|
//! BLE controller.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
extern uint32_t am_hal_ble_set_constant_transmission(void *pHandle, bool enable);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Generate continuously moderated signal for SRRC/CE test on a
|
|
//! specified rf channel.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param channel, 0 to 0x27 for a valid radio channnel while 0xff to set
|
|
//! radio transmit mode to normal.
|
|
//!
|
|
//! This function calls am_hal_ble_set_constant_transmission() and send HCI
|
|
//! test command with channel information to BLE controller.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_set_constant_transmission_ex(void *pHandle, uint8_t channel);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief This is to workaround a bug for channel 1 in DTM mode.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//
|
|
extern uint32_t am_hal_ble_init_rf_channel(void *pHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief This function should be called with enable set to true for
|
|
//! BQB testing.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param enable, true for enabling BQB test mode, false for normal mode
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_BQB_test_init(void *pHandle, bool enable);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Set BLE sleep enable/disable for the BLE core.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param enable 'true' set sleep enable, 'false' set sleep disable
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_sleep_set(void *pHandle, bool enable);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Sends a signal to wake up the BLE controller
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param ui32Mode is determines the value of the WAKE signal.
|
|
//!
|
|
//! The BLE core needs to be awake before we send data to it. This function
|
|
//! sends a signal to the BLE core that tells it that we intend to send it
|
|
//! data. When the BLE core wakes up, it will generate a BLECSSTAT interrupt,
|
|
//! and the SPISTATUS bit in the BSTATUS register will be set.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_wakeup_set(void *pHandle, uint32_t ui32Mode);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Read a register value directly from the BLE Core.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param ui32Address is the address of the register.
|
|
//! @param *pui32Value is a pointer where the register value will be stored.
|
|
//!
|
|
//! This function uses a vendor-specific sequence of blocking HCI commands to
|
|
//! read one of the internal registers within the BLE Core. The value stored in
|
|
//! this register will be written to the location specified by \e pui32Value.
|
|
//!
|
|
//! This function is mostly used during initial radio setup or for internal
|
|
//! test commands. Standard applications will not need to call this function
|
|
//! directly.
|
|
//!
|
|
//! @note This function uses multiple blocking HCI commands in sequence. It
|
|
//! should not be used in any situation where blocking commands are not
|
|
//! desired. Do not use it in applications where interrupt-driven BLE
|
|
//! operations have already started.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_plf_reg_read(void *pHandle, uint32_t ui32Address, uint32_t *pui32Value);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Write a register value directly to the BLE Core.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param ui32Address is the address of the register.
|
|
//! @param ui32Value is the value to write.
|
|
//!
|
|
//! This function uses a vendor-specific sequence of blocking HCI commands to
|
|
//! write one of the internal registers within the BLE Core.
|
|
//!
|
|
//! This function is mostly used during initial radio setup or for internal
|
|
//! test commands. Standard applications will not need to call this function
|
|
//! directly.
|
|
//!
|
|
//! @note This function uses multiple blocking HCI commands in sequence. It
|
|
//! should not be used in any situation where blocking commands are not
|
|
//! desired. Do not use it in applications where interrupt-driven BLE
|
|
//! operations have already started.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_plf_reg_write(void *pHandle, uint32_t ui32Address, uint32_t ui32Value);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Change the sleep behavior of the BLE core.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param enable sets the desired sleep behavior.
|
|
//!
|
|
//! This function uses a vendor-specific sequence of blocking HCI commands to
|
|
//! change the default behavior of the BLE core between radio events. Set \e
|
|
//! enable to true to allow the BLE core to sleep between radio events, or
|
|
//! false to keep the BLE core awake at all times. The default behavior on
|
|
//! startup allows the BLE core to sleep. Most applications will not need to
|
|
//! modify this setting.
|
|
//!
|
|
//! @note This function uses multiple blocking HCI commands in sequence. It
|
|
//! should not be used in any situation where blocking commands are not
|
|
//! desired. Do not use it in applications where interrupt-driven BLE
|
|
//! operations have already started.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_sleep_set(void *pHandle, bool enable);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Check the sleep behavior of the BLE core.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//!
|
|
//! This function uses a vendor-specific sequence of blocking HCI commands to
|
|
//! check whether the BLE core is set to go to sleep between BLE transactions.
|
|
//! This function will return "true" if BLE sleep is enabled, or "false" if it
|
|
//! is disabled.
|
|
//!
|
|
//! @note This function uses multiple blocking HCI commands in sequence. It
|
|
//! should not be used in any situation where blocking commands are not
|
|
//! desired. Do not use it in applications where interrupt-driven BLE
|
|
//! operations have already started.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern bool am_hal_ble_sleep_get(void *pHandle);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! @brief Change the TX power setting of the BLE core.
|
|
//!
|
|
//! @param pHandle is the Handle for the BLE module.
|
|
//! @param uint8_t is the desired power setting.
|
|
//!
|
|
//! This function uses a vendor-specific sequence of blocking HCI commands to
|
|
//! change the TX power setting of the radio.
|
|
//!
|
|
//! @note This function uses multiple blocking HCI commands in sequence. It
|
|
//! should not be used in any situation where blocking commands are not
|
|
//! desired. Do not use it in applications where interrupt-driven BLE
|
|
//! operations have already started.
|
|
//!
|
|
//! @return BLE status code.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_tx_power_set(void *pHandle, uint8_t ui32TxPower);
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Interrupts.
|
|
//
|
|
//*****************************************************************************
|
|
extern uint32_t am_hal_ble_int_service(void *pHandle, uint32_t ui32Status);
|
|
extern uint32_t am_hal_ble_int_enable(void *pHandle, uint32_t ui32InterruptMask);
|
|
extern uint32_t am_hal_ble_int_disable(void *pHandle, uint32_t ui32InterruptMask);
|
|
extern uint32_t am_hal_ble_int_status(void *pHandle, bool bEnabledOnly);
|
|
extern uint32_t am_hal_ble_int_clear(void *pHandle, uint32_t ui32InterruptMask);
|
|
extern uint32_t am_hal_ble_check_32k_clock(void *pHandle);
|
|
//*****************************************************************************
|
|
//
|
|
// Debug trace pins.
|
|
//
|
|
//*****************************************************************************
|
|
#ifdef AM_DEBUG_BLE_TIMING
|
|
|
|
#define BLE_DEBUG_TRACE_01 11
|
|
#define BLE_DEBUG_TRACE_02 28
|
|
#define BLE_DEBUG_TRACE_03 26
|
|
#define BLE_DEBUG_TRACE_04 4
|
|
#define BLE_DEBUG_TRACE_05 18
|
|
#define BLE_DEBUG_TRACE_06 14
|
|
#define BLE_DEBUG_TRACE_07 6
|
|
#define BLE_DEBUG_TRACE_08 45
|
|
#define BLE_DEBUG_TRACE_09 12
|
|
#define BLE_DEBUG_TRACE_10 13
|
|
#define BLE_DEBUG_TRACE_11 10
|
|
#define BLE_LOCK_TRACE_PIN BLE_DEBUG_TRACE_11
|
|
|
|
#define am_hal_debug_gpio_set(x) am_hal_gpio_state_write(x, AM_HAL_GPIO_OUTPUT_SET)
|
|
|
|
#define am_hal_debug_gpio_clear(x) am_hal_gpio_state_write(x, AM_HAL_GPIO_OUTPUT_CLEAR)
|
|
|
|
#define am_hal_debug_gpio_toggle(x) am_hal_gpio_state_write(x, AM_HAL_GPIO_OUTPUT_TOGGLE)
|
|
|
|
#define am_hal_debug_gpio_pinconfig(x) am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_OUTPUT)
|
|
|
|
#else
|
|
|
|
#define am_hal_debug_gpio_set(...)
|
|
#define am_hal_debug_gpio_clear(...)
|
|
#define am_hal_debug_gpio_toggle(...)
|
|
#define am_hal_debug_gpio_pinconfig(...)
|
|
|
|
#endif // AM_DEBUG_BLE_TIMING
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // AM_HAL_BLE_H
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// End Doxygen group.
|
|
//! @}
|
|
//
|
|
//*****************************************************************************
|