1 //*****************************************************************************
2 //
3 //! @file am_util_ble.c
4 //!
5 //! @brief Useful BLE functions not covered by the HAL.
6 //!
7 //! This file contains functions for interacting with the BLE hardware
8 //! that are not already covered by the HAL. Most of these commands either
9 //! adjust RF settings or facilitate RF testing operations.
10 //!
11 //! @addtogroup ble BLE
12 //! @ingroup utils
13 //! @{
14 //
15 //*****************************************************************************
16 
17 //*****************************************************************************
18 //
19 // Copyright (c) 2023, Ambiq Micro, Inc.
20 // All rights reserved.
21 //
22 // Redistribution and use in source and binary forms, with or without
23 // modification, are permitted provided that the following conditions are met:
24 //
25 // 1. Redistributions of source code must retain the above copyright notice,
26 // this list of conditions and the following disclaimer.
27 //
28 // 2. Redistributions in binary form must reproduce the above copyright
29 // notice, this list of conditions and the following disclaimer in the
30 // documentation and/or other materials provided with the distribution.
31 //
32 // 3. Neither the name of the copyright holder nor the names of its
33 // contributors may be used to endorse or promote products derived from this
34 // software without specific prior written permission.
35 //
36 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
40 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 // POSSIBILITY OF SUCH DAMAGE.
47 //
48 // This is part of revision release_sdk_4_4_0-3c5977e664 of the AmbiqSuite Development Package.
49 //
50 //*****************************************************************************
51 
52 #include <stdint.h>
53 #include <stdbool.h>
54 #include <string.h>
55 #include "am_util_delay.h"
56 #include "am_mcu_apollo.h"
57 
58 //*****************************************************************************
59 //
60 // Globals
61 //
62 //*****************************************************************************
63 
64 //*****************************************************************************
65 //
66 // In DTM mode, set TX to constant trans mode for SRRC/FCC/CE
67 // set enable as 'true' to constant trans mode, 'false' back to normal
68 //
69 //*****************************************************************************
70 uint32_t
am_util_ble_set_constant_transmission(void * pHandle,bool enable)71 am_util_ble_set_constant_transmission(void *pHandle, bool enable)
72 {
73     am_hal_ble_state_t *pBLE = pHandle;
74 
75     am_hal_ble_sleep_set(pBLE, false);
76     am_hal_ble_plf_reg_write(pBLE, 0x43000004, 0xFFFFFFFF);
77     if ( enable )
78     {
79         am_hal_ble_plf_reg_write(pBLE, 0x508000E0, 0x00008000);
80     }
81     else
82     {
83         am_hal_ble_plf_reg_write(pBLE, 0x508000E0, 0x00000000);
84     }
85 
86     return AM_HAL_STATUS_SUCCESS;
87 }
88 
89 //*****************************************************************************
90 //
91 // Manually enable/disable transmitter
92 // set ui8TxCtrl as 1 to manually enable transmitter, 0 back to default
93 //
94 //*****************************************************************************
95 uint32_t
am_util_ble_transmitter_control(void * pHandle,uint8_t ui8TxCtrl)96 am_util_ble_transmitter_control(void *pHandle, uint8_t ui8TxCtrl)
97 {
98     am_hal_ble_state_t *pBLE = pHandle;
99     uint32_t RegValueTRX;
100 
101     am_hal_ble_sleep_set(pBLE, false);
102     if (ui8TxCtrl)
103     {
104         RegValueTRX = 0x2000A;
105     }
106     else
107     {
108         RegValueTRX = 0x8;
109     }
110 
111     //
112     // Unlock the BLE registers.
113     //
114     am_hal_ble_plf_reg_write(pBLE, 0x43000004, 0xFFFFFFFF);
115     am_hal_ble_plf_reg_write(pBLE, 0x52400000, RegValueTRX);
116 
117     return AM_HAL_STATUS_SUCCESS;
118 }
119 
120 //*****************************************************************************
121 //
122 // to fix the channel 1 bug in DTM mode
123 //
124 //*****************************************************************************
125 
126 uint32_t
am_util_ble_init_rf_channel(void * pHandle)127 am_util_ble_init_rf_channel(void *pHandle)
128 {
129     if (!APOLLO3_GE_B0)
130     {
131         am_hal_ble_buffer(16) sWriteCommand;
132         am_hal_ble_buffer(16) sResponse;
133         am_hal_ble_state_t *pBLE = pHandle;
134         uint32_t ui32IntEnable;
135 
136         uint32_t ui32Module = pBLE->ui32Module;
137         am_hal_ble_sleep_set(pBLE, false);
138 
139         //
140         //issue the HCI command with to init for the channel 1
141         //
142         sWriteCommand.bytes[0] = 0x01;
143         sWriteCommand.bytes[1] = 0x1d;
144         sWriteCommand.bytes[2] = 0x20;
145         sWriteCommand.bytes[3] = 0x01;
146         sWriteCommand.bytes[4] = 0x00;
147 
148         //
149         // Temporarily disable BLE interrupts.
150         //
151         ui32IntEnable = BLEIFn(ui32Module)->INTEN;
152         BLEIFn(ui32Module)->INTEN = 0;
153 
154         //
155         // reserved packet_payload
156         //
157         am_hal_ble_blocking_hci_write(pBLE,
158                                       AM_HAL_BLE_RAW,
159                                       sWriteCommand.words,
160                                       5);
161         BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
162 
163         //
164         // Wait for the response.
165         //
166         while ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ == 0 );
167         am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
168 
169         am_util_delay_ms(10);
170 
171         //
172         // issue the HCI command with to stop test for the channel 1
173         //
174         sWriteCommand.bytes[0] = 0x01;
175         sWriteCommand.bytes[1] = 0x1f;
176         sWriteCommand.bytes[2] = 0x20;
177         sWriteCommand.bytes[3] = 0x00;
178 
179         //
180         // reserved packet_payload
181         //
182         am_hal_ble_blocking_hci_write(pBLE,
183                                       AM_HAL_BLE_RAW,
184                                       sWriteCommand.words,
185                                       4);
186         BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
187 
188         //
189         // Wait for the response.
190         //
191         while ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ == 0 );
192 
193         am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
194 
195         //
196         // Re-enable BLE interrupts.
197         //
198         BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
199         BLEIFn(ui32Module)->INTEN = ui32IntEnable;
200     }
201 
202     return AM_HAL_STATUS_SUCCESS;
203 }
204 
205 //*****************************************************************************
206 //
207 // BLE init for BQB test
208 // set enable as 'true' to init as BQB test mode, 'false' back to default
209 //
210 //*****************************************************************************
211 uint32_t
am_util_ble_BQB_test_init(void * pHandle,bool enable)212 am_util_ble_BQB_test_init(void *pHandle, bool enable)
213 {
214     am_hal_ble_state_t *pBLE = pHandle;
215 
216     am_hal_ble_sleep_set(pBLE, false);
217     am_hal_ble_plf_reg_write(pBLE, 0x43000004, 0xFFFFFFFF);
218 
219     if ( enable )
220     {
221         am_hal_ble_plf_reg_write(pBLE, 0x51800028, 0x0000209c);
222     }
223     else
224     {
225         am_hal_ble_plf_reg_write(pBLE, 0x51800028, 0x00003ff6);
226     }
227 
228     am_hal_ble_plf_reg_write(pBLE, 0x45800070, 0x100);
229     am_hal_ble_plf_reg_write(pBLE, 0x45800070, 0);
230 
231     return AM_HAL_STATUS_SUCCESS;
232 }
233 
234 //*****************************************************************************
235 //
236 // Set the 32M crystal frequency
237 // based on the tested values at customer side.
238 // set trim value smaller in case of negative frequency offset
239 // ui32TrimValue: default is 0x400
240 //
241 //*****************************************************************************
242 uint32_t
am_util_ble_crystal_trim_set(void * pHandle,uint32_t ui32TrimValue)243 am_util_ble_crystal_trim_set(void *pHandle, uint32_t ui32TrimValue)
244 {
245     am_hal_ble_state_t *pBLE = pHandle;
246     uint32_t RegValueMCGR;
247 
248     ui32TrimValue &= 0x7FF;
249 
250     am_hal_ble_plf_reg_read(pBLE, 0x43000004, &RegValueMCGR);
251 
252     //
253     // Unlock the BLE registers.
254     //
255     am_hal_ble_plf_reg_write(pBLE, 0x43000004, 0xFFFFFFFF);
256     am_hal_ble_plf_reg_write(pBLE, 0x43800004, ui32TrimValue);
257     am_hal_ble_plf_reg_write(pBLE, 0x43000004, RegValueMCGR);
258 
259     return AM_HAL_STATUS_SUCCESS;
260 }
261 
262 //*****************************************************************************
263 //
264 // Manually enable/disable transmitter to output carrier signal
265 // set ui8TxChannel as 0 to 0x27 for each transmit channel, 0xFF back to normal
266 // modulate mode
267 //
268 //*****************************************************************************
269 uint32_t
am_util_ble_hci_reset(void * pHandle)270 am_util_ble_hci_reset(void *pHandle)
271 {
272     am_hal_ble_buffer(16) sWriteCommand;
273     am_hal_ble_buffer(16) sResponse;
274     am_hal_ble_state_t *pBLE = pHandle;
275     uint32_t ui32IntEnable;
276 
277     am_hal_ble_sleep_set(pBLE, false);
278     uint32_t ui32Module = pBLE->ui32Module;
279 
280     //
281     // issue the HCI command with to reset hci
282     //
283     sWriteCommand.bytes[0] = 0x01;
284     sWriteCommand.bytes[1] = 0x03;
285     sWriteCommand.bytes[2] = 0x0c;
286     sWriteCommand.bytes[3] = 0x00;
287 
288     //
289     // Temporarily disable BLE interrupts.
290     //
291     ui32IntEnable = BLEIFn(ui32Module)->INTEN;
292     BLEIFn(ui32Module)->INTEN = 0;
293 
294     am_hal_ble_blocking_hci_write(pBLE,
295                                   AM_HAL_BLE_RAW,
296                                   sWriteCommand.words,
297                                   4);
298     BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
299 
300     //
301     // Wait for the response.
302     //
303     for (uint32_t i = 0; i < 1000; i++)
304     {
305         if ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ != 0 )
306         {
307             break;
308         }
309         else if (i == (1000 - 1))
310         {
311             return AM_HAL_BLE_NO_HCI_RESPONSE;
312         }
313         else
314         {
315             am_util_delay_ms(1);
316         }
317     }
318 
319     am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
320 
321     //
322     // Re-enable BLE interrupts.
323     //
324     BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
325     BLEIFn(ui32Module)->INTEN = ui32IntEnable;
326 
327     return AM_HAL_STATUS_SUCCESS;
328 }
329 
330 //*****************************************************************************
331 //
332 // to do directly output modulation signal. change channel ranges from 0 to 0x27,
333 // pattern from 0 to 7.
334 //
335 //*****************************************************************************
336 uint32_t
am_util_ble_trasmitter_test_ex(void * pHandle,uint8_t channel,uint8_t pattern)337 am_util_ble_trasmitter_test_ex(void *pHandle, uint8_t channel, uint8_t pattern)
338 {
339     am_hal_ble_buffer(16) sWriteCommand;
340     am_hal_ble_buffer(16) sResponse;
341     am_hal_ble_state_t *pBLE = pHandle;
342     uint32_t ui32IntEnable;
343 
344     am_hal_ble_sleep_set(pBLE, false);
345     uint32_t ui32Module = pBLE->ui32Module;
346 
347     //
348     // issue the HCI command with to TX carrier wave
349     //
350     sWriteCommand.bytes[0] = 0x01;
351     sWriteCommand.bytes[1] = 0x1E;
352     sWriteCommand.bytes[2] = 0x20;
353     sWriteCommand.bytes[3] = 0x03;
354     sWriteCommand.bytes[4] = channel;
355     sWriteCommand.bytes[5] = 0x25;
356     sWriteCommand.bytes[6] = pattern;
357 
358     //
359     // Temporarily disable BLE interrupts.
360     //
361     ui32IntEnable = BLEIFn(ui32Module)->INTEN;
362     BLEIFn(ui32Module)->INTEN = 0;
363 
364     am_hal_ble_blocking_hci_write(pBLE,
365                                   AM_HAL_BLE_RAW,
366                                   sWriteCommand.words,
367                                   7);
368     BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
369 
370     //
371     // Wait for the response.
372     //
373     for (uint32_t i = 0; i < 100; i++)
374     {
375         if (BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ != 0)
376         {
377             break;
378         }
379         else if (i == (100 - 1))
380         {
381             return AM_HAL_BLE_NO_HCI_RESPONSE;
382         }
383         else
384         {
385             am_util_delay_ms(1);
386         }
387     }
388 
389     am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
390 
391     //
392     // Re-enable BLE interrupts.
393     //
394     BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
395     BLEIFn(ui32Module)->INTEN = ui32IntEnable;
396     return AM_HAL_STATUS_SUCCESS;
397 }
398 
399 //*****************************************************************************
400 //
401 // to do directly receiver test. change channel ranges from 0 to 0x27, return
402 // received packets in 100ms.
403 //
404 //*****************************************************************************
405 
406 uint32_t
am_util_ble_receiver_test_ex(void * pHandle,uint8_t channel,uint32_t * recvpackets)407 am_util_ble_receiver_test_ex(void *pHandle, uint8_t channel, uint32_t *recvpackets)
408 {
409     am_hal_ble_buffer(16) sWriteCommand;
410     am_hal_ble_buffer(16) sResponse;
411     am_hal_ble_state_t *pBLE = pHandle;
412     uint32_t ui32IntEnable;
413 
414     uint32_t ui32Module = pBLE->ui32Module;
415     am_hal_ble_sleep_set(pBLE, false);
416 
417     sWriteCommand.bytes[0] = 0x01;
418     sWriteCommand.bytes[1] = 0x1d;
419     sWriteCommand.bytes[2] = 0x20;
420     sWriteCommand.bytes[3] = 0x01;
421     sWriteCommand.bytes[4] = channel;
422 
423     //
424     // Temporarily disable BLE interrupts.
425     //
426     ui32IntEnable = BLEIFn(ui32Module)->INTEN;
427     BLEIFn(ui32Module)->INTEN = 0;
428 
429     //
430     // reserved packet_payload
431     //
432     am_hal_ble_blocking_hci_write(pBLE,
433                                   AM_HAL_BLE_RAW,
434                                   sWriteCommand.words,
435                                   5);
436     BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
437 
438     //
439     // Wait for the response.
440     //
441     while ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ == 0 );
442     am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
443 
444     am_util_delay_ms(100);
445 
446     //
447     // issue the HCI command with to stop test for the channel 1
448     //
449     sWriteCommand.bytes[0] = 0x01;
450     sWriteCommand.bytes[1] = 0x1f;
451     sWriteCommand.bytes[2] = 0x20;
452     sWriteCommand.bytes[3] = 0x00;
453 
454     //
455     // reserved packet_payload
456     //
457     am_hal_ble_blocking_hci_write(pBLE,
458                                   AM_HAL_BLE_RAW,
459                                   sWriteCommand.words,
460                                   4);
461     BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
462 
463     //
464     // Wait for the response.
465     //
466     while ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ == 0 );
467 
468     am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
469     *recvpackets = (sResponse.bytes[8] << 8) + sResponse.bytes[7];
470 
471     //
472     // Re-enable BLE interrupts.
473     //
474     BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
475     BLEIFn(ui32Module)->INTEN = ui32IntEnable;
476 
477     return AM_HAL_STATUS_SUCCESS;
478 }
479 
480 //*****************************************************************************
481 //
482 // to directly output carrier wave. change channel ranges from 0 to 0x27.
483 //
484 //*****************************************************************************
485 uint32_t
am_util_ble_set_carrier_wave_ex(void * pHandle,uint8_t channel)486 am_util_ble_set_carrier_wave_ex(void *pHandle, uint8_t channel)
487 {
488     am_hal_ble_buffer(16) sWriteCommand;
489     am_hal_ble_buffer(16) sResponse;
490     am_hal_ble_state_t *pBLE = pHandle;
491     uint32_t ui32IntEnable;
492 
493     //
494     // channel 0xFF to disable the constant transmission
495     //
496     if ( channel == 0xFF )
497     {
498         am_util_ble_transmitter_control(pBLE, false);
499         return AM_HAL_STATUS_SUCCESS;
500     }
501 
502     am_hal_ble_sleep_set(pBLE, false);
503     uint32_t ui32Module = pBLE->ui32Module;
504 
505     //
506     // issue the HCI command with to TX carrier wave
507     //
508     sWriteCommand.bytes[0] = 0x01;
509     sWriteCommand.bytes[1] = 0x1E;
510     sWriteCommand.bytes[2] = 0x20;
511     sWriteCommand.bytes[3] = 0x03;
512     sWriteCommand.bytes[4] = channel;
513     sWriteCommand.bytes[5] = 0x25;
514     sWriteCommand.bytes[6] = 0x00;
515 
516     //
517     // Temporarily disable BLE interrupts.
518     //
519     ui32IntEnable = BLEIFn(ui32Module)->INTEN;
520     BLEIFn(ui32Module)->INTEN = 0;
521 
522     am_hal_ble_blocking_hci_write(pBLE,
523                                   AM_HAL_BLE_RAW,
524                                   sWriteCommand.words,
525                                   7);
526     BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
527 
528     //
529     // Wait for the response.
530     //
531     for (uint32_t i = 0; i < 100; i++)
532     {
533         if (BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ != 0)
534         {
535             break;
536         }
537         else if (i == (100 - 1))
538         {
539             return AM_HAL_BLE_NO_HCI_RESPONSE;
540         }
541         else
542         {
543             am_util_delay_ms(1);
544         }
545     }
546 
547     am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
548 
549     //
550     // Re-enable BLE interrupts.
551     //
552     BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
553     BLEIFn(ui32Module)->INTEN = ui32IntEnable;
554 
555     am_util_ble_transmitter_control(pBLE, true);
556 
557     return AM_HAL_STATUS_SUCCESS;
558 }
559 
560 //*****************************************************************************
561 //
562 // Manually enable/disable transmitter to output carrier wave signal
563 // set ui8TxChannel as 0 to 0x27 for each transmit channel, 0xFF back to normal
564 // modulate mode
565 //
566 //*****************************************************************************
567 uint32_t
am_util_ble_transmitter_control_ex(void * pHandle,uint8_t ui8TxChannel)568 am_util_ble_transmitter_control_ex(void *pHandle, uint8_t ui8TxChannel)
569 {
570     return am_util_ble_set_carrier_wave_ex(pHandle, ui8TxChannel);
571 }
572 
573 //*****************************************************************************
574 //
575 // to directly output constant modulation signal. change channel from 0 to 0x27.
576 //
577 //*****************************************************************************
578 uint32_t
am_util_ble_set_constant_transmission_ex(void * pHandle,uint8_t channel)579 am_util_ble_set_constant_transmission_ex(void *pHandle, uint8_t channel)
580 {
581     am_hal_ble_buffer(16) sWriteCommand;
582     am_hal_ble_buffer(16) sResponse;
583     am_hal_ble_state_t *pBLE = pHandle;
584     uint32_t ui32IntEnable;
585 
586     //
587     // channel 0xFF to disable the constant transmission
588     //
589     if ( channel == 0xFF )
590     {
591         am_util_ble_set_constant_transmission(pBLE, false);
592         return AM_HAL_STATUS_SUCCESS;
593     }
594 
595     uint32_t ui32Module = pBLE->ui32Module;
596     am_util_ble_set_constant_transmission(pBLE, true);
597 
598     //
599     // issue the HCI command with to TX constant transmission
600     //
601     sWriteCommand.bytes[0] = 0x01;
602     sWriteCommand.bytes[1] = 0x1E;
603     sWriteCommand.bytes[2] = 0x20;
604     sWriteCommand.bytes[3] = 0x03;
605     sWriteCommand.bytes[4] = channel;
606     sWriteCommand.bytes[5] = 0x25;
607     sWriteCommand.bytes[6] = 0x00;
608 
609     //
610     // Temporarily disable BLE interrupts.
611     //
612     ui32IntEnable = BLEIFn(ui32Module)->INTEN;
613     BLEIFn(ui32Module)->INTEN = 0;
614 
615     am_hal_ble_blocking_hci_write(pBLE,
616                                   AM_HAL_BLE_RAW,
617                                   sWriteCommand.words,
618                                   7);
619     BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
620 
621     //
622     // Wait for the response.
623     //
624     for (uint32_t i = 0; i < 100; i++)
625     {
626         if (BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ != 0)
627         {
628             break;
629         }
630         else if (i == (100 - 1))
631         {
632             return AM_HAL_BLE_NO_HCI_RESPONSE;
633         }
634         else
635         {
636             am_util_delay_ms(1);
637         }
638     }
639 
640     am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
641 
642     //
643     // Re-enable BLE interrupts.
644     //
645     BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
646     BLEIFn(ui32Module)->INTEN = ui32IntEnable;
647 
648     return AM_HAL_STATUS_SUCCESS;
649 }
650 
651 //*****************************************************************************
652 //
653 // read current modex value from BLEIP
654 //
655 //*****************************************************************************
656 uint32_t
am_util_ble_read_modex_value(void * pHandle)657 am_util_ble_read_modex_value(void *pHandle)
658 {
659     am_hal_ble_state_t *pBLE = pHandle;
660     uint32_t temp = 0;
661     if (APOLLO3_GE_B0)
662     {
663         //
664         // for B0 Chip,the modex value address is changed to 0x20006874
665         //
666         am_hal_ble_plf_reg_read(pBLE, 0x20006874, &temp);
667     }
668     else
669     {
670         am_hal_ble_plf_reg_read(pBLE, 0x20006070, &temp);
671     }
672     return temp;
673 }
674 
675 //*****************************************************************************
676 //
677 // End Doxygen group.
678 //! @}
679 //
680 //*****************************************************************************
681 
682