1 //*****************************************************************************
2 //
3 //! @file am_hal_ble.h
4 //!
5 //! @brief HAL Functions for the BLE Interface.
6 //!
7 //! @addtogroup BLE3 BLE - BLE functions
8 //! @ingroup apollo3_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2024, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_3_2_0-dd5f40c14b of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 
48 #ifndef AM_HAL_BLE_H
49 #define AM_HAL_BLE_H
50 
51 #include "am_hal_global.h"
52 #include "am_hal_status.h"
53 
54 //*****************************************************************************
55 //
56 //! CMSIS-style macro for handling a variable BLEIF module number.
57 //
58 #define BLEIFn(n)   ((BLEIF_Type*)(BLEIF_BASE + (n * (BLEIF_BASE - BLEIF_BASE))))
59 //*****************************************************************************
60 
61 //*****************************************************************************
62 //
63 //! BLE-specific status values.
64 //
65 //*****************************************************************************
66 typedef enum
67 {
68     //
69     //! This error occurs when an HCI read or write function is called while
70     //! another HCI communication function is already in progress.
71     //
72     AM_HAL_BLE_STATUS_BUS_BUSY = AM_HAL_STATUS_MODULE_SPECIFIC_START,
73 
74     //
75     //! This error happens when the MCU tries to execute an HCI read, but the
76     //! BLE core hasn't asserted the BLEIRQ line. Try waiting for a BLEIRQ
77     //! interrupt, or polling the BLECIRQ bit in the BSTATUS register before
78     //! calling an HCI read function.
79     //
80     AM_HAL_BLE_STATUS_IRQ_LOW,
81 
82     //
83     //! This error means that the MCU tried to execute an HCI write, but the BLE
84     //! core didn't assert its SPI_STATUS signal within the allotted timeout.
85     //! This might mean that there has been some error inside the BLE core. This
86     //! may require a reboot of the BLE core.
87     //
88     AM_HAL_BLE_STATUS_SPI_NOT_READY,
89 
90     //
91     //! This error means we were trying to write, but the BLE core has requested
92     //! a READ instead. We will need to perform a read before we can retry this
93     //! write.
94     //
95     AM_HAL_BLE_REQUESTING_READ,
96 
97     //
98     //! We are expecting an HCI response to a packet we just sent, but the BLE
99     //! core isn't asserting BLEIRQ. Its software may have crashed, and it may
100     //! need to restart.
101     //
102     AM_HAL_BLE_NO_HCI_RESPONSE,
103 
104     //
105     //! Any of these errors indicate a problem with the BLE hardware that
106     //! requires a complete restart.
107     //
108     AM_HAL_BLE_FEATURE_DISABLED,
109     AM_HAL_BLE_SHUTDOWN_FAILED,
110     AM_HAL_BLE_REGULATOR_FAILED,
111     AM_HAL_BLE_POWERUP_INCOMPLETE,
112     AM_HAL_BLE_HCI_PACKET_INCOMPLETE,
113     AM_HAL_BLE_FIFO_ERROR,
114     AM_HAL_BLE_32K_CLOCK_UNSTABLE,
115 }
116 am_ble_status_e;
117 
118 //*****************************************************************************
119 //
120 //! BLE power modes.
121 //
122 //*****************************************************************************
123 typedef enum
124 {
125     AM_HAL_BLE_POWER_ACTIVE,
126     AM_HAL_BLE_POWER_OFF,
127 }
128 am_hal_ble_power_state_e;
129 
130 //*****************************************************************************
131 //
132 //! BLE SPI Clock settings.
133 //
134 //*****************************************************************************
135 typedef enum
136 {
137     AM_HAL_BLE_HCI_CLK_DIV2  = BLEIF_CLKCFG_FSEL_HFRC_DIV2,
138     AM_HAL_BLE_HCI_CLK_DIV4  = BLEIF_CLKCFG_FSEL_HFRC_DIV4,
139     AM_HAL_BLE_HCI_CLK_DIV8  = BLEIF_CLKCFG_FSEL_HFRC_DIV8,
140     AM_HAL_BLE_HCI_CLK_DIV16 = BLEIF_CLKCFG_FSEL_HFRC_DIV16,
141     AM_HAL_BLE_HCI_CLK_DIV32 = BLEIF_CLKCFG_FSEL_HFRC_DIV32,
142     AM_HAL_BLE_HCI_CLK_DIV64 = BLEIF_CLKCFG_FSEL_HFRC_DIV8,
143 }
144 am_hal_ble_hci_clock_e;
145 
146 //*****************************************************************************
147 //
148 //! BLE Core Clock settings.
149 //
150 //*****************************************************************************
151 typedef enum
152 {
153     AM_HAL_BLE_CORE_MCU_CLK      = 0x02,
154     AM_HAL_BLE_CORE_INTERNAL_CLK = 0x00,
155 }
156 am_hal_ble_core_clock_e;
157 
158 //*****************************************************************************
159 //
160 //! Interrupts.
161 //
162 //*****************************************************************************
163 //! The B2M_STATE went into the shutdown state
164 #define AM_BLEIF_INT_B2MSHUTDN               AM_REG_BLEIF_INTEN_B2MSHUTDN_M
165 //! The B2M_STATE went into the active state
166 #define AM_BLEIF_INT_B2MACTIVE               AM_REG_BLEIF_INTEN_B2MACTIVE_M
167 //! The B2M_STATE went into the sleep state
168 #define AM_BLEIF_INT_B2MSLEEP                AM_REG_BLEIF_INTEN_B2MSLEEP_M
169 //! command queue received and error
170 #define AM_BLEIF_INT_CQERR                   AM_REG_BLEIF_INTEN_CQERR_M
171 //! CQ write operation performed a register write with the register address bit
172 //! 0 set to 1.  The low address bits in the CQ address fields are unused and
173 //! bit 0 can be used to trigger an interrupt to indicate when this register
174 //! write is performed by the CQ operation.
175 #define AM_BLEIF_INT_CQUPD                   AM_REG_BLEIF_INTEN_CQUPD_M
176 //! The command queue is waiting interrupt
177 #define AM_BLEIF_INT_CQPAUSED                AM_REG_BLEIF_INTEN_CQPAUSED_M
178 //! DMA Error
179 #define AM_BLEIF_INT_DERR                    AM_REG_BLEIF_INTEN_DERR_M
180 //! DMA Complete
181 #define AM_BLEIF_INT_DCMP                    AM_REG_BLEIF_INTEN_DCMP_M
182 //! THis is the BLE Core IRQ signal
183 #define AM_BLEIF_INT_BLECIRQ                 AM_REG_BLEIF_INTEN_BLECIRQ_M
184 //! This is the illegal command interrupt.
185 #define AM_BLEIF_INT_ICMD                    AM_REG_BLEIF_INTEN_ICMD_M
186 //! This is the illegal FIFO access interrupt.
187 #define AM_BLEIF_INT_IACC                    AM_REG_BLEIF_INTEN_IACC_M
188 //! Any change in the B2M_STATE signal from the BLE Core will set this interrupt
189 #define AM_BLEIF_INT_B2MST                   AM_REG_BLEIF_INTEN_B2MST_M
190 //! This is the Write FIFO Overflow interrupt.
191 #define AM_BLEIF_INT_FOVFL                   AM_REG_BLEIF_INTEN_FOVFL_M
192 //! This is the Read FIFO Underflow interrupt.
193 #define AM_BLEIF_INT_FUNDFL                  AM_REG_BLEIF_INTEN_FUNDFL_M
194 //! This is the FIFO Threshold interrupt.
195 #define AM_BLEIF_INT_THR                     AM_REG_BLEIF_INTEN_THR_M
196 //! This is the Command Complete interrupt.
197 #define AM_BLEIF_INT_CMDCMP                  AM_REG_BLEIF_INTEN_CMDCMP_M
198 
199 #define AM_HAL_BLE_INT_B2MSHUTDN    BLEIF_INTEN_B2MSHUTDN_Msk //!< The B2M_STATE went into the shutdown state
200 #define AM_HAL_BLE_INT_B2MACTIVE    BLEIF_INTEN_B2MACTIVE_Msk //!< The B2M_STATE went into the active state
201 #define AM_HAL_BLE_INT_B2MSLEEP     BLEIF_INTEN_B2MSLEEP_Msk  //!< The B2M_STATE went into the sleep state
202 #define AM_HAL_BLE_INT_CQERR        BLEIF_INTEN_CQERR_Msk     //!< command queue received and error
203 
204 //! CQ write operation performed a register write with the register address bit
205 //! 0 set to 1.  The low address bits in the CQ address fields are unused and
206 //! bit 0 can be used to trigger an interrupt to indicate when this register
207 //! write is performed by the CQ operation.
208 #define AM_HAL_BLE_INT_CQUPD        BLEIF_INTEN_CQUPD_Msk
209 
210 #define AM_HAL_BLE_INT_CQPAUSED     BLEIF_INTEN_CQPAUSED_Msk  //!< The command queue is waiting interrupt
211 #define AM_HAL_BLE_INT_DERR         BLEIF_INTEN_DERR_Msk      //!< DMA Error
212 #define AM_HAL_BLE_INT_DCMP         BLEIF_INTEN_DCMP_Msk      //!< DMA Complete
213 #define AM_HAL_BLE_INT_BLECSSTAT    BLEIF_INTEN_BLECSSTAT_Msk //!< This is the BLE Core SPI STATUS signal.
214 #define AM_HAL_BLE_INT_BLECIRQ      BLEIF_INTEN_BLECIRQ_Msk   //!< This is the BLE Core IRQ signal
215 #define AM_HAL_BLE_INT_ICMD         BLEIF_INTEN_ICMD_Msk      //!< This is the illegal command interrupt.
216 #define AM_HAL_BLE_INT_IACC         BLEIF_INTEN_IACC_Msk      //!< This is the illegal FIFO access interrupt.
217 #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
218 #define AM_HAL_BLE_INT_FOVFL        BLEIF_INTEN_FOVFL_Msk     //!< This is the Write FIFO Overflow interrupt.
219 #define AM_HAL_BLE_INT_FUNDFL       BLEIF_INTEN_FUNDFL_Msk    //!< This is the Read FIFO Underflow interrupt.
220 #define AM_HAL_BLE_INT_THR          BLEIF_INTEN_THR_Msk       //!< This is the FIFO Threshold interrupt.
221 #define AM_HAL_BLE_INT_CMDCMP       BLEIF_INTEN_CMDCMP_Msk    //!< This is the Command Complete interrupt.
222 
223 #define AM_HAL_BLE_INT_BLECSSTATN       BLEIF_INTSTAT_B2MSHUTDN_Msk
224 #define AM_HAL_BLE_INT_BLECIRQN         BLEIF_INTSTAT_B2MACTIVE_Msk
225 
226 //*****************************************************************************
227 //
228 // Type definitions.
229 //
230 //*****************************************************************************
231 #define am_hal_ble_buffer(A)                                                  \
232     union                                                                     \
233     {                                                                         \
234         uint32_t words[(A + 3) >> 2];                                         \
235         uint8_t bytes[A];                                                     \
236     }
237 
238 //! Function pointer for non-blocking ble read callbacks.
239 typedef void (*am_hal_ble_transfer_complete_cb_t)(uint8_t *pui8Data, uint32_t ui32Length, void *pvContext);
240 
241 //
242 //! Patch container
243 //
244 typedef struct
245 {
246     uint32_t ui32Type;
247     uint32_t ui32Length;
248     uint32_t ui32CRC;
249     const uint32_t *pui32Data;
250 }
251 am_hal_ble_patch_t;
252 
253 //
254 //! Configuration structure for the BLE module.
255 //
256 typedef struct
257 {
258     // HCI interface options.
259     uint32_t ui32SpiClkCfg;         //!< Configure the HCI interface clock.
260     uint32_t ui32ReadThreshold;     //!< Internal HCI READ FIFO size
261     uint32_t ui32WriteThreshold;    //!< Internal HCI WRITE FIFO size.
262 
263     // BLE options.
264     uint32_t ui32BleClockConfig;    //!< Configure the BLE core clock.
265     uint32_t ui32ClockDrift;        //!< Set the expected BLE clock drift.
266     uint32_t ui32SleepClockDrift;   //!< Set the expected sleep clock accuracy.
267     bool bAgcEnabled;               //!< Enable/Disable AGC
268     bool bSleepEnabled;             //!< Enable/Disable Sleep Algorithm
269 
270     // Patches
271     bool bUseDefaultPatches;        //!< Apply the default patches?
272 }
273 am_hal_ble_config_t;
274 
275 //
276 //! Default options for the BLE module.
277 //
278 extern const am_hal_ble_config_t am_hal_ble_default_config;
279 
280 //*****************************************************************************
281 //
282 //! Structure for sending SPI commands.
283 //
284 //*****************************************************************************
285 typedef struct
286 {
287     uint32_t *pui32Data;
288     uint8_t pui8Offset[3];
289     uint8_t ui8OffsetLen;
290     uint16_t ui16Length;
291     uint8_t ui8Command;
292     uint8_t ui8RepeatCount;
293     bool bContinue;
294     am_hal_ble_transfer_complete_cb_t pfnTransferCompleteCB;
295     void *pvContext;
296 }
297 am_hal_ble_transfer_t;
298 
299 //*****************************************************************************
300 //
301 //! Vendor Specific commands.
302 //
303 //! @note  Lengths are reported as "4 + <parameter length>". Each vendor-specific
304 //! header is 4 bytes long. This definition allows the macro version of the
305 //! length to be used in all BLE APIs.
306 //
307 //*****************************************************************************
308 #define AM_HAL_BLE_SET_BD_ADDR_OPCODE               0xFC32
309 #define AM_HAL_BLE_SET_BD_ADDR_LENGTH               (4 + 6)
310 
311 #define AM_HAL_BLE_SET_TX_POWER_OPCODE              0xFC3B
312 #define AM_HAL_BLE_SET_TX_POWER_LENGTH              (4 + 3)
313 
314 #define AM_HAL_BLE_READ_VERSIONS_OPCODE             0xFD01
315 #define AM_HAL_BLE_READ_VERSIONS_LENGTH             (4 + 0)
316 
317 #define AM_HAL_BLE_PLF_REGISTER_READ_OPCODE         0xFD02
318 #define AM_HAL_BLE_PLF_REGISTER_READ_LENGTH         (4 + 4)
319 
320 #define AM_HAL_BLE_PLF_REGISTER_WRITE_OPCODE        0xFD03
321 #define AM_HAL_BLE_PLF_REGISTER_WRITE_LENGTH        (4 + 8)
322 
323 #define AM_HAL_BLE_GET_RSSI_OPCODE                  0x1405
324 #define AM_HAL_BLE_GET_RSSI_LENGTH                  (4 + 0)
325 
326 #define AM_HAL_BLE_SET_SLEEP_OPCODE                 0xFD09
327 #define AM_HAL_BLE_SET_SLEEP_LENGTH                 (4 + 0)
328 
329 #define AM_HAL_BLE_SPI_SENDFRAME_OPCODE             0xFD04
330 #define AM_HAL_BLE_SPI_SENDFRAME_LENGTH             (4 + 1)
331 
332 #define AM_HAL_BLE_SET_BD_ADDR_CMD(...)         {0x01, 0x32, 0xFC, 0x06, __VA_ARGS__}
333 #define AM_HAL_BLE_SET_TX_POWER_CMD(...)        {0x01, 0x3B, 0xFC, 0x03, __VA_ARGS__}
334 #define AM_HAL_BLE_SET_READ_VERSIONS_CMD()      {0x01, 0x01, 0xFD, 0x00}
335 #define AM_HAL_BLE_PLF_REGISTER_READ_CMD(...)   {0x01, 0x02, 0xFD, 0x04, __VA_ARGS__}
336 #define AM_HAL_BLE_PLF_REGISTER_WRITE_CMD(...)  {0x01, 0x03, 0xFD, 0x08, __VA_ARGS__}
337 #define AM_HAL_BLE_GET_RSSI_CMD()               {0x01, 0x05, 0x14, 0x00}
338 #define AM_HAL_BLE_SET_SLEEP_CMD()              {0x01, 0x09, 0xFD, 0x00}
339 #define AM_HAL_BLE_SPI_SENDFRAME_CMD(...)       {0x01, 0x04, 0xFD, 0x01, __VA_ARGS__}
340 
341 //*****************************************************************************
342 //
343 //! State variables for the BLE module.
344 //
345 //*****************************************************************************
346 typedef struct
347 {
348     //! Handle validation prefix.
349     am_hal_handle_prefix_t prefix;
350 
351     //! Which BLE module instance is this?
352     uint32_t ui32Module;
353 
354     //! Apply the default patches during the "boot" function?
355     bool bUseDefaultPatches;
356 
357     //! What was the last command that we started?
358     am_hal_ble_transfer_t sCurrentTransfer;
359 
360     //! If a write is interrupted by a read, we have to save the write
361     //! transaction to execute later. That saved write goes here.
362     am_hal_ble_transfer_t sSavedTransfer;
363 
364     //! How far along are we?
365     uint32_t ui32TransferIndex;
366 
367     //! Has this radio already been patched?
368     bool bPatchComplete;
369 
370     //! Are we in the middle of a continue packet?
371     bool bContinuePacket;
372 
373     //! Was our last operation to send a TX packet? If we have two TX packets in
374     //! a row, we need special handling to get the timing right.
375     bool bLastPacketWasTX;
376 
377     //! Do we have a saved packet?
378     bool bSavedPacket;
379 
380     //! Is the bus already in use?
381     bool bBusy;
382 
383     //! Has the last command completed?
384     bool bCmdComplete;
385 
386     //! Has the last DMA action completed?
387     bool bDmaComplete;
388 
389     //! Has the BLE core's flow control signal been reset?
390     bool bFlowControlComplete;
391 }
392 am_hal_ble_state_t;
393 
394 //*****************************************************************************
395 //
396 //! SPI command macros.
397 //
398 //*****************************************************************************
399 #define AM_HAL_BLE_WRITE                    1
400 #define AM_HAL_BLE_READ                     2
401 
402 //*****************************************************************************
403 //
404 //! HCI packet types.
405 //
406 //*****************************************************************************
407 #define AM_HAL_BLE_RAW                      0x0
408 #define AM_HAL_BLE_CMD                      0x1
409 #define AM_HAL_BLE_ACL                      0x2
410 #define AM_HAL_BLE_EVT                      0x4
411 
412 //*****************************************************************************
413 //
414 // External function declarations.
415 //
416 //*****************************************************************************
417 #ifdef __cplusplus
418 extern "C"
419 {
420 #endif
421 
422 //*****************************************************************************
423 //
424 // Basics
425 //
426 // Initialization, enable/disable, and general configuration.
427 //
428 //*****************************************************************************
429 
430 //*****************************************************************************
431 //
432 //! @brief Initialize the internal state variables for the BLE module.
433 //!
434 //! @param ui32Module - Which BLE module to use.
435 //! @param ppHandle - Pointer to a handle variable to be initialized.
436 //!
437 //! @details This function initializes the internal state variables associated with a
438 //! particular BLE module and yields a handle that may be used to perform
439 //! additional operations with that BLE module.
440 //!
441 //! This function must be called before any other BLE module operation.
442 //!
443 //! @return BLE status code.
444 //
445 //*****************************************************************************
446 extern uint32_t am_hal_ble_initialize(uint32_t ui32Module, void **ppHandle);
447 
448 //*****************************************************************************
449 //
450 //! @brief De-initialize the internal state variables for the BLE module.
451 //!
452 //! @param pHandle - Handle variable to be de-initialized.
453 //!
454 //! @note This function invalidates a previously initialized BLE module handle and
455 //! deletes the contents of the internal state variables associated with it.
456 //! This could be used in situations where the caller wants to prevent future
457 //! function calls to a particular BLE module.
458 //!
459 //! @return BLE status code.
460 //
461 //*****************************************************************************
462 extern uint32_t am_hal_ble_deinitialize(void *pHandle);
463 
464 //*****************************************************************************
465 //
466 //! @brief Configure a BLE module.
467 //!
468 //! @param pHandle - Handle for the BLE module.
469 //! @param psConfig - Pointer to a BLE configuration structure.
470 //!
471 //! @details This routine performs the necessary configuration steps to prepare the
472 //! physical BLE interface for operation. This function should be called after
473 //! \e am_hal_ble_enable() and before any other BLE operation. The \e psConfig
474 //! parameter may be used to set a specific interface clock frequency or modify
475 //! the FIFO read and write thresholds, but most users will get the best
476 //! results from the default settings stored in the global configuration
477 //! structure \e am_hal_ble_default_config.
478 //!
479 //! @note This function will only work if the BLE module has previously been
480 //! enabled.
481 //!
482 //! @return BLE status code.
483 //
484 //*****************************************************************************
485 extern uint32_t am_hal_ble_config(void *pHandle, const am_hal_ble_config_t *psConfig);
486 
487 //*****************************************************************************
488 //
489 //! @brief Enable the BLE module.
490 //!
491 //! @note Performs the power-up or power-down sequence for the BLE module referred to
492 //! be \e pHandle. This should be called after am_hal_ble_initialize(), but
493 //! before am_hal_ble_config().
494 //! @par
495 //! @note The ui32PowerState variable must be set to either AM_HAL_BLE_POWER_ACTIVE
496 //! or AM_HAL_BLE_POWER_OFF.
497 //! @par
498 //! @note After this function is called, the BLE core will be in its startup or
499 //! "patching" mode.
500 //!
501 //! @param pHandle - Handle for the BLE module.
502 //! @param ui32PowerState - Determines whether BLE is powered on or off.
503 //!
504 //! @return BLE status code.
505 //!
506 //
507 //*****************************************************************************
508 uint32_t am_hal_ble_power_control(void *pHandle, uint32_t ui32PowerState);
509 
510 //*****************************************************************************
511 //
512 //! @brief Boot the BLE module
513 //!
514 //! @note This function performs the complete patching process for the BLE core and
515 //! returns with the BLE core in HCI mode. If you ask for the default patches
516 //! your am_hal_ble_config_t structure, then this is the last function you need
517 //! to call on startup. You don't need to call any of the patching functions.
518 //!
519 //! @param pHandle - Handle for the BLE module.
520 //!
521 //! @return BLE status code.
522 //
523 //*****************************************************************************
524 extern uint32_t am_hal_ble_boot(void *pHandle);
525 
526 //*****************************************************************************
527 //
528 //! @brief Patching functions.
529 //
530 //! @note The following functions allow the caller to apply "patches" to the BLE core
531 //! during its startup phase. These are pre-made configuration files that change
532 //! the operation parameters of the BLE radio. If you have received a patch file
533 //! from the manufacturer, you may use the \e am_hal_ble_patch_apply() function
534 //! during startup to apply these settings to the BLE core. Otherwise, you may
535 //! skip this step by calling the \e am_hal_ble_patch_complete() function.
536 //
537 //*****************************************************************************
538 
539 //*****************************************************************************
540 //
541 //! @brief Apply a patch to the BLE core.
542 //!
543 //! @param pHandle - Handle for the BLE module.
544 //! @param psPatch - Pointer to a structure describing the patch.
545 //!
546 //! The BLE core is an independent processor that executes code from an
547 //! on-board ROM. Its behavior can be altered through "patches" which are
548 //! binary snippets of code that may be loaded at startup to overlay or replace
549 //! sections of the original ROM (for instance, to modify trim settings). This
550 //! function allows the caller to apply one of these patches.
551 //!
552 //! @note Patches must be applied after the BLE module is enabled and configured, but
553 //! before standard HCI operation begins. This is the only time where the BLE
554 //! core is able to accept patch files.
555 //!
556 //! @return BLE status code.
557 //
558 //*****************************************************************************
559 extern uint32_t am_hal_ble_patch_apply(void *pHandle, am_hal_ble_patch_t *psPatch);
560 
561 //*****************************************************************************
562 //! @brief
563 //!
564 //! @param pHandle
565 //! @return uint32_t
566 //*****************************************************************************
567 extern uint32_t am_hal_ble_default_copy_patch_apply(void *pHandle);
568 
569 //*****************************************************************************
570 //! @brief Apply a B0 silicon patch to the BLE core
571 //!
572 //! @param pHandle - Handle for BLE Module
573 //!
574 //! @return BLE status code
575 //*****************************************************************************
576 extern uint32_t am_hal_ble_patch_preload(void *pHandle);
577 
578 //*****************************************************************************
579 //
580 //! @brief Apply the default manufacturer patch to the BLE core.
581 //!
582 //! @param pHandle Handle for the BLE module.
583 //!
584 //! The BLE core is an independent processor that executes code from an
585 //! on-board ROM. Its behavior can be altered through "patches" which are
586 //! binary snippets of code that may be loaded at startup to overlay or replace
587 //! sections of the original ROM (for instance, to modify trim settings). This
588 //! function allows the caller to apply one of these patches.
589 //!
590 //! Patches must be applied after the BLE module is enabled and configured, but
591 //! before standard HCI operation begins. This is the only time where the BLE
592 //! core is able to accept patch files.
593 //!
594 //! @return BLE status code.
595 //
596 //*****************************************************************************
597 extern uint32_t am_hal_ble_default_patch_apply(void *pHandle);
598 
599 //*****************************************************************************
600 //
601 //! @brief Complete the patching phase.
602 //!
603 //! @param pHandle Handle for the BLE module.
604 //!
605 //! After the BLE core is enabled and configured, it enters a "patching mode"
606 //! where it can accept patches from the main CPU. Once all patches have been
607 //! applied using the \e am_hal_ble_patch_apply() function. The application
608 //! must call this function to command the BLE core to switch to standard HCI
609 //! mode.
610 //!
611 //! @return BLE status code.
612 //
613 //*****************************************************************************
614 extern uint32_t am_hal_ble_patch_complete(void *pHandle);
615 
616 //*****************************************************************************
617 //
618 //! @brief Manually set modulation characteristic
619 //! based on the tested values at customer side.
620 //! manually set frequency offset for 10101010 or 01010101 pattern
621 //! @param pHandle
622 //! @param ui8ModFrqOffset
623 //! @return
624 //
625 //*****************************************************************************
626 extern uint32_t am_hal_ble_transmitter_modex_set(void *pHandle, uint8_t ui8ModFrqOffset);
627 
628 //*****************************************************************************
629 //
630 //! @brief Performs a blocking read or write to the BLE core.
631 //!
632 //! @param pHandle - Handle for the BLE module.
633 //! @param psTransfer - Structure describing the transaction to execute.
634 //!
635 //! @return BLE status code.
636 //*****************************************************************************
637 extern uint32_t am_hal_ble_blocking_transfer(void *pHandle, am_hal_ble_transfer_t *psTransfer);
638 
639 //*****************************************************************************
640 //
641 //! @brief Complete the patching phase.
642 //!
643 //! @param pHandle    - Handle for the BLE module.
644 //! @param psTransfer - pointer to transfer parameters
645 //!
646 //! After the BLE core is enabled and configured, it enters a "patching mode"
647 //! where it can accept patches from the main CPU. Once all patches have been
648 //! applied using the \e am_hal_ble_patch_apply() function. The application
649 //! must call this function to command the BLE core to switch to standard HCI
650 //! mode.
651 //!
652 //! @return BLE status code.
653 //
654 //*****************************************************************************
655 extern uint32_t am_hal_ble_nonblocking_transfer(void *pHandle, am_hal_ble_transfer_t *psTransfer);
656 
657 // High-level HCI APIs
658 
659 
660 //*****************************************************************************
661 //!  @brief
662 //!
663 //!  @param pui32Command
664 //!  @param ui32OpCode
665 //!  @param ui32TotalLength
666 //!  @param pui8Parameters
667 //!  @return uint32_t
668 //
669 //*****************************************************************************
670 extern uint32_t am_hal_ble_vs_command_build(uint32_t *pui32Command,
671                                             uint32_t ui32OpCode,
672                                             uint32_t ui32TotalLength,
673                                             uint8_t *pui8Parameters);
674 //*****************************************************************************
675 //!  @brief
676 //!
677 //!  @param pHandle
678 //!  @param pui32Data
679 //!  @param pui32BytesReceived
680 //!  @return uint32_t
681 //
682 //*****************************************************************************
683 extern uint32_t am_hal_ble_blocking_hci_read(void *pHandle,
684                                              uint32_t *pui32Data,
685                                              uint32_t *pui32BytesReceived);
686 //*****************************************************************************
687 //!  @brief
688 //!
689 //!  @param pHandle
690 //!  @param ui8Type
691 //!  @param pui32Data
692 //!  @param ui32NumBytes
693 //!  @return uint32_t
694 //
695 //*****************************************************************************
696 extern uint32_t am_hal_ble_blocking_hci_write(void *pHandle,
697                                               uint8_t ui8Type,
698                                               uint32_t *pui32Data,
699                                               uint32_t ui32NumBytes);
700 
701 //*****************************************************************************
702 //!  @brief
703 //!
704 //!  @param pHandle
705 //!  @param pui32Data
706 //!  @param pfnCallback
707 //!  @param pvContext
708 //!  @return uint32_t
709 //
710 //*****************************************************************************
711 extern uint32_t am_hal_ble_nonblocking_hci_read(void *pHandle,
712                                                 uint32_t *pui32Data,
713                                                 am_hal_ble_transfer_complete_cb_t pfnCallback,
714                                                 void *pvContext);
715 
716 //*****************************************************************************
717 //!  @brief
718 //!
719 //!  @param pHandle
720 //!  @param ui8Type
721 //!  @param pui32Data
722 //!  @param ui32NumBytes
723 //!  @param pfnCallback
724 //!  @param pvContext
725 //!  @return uint32_t
726 //
727 //*****************************************************************************
728 extern uint32_t am_hal_ble_nonblocking_hci_write(void *pHandle,
729                                                  uint8_t ui8Type,
730                                                  uint32_t *pui32Data,
731                                                  uint32_t ui32NumBytes,
732                                                  am_hal_ble_transfer_complete_cb_t pfnCallback,
733                                                  void *pvContext);
734 
735 //*****************************************************************************
736 //
737 //! @brief Set one of the trim values for the BLE core.
738 //!
739 //! @param pHandle is the BLE module handle
740 //! @param ui32BleCoreAddress is the target address for the trim value.
741 //! @param ui32TrimValue is the trim value to write to the BLE core.
742 //! @param ui32TrimMask  is the trim mask for ui32TrimValue
743 //!
744 //! This function takes a BLE core trim value from the MCU memory and writes it
745 //! to a trim register in the BLE core.
746 //!
747 //! @return BLE status code.
748 //
749 //*****************************************************************************
750 extern uint32_t am_hal_ble_trim_set(void *pHandle,
751                                     uint32_t ui32BleCoreAddress,
752                                     uint32_t ui32TrimValue,
753                                     uint32_t ui32TrimMask);
754 
755 //*****************************************************************************
756 //
757 //! @brief Sets the default trim values for the BLE core.
758 //!
759 //! @param pHandle is the BLE module handle
760 //!
761 //! @details This function reads the default trim values for the BLE core from
762 //! non-volatile memory, and writes them to the BLE core registers.
763 //! Specifically, this function adjusts the BLE core bandgap voltage, bandgap
764 //! current, and memory-retention LDO voltage based on chip-specific,
765 //! manufacturer-determined settings.
766 //!
767 //! @note For best performance and power consumption, this function should be called
768 //! after the patching process is complete, but before normal HCI operation
769 //! begins.
770 //!
771 //! @return BLE status code.
772 //
773 //*****************************************************************************
774 extern uint32_t am_hal_ble_default_trim_set(void *pHandle);
775 
776 //*****************************************************************************
777 //! @brief Set the bandgap voltage, bandgap current, and retention LDO output values
778 //!
779 //! @details Set the bandgap voltage, bandgap current, and retention LDO output
780 //! valuesbased on the tested values stored in non-volatile memory.
781 //!
782 //! @param pHandle
783 //! @return uint32_t
784 //*****************************************************************************
785 uint32_t am_hal_ble_default_trim_set_ramcode(void *pHandle);
786 
787 //*****************************************************************************
788 //
789 //! @brief Change the TX power setting of the BLE core.
790 //!
791 //! @param pHandle     - The Handle for the BLE module.
792 //! @param ui32TxPower - The desired power setting.
793 //!
794 //! This function uses a vendor-specific sequence of blocking HCI commands to
795 //! change the TX power setting of the radio.
796 //!
797 //! @note This function uses multiple blocking HCI commands in sequence. It
798 //! should not be used in any situation where blocking commands are not
799 //! desired. Do not use it in applications where interrupt-driven BLE
800 //! operations have already started.
801 //!
802 //! @return BLE status code.
803 //
804 //*****************************************************************************
805 extern uint32_t am_hal_ble_tx_power_set(void *pHandle, uint8_t ui32TxPower);
806 
807 //*****************************************************************************
808 //
809 //! @brief Generate continuously moderated signal for SRRC/CE test.
810 //!
811 //! @param pHandle - the Handle for the BLE module.
812 //! @param enable  - true for enabling continous signal, false for disable
813 //!
814 //! This function programs an internal register to control transmit mode in
815 //! BLE controller.
816 //!
817 //! @return BLE status code.
818 //
819 //*****************************************************************************
820 extern uint32_t am_hal_ble_set_constant_transmission(void *pHandle, bool enable);
821 
822 //*****************************************************************************
823 //
824 //! @brief Generate continuously moderated signal for SRRC/CE test on a
825 //! specified rf channel.
826 //!
827 //! @param pHandle - is the Handle for the BLE module.
828 //! @param channel - 0 to 0x27 for a valid radio channnel while 0xff to set
829 //!                   radio transmit mode to normal.
830 //!
831 //! This function calls am_hal_ble_set_constant_transmission() and send HCI
832 //! test command with channel information to BLE controller.
833 //!
834 //! @return BLE status code.
835 //
836 //*****************************************************************************
837 extern uint32_t am_hal_ble_set_constant_transmission_ex(void *pHandle, uint8_t channel);
838 
839 //*****************************************************************************
840 //
841 //! @brief This is to workaround a bug for channel 1 in DTM mode.
842 //!
843 //! @param pHandle - is the Handle for the BLE module.
844 //!
845 //! @return BLE status code.
846 //
847 //*****************************************************************************
848 extern uint32_t am_hal_ble_init_rf_channel(void *pHandle);
849 
850 
851 //*****************************************************************************
852 //
853 //! @brief Sends a signal to wake up the BLE controller
854 //!
855 //! @param pHandle is the Handle for the BLE module.
856 //! @param ui32Mode is determines the value of the WAKE signal.
857 //!
858 //! The BLE core needs to be awake before we send data to it. This function
859 //! sends a signal to the BLE core that tells it that we intend to send it
860 //! data. When the BLE core wakes up, it will generate a BLECSSTAT interrupt,
861 //! and the SPISTATUS bit in the BSTATUS register will be set.
862 //!
863 //! @return BLE status code.
864 //
865 //*****************************************************************************
866 extern uint32_t am_hal_ble_wakeup_set(void *pHandle, uint32_t ui32Mode);
867 
868 //*****************************************************************************
869 //
870 //! @brief Read a register value directly from the BLE Core.
871 //!
872 //! @param pHandle is the Handle for the BLE module.
873 //! @param ui32Address is the address of the register.
874 //! @param *pui32Value is a pointer where the register value will be stored.
875 //!
876 //! This function uses a vendor-specific sequence of blocking HCI commands to
877 //! read one of the internal registers within the BLE Core. The value stored in
878 //! this register will be written to the location specified by \e pui32Value.
879 //!
880 //! This function is mostly used during initial radio setup or for internal
881 //! test commands. Standard applications will not need to call this function
882 //! directly.
883 //!
884 //! @note This function uses multiple blocking HCI commands in sequence. It
885 //! should not be used in any situation where blocking commands are not
886 //! desired. Do not use it in applications where interrupt-driven BLE
887 //! operations have already started.
888 //!
889 //! @return BLE status code.
890 //
891 //*****************************************************************************
892 extern uint32_t am_hal_ble_plf_reg_read(void *pHandle, uint32_t ui32Address, uint32_t *pui32Value);
893 
894 //*****************************************************************************
895 //
896 //! @brief Write a register value directly to the BLE Core.
897 //!
898 //! @param pHandle     - the Handle for the BLE module.
899 //! @param ui32Address - the address of the register.
900 //! @param ui32Value   - the value to write.
901 //!
902 //! This function uses a vendor-specific sequence of blocking HCI commands to
903 //! write one of the internal registers within the BLE Core.
904 //!
905 //! This function is mostly used during initial radio setup or for internal
906 //! test commands. Standard applications will not need to call this function
907 //! directly.
908 //!
909 //! @note This function uses multiple blocking HCI commands in sequence. It
910 //! should not be used in any situation where blocking commands are not
911 //! desired. Do not use it in applications where interrupt-driven BLE
912 //! operations have already started.
913 //!
914 //! @return BLE status code.
915 //
916 //*****************************************************************************
917 extern uint32_t am_hal_ble_plf_reg_write(void *pHandle, uint32_t ui32Address, uint32_t ui32Value);
918 
919 //*****************************************************************************
920 //
921 //! @brief Change the sleep behavior of the BLE core.
922 //!
923 //! Set BLE sleep enable/disable for the BLE core.
924 //!
925 //! @param pHandle  - the Handle for the BLE module.
926 //! @param enable   - sets the desired sleep behavior.
927 //!         - 'true' set sleep enable,
928 //!         - 'false' set sleep disable
929 //!
930 //! This function uses a vendor-specific sequence of blocking HCI commands to
931 //! change the default behavior of the BLE core between radio events. Set \e
932 //! enable to true to allow the BLE core to sleep between radio events, or
933 //! false to keep the BLE core awake at all times. The default behavior on
934 //! startup allows the BLE core to sleep. Most applications will not need to
935 //! modify this setting.
936 //!
937 //! @note This function uses multiple blocking HCI commands in sequence. It
938 //! should not be used in any situation where blocking commands are not
939 //! desired. Do not use it in applications where interrupt-driven BLE
940 //! operations have already started.
941 //!
942 //! @return BLE status code.
943 //
944 //*****************************************************************************
945 extern uint32_t am_hal_ble_sleep_set(void *pHandle, bool enable);
946 
947 //*****************************************************************************
948 //
949 //! @brief Check the sleep behavior of the BLE core.
950 //!
951 //! @param pHandle  - is the Handle for the BLE module.
952 //!
953 //! This function uses a vendor-specific sequence of blocking HCI commands to
954 //! check whether the BLE core is set to go to sleep between BLE transactions.
955 //! This function will return "true" if BLE sleep is enabled, or "false" if it
956 //! is disabled.
957 //!
958 //! @note This function uses multiple blocking HCI commands in sequence. It
959 //! should not be used in any situation where blocking commands are not
960 //! desired. Do not use it in applications where interrupt-driven BLE
961 //! operations have already started.
962 //!
963 //! @return BLE status code.
964 //
965 //*****************************************************************************
966 extern bool am_hal_ble_sleep_get(void *pHandle);
967 
968 //*****************************************************************************
969 //
970 // Interrupts.
971 //
972 //*****************************************************************************
973 //*****************************************************************************
974 //!  @brief
975 //!
976 //!  @param pHandle
977 //!  @param ui32Status
978 //!  @return uint32_t
979 //*****************************************************************************
980 extern uint32_t am_hal_ble_int_service(void *pHandle, uint32_t ui32Status);
981 
982 //*****************************************************************************
983 //!  @brief
984 //!
985 //!  @param pHandle
986 //!  @param ui32InterruptMask
987 //!  @return uint32_t
988 //*****************************************************************************
989 extern uint32_t am_hal_ble_int_enable(void *pHandle, uint32_t ui32InterruptMask);
990 
991 //*****************************************************************************
992 //!  @brief
993 //!
994 //!  @param pHandle
995 //!  @param ui32InterruptMask
996 //!  @return uint32_t
997 //*****************************************************************************
998 extern uint32_t am_hal_ble_int_disable(void *pHandle, uint32_t ui32InterruptMask);
999 
1000 //*****************************************************************************
1001 //!  @brief
1002 //!
1003 //!  @param pHandle
1004 //!  @param bEnabledOnly
1005 //!  @return uint32_t
1006 //*****************************************************************************
1007 extern uint32_t am_hal_ble_int_status(void *pHandle, bool bEnabledOnly);
1008 
1009 //*****************************************************************************
1010 //!  @brief
1011 //!
1012 //!  @param pHandle
1013 //!  @param ui32InterruptMask
1014 //!  @return uint32_t
1015 //*****************************************************************************
1016 extern uint32_t am_hal_ble_int_clear(void *pHandle, uint32_t ui32InterruptMask);
1017 //*****************************************************************************
1018 //!  @brief
1019 //!
1020 //!  @param pHandle
1021 //!  @return uint32_t
1022 //*****************************************************************************
1023 extern uint32_t am_hal_ble_check_32k_clock(void *pHandle);
1024 
1025 
1026 //*****************************************************************************
1027 //
1028 //! Debug trace pins.
1029 //
1030 //*****************************************************************************
1031 #ifdef AM_DEBUG_BLE_TIMING
1032 
1033 #define BLE_DEBUG_TRACE_01            11
1034 #define BLE_DEBUG_TRACE_02            28
1035 #define BLE_DEBUG_TRACE_03            26
1036 #define BLE_DEBUG_TRACE_04            4
1037 #define BLE_DEBUG_TRACE_05            18
1038 #define BLE_DEBUG_TRACE_06            14
1039 #define BLE_DEBUG_TRACE_07            6
1040 #define BLE_DEBUG_TRACE_08            45
1041 #define BLE_DEBUG_TRACE_09            12
1042 #define BLE_DEBUG_TRACE_10            13
1043 #define BLE_DEBUG_TRACE_11            10
1044 #define BLE_LOCK_TRACE_PIN            BLE_DEBUG_TRACE_11
1045 
1046 #define am_hal_debug_gpio_set(x)    am_hal_gpio_state_write(x, AM_HAL_GPIO_OUTPUT_SET)
1047 
1048 #define am_hal_debug_gpio_clear(x)    am_hal_gpio_state_write(x, AM_HAL_GPIO_OUTPUT_CLEAR)
1049 
1050 #define am_hal_debug_gpio_toggle(x)    am_hal_gpio_state_write(x, AM_HAL_GPIO_OUTPUT_TOGGLE)
1051 
1052 #define am_hal_debug_gpio_pinconfig(x)    am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_OUTPUT)
1053 
1054 #else
1055 
1056 #define am_hal_debug_gpio_set(...)
1057 #define am_hal_debug_gpio_clear(...)
1058 #define am_hal_debug_gpio_toggle(...)
1059 #define am_hal_debug_gpio_pinconfig(...)
1060 
1061 #endif // AM_DEBUG_BLE_TIMING
1062 
1063 #ifdef __cplusplus
1064 }
1065 #endif
1066 
1067 #endif // AM_HAL_BLE_H
1068 
1069 //*****************************************************************************
1070 //
1071 // End Doxygen group.
1072 //! @}
1073 //
1074 //*****************************************************************************
1075