1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_hal_radio.h
4   * @author  GPM WBL Application Team
5   * @brief   This file provides all the Radio Driver APIs.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2024 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file
13   * in the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   */
18 
19 /* Includes ------------------------------------------------------------------*/
20 #include "stm32wb0x_hal.h"
21 
22 /** @addtogroup STM32WB0x_HAL_Driver
23   * @{
24   */
25 
26 /** @addtogroup RADIO
27   * @{
28   */
29 
30 /** @defgroup RADIO_Private_Constants RADIO Private Constants
31   * @{
32   */
33 
34 #define RSSI_OFFSET 119
35 
36 /* Access address used only to sense medium with HAL_RADIO_CarrierSense() */
37 #define FAKE_NETWORK_ID 0xAAAAAAAA
38 
39 #define VALIDITY_TAG 0xFCBCECCC
40 #define VALIDITY_LOCATION    0x10001EF8
41 #define MR_TRIMMING_LOCATION 0x10001EE8
42 
43 #define MR_BLE_IBIAS_TRIM_Pos         (8)
44 #define MR_BLE_IBIAS_TRIM_Msk         (0x0F << MR_BLE_IBIAS_TRIM_Pos)
45 #define MR_BLE_IPTAT_TRIM_Pos         (12)
46 #define MR_BLE_IPTAT_TRIM_Msk         (0x0F << MR_BLE_IPTAT_TRIM_Pos)
47 #define MR_BLE_VBG_TRIM_Pos           (16)
48 #define MR_BLE_VBG_TRIM_Msk           (0x0F << MR_BLE_VBG_TRIM_Pos)
49 #define MR_BLE_RXADC_DELAY_I_TRIM_Pos (20)
50 #define MR_BLE_RXADC_DELAY_I_TRIM_Msk (0x07 << MR_BLE_RXADC_DELAY_I_TRIM_Pos)
51 #define MR_BLE_RXADC_DELAY_Q_TRIM_Pos (24)
52 #define MR_BLE_RXADC_DELAY_Q_TRIM_Msk (0x07 << MR_BLE_RXADC_DELAY_Q_TRIM_Pos)
53 
54 /* AFC Configuration */
55 #define AFC_DELAY_BEFORE    (0x05)
56 #define AFC_DELAY_AFTER     (0x05)
57 #define CR_GAIN_BEFORE      (0x06)
58 #define CR_GAIN_AFTER       (0x06)
59 #define CR_LR_GAIN_BEFORE   (0x05)
60 #define CR_LR_GAIN_AFTER    (0x05)
61 #define LR_RSSI_THR         (0x1D)
62 #define LR_PD_THR           (0x59)
63 #define LR_AAC_THR          (0x32)
64 
65 /* Fine tuning values for antenna switching and IQ samplig */
66 #define RX_TIME_TO_SAMPLE   (0x1F)
67 #define RX_TIME_TO_SWITCH   (0x09)
68 
69 /** @defgroup Sequencer_timeouts Sequencer Timeouts
70   * @{
71   */
72 
73 /* initDelay */
74 #define INITDELAY_WAKEUP          (0x40U)
75 #define INITDELAY_TIMER12_CAL     (0x3FU)
76 #define INITDELAY_TIMER2_NOCAL    (0x9U)
77 
78 /* Init_radio_delay */
79 #if defined (STM32WB05) || defined(STM32WB09 )
80 #define DELAYCHK_TRANSMIT_CAL     (0x5AU)
81 #define DELAYCHK_TRANSMIT_NOCAL   (0x32U)
82 #define DELAYCHK_RECEIVE_CAL      (0x5AU)
83 #define DELAYCHK_RECEIVE_NOCAL    (0x32U)
84 #endif
85 #if defined (STM32WB06) || defined (STM32WB07)
86 #define DELAYCHK_TRANSMIT_CAL     (0x76U)
87 #define DELAYCHK_TRANSMIT_NOCAL   (0x3AU)
88 #define DELAYCHK_RECEIVE_CAL      (0x74U)
89 #define DELAYCHK_RECEIVE_NOCAL    (0x38U)
90 #endif
91 
92 /* ConfigEndDuration */
93 #define CONFIG_END_DURATION       (0x14U)
94 
95 /* DataInit phase start */
96 #define CHECK_TXDATAREADY         (0x5U)
97 
98 /* TX parameters init */
99 #if defined (STM32WB05) || defined(STM32WB09 )
100 #define TXREADY_TIMEOUT          (0x4U)
101 #endif
102 #if defined (STM32WB06) || defined(STM32WB07)
103 #define TXREADY_TIMEOUT          (0x5U)
104 #endif
105 #define TXDELAY_START            (0x10U)
106 #define TXDELAY_END              (0x10U)
107 
108 /* RX parameter init */
109 #define RCV_TIMEOUT              (0x100)
110 
111 /* Number of state machine used */
112 #define STATEMACHINE_COUNT   (CFG_NUM_RADIO_TASKS)
113 /**
114   * @}
115   */
116 
117 /**
118   * @}
119   */
120 
121 
122 /** @defgroup RADIO_Private_Macros RADIO Private Macros
123   * @{
124   */
125 #define IS_STATE_VALID(STATEMACHINE_NO) (STATEMACHINE_NO < STATEMACHINE_COUNT)
126 #define IS_POWERLEVEL_VALID(POWER) (POWER < 0x20)
127 #define IS_RFCHANNEL_VALID(RF_CHANNEL) (RF_CHANNEL <40)
128 #define IS_FREQOFFSET_VALID(FREQ_OFFSET) (FREQ_OFFSET >2)
129 #define IS_PHY_VALID(PHY) (PHY==PHY_1M || PHY==PHY_2M || PHY==PHY_CODED_S_2 || PHY==PHY_CODED_S_8)
130 #define IS_PREALEN_VALID(PREA) (PREA < 16)
131 
132 
133 #define MASK_INTERRUPTS() __disable_irq();
134 #define UNMASK_INTERRUPTS() __enable_irq();
135 
136 
137 #define TIME_DIFF(a, b)       ((int32_t)(a - b))
138 /**
139   * @}
140   */
141 
142 /** @defgroup RADIO_Private_Variables RADIO Private Variables
143   * @{
144   */
145 
146 #if USE_RADIO_PROPRIETARY_DRIVER
147 
148 RadioGlobalParameters_t globalParameters;
149 
150 static ActionPacket aPacket[2];
151 static uint32_t networkID = 0x88DF88DF;
152 
153 #endif /* USE_RADIO_PROPRIETARY_DRIVER */
154 
155 /**
156   * @}
157   */
158 
159 /** @defgroup RADIO_Private_Functions RADIO Private Functions
160   * @{
161   */
162 
163 #if USE_RADIO_PROPRIETARY_DRIVER
164 
CondRoutineTrue(ActionPacket * p)165 static uint8_t CondRoutineTrue(ActionPacket *p)
166 {
167   return TRUE;
168 }
169 
DataRoutineNull(ActionPacket * current_action_packet,ActionPacket * next)170 static uint8_t DataRoutineNull(ActionPacket *current_action_packet, ActionPacket *next)
171 {
172   return TRUE;
173 }
174 
CondRoutineRxTrue(ActionPacket * p)175 static uint8_t CondRoutineRxTrue(ActionPacket *p)
176 {
177   /* received a packet */
178   if ((p->status & BLUE_INTERRUPT1REG_RCVOK) != 0)
179   {
180     /* packet received without CRC error */
181     return TRUE;
182   }
183   return FALSE;
184 }
185 
186 #endif /* USE_RADIO_PROPRIETARY_DRIVER */
187 
188 
189 /**
190   * @}
191   */
192 
193 /** @defgroup RADIO_Global_Variables RADIO Global Variables
194   * @{
195   */
196 
197 /* ------------------------------------------------------------------------------
198 *  volatile uint32_t hot_table_radio_config_u32[]
199 *
200 *  Hot table radio configuration storage.
201 *  This variable is only used during the smart power management
202 *  procedure
203 *  ------------------------------------------------------------------------------ */
204 /* Round up HOT_TABLE_SIZE to an integer number of words then add 4 words for table management pointers */
205 volatile uint32_t hot_table_radio_config_u32[((HOT_TABLE_SIZE + 3) >> 2) + 4] = {0x00};
206 
207 #if 0 /** PATCH: do not define __blue_RAM here */
208 /* BLUE RAM, reserved for radio communication. Not usable from the application */
209 __SECTION(".bss.__blue_RAM")
210 #if defined(STM32WB05) || defined(STM32WB09)
211 __REQUIRED(uint8_t __blue_RAM[CFG_NUM_RADIO_TASKS * 92 + 28]) = {0,};
212 #elif defined(STM32WB06) || defined (STM32WB07)
213 __REQUIRED(uint8_t __blue_RAM[CFG_NUM_RADIO_TASKS * 80 + 28]) = {0,};
214 #else
215 #warning "No Blue RAM allocated"
216 #endif
217 #endif /* ENDOF PATCH */
218 
219 /**
220   * @}
221   */
222 
223 /** @defgroup RADIO_Exported_Functions RADIO Exported Functions
224   * @{
225   */
226 
227 /**
228   * @brief  Initializes the radio.
229   * @retval None
230   */
HAL_RADIO_Init(RADIO_HandleTypeDef * hradio)231 void HAL_RADIO_Init(RADIO_HandleTypeDef *hradio)
232 {
233   uint32_t mr_ble_ibias;
234   uint32_t mr_ble_iptat;
235   uint32_t mr_ble_vbg;
236   uint32_t mr_ble_rxadc_delay_i;
237   uint32_t mr_ble_rxadc_delay_q;
238   uint8_t mr_ble_rxadc_delay_flag;
239   uint8_t *hot_table_radio_config = (uint8_t *)&hot_table_radio_config_u32[4];
240   uint8_t index;
241 
242   /* Retrieve Trimming values from engineering flash locations */
243   if (*(volatile uint32_t *)VALIDITY_LOCATION == VALIDITY_TAG)
244   {
245     mr_ble_ibias            = ((*(volatile uint32_t *)MR_TRIMMING_LOCATION) & MR_BLE_IBIAS_TRIM_Msk) >> MR_BLE_IBIAS_TRIM_Pos;
246     mr_ble_iptat            = ((*(volatile uint32_t *)MR_TRIMMING_LOCATION) & MR_BLE_IPTAT_TRIM_Msk) >> MR_BLE_IPTAT_TRIM_Pos;
247     mr_ble_vbg              = ((*(volatile uint32_t *)MR_TRIMMING_LOCATION) & MR_BLE_VBG_TRIM_Msk) >> MR_BLE_VBG_TRIM_Pos;
248     mr_ble_rxadc_delay_i    = ((*(volatile uint32_t *)MR_TRIMMING_LOCATION) & MR_BLE_RXADC_DELAY_I_TRIM_Msk) >> MR_BLE_RXADC_DELAY_I_TRIM_Pos;
249     mr_ble_rxadc_delay_q    = ((*(volatile uint32_t *)MR_TRIMMING_LOCATION) & MR_BLE_RXADC_DELAY_Q_TRIM_Msk) >> MR_BLE_RXADC_DELAY_Q_TRIM_Pos;
250     mr_ble_rxadc_delay_flag = TRUE;
251   }
252   else
253   {
254     mr_ble_ibias = 0x08;
255     mr_ble_iptat = 0x07;
256     mr_ble_vbg   = 0x08;
257     mr_ble_rxadc_delay_flag = FALSE;
258 #if defined(STM32WB05) || defined(STM32WB09)
259     mr_ble_rxadc_delay_i    = 3;
260     mr_ble_rxadc_delay_q    = 3;
261     mr_ble_rxadc_delay_flag = TRUE;
262 #endif /* STM32WB05 or STM32WB09 */
263   }
264 
265   BLUEGLOB->BYTE4 = BLUE_IDLE_0;
266   if (hradio != NULL)
267   {
268     HAL_RADIO_MspInit(hradio);
269   }
270   LL_RADIO_TIMER_DisableTimer1(BLUE);
271   LL_RADIO_TIMER_DisableTimer2(BLUE);
272   LL_RADIO_TIMER_DisableBLEWakeupTimer(WAKEUP);
273 
274   /* Write Radio Trimming values in the registers: Cbias' VBG, Cbias' IPTAT, Cbias' IBIAS, RxAnaUsr Delay Trim I & Q */
275   MODIFY_REG_FIELD(RRM->CBIAS1_ANA_ENG, RRM_CBIAS1_ANA_ENG_RFD_CBIAS_VBG_TRIM, mr_ble_vbg);
276   MODIFY_REG_FIELD(RRM->CBIAS0_ANA_ENG, RRM_CBIAS0_ANA_ENG_RFD_CBIAS_IPTAT_TRIM, mr_ble_iptat);
277   MODIFY_REG_FIELD(RRM->CBIAS0_ANA_ENG, RRM_CBIAS0_ANA_ENG_RFD_CBIAS_IBIAS_TRIM, mr_ble_ibias);
278   if (mr_ble_rxadc_delay_flag)
279   {
280     MODIFY_REG_FIELD(RRM->RXADC_ANA_USR, RRM_RXADC_ANA_USR_RFD_RXADC_DELAYTRIM_I, mr_ble_rxadc_delay_i);
281     MODIFY_REG_FIELD(RRM->RXADC_ANA_USR, RRM_RXADC_ANA_USR_RFD_RXADC_DELAYTRIM_Q, mr_ble_rxadc_delay_q);
282   }
283 
284   /* Radio AFC configuration */
285   MODIFY_REG(RRM->AFC1_DIG_ENG, RRM_AFC1_DIG_ENG_AFC_DELAY_AFTER | RRM_AFC1_DIG_ENG_AFC_DELAY_BEFORE,
286              ((AFC_DELAY_BEFORE << RRM_AFC1_DIG_ENG_AFC_DELAY_BEFORE_Pos) & RRM_AFC1_DIG_ENG_AFC_DELAY_BEFORE_Msk) |
287              ((AFC_DELAY_AFTER << RRM_AFC1_DIG_ENG_AFC_DELAY_AFTER_Pos) & RRM_AFC1_DIG_ENG_AFC_DELAY_AFTER_Msk));
288   MODIFY_REG(RRM->CR0_DIG_ENG, RRM_CR0_DIG_ENG_CR_GAIN_BEFORE | RRM_CR0_DIG_ENG_CR_GAIN_AFTER,
289              ((CR_GAIN_BEFORE << RRM_CR0_DIG_ENG_CR_GAIN_BEFORE_Pos) & RRM_CR0_DIG_ENG_CR_GAIN_BEFORE_Msk) |
290              ((CR_GAIN_AFTER << RRM_CR0_DIG_ENG_CR_GAIN_AFTER_Pos) & RRM_CR0_DIG_ENG_CR_GAIN_AFTER_Msk));
291   MODIFY_REG(RRM->CR0_LR, RRM_CR0_LR_CR_LR_GAIN_BEFORE | RRM_CR0_LR_CR_LR_GAIN_AFTER,
292              ((CR_LR_GAIN_BEFORE << RRM_CR0_LR_CR_LR_GAIN_BEFORE_Pos) & RRM_CR0_LR_CR_LR_GAIN_BEFORE_Msk) |
293              ((CR_LR_GAIN_AFTER << RRM_CR0_LR_CR_LR_GAIN_AFTER_Pos) & RRM_CR0_LR_CR_LR_GAIN_AFTER_Msk));
294 
295   /* Radio RSSI Threshold configuration */
296   MODIFY_REG_FIELD(RRM->LR_RSSI_THR_DIG_ENG, RRM_LR_RSSI_THR_DIG_ENG_LR_RSSI_THR, LR_RSSI_THR);
297   MODIFY_REG_FIELD(RRM->LR_PD_THR_DIG_ENG, RRM_LR_PD_THR_DIG_ENG_LR_PD_THR, LR_PD_THR);
298   MODIFY_REG_FIELD(RRM->LR_AAC_THR_DIG_ENG, RRM_LR_AAC_THR_DIG_ENG_LR_AAC_THR, LR_AAC_THR);
299 
300   /* Enable Viterbi */
301   SET_BIT(RRM->VIT_CONF_DIG_ENG, RRM_VIT_CONF_DIG_ENG_VIT_CONF_0);
302 
303 #if defined(STM32WB05) || defined(STM32WB09)
304   MODIFY_REG_FIELD(RRM->ANTSW_DIG0_USR, RRM_ANTSW0_DIG_USR_RX_TIME_TO_SAMPLE, RX_TIME_TO_SAMPLE);
305   MODIFY_REG_FIELD(RRM->ANTSW_DIG1_USR, RRM_ANTSW1_DIG_USR_RX_TIME_TO_SWITCH, RX_TIME_TO_SWITCH);
306 #endif /* STM32WB05 or STM32WB09 */
307 
308   /*Set InitDelay*/
309   LL_RADIO_SetWakeupInitDelay(INITDELAY_WAKEUP);
310   LL_RADIO_SetTimer12InitDelayCal(INITDELAY_TIMER12_CAL);
311   LL_RADIO_SetTimer12InitDelayNoCal(INITDELAY_TIMER2_NOCAL);
312 
313   /*Set Init_radio_delay*/
314   LL_RADIO_SetReceivedCalDelayChk(DELAYCHK_RECEIVE_CAL);
315   LL_RADIO_SetReceivedNoCalDelayChk(DELAYCHK_RECEIVE_NOCAL);
316   LL_RADIO_SetTransmitCalDelayChk(DELAYCHK_TRANSMIT_CAL);
317   LL_RADIO_SetTransmitNoCalDelayChk(DELAYCHK_TRANSMIT_NOCAL);
318 
319   /* Initial and final TX delays: control the on-air start time of the TX packet
320   *  and the length of the packet "tail" after last bit is transmitted
321   */
322   LL_RADIO_SetTxDelayStart(TXDELAY_START);
323   LL_RADIO_SetTxDelayEnd(TXDELAY_END);
324 
325   /* Timeout for TX ready signal from the radio FSM after the 2nd init phase
326   *  has expired
327   */
328   LL_RADIO_SetTransmissionReadyTimeout(TXREADY_TIMEOUT);
329 
330   /* Timing for the various programming phases of the radio, modem and memory
331   *  pointers.
332   */
333   LL_RADIO_SetConfigurationEndDuration(CONFIG_END_DURATION);
334   LL_RADIO_SetTxDataReadyCheck(CHECK_TXDATAREADY);
335 
336   LL_RADIO_ChkFlagAutoclearEnable_Enable();
337   LL_RADIO_NoActiveLErrorInterrupt_Enable();
338   LL_RADIO_TxRxSkipInterrupt_Enable();
339 
340 #if defined(GLOBAL_WORD6_DEFAULTANTENNAID_Msk)
341   LL_RADIO_SetDefaultAntennaID(0);
342 #else
343   /* nothing to do */
344 #endif
345 
346   /* The commands in the hot table start at word 4
347   * The words 0 t0 2 are used to point to the command list
348   * for the various trigger events, word 3 is a null command
349   * (see function BLEPLAT_CNTR_SetRadioConfigData)
350   */
351   index = 0;
352   hot_table_radio_config[index++] = 0x01;
353   hot_table_radio_config[index++] = RRM_CBIAS1_ANA_ENG;
354   hot_table_radio_config[index++] = RRM->CBIAS1_ANA_ENG;
355   hot_table_radio_config[index++] = 0x01;
356   hot_table_radio_config[index++] = RRM_CBIAS0_ANA_ENG;
357   hot_table_radio_config[index++] = RRM->CBIAS0_ANA_ENG;
358 
359   hot_table_radio_config[index++] = 0x01;
360   hot_table_radio_config[index++] = RRM_RXADC_ANA_USR;
361   hot_table_radio_config[index++] = RRM->RXADC_ANA_USR;
362 
363   hot_table_radio_config[index++] = 0x01;
364   hot_table_radio_config[index++] = RRM_AFC1_DIG_ENG;
365   hot_table_radio_config[index++] = RRM->AFC1_DIG_ENG;
366   hot_table_radio_config[index++] = 0x01;
367   hot_table_radio_config[index++] = RRM_CR0_DIG_ENG;
368   hot_table_radio_config[index++] = RRM->CR0_DIG_ENG;
369   hot_table_radio_config[index++] = 0x01;
370   hot_table_radio_config[index++] = RRM_CR0_LR;
371   hot_table_radio_config[index++] = RRM->CR0_LR;
372   hot_table_radio_config[index++] = 0x01;
373   hot_table_radio_config[index++] = RRM_LR_RSSI_THR_DIG_ENG;
374   hot_table_radio_config[index++] = RRM->LR_RSSI_THR_DIG_ENG;
375   hot_table_radio_config[index++] = 0x01;
376   hot_table_radio_config[index++] = RRM_LR_PD_THR_DIG_ENG;
377   hot_table_radio_config[index++] = RRM->LR_PD_THR_DIG_ENG;
378   hot_table_radio_config[index++] = 0x01;
379   hot_table_radio_config[index++] = RRM_LR_AAC_THR_DIG_ENG;
380   hot_table_radio_config[index++] = RRM->LR_AAC_THR_DIG_ENG;
381   hot_table_radio_config[index++] = 0x01;
382   hot_table_radio_config[index++] = RRM_VIT_CONF_DIG_ENG;
383   hot_table_radio_config[index++] = RRM->VIT_CONF_DIG_ENG;
384 #if defined(STM32WB05) || defined(STM32WB09)
385   hot_table_radio_config[index++] = 0x01;
386   hot_table_radio_config[index++] = RRM_ANTSW_DIG0_USR;
387   hot_table_radio_config[index++] = RRM->ANTSW_DIG0_USR;
388   hot_table_radio_config[index++] = 0x01;
389   hot_table_radio_config[index++] = RRM_ANTSW_DIG1_USR;
390   hot_table_radio_config[index++] = RRM->ANTSW_DIG1_USR;
391 #endif
392   hot_table_radio_config[index++] = 0x00;
393 
394   hot_table_radio_config_u32[0] = (uint32_t)(&hot_table_radio_config_u32[4]); /* Point to Port 0 command list 1 executed when Wakeup timer triggers */
395   hot_table_radio_config_u32[1] = (uint32_t)(&hot_table_radio_config_u32[4]); /* Point to Port 0 command list 2 executed when Timer1 triggers       */
396   hot_table_radio_config_u32[2] = (uint32_t)(&hot_table_radio_config_u32[3]); /* Point to Port 0 command list 3 executed when Timer2 triggers       */
397   hot_table_radio_config_u32[3] = 0x00000000;                /* Null command */
398 
399   LL_RADIO_SetRadioConfigurationAddressPointer(hot_table_radio_config_u32[0]);
400   /* Reload radio config pointer */
401   *(uint32_t *)(RRM_BASE + 0x10U) = 0x01U;
402   LL_RADIO_Active2ErrorInterrupt_Enable();
403 
404 #if USE_RADIO_PROPRIETARY_DRIVER
405   globalParameters.back2backTime = BACK_TO_BACK_TIME;
406   globalParameters.tone_start_stop_flag = 0;
407 #endif
408 
409   /*Clear all interrupts of the BLUE Controller*/
410   uint32_t int_val_tmp = BLUE->INTERRUPT1REG;
411   BLUE->INTERRUPT1REG = int_val_tmp;
412 
413   /*BLE wake up IRQ Status clearing and enable*/
414   WAKEUP->WAKEUP_BLE_IRQ_STATUS |= 1;
415   WAKEUP->WAKEUP_BLE_IRQ_ENABLE |= 1;
416 
417   /* If the device is configured with
418      System clock = 64 MHz and BLE clock = 16 MHz
419      a register read is necessary to end fine
420      the clear interrupt register operation,
421      due the AHB down converter latency */
422   int_val_tmp = BLUE->INTERRUPT1REG;
423 
424   return;
425 }
426 
427 /**
428   * @brief  Read RSSI
429   * @retval int8_t: RSSI in dBm
430   */
HAL_RADIO_ReadRSSI(void)431 int8_t HAL_RADIO_ReadRSSI(void)
432 {
433   int32_t rssi_dbm;
434   uint32_t rssi0 = RRM->RSSI0_DIG_OUT;
435   uint32_t rssi1 = RRM->RSSI1_DIG_OUT;
436 
437   uint32_t rssi_int16 = ((rssi1 & 0xFF) << 8) | (rssi0 & 0xFF);
438   uint32_t reg_agc = RRM->AGC_DIG_OUT;
439 
440   if ((rssi_int16 == 0U) || (reg_agc > 0xbU))
441   {
442     rssi_dbm = 127 ;
443   }
444   else
445   {
446     rssi_dbm = (int32_t)reg_agc * 6 - RSSI_OFFSET;//127 ;
447     while (rssi_int16 > 30U)
448     {
449       rssi_dbm = rssi_dbm + 6 ;
450       rssi_int16 = (rssi_int16 >> 1) ;
451     }
452     rssi_dbm = rssi_dbm + (int32_t)(uint32_t)((417U * rssi_int16 + 18080U) >> 10);
453   }
454   return (int8_t)rssi_dbm;
455 }
456 
457 #if USE_RADIO_PROPRIETARY_DRIVER
458 
459 /**
460   * @brief  This routine is called when a RADIO event is complete.
461   * @param  p: Current action packet which its transaction has been completed.
462   * @param  next: Next action packet which is going to be scheduled.
463   * @retval return value: TRUE
464   */
HAL_RADIO_Callback(ActionPacket * p,ActionPacket * next)465 uint8_t HAL_RADIO_Callback(ActionPacket *p, ActionPacket *next)
466 {
467   /* Event is a reception */
468   if ((p->status & BLUE_STATUSREG_PREVTRANSMIT) == 0)
469   {
470     RxStats_t receivedStats = {0};
471     /* Reception ends with no errors */
472     if ((p->status & BLUE_INTERRUPT1REG_RCVOK) != 0)
473     {
474       if ((p->status & BLUE_INTERRUPT1REG_ENCERROR) != 0)
475       {
476         receivedStats.rssi = p->rssi;
477         receivedStats.timestamp_receive = p->timestamp_receive;
478         HAL_RADIO_CallbackRcvEncryptErr(&receivedStats);
479       }
480       else
481       {
482         receivedStats.rssi = p->rssi;
483         receivedStats.timestamp_receive = p->timestamp_receive;
484         HAL_RADIO_CallbackRcvOk(&receivedStats);
485       }
486     }
487     /* Reception ends with timeout */
488     else if ((p->status & BLUE_INTERRUPT1REG_RCVTIMEOUT) != 0)
489     {
490       receivedStats.rssi = p->rssi;
491       receivedStats.timestamp_receive = 0;
492       HAL_RADIO_CallbackRcvTimeout(&receivedStats);
493     }
494     /* Reception ends with errors */
495     else if ((p->status & BLUE_INTERRUPT1REG_RCVCRCERR) != 0)
496     {
497       receivedStats.rssi = p->rssi;
498       receivedStats.timestamp_receive = p->timestamp_receive;
499       HAL_RADIO_CallbackRcvError(&receivedStats);
500     }
501   }
502   /* Event is a transmission */
503   else if ((p->status & BLUE_INTERRUPT1REG_DONE) != 0)
504   {
505     /* RADIO TX operation done */
506     HAL_RADIO_CallbackTxDone();
507   }
508   return TRUE;
509 }
510 
HAL_RADIO_CallbackRcvError(RxStats_t * rxPacketStats)511 __weak void HAL_RADIO_CallbackRcvError(RxStats_t *rxPacketStats) {}
HAL_RADIO_CallbackRcvTimeout(RxStats_t * rxPacketStats)512 __weak void HAL_RADIO_CallbackRcvTimeout(RxStats_t *rxPacketStats) {}
HAL_RADIO_CallbackRcvEncryptErr(RxStats_t * rxPacketStats)513 __weak void HAL_RADIO_CallbackRcvEncryptErr(RxStats_t *rxPacketStats) {}
HAL_RADIO_CallbackRcvOk(RxStats_t * rxPacketStats)514 __weak void HAL_RADIO_CallbackRcvOk(RxStats_t *rxPacketStats) {}
HAL_RADIO_CallbackTxDone(void)515 __weak void HAL_RADIO_CallbackTxDone(void) {}
516 
517 /**
518   * @brief  Radio ISR.
519   *         Besides, next packet is scheduled here.
520   * @retval None
521   */
HAL_RADIO_ActionPacketIsr(uint32_t int_flags)522 static void HAL_RADIO_ActionPacketIsr(uint32_t int_flags)
523 {
524   if ((int_flags & BLUE_INTERRUPT1REG_DONE) != 0)
525   {
526 
527     ActionPacket *next, *actionPacketBackup;
528     BlueTransStruct *p;
529     uint32_t time;
530 
531     /* Copy status in order for callback to access it. */
532     globalParameters.current_action_packet->status = int_flags | \
533                                                      (BLUE->STATUSREG & BLUE_STATUSREG_PREVTRANSMIT_Msk);
534 
535     if ((globalParameters.current_action_packet->condRoutine(globalParameters.current_action_packet)) == TRUE)
536     {
537       next = globalParameters.current_action_packet->next_true;
538     }
539     else
540     {
541       next = globalParameters.current_action_packet->next_false;
542     }
543     /*The radio event is started. So here a check on the next packet of the event is made*/
544     if (next == NULL_0)
545     {
546       /* timer2 off */
547       LL_RADIO_TIMER_DisableTimer1(BLUE);
548       LL_RADIO_TIMER_DisableTimer2(BLUE);
549       LL_RADIO_TIMER_DisableBLEWakeupTimer(WAKEUP);
550       MODIFY_REG(BLUEGLOB->BYTE4, GLOBAL_BYTE4_ACTIVE_Msk, BLUE_IDLE_0);
551     }
552     else
553     {
554       BLUEGLOB->BYTE4 = (next->StateMachineNo | GLOBAL_BYTE4_ACTIVE_Msk);
555       p = &next->trans_packet;
556       MODIFY_REG((bluedata + next->StateMachineNo)->BYTE0, STATEMACH_BYTE0_TXMODE_Msk,
557                  next->trans_config);/* Transmission or reception*/
558       (bluedata + next->StateMachineNo)->TXPOINT = BLUE_STRUCT_PTR_CAST(p);
559       (bluedata + next->StateMachineNo)->RCVPOINT = BLUE_STRUCT_PTR_CAST(p);
560       (bluedata + next->StateMachineNo)->MAXRECEIVEDLENGTH = next->MaxReceiveLength;
561 
562       /* Packet will execute on time specified by WakeupTime */
563       if ((next->ActionTag & TIMER_WAKEUP) != 0)
564       {
565         /* timer1/2 off */
566         LL_RADIO_TIMER_DisableTimer1(BLUE);
567         LL_RADIO_TIMER_DisableTimer2(BLUE);
568 
569         /* program timer at next->wakeuptime */
570         if ((next->ActionTag & RELATIVE) != 0)
571         {
572           time = HAL_RADIO_TIMER_GetCurrentSysTime() + HAL_RADIO_TIMER_UsToSystime(next->WakeupTime);
573           HAL_RADIO_TIMER_SetRadioTimerValue(time, (next->trans_config == STATEMACH_BYTE0_TXMODE_Msk), (next->ActionTag & PLL_TRIG));
574         }
575         else
576         {
577           HAL_RADIO_TIMER_SetRadioTimerValue(next->WakeupTime, (next->trans_config == STATEMACH_BYTE0_TXMODE_Msk), (next->ActionTag & PLL_TRIG));
578         }
579       }
580       else
581       {
582         /* back to back */
583       }
584     }
585 
586     /* Accept the packet even with CRC Error */
587     if (((int_flags & BLUE_INTERRUPT1REG_RCVOK) != 0) || ((int_flags & BLUE_INTERRUPT1REG_RCVCRCERR) != 0))
588     {
589 
590       uint64_t current_system_time;
591       /* read RSSI */
592       globalParameters.current_action_packet->rssi =  HAL_RADIO_ReadRSSI();
593 
594       /* bluedata->config = bluedata->config ^ 0x80 ;  toggle NESN bit
595       bluedata->config = bluedata->config & 0x7F ;  //reset NESN bit */
596 
597       /* read time stamp */
598       globalParameters.current_action_packet->timestamp_receive = HAL_RADIO_TIMER_GetAnchorPoint(&current_system_time);
599     }
600     else if ((int_flags & BLUE_INTERRUPT1REG_RCVTIMEOUT) != 0)
601     {
602       /* read RSSI even if a timeout happens */
603       globalParameters.current_action_packet->rssi =  HAL_RADIO_ReadRSSI();
604     }
605 
606     actionPacketBackup = globalParameters.current_action_packet;
607     globalParameters.current_action_packet = next;
608     actionPacketBackup->dataRoutine(actionPacketBackup, next);
609   }
610 
611   return ;
612 }
613 
614 /**
615   * @brief RADIO MSP Init
616   * @param  hradio pointer to a RADIO_HandleTypeDef structure that contains
617   *         the configuration information for RADIO module
618   * @retval None
619   */
HAL_RADIO_MspInit(RADIO_HandleTypeDef * hradio)620 __weak void HAL_RADIO_MspInit(RADIO_HandleTypeDef *hradio)
621 {
622   /* Prevent unused argument(s) compilation warning */
623   UNUSED(hradio);
624 
625   /* NOTE : This function Should not be modified, when the callback is needed,
626             the HAL_I2S_MspInit could be implemented in the user file
627    */
628 }
629 
630 /**
631   * @brief RADIO MSP DeInit
632   * @param  hradio pointer to a RADIO_HandleTypeDef structure that contains
633   *         the configuration information for RADIO module
634   * @retval None
635   */
HAL_RADIO_MspDeInit(RADIO_HandleTypeDef * hradio)636 __weak void HAL_RADIO_MspDeInit(RADIO_HandleTypeDef *hradio)
637 {
638   /* Prevent unused argument(s) compilation warning */
639   UNUSED(hradio);
640 
641   /* NOTE : This function Should not be modified, when the callback is needed,
642             the HAL_RADIO_MspDeInit could be implemented in the user file
643    */
644 }
645 
646 
647 /**
648   * @brief  This routine force the radio to be stopped. After calling this function,
649   *         the ISR is not triggered unless, "MakeActionPacketPending" API called again.
650   * @retval 0 if the radio activity has been cleared successfully.
651   * @retval 1 if it is too late to clear the last radio activity.
652   * @retval 2 if it might not be possible to clear the last radio activity.
653   */
HAL_RADIO_StopActivity(void)654 uint8_t HAL_RADIO_StopActivity(void)
655 {
656   uint8_t retval;
657   MASK_INTERRUPTS();
658   MODIFY_REG(BLUEGLOB->BYTE4, GLOBAL_BYTE4_ACTIVE_Msk, BLUE_IDLE_0);
659   retval = HAL_RADIO_TIMER_ClearRadioTimerValue();
660   globalParameters.current_action_packet = 0;
661   UNMASK_INTERRUPTS();
662   return retval;
663 }
664 
665 /**
666   * @brief  This routine sets the channel map. If channel map is not in use, do not use it. The
667   *         chan_remap constant is a 37-bit vector, one bit per channel from 0 to 36, with the
668   *         LSB corresponding to the channel 0. If the corresponding bit is set, the channel is in use; if it is cleared,
669   *         there is an automatic remap to another channel, as defined in the Bluetooth Low
670   *         Energy specification.
671   *         Setting all bits of the array to one, disables the channel remapping, and this is the mode
672   *         that should be used if the Bluetooth channel remap is not in use.
673   * @param  StateMachineNo: state machine number in multi state.
674   * @param  chan_remap: a 37-bit vector, one bit per channel from 0 to 36, with the LSB corresponding to the channel 0
675   * @retval None
676   */
HAL_RADIO_SetChannelMap(uint8_t StateMachineNo,uint8_t * chan_remap)677 void HAL_RADIO_SetChannelMap(uint8_t StateMachineNo, uint8_t *chan_remap)
678 {
679   /* Check the parameters */
680   assert_param(IS_STATE_VALID(StateMachineNo));
681 
682   for (uint8_t i = 0; i < 5; i++)
683   {
684     (bluedata + StateMachineNo)->USEDCHANNELFLAGS[i] = chan_remap[i];
685   }
686   (bluedata + StateMachineNo)->USEDCHANNELFLAGS[4] &= 0x1F;
687   return;
688 }
689 
690 /**
691   * @brief  This routine sets the channel and the channel increment. Channel and channel
692   *         increment follows channel mapping corresponding to Bluetooth specification.
693   *         RF channel 0:  2402 MHz -> ble channel index 37
694   *         RF channel 1:  2404 MHz -> ble channel index 0
695   *         RF channel 2:  2406 MHz -> ble channel index 1
696   *         ...
697   *         RF channel 11: 2424 MHz -> ble channel index 10
698   *         RF channel 12: 2426 MHz -> ble channel index 38
699   *         RF channel 13: 2428 MHz -> ble channel index 11
700   *         RF channel 14: 2430 MHz -> ble channel index 12
701   *         ...
702   *         RF channel 38: 2478 MHz -> ble channel index 36
703   *         RF channel 39: 2480 MHz -> ble channel index 39
704   *
705   *         For the ble channel index 37, 38 and 39 (RF channel 0, 12, 39):
706   *          - The crc_init value should always be 0x555555.
707   *          - There is no encryption.
708   *          - The channel increment is dedicated, the channel sequence is:
709   *            37 -> 38 -> 39 -> 37 -> ... while for the other channels is:
710   *            0 -> 1 -> ... -> 36 -> 0 -> ...
711   *            There is no channel map for these three channels.
712   *            Valid values for packet length for these channels are from 6 to 37.
713   * @param  StateMachineNo: state machine number in multi state.
714   * @param  channel: ble channel index. From 0 to 39.
715   * @param  channel_increment: determines the hoping value.
716   * @retval None
717   */
HAL_RADIO_SetChannel(uint8_t StateMachineNo,uint8_t channel,uint8_t channel_increment)718 void HAL_RADIO_SetChannel(uint8_t StateMachineNo, uint8_t channel, uint8_t channel_increment)
719 {
720   /* Check the parameters */
721   assert_param(IS_STATE_VALID(StateMachineNo));
722   assert_param(IS_RFCHANNEL_VALID(channel));
723 
724   MODIFY_REG((bluedata + StateMachineNo)->BYTE0, STATEMACH_BYTE0_UCHAN_Msk, channel);
725   /*if TxRxPack.incchan = 0, then remap_chan is used as physical channel*/
726   MODIFY_REG((bluedata + StateMachineNo)->BYTE1, STATEMACH_BYTE1_REMAP_CHAN_Msk, channel);
727   (bluedata + StateMachineNo)->HOPINCR = channel_increment;
728   return;
729 }
730 
731 /**
732   * @brief  This routine sets the NetworkID and the CRC init.
733   * @param  StateMachineNo: state machine number in multi state.
734   * @param  NetworkID: The NetworkID is the ID of the device.
735   *         The user shall ensure that the NetworkID meets the following requirements:
736   *           - It shall have no more than six consecutive zeros or ones.
737   *           - It shall not have all four octets equal.
738   *           - It shall have no more than 24 transitions.
739   *           - It shall have a minimum of two transitions in the most significant six bits.
740   * @param  crc_init: CRC initialization value.
741   *         This value must be 0x555555 when channel frequency is one of these values: 37, 38, 39.
742   * @retval None
743   */
HAL_RADIO_SetTxAttributes(uint8_t StateMachineNo,uint32_t NetworkID,uint32_t crc_init)744 void HAL_RADIO_SetTxAttributes(uint8_t StateMachineNo, uint32_t NetworkID, uint32_t crc_init)
745 {
746   /* Check the parameters */
747   assert_param(IS_STATE_VALID(StateMachineNo));
748 
749   (bluedata + StateMachineNo)->ACCADDR = NetworkID;
750   (bluedata + StateMachineNo)->CRCINIT[0] = crc_init;
751   (bluedata + StateMachineNo)->CRCINIT[1] = crc_init >> 8;
752   (bluedata + StateMachineNo)->CRCINIT[2] = crc_init >> 16;
753   return;
754 }
755 
756 /**
757   * @brief  This routine sets the 40-bit receive and transmit packet count, to be used in
758   *         encryption calculation.
759   *         Both are pointers to char, and set the 39-bit counter + 1-bit MSB as defined in the
760   *         Bluetooth Low Energy spec. One is for transmit packets, the other is for receive packets.
761   * @param  StateMachineNo: state machine number in multi state.
762   * @param  count_tx: 40-bit transmit packet count, to be used in encryption nounce calculation.
763   * @param  count_rcv: 40-bit receive packet count, to be used in encryption nounce calculation.
764   * @retval None
765   */
HAL_RADIO_SetEncryptionCount(uint8_t StateMachineNo,uint8_t * count_tx,uint8_t * count_rcv)766 void HAL_RADIO_SetEncryptionCount(uint8_t StateMachineNo, uint8_t *count_tx, uint8_t *count_rcv)
767 {
768   /* Check the parameters */
769   assert_param(IS_STATE_VALID(StateMachineNo));
770 
771   for (uint8_t i = 0; i < 5; i++)
772   {
773     (bluedata + StateMachineNo)->PCNTRCV[i] = count_rcv[i];
774     (bluedata + StateMachineNo)->PCNTTX[i] = count_tx[i];
775   }
776   return;
777 }
778 
779 /**
780   * @brief  This routines sets the 8-byte encryption initial vector, and the 16-byte encryption key.
781   *         The definition of the encryption key and its initial value is according the Bluetooth Low Energy spec.
782   * @param  StateMachineNo: state machine number in multi state.
783   * @param  enc_iv: 8-byte encryption initial vector.
784   * @param  enc_key: 16-byte encryption key.
785   * @retval None
786   */
HAL_RADIO_SetEncryptionAttributes(uint8_t StateMachineNo,uint8_t * enc_iv,uint8_t * enc_key)787 void HAL_RADIO_SetEncryptionAttributes(uint8_t StateMachineNo, uint8_t *enc_iv, uint8_t *enc_key)
788 {
789   uint8_t i = 0;
790   /* Check the parameters */
791   assert_param(IS_STATE_VALID(StateMachineNo));
792 
793   for (i = 0; i < 8; i++)
794   {
795     (bluedata + StateMachineNo)->ENCRYPTIV[i] = enc_iv[i];
796     (bluedata + StateMachineNo)->ENCRYPTK[i] = enc_key[i];
797   }
798   for (i = 8; i < 16; i++)
799   {
800     (bluedata + StateMachineNo)->ENCRYPTK[i] = enc_key[i];
801   }
802 
803   return;
804 }
805 
806 /**
807   * @brief  Set the maximum length of a received packet.
808   * @param  StateMachineNo: state machine number in multi state.
809   * @param  MaxReceivedLength: Upper limit for the length of a received packet.
810   *                            From 0 to 255 bytes.
811   * @retval None
812   */
HAL_RADIO_SetMaxReceivedLength(uint8_t StateMachineNo,uint8_t MaxReceivedLength)813 void HAL_RADIO_SetMaxReceivedLength(uint8_t StateMachineNo, uint8_t MaxReceivedLength)
814 {
815   (bluedata + StateMachineNo)->MAXRECEIVEDLENGTH = MaxReceivedLength;
816   return;
817 }
818 
819 /**
820   * @brief  Initializes the time between back-to-back radio transmissions.
821   * @param  back_to_back_time: time between two packets if wakeupTimer is not used. Resolution is 1 us.
822   * @retval None
823   */
HAL_RADIO_SetBackToBackTime(uint32_t back_to_back_time)824 void HAL_RADIO_SetBackToBackTime(uint32_t back_to_back_time)
825 {
826   globalParameters.back2backTime = back_to_back_time;
827   return;
828 }
829 
830 
831 /**
832   * @brief Phy selection
833   * @param  StateMachineNo: state machine number in multi state.
834   * @param  phy:
835   *         0x0  PHY is not coded 1Mbps
836   *         0x1  PHY is not coded 2Mbps
837   *         0x4  PHY is coded 1Mbps with S=8
838   *         0x6  PHY is coded 1Mbps with S=2
839   * @retval None
840   */
HAL_RADIO_SetPhy(uint8_t StateMachineNo,uint8_t phy)841 void HAL_RADIO_SetPhy(uint8_t StateMachineNo, uint8_t phy)
842 {
843   assert_param(IS_PHY_VALID(phy));
844 
845   MODIFY_REG((bluedata + StateMachineNo)->BYTE3, STATEMACH_BYTE3_TXPHY_Msk, phy);
846   MODIFY_REG((bluedata + StateMachineNo)->BYTE3, STATEMACH_BYTE3_RXPHY_Msk, phy << 4);
847 
848   return;
849 }
850 
851 /**
852   * @brief  This routine turns encrypt ON and OFF. When the encryption is enabled, the hardware will add 4 bytes
853   *         at the end of the packet as MIC (Message Authentication Code). So the user need to add 4 byte to the
854   *         length of the packet. The parameters enable the encryption for both. There are two separated parameters
855   *         for this function just compliance with previous version of the driver.
856   * @param  StateMachineNo: state machine number in multi state.
857   * @param  EncryptFlagTx: DISABLE: encryption is turned OFF for both TX and RX operations.
858   *              ENABLE: encryption is turned OFF for both TX and RX operations.
859   *         This parameter can be: ENABLE or DISABLE.
860   * @param  EncryptFlagRcv: encryption is turned OFF for both TX and RX operations.
861   *              ENABLE: encryption is turned OFF for both TX and RX operations.
862   *          This parameter can be: ENABLE or DISABLE.
863   * @retval None
864   */
HAL_RADIO_SetEncryptFlags(uint8_t StateMachineNo,FunctionalState EncryptFlagTx,FunctionalState EncryptFlagRcv)865 void HAL_RADIO_SetEncryptFlags(uint8_t StateMachineNo, FunctionalState EncryptFlagTx, FunctionalState EncryptFlagRcv)
866 {
867   /* Check the parameters */
868   assert_param(IS_STATE_VALID(StateMachineNo));
869   assert_param(IS_FUNCTIONAL_STATE(EncryptFlagTx));
870   assert_param(IS_FUNCTIONAL_STATE(EncryptFlagRcv));
871 
872   if (EncryptFlagTx == ENABLE || EncryptFlagRcv == ENABLE)
873   {
874     (bluedata + StateMachineNo)->BYTE2 |= STATEMACH_BYTE2_ENCRYPTON_Msk;
875     (bluedata + StateMachineNo)->BYTE35 |= STATEMACH_BYTE35_INTENCERROR_Msk;
876   }
877   else
878   {
879     (bluedata + StateMachineNo)->BYTE2 &= (~STATEMACH_BYTE2_ENCRYPTON_Msk);
880   }
881   (bluedata + StateMachineNo)->BYTE35 |= STATEMACH_BYTE35_INTRXOVERFLOWERROR_Msk;
882   return;
883 }
884 
885 /**
886   * @brief  Set the receive window length.
887   *         Define the maximum duration to stay in reception without any preamble
888   *         and access address detection.
889   * @param  ReceiveTimeout: receive window length in microseconds.
890   * @retval None
891   */
HAL_RADIO_SetGlobalReceiveTimeout(uint32_t ReceiveTimeout)892 void HAL_RADIO_SetGlobalReceiveTimeout(uint32_t ReceiveTimeout)
893 {
894   /* Set the Rx window Timeout expressed as: 4^(RCVTIMEOUT_19_18)*RCVTIMEOUT_17_0 */
895   if (ReceiveTimeout < 0x40000)
896   {
897     BLUEGLOB->RCVTIMEOUT[0] = (ReceiveTimeout)       & 0x000000FF;
898     BLUEGLOB->RCVTIMEOUT[1] = (ReceiveTimeout >> 8)  & 0x000000FF;
899     BLUEGLOB->RCVTIMEOUT[2] = (ReceiveTimeout >> 16) & 0x00000003;
900   }
901   else if (ReceiveTimeout < 0x100000)
902   {
903     BLUEGLOB->RCVTIMEOUT[0] = (ReceiveTimeout >> 2)  & 0x000000FF;
904     BLUEGLOB->RCVTIMEOUT[1] = (ReceiveTimeout >> 10) & 0x000000FF;
905     BLUEGLOB->RCVTIMEOUT[2] = (ReceiveTimeout >> 18) & 0x00000003;
906 
907     BLUEGLOB->RCVTIMEOUT[2] |= 0x04;
908   }
909   else if (ReceiveTimeout < 0x400000)
910   {
911     BLUEGLOB->RCVTIMEOUT[0] = (ReceiveTimeout >> 4)  & 0x000000FF;
912     BLUEGLOB->RCVTIMEOUT[1] = (ReceiveTimeout >> 12) & 0x000000FF;
913     BLUEGLOB->RCVTIMEOUT[2] = (ReceiveTimeout >> 20) & 0x00000003;
914 
915     BLUEGLOB->RCVTIMEOUT[2] |= 0x08;
916   }
917   else if (ReceiveTimeout < 0x1000000)
918   {
919     BLUEGLOB->RCVTIMEOUT[0] = (ReceiveTimeout >> 6)  & 0x000000FF ;
920     BLUEGLOB->RCVTIMEOUT[1] = (ReceiveTimeout >> 14) & 0x000000FF ;
921     BLUEGLOB->RCVTIMEOUT[2] = (ReceiveTimeout >> 22) & 0x00000003 ;
922 
923     BLUEGLOB->RCVTIMEOUT[2] |= 0x0C;
924   }
925   else
926   {
927     /* error */
928   }
929 }
930 
931 /**
932   * @brief  This routine should be called after writing/modifying an action packet, and before it
933   *         is executed via either the API mechanism, or the next mechanism.
934   * @param  p: pointer to action packet.
935   * @retval None
936   */
HAL_RADIO_SetReservedArea(ActionPacket * p)937 void HAL_RADIO_SetReservedArea(ActionPacket *p)
938 {
939   uint32_t relTimeout;
940   uint32_t cnt;
941 
942   /*Init to 0 the TxRxPack*/
943   for (cnt = 0; cnt < sizeof(p->trans_packet); cnt++)
944   {
945     ((uint8_t *)(&(p->trans_packet)))[cnt] = 0;
946   }
947 
948   /*Set the TxRxPack for the next transaction. The list cannot be empty.
949   At least,it can be composed by one only packet that points to itself*/
950   p->trans_packet.NEXTPTR = BLUE_STRUCT_PTR_CAST(&(p->trans_packet));
951 
952   /* Set the buffer that contains the values to send or that stores
953   the data received */
954   p->trans_packet.DATAPTR = BLUE_DATA_PTR_CAST(p->data);
955 
956   /* Compensate the radio setup time from the back2back time */
957   relTimeout = globalParameters.back2backTime - 70;
958 
959   /*Check if there is some action to perform next*/
960 //  if (p->next_false || p->next_true){ /* Host timer workaround */
961   /* Set the Timeout for the Timer2 */
962   p->trans_packet.TIMER2[0] = relTimeout & 0xFF;
963   p->trans_packet.TIMER2[1] = (relTimeout >> 8) & 0xFF;
964   p->trans_packet.BYTE14 = (relTimeout >> 16) & TXRXPACK_BYTE14_TIMER2_19_16_Msk;
965   /*Enable relative timer*/
966   p->trans_packet.BYTE14 |= TXRXPACK_BYTE14_TIMER2EN_Msk;
967 //  }
968 
969   /* TrigDone or TrigReceive */
970   if ((p->ActionTag & TIMESTAMP_POSITION) == 0)
971   {
972     p->trans_packet.BYTE14 |= TIMESTAMP_POSITION_LASTBIT;
973   }
974   else
975   {
976     p->trans_packet.BYTE14 |= TIMESTAMP_POSITION_ACCESSADDRESS;
977   }
978 
979   p->trans_packet.BYTE4 |= TXRXPACK_BYTE4_KEEPSEMAREQ_Msk | \
980                            (p->ActionTag & INC_CHAN) | \
981                            (p->ActionTag & PLL_TRIG);
982 
983   p->trans_packet.BYTE5 |= (p->ActionTag & WHITENING_DISABLE) | \
984                            TXRXPACK_BYTE5_TXDATAREADY_Msk | \
985                            TXRXPACK_BYTE5_ALLTABLEREADY_Msk;
986 
987   /* Enable all interrupts */
988   p->trans_packet.BYTE15 = TXRXPACK_BYTE15_INT_EN_Msk;
989 
990   /* By Default the next action is considered as next_true */
991   if ((p->next_true->ActionTag & TXRX) != 0)
992   {
993     /* Set the type of the next activity */
994     p->trans_packet.BYTE5 |= TXRXPACK_BYTE5_NEXTTXMODE_Msk;
995   }
996 
997   p->trans_config = 0; // Rx
998   if ((p->ActionTag & TXRX) != 0)
999   {
1000     p->trans_config = STATEMACH_BYTE0_TXMODE_Msk; // Tx
1001   }
1002   return ;
1003 }
1004 
1005 
1006 /**
1007   * @brief  This routine should be called for the first actionPacket that needs to be scheduled
1008   *         on the radio. For it to work OK, the WakeupTime should be valid.
1009   *         Subsequent packets can be dispatched using the same process, or by providing non-NULL pointers
1010   *         to the next_true and next_false pointers of the ActionPacket.
1011   * @param  p: pointer to action packet.
1012   * @retval uint8_t with following values:
1013   *          - 0x00 : Success.
1014   *          - 0xC4 : Radio is busy, action packet has not been executed.
1015   */
HAL_RADIO_MakeActionPacketPending(ActionPacket * p)1016 uint8_t HAL_RADIO_MakeActionPacketPending(ActionPacket *p)
1017 {
1018   uint8_t returnValue = SUCCESS_0;
1019   uint32_t time;
1020   uint32_t dummyTime;
1021   if (HAL_RADIO_GetStatus(&dummyTime) == BLUE_IDLE_0)
1022   {
1023     uint8_t  statemachineNo;
1024     BlueTransStruct *p1 ;
1025 
1026     /* timer1/2 off */
1027     LL_RADIO_TIMER_DisableTimer1(BLUE);
1028     LL_RADIO_TIMER_DisableTimer2(BLUE);
1029 
1030     statemachineNo = 0x7F & p->StateMachineNo;
1031 
1032     BLUEGLOB->BYTE4 = (p->StateMachineNo | GLOBAL_BYTE4_ACTIVE_Msk);
1033 
1034     p1 = &p->trans_packet;
1035     (bluedata + statemachineNo)->RCVPOINT = BLUE_STRUCT_PTR_CAST(p1);
1036     (bluedata + statemachineNo)->TXPOINT = BLUE_STRUCT_PTR_CAST(p1);
1037     (bluedata + statemachineNo)->MAXRECEIVEDLENGTH = p->MaxReceiveLength;
1038 
1039 #if defined (STM32WB05) || defined(STM32WB09 )
1040     (bluedata + statemachineNo)->BYTE3 |= 1 << 3;
1041 #endif
1042 
1043     globalParameters.current_action_packet = p;
1044 
1045     MODIFY_REG((bluedata + statemachineNo)->BYTE0, STATEMACH_BYTE0_TXMODE_Msk,
1046                p->trans_config); /* Transmission or reception */
1047 
1048     /* program timer at next->wakeuptime */
1049     MASK_INTERRUPTS();
1050     if ((p->ActionTag & RELATIVE) != 0)
1051     {
1052       time = HAL_RADIO_TIMER_GetCurrentSysTime() + HAL_RADIO_TIMER_UsToSystime(p->WakeupTime);
1053       returnValue = HAL_RADIO_TIMER_SetRadioTimerValue(time, (p->trans_config == STATEMACH_BYTE0_TXMODE_Msk), (p->ActionTag & PLL_TRIG));
1054     }
1055     else /*absolute time*/
1056     {
1057       returnValue = HAL_RADIO_TIMER_SetRadioTimerValue(p->WakeupTime, (p->trans_config == STATEMACH_BYTE0_TXMODE_Msk), (p->ActionTag & PLL_TRIG));
1058     }
1059 
1060     UNMASK_INTERRUPTS();
1061   }
1062   else
1063   {
1064     returnValue = RADIO_BUSY_C4;
1065   }
1066   return returnValue;
1067 }
1068 
1069 /**
1070   * @brief  Get the status of the radio and if it is active
1071   *         the last programmed value in MTU.
1072   * @param  time: where to store the last value programmed.
1073   * @retval 0 if the radio controller is IDLE or no timer has been programmed
1074   * @retval 1 if the radio is ACTIVE and a radio timer has been programmed
1075   */
HAL_RADIO_GetStatus(uint32_t * time)1076 uint8_t HAL_RADIO_GetStatus(uint32_t *time)
1077 {
1078   uint8_t retValue = BLUE_IDLE_0;
1079   if ((BLUEGLOB->BYTE4 & GLOBAL_BYTE4_ACTIVE_Msk) != 0)
1080   {
1081     retValue = HAL_RADIO_TIMER_GetRadioTimerValue(time);
1082   }
1083   return retValue;
1084 }
1085 
1086 /**
1087   * @brief  Configures the transmit power level.
1088   * @param  PowerLevel: power level which should set to this value.
1089   *         See the documentation inside the datasheet.
1090   * @retval None
1091   */
HAL_RADIO_SetTxPower(uint8_t PowerLevel)1092 void HAL_RADIO_SetTxPower(uint8_t PowerLevel)
1093 {
1094   /* Check the parameters */
1095   assert_param(IS_POWERLEVEL_VALID(PowerLevel));
1096 
1097   for (uint8_t n = 0; n < STATEMACHINE_COUNT ; n++)
1098   {
1099     (bluedata + n)->PAPOWER = PowerLevel;
1100   }
1101   return;
1102 }
1103 
1104 
1105 /**
1106   * @brief  Restore default preamble length to one byte.
1107   * @param  StateMachineNo: state machine number in multi state.
1108   * @retval None
1109   */
HAL_RADIO_SetDefaultPreambleLen(uint8_t StateMachineNo)1110 void HAL_RADIO_SetDefaultPreambleLen(uint8_t StateMachineNo)
1111 {
1112   (bluedata + StateMachineNo)->BYTE34 &= ~(STATEMACH_BYTE34_ENAPREAMBLEREP_Msk);
1113   return;
1114 }
1115 
1116 /**
1117   * @brief  Set how many times repeat the preamble.
1118   * @param  StateMachineNo: state machine number in multi state.
1119   * @param  PreaLen: preamble length in byte for coded or uncoded phy.
1120   * @retval None
1121   */
HAL_RADIO_SetPreambleRep(uint8_t StateMachineNo,uint8_t PreaLen)1122 void HAL_RADIO_SetPreambleRep(uint8_t StateMachineNo, uint8_t PreaLen)
1123 {
1124   /* Check the parameters */
1125   assert_param(IS_PREALEN_VALID(PreaLen));
1126 
1127   (bluedata + StateMachineNo)->BYTE34 |= STATEMACH_BYTE34_ENAPREAMBLEREP_Msk;
1128   (bluedata + StateMachineNo)->BYTE34 |= (PreaLen & STATEMACH_BYTE34_PREAMBLEREP_Msk);
1129   return;
1130 }
1131 
1132 /**
1133   * @brief  Enable or disable the CRC hardware functionality.
1134   * By default the CRC hardware feature is enabled. So, it can be enabled again
1135   * if it has been disabled.
1136   * If disabled, the CRC will be neither checked in reception nor appended in transmission.
1137   * @warning ALPHA version. In reception just ignore the CRC error and don't use this feature.
1138   * @param  StateMachineNo: state machine number in multi state.
1139   * @param  hwCRC:
1140   *         - ENABLE: enable the CRC hardware feature.
1141   *         - DISABLE: disable the CRC hardware feature.
1142   * @retval None
1143   */
HAL_RADIO_DisableCRC(uint8_t StateMachineNo,FunctionalState hwCRC)1144 void HAL_RADIO_DisableCRC(uint8_t StateMachineNo, FunctionalState hwCRC)
1145 {
1146   if (hwCRC != DISABLE)
1147   {
1148     (bluedata + StateMachineNo)->BYTE34 &= ~STATEMACH_BYTE34_DISABLECRC_Msk;
1149   }
1150   else
1151   {
1152     (bluedata + StateMachineNo)->BYTE34 |= STATEMACH_BYTE34_DISABLECRC_Msk;
1153   }
1154   return;
1155 }
1156 
1157 /**
1158   * @brief  Starts tone transmission on selected channel.
1159   *         This API is dedicated for test and destroys context and multistate.
1160   *         So, after calling this function the radio should be re-initialized.
1161   * @param  RF_Channel: radio frequency channel number from 0 to 39.
1162   *         Note that RF channel index is different from ble channel index due to advertising channels,
1163   *         Please refer following table:
1164   *         RF channel 0:  2402 MHz -> ble channel index 37
1165   *         RF channel 1:  2404 MHz -> ble channel index 0
1166   *         RF channel 2:  2406 MHz -> ble channel index 1
1167   *         ...
1168   *         RF channel 11: 2424 MHz -> ble channel index 10
1169   *         RF channel 12: 2426 MHz -> ble channel index 38
1170   *         RF channel 13: 2428 MHz -> ble channel index 11
1171   *         RF channel 14: 2430 MHz -> ble channel index 12
1172   *         ...
1173   *         RF channel 38: 2478 MHz -> ble channel index 36
1174   *         RF channel 39: 2480 MHz -> ble channel index 39
1175   * @param  powerLevel: power level which should set.
1176   * @param  freq_offset: Specify if the tone must be emitted with an offset from the channel center frequency.
1177   *         If 0, the tone is emitted at the channel center frequency.
1178   *         If 1 or 2, the device will continuously emit the tone at the center
1179   *         frequency plus or minus 250 kHz respectively..
1180   * @retval None
1181   */
HAL_RADIO_StartTone(uint8_t RF_Channel,uint8_t powerLevel,uint8_t freq_offset)1182 uint8_t HAL_RADIO_StartTone(uint8_t RF_Channel, uint8_t powerLevel, uint8_t freq_offset)
1183 {
1184   /* Check the parameters */
1185   assert_param(IS_RFCHANNEL_VALID(RF_Channel));
1186   assert_param(IS_POWERLEVEL_VALID(powerLevel));
1187   assert_param(IS_FREQOFFSET_VALID(freq_offset)); /*TBR*/
1188 
1189   uint8_t retVal;
1190   uint32_t dummyTime;
1191 
1192   if (globalParameters.tone_start_stop_flag != 0U)
1193   {
1194     retVal = 1;
1195   }
1196   else
1197   {
1198     if ((RF_Channel >= 40U) || (freq_offset > 2U)) /*TBR*/
1199     {
1200       retVal = 1;
1201     }
1202     else
1203     {
1204       if (HAL_RADIO_GetStatus(&dummyTime) == BLUE_IDLE_0)
1205       {
1206         globalParameters.tone_start_stop_flag = 1;
1207         /* [EM:] Calculate the synt divide factor for 16 MHz quarts and +250 kHz offset wrt the channel center frequency
1208         *  Algorithmically MAK = F_rf*(2^20)/32 = F_rf*(2^15)
1209         *  With F_rf = (2402+2*RF_Channel)+0.25 MHz
1210         *  K corresponds to b19-b0  of MAK
1211         *  A corresponds to b22-b20 of MAK
1212         *  M corresponds to b27-b23 of MAK
1213         */
1214         uint32_t kHz_250_scaled = 8192; // = 0.250*2^20/32
1215         uint32_t MAK = ((2402UL + 2UL * RF_Channel) << 15);
1216 
1217         if (freq_offset == 1U)
1218         {
1219           MAK += kHz_250_scaled;
1220         }
1221         else if (freq_offset == 2U)
1222         {
1223           MAK -= kHz_250_scaled;
1224         }
1225         else
1226         {
1227         }
1228 
1229         uint8_t  M  = ((uint8_t)(MAK >> 23) & 0x1FU);
1230         uint8_t  A  = ((uint8_t)(MAK >> 20) & 0x07U);
1231         uint32_t K = (MAK & 0x000FFFFFUL) + 1UL;
1232 
1233         uint32_t MOD3_DIG_TEST = (M << 3) | (A & 0x7U);
1234         uint32_t MOD2_DIG_TEST = (K >> 12) & 0xFFU;
1235         uint32_t MOD1_DIG_TEST = (K >> 4) & 0xFFU;
1236         uint32_t MOD0_DIG_TEST = ((K & 0x0FU) << 4) | 0x09U;
1237         uint32_t RADIO_FSM_USR = ((powerLevel) << 3) | 0x06;
1238 
1239         RRM->RADIO_FSM_USR = RADIO_FSM_USR;
1240         RRM->MOD3_DIG_TST = MOD3_DIG_TEST;
1241         RRM->MOD2_DIG_TST = MOD2_DIG_TEST;
1242         RRM->MOD1_DIG_TST = MOD1_DIG_TEST;
1243         RRM->MOD0_DIG_TST = MOD0_DIG_TEST;
1244 
1245         /* Take control of the radio FSM through the test bus */
1246         RRM->DTB5_DIG_ENG = 0x09;
1247         uint32_t *rrm_udra_test = ((uint32_t *)&RRM->RRM_CTRL) + 0x01;
1248         *rrm_udra_test = 0x03;
1249         RRM->DTB5_DIG_ENG = 0x39;
1250         while (RRM->FSM_STATUS_DIG_OUT != 0x04);
1251         RRM->DTB5_DIG_ENG = 0x3B;
1252         retVal = 0;
1253       }
1254       else
1255       {
1256         retVal = 1;
1257       }
1258     }
1259   }
1260   return retVal;
1261 }
1262 
1263 /**
1264   * @brief  This routine stop tone transmission.
1265   *         This API is dedicated for test and destroys context and multistate.
1266   *         So, after calling this function the radio should be re-initialized.
1267   * @retval None
1268   */
HAL_RADIO_StopTone(void)1269 uint8_t HAL_RADIO_StopTone(void)
1270 {
1271   uint8_t retVal;
1272 
1273   if (globalParameters.tone_start_stop_flag != 0U)
1274   {
1275     globalParameters.tone_start_stop_flag = 0;
1276     /* Release control of the radio FSM through the test bus */
1277     RRM->DTB5_DIG_ENG = 0x00;
1278     uint32_t *rrm_udra_test = ((uint32_t *)&RRM->RRM_CTRL) + 0x01;
1279     *rrm_udra_test = 0x00;
1280     retVal = 0;
1281   }
1282   else
1283   {
1284     retVal = 1;
1285   }
1286   return retVal;
1287 }
1288 
1289 
1290 /**
1291   * @brief  Encrypts plain text data using AES encryption with given input key and
1292   *         128 bit block size
1293   * @param  Key: encryption key to be used.
1294   * @param  plainData: text data to be encrypted.
1295   * @param  cypherData: contains the encrypted data.
1296   * @retval None
1297   */
HAL_RADIO_EncryptPlainData(uint8_t * Key,uint8_t * plainData,uint8_t * cypherData)1298 void HAL_RADIO_EncryptPlainData(uint8_t *Key, uint8_t *plainData, uint8_t *cypherData)
1299 {
1300   uint32_t key[4] ;
1301   uint32_t cleartext[4] ;
1302   uint32_t ciphertext[4] ;
1303   volatile uint32_t ii ;
1304 
1305   for (uint8_t i = 0; i < 4; i++)
1306   {
1307     key[i] = ((uint32_t)Key[i * 4]) | ((uint32_t)Key[i * 4 + 1]) << 8 | ((uint32_t)Key[i * 4 + 2]) << 16 | ((uint32_t)Key[ i * 4 + 3]) << 24;
1308     cleartext[i] = ((uint32_t)plainData[i * 4]) | ((uint32_t)plainData[i * 4 + 1]) << 8 | ((uint32_t)plainData[i * 4 + 2]) << 16 | ((uint32_t)plainData[i * 4 + 3]) << 24;
1309   }
1310 
1311   BLUE->MANAESKEY0REG = key[3];
1312   BLUE->MANAESKEY1REG = key[2];
1313   BLUE->MANAESKEY2REG = key[1];
1314   BLUE->MANAESKEY3REG = key[0];
1315 
1316   BLUE->MANAESCLEARTEXT0REG = cleartext[3];
1317   BLUE->MANAESCLEARTEXT1REG = cleartext[2];
1318   BLUE->MANAESCLEARTEXT2REG = cleartext[1];
1319   BLUE->MANAESCLEARTEXT3REG = cleartext[0];
1320 
1321   BLUE->MANAESCMDREG = 1;
1322 
1323   ii = 0 ;
1324   while ((BLUE->MANAESSTATREG == 0) && ii < 100)
1325   {
1326     ii++;
1327   }
1328 
1329   ciphertext[0] = BLUE->MANAESCIPHERTEXT3REG;
1330   ciphertext[1] = BLUE->MANAESCIPHERTEXT2REG;
1331   ciphertext[2] = BLUE->MANAESCIPHERTEXT1REG;
1332   ciphertext[3] = BLUE->MANAESCIPHERTEXT0REG;
1333 
1334   for (uint8_t i = 0; i < 4; i++)
1335   {
1336     cypherData[i * 4] = ((uint8_t)ciphertext[i]);
1337     cypherData[i * 4 + 1] = (uint8_t)(ciphertext[i] >> 8);
1338     cypherData[i * 4 + 2] = (uint8_t)(ciphertext[i] >> 16);
1339     cypherData[i * 4 + 3] = (uint8_t)(ciphertext[i] >> 24);
1340   }
1341 
1342   return ;
1343 }
1344 
1345 
1346 /**
1347   * @brief  This routine sets the network ID field for packet transmission and filtering for the receiving.
1348   *         Only two devices with same networkID can communicate with each other.
1349   * @param  ID: network ID based on bluetooth specification:
1350   *           1. It shall have no more than six consecutive zeros or ones.
1351   *           2. It shall not have all four octets equal.
1352   *           3. It shall have no more than 24 transitions.
1353   *           4. It shall have a minimum of two transitions in the most significant six bits.
1354   *
1355   * @retval uint8_t: return value
1356   *           - 0x00 : Success.
1357   *           - 0xC0 : Invalid parameter.
1358   */
HAL_RADIO_SetNetworkID(uint32_t ID)1359 uint8_t HAL_RADIO_SetNetworkID(uint32_t ID)
1360 {
1361   networkID = ID;
1362   return 0;
1363 }
1364 
1365 
1366 /**
1367   * @brief  This routine sends a packet on a specific channel and at a specific time.
1368   * @param  channel: BLE channel index between 0 to 39.
1369   * @param  wakeup_time: Time of transmission in us. This is relative time regarding now.
1370   *         Minimum wakeup_time of 230 us. TBR
1371   * @param  txBuffer: Pointer to TX data buffer. Second byte of this buffer must be the length of the data.
1372   * @param  Callback: This function is being called as data routine.
1373   *         First ActionPacket is current action packet and the second one is next action packet.
1374   * @retval uint8_t return value
1375   *           - 0x00 : Success.
1376   *           - 0xC0 : Invalid parameter.
1377   *           - 0xC4 : Radio is busy, receiving has not been triggered.
1378   */
HAL_RADIO_SendPacket(uint8_t channel,uint32_t wakeup_time,uint8_t * txBuffer,uint8_t (* Callback)(ActionPacket *,ActionPacket *))1379 uint8_t HAL_RADIO_SendPacket(uint8_t channel, uint32_t wakeup_time, uint8_t *txBuffer,
1380                              uint8_t (*Callback)(ActionPacket *, ActionPacket *))
1381 {
1382   uint8_t returnValue = SUCCESS_0;
1383   uint32_t dummy;
1384   uint32_t time;
1385 
1386   time = (uint32_t)HAL_RADIO_TIMER_GetCurrentSysTime() + HAL_RADIO_TIMER_UsToSystime(wakeup_time);
1387 
1388   if (channel > 39)
1389   {
1390     returnValue = INVALID_PARAMETER_C0;
1391   }
1392 
1393   if (HAL_RADIO_GetStatus(&dummy) != BLUE_IDLE_0)
1394   {
1395     returnValue = RADIO_BUSY_C4;
1396   }
1397 
1398   if (returnValue == SUCCESS_0)
1399   {
1400     uint8_t map[5] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1401     HAL_RADIO_SetChannelMap(0, &map[0]);
1402     HAL_RADIO_SetChannel(0, channel, 0);
1403     HAL_RADIO_SetTxAttributes(0, networkID, 0x555555);
1404 
1405     aPacket[0].StateMachineNo = 0;
1406     aPacket[0].ActionTag =  TXRX | PLL_TRIG;
1407     aPacket[0].WakeupTime = time;
1408     aPacket[0].MaxReceiveLength = 0; /* does not affect for Tx */
1409     aPacket[0].data = txBuffer;
1410     aPacket[0].next_true = NULL_0;
1411     aPacket[0].next_false = NULL_0;
1412     aPacket[0].condRoutine = CondRoutineTrue;
1413     aPacket[0].dataRoutine = Callback;
1414 
1415     HAL_RADIO_SetReservedArea(&aPacket[0]);
1416     returnValue = HAL_RADIO_MakeActionPacketPending(&aPacket[0]);
1417   }
1418 
1419   return returnValue;
1420 }
1421 
1422 
1423 /**
1424   * @brief  This routine sends a packet on a specific channel and at a certain time then wait for receiving acknowledge.
1425   * @param  channel: BLE channel index between 0 to 39.
1426   * @param  wakeup_time: Time of transmission based on us. This is relative time regarding now.
1427   *         Minimum wakeup_time of 250 us. TBR
1428   * @param  txBuffer: Pointer to TX data buffer. Second byte of this buffer must be the length of the data.
1429   * @param  rxBuffer: Pointer to RX data buffer. Second byte of this buffer must be the length of the data.
1430   * @param  receive_timeout: Time of RX window used to wait for the packet on us.
1431   * @param  receive_length: number of bytes that the link layer accepts in reception.
1432   * @param  Callback: This function is being called as data routine.
1433   *         First ActionPacket is current action packet and the second one is next action packet.
1434   * @retval uint8_t return value
1435   *           - 0x00 : Success.
1436   *           - 0xC0 : Invalid parameter.
1437   *           - 0xC4 : Radio is busy, receiving has not been triggered.
1438   */
HAL_RADIO_SendPacketWithAck(uint8_t channel,uint32_t wakeup_time,uint8_t * txBuffer,uint8_t * rxBuffer,uint32_t receive_timeout,uint8_t receive_length,uint8_t (* Callback)(ActionPacket *,ActionPacket *))1439 uint8_t HAL_RADIO_SendPacketWithAck(uint8_t channel, uint32_t wakeup_time, uint8_t *txBuffer, uint8_t *rxBuffer,
1440                                     uint32_t receive_timeout,
1441                                     uint8_t receive_length,
1442                                     uint8_t (*Callback)(ActionPacket *, ActionPacket *))
1443 {
1444   uint8_t returnValue = SUCCESS_0;
1445   uint32_t dummy;
1446   uint32_t time;
1447 
1448   time = (uint32_t)HAL_RADIO_TIMER_GetCurrentSysTime() + HAL_RADIO_TIMER_UsToSystime(wakeup_time);
1449 
1450   if (channel > 39)
1451   {
1452     returnValue = INVALID_PARAMETER_C0;
1453   }
1454 
1455   if (HAL_RADIO_GetStatus(&dummy) != BLUE_IDLE_0)
1456   {
1457     returnValue = RADIO_BUSY_C4;
1458   }
1459 
1460   uint8_t map[5] = {0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
1461   HAL_RADIO_SetChannelMap(0, &map[0]);
1462   HAL_RADIO_SetChannel(0, channel, 0);
1463   HAL_RADIO_SetTxAttributes(0, networkID, 0x555555);
1464   HAL_RADIO_SetGlobalReceiveTimeout(receive_timeout);
1465 
1466   aPacket[0].StateMachineNo = 0;
1467   aPacket[0].ActionTag = TXRX | PLL_TRIG;
1468   aPacket[0].WakeupTime = time;
1469   aPacket[0].MaxReceiveLength = 0; /* does not affect for Tx */
1470   aPacket[0].data = txBuffer;
1471   aPacket[0].next_true = &aPacket[1];
1472   aPacket[0].next_false = &aPacket[1];
1473   aPacket[0].condRoutine = CondRoutineTrue;
1474   aPacket[0].dataRoutine = DataRoutineNull;
1475 
1476   aPacket[1].StateMachineNo = 0;
1477   aPacket[1].ActionTag = 0;
1478   aPacket[1].WakeupTime = time;
1479   aPacket[1].MaxReceiveLength = receive_length;
1480   aPacket[1].data = rxBuffer;
1481   aPacket[1].next_true = NULL_0;
1482   aPacket[1].next_false = NULL_0;
1483   aPacket[1].condRoutine = CondRoutineTrue;
1484   aPacket[1].dataRoutine = Callback;
1485 
1486   HAL_RADIO_SetReservedArea(&aPacket[0]);
1487   HAL_RADIO_SetReservedArea(&aPacket[1]);
1488   returnValue = HAL_RADIO_MakeActionPacketPending(&aPacket[0]);
1489 
1490   return returnValue;
1491 }
1492 
1493 #if defined (STM32WB06) || defined (STM32WB07)
1494 
CarrierSenseCallback(ActionPacket * p,ActionPacket * next)1495 static uint8_t CarrierSenseCallback(ActionPacket *p, ActionPacket *next)
1496 {
1497   return TRUE;
1498 }
1499 
1500 /**
1501   * @brief  This function puts the radio in RX state to read the RSSI.
1502   * @note   The function uses a busy loop to wait for the RSSI value and then exits
1503   *         from RX state.
1504   * @param      channel: BLE channel index between 0 to 39.
1505   * @param[out] rssi: the measured RSSI value on the channel
1506   * @retval uint8_t return value
1507   *           - 0x00 : Success.
1508   *           - 0xC0 : Invalid parameter.
1509   *           - 0xC4 : Radio is busy, receiving has not been triggered.
1510   */
HAL_RADIO_CarrierSense(uint8_t channel,int8_t * rssi)1511 uint8_t HAL_RADIO_CarrierSense(uint8_t channel, int8_t *rssi)
1512 {
1513   uint8_t ret;
1514   uint16_t loop = 0;
1515   uint32_t *DEMOD_DIG_TST_p = (uint32_t *)0x60001564;
1516   uint32_t end_time;
1517   static uint8_t buffer[1];
1518 
1519   *rssi = 127;
1520 
1521   uint32_t networkID_tmp = networkID;
1522 
1523   networkID = FAKE_NETWORK_ID;
1524 
1525   ret = HAL_RADIO_ReceivePacket(channel, 300, buffer, 1000, sizeof(buffer), CarrierSenseCallback);
1526 
1527   networkID = networkID_tmp;
1528 
1529   if (ret)
1530   {
1531     return ret;
1532   }
1533 
1534   /* loop variable just to protect from infinite loop */
1535   while ((RRM->FSM_STATUS_DIG_OUT & RRM_FSM_STATUS_DIG_OUT_STATUS) != 0x1A && loop++ < 60000);
1536   end_time = WAKEUP->ABSOLUTE_TIME + 20;
1537   while (TIME_DIFF(end_time, WAKEUP->ABSOLUTE_TIME) > 0);
1538   *DEMOD_DIG_TST_p = 0x02;
1539   /* Need to wait at least 3 BLE clocks. In worst case (sysclock = 64 MHz and blesysclk = 16 MHz)
1540      this means 12 cpu cycles. Some cycles are already used by the call to HAL_RADIO_ReadRSSI()
1541      and at the beginning of the function. */
1542   __NOP();
1543   __NOP();
1544   __NOP();
1545   __NOP();
1546   __NOP();
1547   __NOP();
1548   __NOP();
1549   __NOP();
1550   *rssi = HAL_RADIO_ReadRSSI();
1551   *DEMOD_DIG_TST_p = 0x00;
1552   BLUE->CMDREG = BLUE_CMDREG_TXRXSKIP;
1553 
1554   return 0;
1555 }
1556 
1557 #elif defined(STM32WB05) || defined(STM32WB09 )
1558 
1559 static volatile int8_t _rssi;
1560 static volatile uint8_t _timeout;
1561 
CarrierSenseCallback(ActionPacket * p,ActionPacket * next)1562 static uint8_t CarrierSenseCallback(ActionPacket *p, ActionPacket *next)
1563 {
1564   _rssi = 127;
1565 
1566   if ((p->status & BLUE_INTERRUPT1REG_DONE) && (p->status & BLUE_STATUSREG_PREVTRANSMIT) == 0 &&
1567       ((p->status & BLUE_INTERRUPT1REG_RCVOK) || (p->status & BLUE_INTERRUPT1REG_RCVTIMEOUT)
1568        || (p->status & BLUE_INTERRUPT1REG_RCVCRCERR)))
1569   {
1570     _rssi = p->rssi;
1571   }
1572   _timeout = TRUE;
1573 
1574   return TRUE;
1575 }
1576 
1577 /**
1578   * @brief  This function puts the radio in RX state to read the RSSI.
1579   * @note   The function uses a busy loop to wait for the RSSI value and then exits
1580   *         from RX state.
1581   * @param      channel: BLE channel index between 0 to 39.
1582   * @param[out] rssi: the measured RSSI value on the channel
1583   * @retval uint8_t return value
1584   *           - 0x00 : Success.
1585   *           - 0xC0 : Invalid parameter.
1586   *           - 0xC4 : Radio is busy, receiving has not been triggered.
1587   */
HAL_RADIO_CarrierSense(uint8_t channel,int8_t * rssi)1588 uint8_t HAL_RADIO_CarrierSense(uint8_t channel, int8_t *rssi)
1589 {
1590   uint8_t ret;
1591   uint16_t loop = 0;
1592   static uint8_t buffer[1];
1593 
1594   *rssi = 127;
1595 
1596   uint32_t networkID_tmp = networkID;
1597 
1598   networkID = FAKE_NETWORK_ID;
1599 
1600   _timeout = FALSE;
1601 
1602   ret = HAL_RADIO_ReceivePacket(channel, 300, buffer, 5, sizeof(buffer), CarrierSenseCallback);
1603 
1604   networkID = networkID_tmp;
1605 
1606   if (ret)
1607   {
1608     return ret;
1609   }
1610 
1611   /* loop variable just to protect from infinite loop */
1612   while (_timeout == FALSE && loop++ < 60000);
1613   *rssi = _rssi;
1614 
1615   return 0;
1616 }
1617 
1618 #endif
1619 
1620 /**
1621   * @brief  This routine receives a packet on a specific channel and at a certain time.
1622   * @param  channel: BLE channel index between 0 to 39.
1623   * @param  wakeup_time: Time of transmission based on us. This is relative time regarding now.
1624   *         Minimum wakeup_time of 230 us. TBR
1625   * @param  rxBuffer: Pointer to RX data buffer. Second byte of this buffer must be the length of the data.
1626   * @param  receive_timeout: Time of RX window used to wait for the packet on us.
1627   * @param  receive_length: number of bytes that the link layer accepts in reception.
1628   * @param  Callback: This function is being called as data routine.
1629   *         First ActionPacket is current action packet and the second one is next action packet.
1630   * @retval uint8_t return value
1631   *           - 0x00 : Success.
1632   *           - 0xC0 : Invalid parameter.
1633   *           - 0xC4 : Radio is busy, receiving has not been triggered.
1634   */
HAL_RADIO_ReceivePacket(uint8_t channel,uint32_t wakeup_time,uint8_t * rxBuffer,uint32_t receive_timeout,uint8_t receive_length,uint8_t (* Callback)(ActionPacket *,ActionPacket *))1635 uint8_t HAL_RADIO_ReceivePacket(uint8_t channel, uint32_t wakeup_time, uint8_t *rxBuffer, uint32_t receive_timeout,
1636                                 uint8_t receive_length,
1637                                 uint8_t (*Callback)(ActionPacket *, ActionPacket *))
1638 {
1639   uint8_t returnValue = SUCCESS_0;
1640   uint32_t dummy;
1641   uint32_t time;
1642   time = (uint32_t)HAL_RADIO_TIMER_GetCurrentSysTime() + HAL_RADIO_TIMER_UsToSystime(wakeup_time);
1643 
1644   if (channel > 39)
1645   {
1646     returnValue = INVALID_PARAMETER_C0;
1647   }
1648 
1649   if (HAL_RADIO_GetStatus(&dummy) != BLUE_IDLE_0)
1650   {
1651     returnValue = RADIO_BUSY_C4;
1652   }
1653 
1654   if (returnValue == SUCCESS_0)
1655   {
1656     uint8_t map[5] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1657     HAL_RADIO_SetChannelMap(0, &map[0]);
1658     HAL_RADIO_SetChannel(0, channel, 0);
1659     HAL_RADIO_SetTxAttributes(0, networkID, 0x555555);
1660     HAL_RADIO_SetGlobalReceiveTimeout(receive_timeout);
1661 
1662 
1663     aPacket[0].StateMachineNo = 0;
1664     aPacket[0].ActionTag =  PLL_TRIG;
1665     aPacket[0].WakeupTime = time;
1666     aPacket[0].MaxReceiveLength = receive_length;
1667     aPacket[0].data = rxBuffer;
1668     aPacket[0].next_true = NULL_0;
1669     aPacket[0].next_false = NULL_0;
1670     aPacket[0].condRoutine = CondRoutineTrue;
1671     aPacket[0].dataRoutine = Callback;
1672 
1673     HAL_RADIO_SetReservedArea(&aPacket[0]);
1674     returnValue = HAL_RADIO_MakeActionPacketPending(&aPacket[0]);
1675   }
1676 
1677   return returnValue;
1678 }
1679 
1680 /**
1681   * @brief  This routine receives a packet on a specific channel and at a certain time.
1682   *         Then sends a packet as an acknowledgment.
1683   * @param  channel: BLE channel index between 0 to 39.
1684   * @param  wakeup_time: time of transmission based on us. This is relative time regarding now.
1685   *         Minimum wakeup_time of 250 us. TBR
1686   * @param  rxBuffer: points to received data buffer. second byte of this buffer determines the length of the data.
1687   * @param  txBuffer: points to data buffer to send. second byte of this buffer must be the length of the buffer.
1688   * @param  receive_timeout: Time of RX window used to wait for the packet on us.
1689   * @param  receive_length: number of bytes that the link layer accepts in reception.
1690   * @param  Callback: This function is being called as data routine.
1691   *         First ActionPacket is current action packet and the second one is next action packet.
1692   * @retval uint8_t return value
1693   *           - 0x00 : Success.
1694   *           - 0xC0 : Invalid parameter.
1695   *           - 0xC4 : Radio is busy, receiving has not been triggered.
1696   */
HAL_RADIO_ReceivePacketWithAck(uint8_t channel,uint32_t wakeup_time,uint8_t * rxBuffer,uint8_t * txBuffer,uint32_t receive_timeout,uint8_t receive_length,uint8_t (* Callback)(ActionPacket *,ActionPacket *))1697 uint8_t HAL_RADIO_ReceivePacketWithAck(uint8_t channel, uint32_t wakeup_time, uint8_t *rxBuffer, uint8_t *txBuffer,
1698                                        uint32_t receive_timeout,
1699                                        uint8_t receive_length,
1700                                        uint8_t (*Callback)(ActionPacket *, ActionPacket *))
1701 {
1702   uint8_t returnValue = SUCCESS_0;
1703   uint32_t dummy;
1704   uint32_t time;
1705 
1706   time = (uint32_t)HAL_RADIO_TIMER_GetCurrentSysTime() + HAL_RADIO_TIMER_UsToSystime(wakeup_time);
1707 
1708   if (channel > 39)
1709   {
1710     returnValue = INVALID_PARAMETER_C0;
1711   }
1712 
1713   if (HAL_RADIO_GetStatus(&dummy) != BLUE_IDLE_0)
1714   {
1715     returnValue = RADIO_BUSY_C4;
1716   }
1717 
1718   if (returnValue == SUCCESS_0)
1719   {
1720     uint8_t map[5] = {0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
1721 
1722     HAL_RADIO_SetChannelMap(0, &map[0]);
1723     HAL_RADIO_SetChannel(0, channel, 0);
1724     HAL_RADIO_SetTxAttributes(0, networkID, 0x555555);
1725     HAL_RADIO_SetGlobalReceiveTimeout(receive_timeout);
1726 
1727     aPacket[0].StateMachineNo = 0;
1728     aPacket[0].ActionTag =  PLL_TRIG;
1729     aPacket[0].WakeupTime = time;
1730     aPacket[0].MaxReceiveLength = receive_length;
1731     aPacket[0].data = rxBuffer;
1732     aPacket[0].next_true = &aPacket[1];
1733     aPacket[0].next_false = NULL_0;
1734     aPacket[0].condRoutine = CondRoutineRxTrue;
1735     aPacket[0].dataRoutine = Callback;
1736 
1737     aPacket[1].StateMachineNo = 0;
1738     aPacket[1].ActionTag =  TXRX;
1739     aPacket[1].WakeupTime = time;
1740     aPacket[1].MaxReceiveLength = 0; /* does not affect for Tx */
1741     aPacket[1].data = txBuffer;
1742     aPacket[1].next_true = NULL_0;
1743     aPacket[1].next_false = NULL_0;
1744     aPacket[1].condRoutine = CondRoutineTrue;
1745     aPacket[1].dataRoutine = Callback;
1746 
1747     HAL_RADIO_SetReservedArea(&aPacket[0]);
1748     HAL_RADIO_SetReservedArea(&aPacket[1]);
1749     returnValue = HAL_RADIO_MakeActionPacketPending(&aPacket[0]);
1750   }
1751 
1752   return returnValue;
1753 }
1754 
1755 #endif /* USE_RADIO_PROPRIETARY_DRIVER */
1756 
HAL_RADIO_TxRxCallback(uint32_t flags)1757 __weak void HAL_RADIO_TxRxCallback(uint32_t flags)
1758 {
1759 }
1760 
1761 
HAL_RADIO_TxRxSeqCallback(void)1762 __weak void HAL_RADIO_TxRxSeqCallback(void)
1763 {
1764 }
1765 
HAL_RADIO_TXRX_IRQHandler(void)1766 void HAL_RADIO_TXRX_IRQHandler(void)
1767 {
1768   uint32_t blue_status = BLUE->STATUSREG;
1769   uint32_t blue_interrupt = BLUE->INTERRUPT1REG;
1770 
1771   /** clear all pending interrupts */
1772   BLUE->INTERRUPT1REG = blue_interrupt;
1773 
1774   HAL_RADIO_TIMER_EndOfRadioActivityIsr();
1775 
1776 #if (USE_RADIO_PROPRIETARY_DRIVER == 1)
1777   HAL_RADIO_ActionPacketIsr(blue_status | blue_interrupt);
1778 #endif
1779 
1780   HAL_RADIO_TxRxCallback(blue_status | blue_interrupt);
1781 
1782   HAL_RADIO_TIMER_RadioTimerIsr();
1783 
1784   /* If the device is configured with
1785      System clock = 64 MHz and BLE clock = 16 MHz
1786      a register read is necessary to end fine
1787      the clear interrupt register operation,
1788      due the AHB down converter latency */
1789   blue_interrupt = BLUE->INTERRUPT1REG;
1790 }
1791 
1792 
HAL_RADIO_TXRX_SEQ_IRQHandler(void)1793 void HAL_RADIO_TXRX_SEQ_IRQHandler(void)
1794 {
1795   HAL_RADIO_TxRxSeqCallback();
1796 }
1797 
1798 /**
1799   * @}
1800   */
1801 
1802 /**
1803   * @}
1804   */
1805 
1806 /**
1807   * @}
1808   */
1809