1 /*******************************************************************************
2 * @file stm32wlxx_hal_subghz.c
3 * @author MCD Application Team
4 * @brief SUBGHZ HAL module driver.
5 * This file provides firmware functions to manage the following
6 * functionalities of the SUBGHZ peripheral:
7 * + Initialization and de-initialization functions
8 * + IO operation functions
9 * + Peripheral State and Errors functions
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2020 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 @verbatim
23 ==============================================================================
24 ##### How to use this driver #####
25 ==============================================================================
26 [..]
27 The SUBGHZ HAL driver can be used as follows:
28
29 (#) Declare a SUBGHZ_HandleTypeDef handle structure, for example:
30 SUBGHZ_HandleTypeDef hUserSubghz;
31
32 (#) Initialize the SUBGHZ low level resources by implementing the @ref HAL_SUBGHZ_MspInit() API:
33 (##) PWR configuration
34 (+++) Enable the SUBGHZSPI interface clock
35 (+++) Enable wakeup signal of the Radio peripheral
36 (##) NVIC configuration:
37 (+++) Enable the NVIC Radio IRQ ITs for CPU1 (EXTI 44)
38 (+++) Configure the Radio interrupt priority
39
40 (#) Initialize the SUBGHZ handle and SUBGHZSPI SPI registers by calling the @ref HAL_SUBGHZ_Init(&hUserSubghz),
41 configures also the low level Hardware (GPIO, CLOCK, NVIC...etc) by calling
42 the customized @ref HAL_SUBGHZ_MspInit() API.
43
44 (#) For SUBGHZ IO operations, polling operation modes is available within this driver :
45
46 *** Polling mode IO operation ***
47 =====================================
48 [..]
49 (+) Set and execute a command in blocking mode using @ref HAL_SUBGHZ_ExecSetCmd()
50 (+) Get a status blocking mode using @ref HAL_SUBGHZ_ExecGetCmd()
51 (+) Write a Data Buffer in blocking mode using @ref HAL_SUBGHZ_WriteBuffer()
52 (+) Read a Data Buffer in blocking mode using @ref HAL_SUBGHZ_ReadBuffer()
53 (+) Write Registers (more than 1 byte) in blocking mode using @ref HAL_SUBGHZ_WriteRegisters()
54 (+) Read Registers (more than 1 byte) in blocking mode using @ref HAL_SUBGHZ_ReadRegisters()
55 (+) Write Register (1 byte) in blocking mode using @ref HAL_SUBGHZ_WriteRegister()
56 (+) Read Register (1 byte) in blocking mode using @ref HAL_SUBGHZ_ReadRegister()
57
58 *** SUBGHZ HAL driver macros list ***
59 =====================================
60 [..]
61 (+) @ref __HAL_SUBGHZ_RESET_HANDLE_STATE: Reset the SUBGHZ handle state
62
63 #if defined(GENERATOR_CALLBACK_REGISTERING_PRESENT)
64 *** SUBGHZ Callback registration ***
65 =====================================
66
67 [..]
68 The compilation flag USE_HAL_SUBGHZ_REGISTER_CALLBACKS when set to 1
69 allows the user to configure dynamically the driver callbacks.
70 Use Functions @ref HAL_SUBGHZ_RegisterCallback() or @ref HAL_SUBGHZ_RegisterAddrCallback()
71 to register an interrupt callback.
72
73 [..]
74 Function @ref HAL_SUBGHZ_RegisterCallback() allows to register following callbacks:
75 (+) TxCpltCallback : callback for Tx Completed.
76 (+) RxCpltCallback : callback for Rx Completed.
77 (+) PreambleDetectedCallback : callback for Preamble detected.
78 (+) SyncWordValidCallback : callback for Synchro word valid.
79 (+) HeaderValidCallback : callback for Header valid.
80 (+) HeaderErrorCallback : callback for Header error.
81 (+) CRCErrorCallback : callback for CRC Error.
82 (+) RxTxTimeoutCallback : callback for Rx Tx Timeout.
83 (+) MspInitCallback : callback for Msp Init.
84 (+) MspDeInitCallback : callback for Msp DeInit.
85 (+) LrFhssHopCallback : callback for LoRa Frequency Hopping Spread Spectrum Hopping.
86 This function takes as parameters the HAL peripheral handle, the Callback ID
87 and a pointer to the user callback function.
88 [..]
89 For specific callback CADStatusCallback use dedicated register callbacks :
90 @ref HAL_SUBGHZ_RegisterCadStatusCallback().
91 [..]
92 Use function @ref HAL_SUBGHZ_UnRegisterCallback to reset a callback to the default
93 weak function.
94 @ref HAL_SUBGHZ_UnRegisterCallback takes as parameters the HAL peripheral handle,
95 and the Callback ID.
96 This function allows to reset following callbacks:
97 (+) TxCpltCallback : callback for Tx Completed.
98 (+) RxCpltCallback : callback for Rx Completed.
99 (+) PreambleDetectedCallback : callback for Preamble detected.
100 (+) SyncWordValidCallback : callback for Synchro word valid.
101 (+) HeaderValidCallback : callback for Header valid.
102 (+) HeaderErrorCallback : callback for Header error.
103 (+) CRCErrorCallback : callback for CRC Error.
104 (+) RxTxTimeoutCallback : callback for Rx Tx Timeout.
105 (+) MspInitCallback : callback for Msp Init.
106 (+) MspDeInitCallback : callback for Msp DeInit.
107 (+) LrFhssHopCallback : callback for LoRa Frequency Hopping Spread Spectrum Hopping.
108 [..]
109 For specific callback CADStatusCallback use dedicated register callbacks :
110 @ref HAL_SUBGHZ_UnRegisterCadStatusCallback().
111 [..]
112 MspInit and MspDeInit functions are reset to the legacy weak functions in the
113 @ref HAL_SUBGHZ_Init()/ @ref HAL_SUBGHZ_DeInit() only when these callbacks are null
114 (not registered beforehand).
115 If MspInit or MspDeInit are not null, the @ref HAL_SUBGHZ_Init()/ @ref HAL_SUBGHZ_DeInit()
116 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
117
118 [..]
119 Callbacks for MspInit/MspDeInit functions can be registered/unregistered
120 in @ref HAL_SUBGHZ_STATE_READY or @ref HAL_SUBGHZ_STATE_RESET state,
121 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
122 Then, the user first registers the MspInit/MspDeInit user callbacks
123 using @ref HAL_SUBGHZ_RegisterCallback() before calling @ref HAL_SUBGHZ_DeInit()
124 or @ref HAL_SUBGHZ_Init() function.
125
126 [..]
127 When the compilation flag USE_HAL_SUBGHZ_REGISTER_CALLBACKS is set to 0 or
128 not defined, the callback registration feature is not available and all callbacks
129 are set to the corresponding weak functions.
130 #endif
131 */
132
133 /* Includes ------------------------------------------------------------------*/
134 #include "stm32wlxx_hal.h"
135
136 /** @addtogroup STM32WLxx_HAL_Driver
137 * @{
138 */
139
140 /** @defgroup SUBGHZ SUBGHZ
141 * @brief SUBGHZ HAL module driver
142 * @{
143 */
144 #ifdef HAL_SUBGHZ_MODULE_ENABLED
145
146 /* Private typedef -----------------------------------------------------------*/
147 /* Private defines -----------------------------------------------------------*/
148 /** @defgroup SUBGHZ_Private_Constants SUBGHZ Private Constants
149 * @{
150 */
151 #define SUBGHZ_DEFAULT_TIMEOUT 100U /* HAL Timeout in ms */
152 #define SUBGHZ_DUMMY_DATA 0xFFU /* SUBGHZSPI Dummy Data use for Tx */
153 #define SUBGHZ_DEEP_SLEEP_ENABLE 1U /* SUBGHZ Radio in Deep Sleep */
154 #define SUBGHZ_DEEP_SLEEP_DISABLE 0U /* SUBGHZ Radio not in Deep Sleep */
155
156 /* SystemCoreClock dividers. Corresponding to time execution of while loop. */
157 #define SUBGHZ_DEFAULT_LOOP_TIME ((SystemCoreClock*28U)>>19U)
158 #define SUBGHZ_RFBUSY_LOOP_TIME ((SystemCoreClock*24U)>>20U)
159 #define SUBGHZ_NSS_LOOP_TIME ((SystemCoreClock*24U)>>16U)
160 /**
161 * @}
162 */
163
164 /* Private macros ------------------------------------------------------------*/
165 /* Private variables ---------------------------------------------------------*/
166 /* Private function prototypes -----------------------------------------------*/
167 /** @defgroup SUBGHZ_Private_Functions SUBGHZ Private Functions
168 * @{
169 */
170 void SUBGHZSPI_Init(uint32_t BaudratePrescaler);
171 void SUBGHZSPI_DeInit(void);
172 HAL_StatusTypeDef SUBGHZSPI_Transmit(SUBGHZ_HandleTypeDef *hsubghz, uint8_t Data);
173 HAL_StatusTypeDef SUBGHZSPI_Receive(SUBGHZ_HandleTypeDef *hsubghz, uint8_t *pData);
174 HAL_StatusTypeDef SUBGHZ_WaitOnBusy(SUBGHZ_HandleTypeDef *hsubghz);
175 HAL_StatusTypeDef SUBGHZ_CheckDeviceReady(SUBGHZ_HandleTypeDef *hsubghz);
176 /**
177 * @}
178 */
179
180 /* Exported functions --------------------------------------------------------*/
181 /** @defgroup SUBGHZ_Exported_Functions SUBGHZ Exported Functions
182 * @{
183 */
184
185 /** @defgroup SUBGHZ_Exported_Functions_Group1 Initialization and de-initialization functions
186 * @brief Initialization and Configuration functions
187 *
188 @verbatim
189 ===============================================================================
190 ##### Initialization and de-initialization functions #####
191 ===============================================================================
192 [..] This subsection provides a set of functions allowing to initialize and
193 de-initialize the SUBGHZ peripheral:
194
195 (+) User must implement HAL_SUBGHZ_MspInit() function in which he configures
196 all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
197
198 (+) Call the function HAL_SUBGHZ_Init() to configure SUBGHZSPI peripheral
199 and initialize SUBGHZ Handle.
200
201 (+) Call the function HAL_SUBGHZ_DeInit() to restore the default configuration
202 of the SUBGHZ peripheral.
203
204 @endverbatim
205 * @{
206 */
207
208 /**
209 * @brief Initialize the SUBGHZ according to the specified parameters
210 * in the SUBGHZ_HandleTypeDef and initialize the associated handle.
211 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
212 * the handle information for SUBGHZ module.
213 * @note In case of exiting from Standby mode, before calling this function,
214 * set the state to HAL_SUBGHZ_STATE_RESET_RF_READY with __HAL_SUBGHZ_RESET_HANDLE_STATE_RF_READY
215 * to avoid the reset of Radio peripheral.
216 * @retval HAL status
217 */
HAL_SUBGHZ_Init(SUBGHZ_HandleTypeDef * hsubghz)218 HAL_StatusTypeDef HAL_SUBGHZ_Init(SUBGHZ_HandleTypeDef *hsubghz)
219 {
220 HAL_StatusTypeDef status;
221 __IO uint32_t count;
222 HAL_SUBGHZ_StateTypeDef subghz_state;
223
224 /* Check the hsubghz handle allocation */
225 if (hsubghz == NULL)
226 {
227 status = HAL_ERROR;
228 return status;
229 }
230 else
231 {
232 status = HAL_OK;
233 }
234
235 assert_param(IS_SUBGHZSPI_BAUDRATE_PRESCALER(hsubghz->Init.BaudratePrescaler));
236
237 subghz_state = hsubghz->State;
238 if ((subghz_state == HAL_SUBGHZ_STATE_RESET) ||
239 (subghz_state == HAL_SUBGHZ_STATE_RESET_RF_READY))
240 {
241 /* Allocate lock resource and initialize it */
242 hsubghz->Lock = HAL_UNLOCKED;
243
244 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1)
245 /* Init the SUBGHZ Legacy weak Callback settings */
246 hsubghz->TxCpltCallback = HAL_SUBGHZ_TxCpltCallback;
247 hsubghz->RxCpltCallback = HAL_SUBGHZ_RxCpltCallback;
248 hsubghz->PreambleDetectedCallback = HAL_SUBGHZ_PreambleDetectedCallback;
249 hsubghz->SyncWordValidCallback = HAL_SUBGHZ_SyncWordValidCallback;
250 hsubghz->HeaderValidCallback = HAL_SUBGHZ_HeaderValidCallback;
251 hsubghz->HeaderErrorCallback = HAL_SUBGHZ_HeaderErrorCallback;
252 hsubghz->CRCErrorCallback = HAL_SUBGHZ_CRCErrorCallback;
253 hsubghz->CADStatusCallback = HAL_SUBGHZ_CADStatusCallback;
254 hsubghz->RxTxTimeoutCallback = HAL_SUBGHZ_RxTxTimeoutCallback;
255 hsubghz->LrFhssHopCallback = HAL_SUBGHZ_LrFhssHopCallback;
256
257 if (hsubghz->MspInitCallback == NULL)
258 {
259 hsubghz->MspInitCallback = HAL_SUBGHZ_MspInit; /* Legacy weak MspInit */
260 }
261
262 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
263 hsubghz->MspInitCallback(hsubghz);
264 #else
265 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
266 HAL_SUBGHZ_MspInit(hsubghz);
267 #endif /* USE_HAL_ SUBGHZ_REGISTER_CALLBACKS */
268
269 #if defined(CM0PLUS)
270 /* Enable EXTI 44 : Radio IRQ ITs for CPU2 */
271 LL_C2_EXTI_EnableIT_32_63(LL_EXTI_LINE_44);
272 #else
273 /* Enable EXTI 44 : Radio IRQ ITs for CPU1 */
274 LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_44);
275 #endif /* CM0PLUS */
276 }
277
278 if (subghz_state == HAL_SUBGHZ_STATE_RESET)
279 {
280 /* Reinitialize Radio peripheral only if SUBGHZ is in full RESET state */
281 hsubghz->State = HAL_SUBGHZ_STATE_BUSY;
282
283 /* De-asserts the reset signal of the Radio peripheral */
284 LL_RCC_RF_DisableReset();
285
286 /* Verify that Radio in reset status flag is set */
287 count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME;
288
289 do
290 {
291 if (count == 0U)
292 {
293 status = HAL_ERROR;
294 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT;
295 break;
296 }
297 count--;
298 } while (LL_RCC_IsRFUnderReset() != 0UL);
299
300 /* Asserts the reset signal of the Radio peripheral */
301 LL_PWR_UnselectSUBGHZSPI_NSS();
302
303 #if defined(CM0PLUS)
304 /* Enable wakeup signal of the Radio peripheral */
305 LL_C2_PWR_SetRadioBusyTrigger(LL_PWR_RADIO_BUSY_TRIGGER_WU_IT);
306 #else
307 /* Enable wakeup signal of the Radio peripheral */
308 LL_PWR_SetRadioBusyTrigger(LL_PWR_RADIO_BUSY_TRIGGER_WU_IT);
309 #endif /* CM0PLUS */
310 }
311
312 /* Clear Pending Flag */
313 LL_PWR_ClearFlag_RFBUSY();
314
315 if (status == HAL_OK)
316 {
317 /* Initialize SUBGHZSPI Peripheral */
318 SUBGHZSPI_Init(hsubghz->Init.BaudratePrescaler);
319
320 hsubghz->DeepSleep = SUBGHZ_DEEP_SLEEP_ENABLE;
321 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_NONE;
322 }
323
324 hsubghz->State = HAL_SUBGHZ_STATE_READY;
325
326 return status;
327 }
328
329 /**
330 * @brief De-Initialize the SUBGHZ peripheral.
331 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
332 * the handle information for SUBGHZ module.
333 * @retval HAL status
334 */
HAL_SUBGHZ_DeInit(SUBGHZ_HandleTypeDef * hsubghz)335 HAL_StatusTypeDef HAL_SUBGHZ_DeInit(SUBGHZ_HandleTypeDef *hsubghz)
336 {
337 HAL_StatusTypeDef status;
338 __IO uint32_t count;
339
340 /* Check the SUBGHZ handle allocation */
341 if (hsubghz == NULL)
342 {
343 status = HAL_ERROR;
344 return status;
345 }
346 else
347 {
348 status = HAL_OK;
349 }
350
351 hsubghz->State = HAL_SUBGHZ_STATE_BUSY;
352
353 /* DeInitialize SUBGHZSPI Peripheral */
354 SUBGHZSPI_DeInit();
355
356 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1)
357 if (hsubghz->MspDeInitCallback == NULL)
358 {
359 hsubghz->MspDeInitCallback = HAL_SUBGHZ_MspDeInit; /* Legacy weak MspDeInit */
360 }
361
362 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
363 hsubghz->MspDeInitCallback(hsubghz);
364 #else
365 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
366 HAL_SUBGHZ_MspDeInit(hsubghz);
367 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
368
369 #if defined(CM0PLUS)
370 /* Disable EXTI 44 : Radio IRQ ITs for CPU2 */
371 LL_C2_EXTI_DisableIT_32_63(LL_EXTI_LINE_44);
372
373 /* Disable wakeup signal of the Radio peripheral */
374 LL_C2_PWR_SetRadioBusyTrigger(LL_PWR_RADIO_BUSY_TRIGGER_NONE);
375 #else
376 /* Disable EXTI 44 : Radio IRQ ITs for CPU1 */
377 LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_44);
378
379 /* Disable wakeup signal of the Radio peripheral */
380 LL_PWR_SetRadioBusyTrigger(LL_PWR_RADIO_BUSY_TRIGGER_NONE);
381 #endif /* CM0PLUS */
382
383 /* Clear Pending Flag */
384 LL_PWR_ClearFlag_RFBUSY();
385
386 /* Re-asserts the reset signal of the Radio peripheral */
387 LL_RCC_RF_EnableReset();
388
389 /* Verify that Radio in reset status flag is set */
390 count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME;
391
392 do
393 {
394 if (count == 0U)
395 {
396 status = HAL_ERROR;
397 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT;
398 break;
399 }
400 count--;
401 } while (LL_RCC_IsRFUnderReset() != 1UL);
402
403 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_NONE;
404 hsubghz->State = HAL_SUBGHZ_STATE_RESET;
405
406 /* Release Lock */
407 __HAL_UNLOCK(hsubghz);
408
409 return status;
410 }
411
412 /**
413 * @brief Initialize the SUBGHZ MSP.
414 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
415 * the handle information for SUBGHZ module.
416 * @retval None
417 */
HAL_SUBGHZ_MspInit(SUBGHZ_HandleTypeDef * hsubghz)418 __weak void HAL_SUBGHZ_MspInit(SUBGHZ_HandleTypeDef *hsubghz)
419 {
420 /* NOTE : This function should not be modified, when the callback is needed,
421 the HAL_SUBGHZ_MspInit should be implemented in the user file
422 */
423
424 /* Prevent unused argument(s) compilation warning */
425 UNUSED(hsubghz);
426 }
427
428 /**
429 * @brief De-Initialize the SUBGHZ MSP.
430 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
431 * the handle information for SUBGHZ module.
432 * @retval None
433 */
HAL_SUBGHZ_MspDeInit(SUBGHZ_HandleTypeDef * hsubghz)434 __weak void HAL_SUBGHZ_MspDeInit(SUBGHZ_HandleTypeDef *hsubghz)
435 {
436 /* NOTE : This function should not be modified, when the callback is needed,
437 the HAL_SUBGHZ_MspDeInit should be implemented in the user file
438 */
439
440 /* Prevent unused argument(s) compilation warning */
441 UNUSED(hsubghz);
442 }
443
444 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1)
445 /**
446 * @brief Register a User SUBGHZ Callback
447 * To be used instead of the weak predefined callback
448 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
449 * the configuration information for the specified SUBGHZ.
450 * @param CallbackID ID of the callback to be registered
451 * @param pCallback pointer to the Callback function
452 * @retval HAL status
453 */
HAL_SUBGHZ_RegisterCallback(SUBGHZ_HandleTypeDef * hsubghz,HAL_SUBGHZ_CallbackIDTypeDef CallbackID,pSUBGHZ_CallbackTypeDef pCallback)454 HAL_StatusTypeDef HAL_SUBGHZ_RegisterCallback(SUBGHZ_HandleTypeDef *hsubghz,
455 HAL_SUBGHZ_CallbackIDTypeDef CallbackID,
456 pSUBGHZ_CallbackTypeDef pCallback)
457 {
458 HAL_StatusTypeDef status = HAL_OK;
459
460 if (pCallback == NULL)
461 {
462 /* Update the error code */
463 hsubghz->ErrorCode |= HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
464
465 return HAL_ERROR;
466 }
467
468 /* Process locked */
469 __HAL_LOCK(hsubghz);
470
471 if (HAL_SUBGHZ_STATE_READY == hsubghz->State)
472 {
473 switch (CallbackID)
474 {
475 case HAL_SUBGHZ_TX_COMPLETE_CB_ID :
476 hsubghz->TxCpltCallback = pCallback;
477 break;
478
479 case HAL_SUBGHZ_RX_COMPLETE_CB_ID :
480 hsubghz->RxCpltCallback = pCallback;
481 break;
482
483 case HAL_SUBGHZ_PREAMBLE_DETECTED_CB_ID :
484 hsubghz->PreambleDetectedCallback = pCallback;
485 break;
486
487 case HAL_SUBGHZ_SYNCWORD_VALID_CB_ID :
488 hsubghz->SyncWordValidCallback = pCallback;
489 break;
490
491 case HAL_SUBGHZ_HEADER_VALID_CB_ID :
492 hsubghz->HeaderValidCallback = pCallback;
493 break;
494
495 case HAL_SUBGHZ_HEADER_ERROR_CB_ID :
496 hsubghz->HeaderErrorCallback = pCallback;
497 break;
498
499 case HAL_SUBGHZ_CRC_ERROR_CB_ID :
500 hsubghz->CRCErrorCallback = pCallback;
501 break;
502
503 case HAL_SUBGHZ_RX_TX_TIMEOUT_CB_ID :
504 hsubghz->RxTxTimeoutCallback = pCallback;
505 break;
506
507 case HAL_SUBGHZ_MSPINIT_CB_ID :
508 hsubghz->MspInitCallback = pCallback;
509 break;
510
511 case HAL_SUBGHZ_MSPDEINIT_CB_ID :
512 hsubghz->MspDeInitCallback = pCallback;
513 break;
514
515 case HAL_SUBGHZ_LR_FHSS_HOP_CB_ID :
516 hsubghz->LrFhssHopCallback = pCallback;
517 break;
518
519 default :
520 /* Update the error code */
521 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
522
523 /* Return error status */
524 status = HAL_ERROR;
525 break;
526 }
527 }
528 else if (HAL_SUBGHZ_STATE_RESET == hsubghz->State)
529 {
530 switch (CallbackID)
531 {
532 case HAL_SUBGHZ_MSPINIT_CB_ID :
533 hsubghz->MspInitCallback = pCallback;
534 break;
535
536 case HAL_SUBGHZ_MSPDEINIT_CB_ID :
537 hsubghz->MspDeInitCallback = pCallback;
538 break;
539
540 default :
541 /* Update the error code */
542 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
543
544 /* Return error status */
545 status = HAL_ERROR;
546 break;
547 }
548 }
549 else
550 {
551 /* Update the error code */
552 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
553
554 /* Return error status */
555 status = HAL_ERROR;
556 }
557
558 /* Release Lock */
559 __HAL_UNLOCK(hsubghz);
560
561 return status;
562 }
563
564 /**
565 * @brief Unregister an SUBGHZ Callback
566 * SUBGHZ callback is redirected to the weak predefined callback
567 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
568 * the configuration information for the specified SUBGHZ.
569 * @param CallbackID ID of the callback to be unregistered
570 * @retval HAL status
571 */
HAL_SUBGHZ_UnRegisterCallback(SUBGHZ_HandleTypeDef * hsubghz,HAL_SUBGHZ_CallbackIDTypeDef CallbackID)572 HAL_StatusTypeDef HAL_SUBGHZ_UnRegisterCallback(SUBGHZ_HandleTypeDef *hsubghz,
573 HAL_SUBGHZ_CallbackIDTypeDef CallbackID)
574 {
575 HAL_StatusTypeDef status = HAL_OK;
576
577 /* Process locked */
578 __HAL_LOCK(hsubghz);
579
580 if (HAL_SUBGHZ_STATE_READY == hsubghz->State)
581 {
582 /* call legacy weak callback function */
583 switch (CallbackID)
584 {
585 case HAL_SUBGHZ_TX_COMPLETE_CB_ID :
586 hsubghz->TxCpltCallback = HAL_SUBGHZ_TxCpltCallback;
587 break;
588
589 case HAL_SUBGHZ_RX_COMPLETE_CB_ID :
590 hsubghz->RxCpltCallback = HAL_SUBGHZ_RxCpltCallback;
591 break;
592
593 case HAL_SUBGHZ_PREAMBLE_DETECTED_CB_ID :
594 hsubghz->PreambleDetectedCallback = HAL_SUBGHZ_PreambleDetectedCallback;
595 break;
596
597 case HAL_SUBGHZ_SYNCWORD_VALID_CB_ID :
598 hsubghz->SyncWordValidCallback = HAL_SUBGHZ_SyncWordValidCallback;
599 break;
600
601 case HAL_SUBGHZ_HEADER_VALID_CB_ID :
602 hsubghz->HeaderValidCallback = HAL_SUBGHZ_HeaderValidCallback;
603 break;
604
605 case HAL_SUBGHZ_HEADER_ERROR_CB_ID :
606 hsubghz->HeaderErrorCallback = HAL_SUBGHZ_HeaderErrorCallback;
607 break;
608
609 case HAL_SUBGHZ_CRC_ERROR_CB_ID :
610 hsubghz->CRCErrorCallback = HAL_SUBGHZ_CRCErrorCallback;
611 break;
612
613 case HAL_SUBGHZ_RX_TX_TIMEOUT_CB_ID :
614 hsubghz->RxTxTimeoutCallback = HAL_SUBGHZ_RxTxTimeoutCallback;
615 break;
616
617 case HAL_SUBGHZ_MSPINIT_CB_ID :
618 hsubghz->MspInitCallback = HAL_SUBGHZ_MspInit;
619 break;
620
621 case HAL_SUBGHZ_MSPDEINIT_CB_ID :
622 hsubghz->MspDeInitCallback = HAL_SUBGHZ_MspDeInit;
623 break;
624
625 case HAL_SUBGHZ_LR_FHSS_HOP_CB_ID :
626 hsubghz->LrFhssHopCallback = HAL_SUBGHZ_LrFhssHopCallback;
627 break;
628
629 default :
630 /* Update the error code */
631 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
632
633 /* Return error status */
634 status = HAL_ERROR;
635 break;
636 }
637 }
638 else if (HAL_SUBGHZ_STATE_RESET == hsubghz->State)
639 {
640 switch (CallbackID)
641 {
642 case HAL_SUBGHZ_MSPINIT_CB_ID :
643 hsubghz->MspInitCallback = HAL_SUBGHZ_MspInit;
644 break;
645
646 case HAL_SUBGHZ_MSPDEINIT_CB_ID :
647 hsubghz->MspDeInitCallback = HAL_SUBGHZ_MspDeInit;
648 break;
649
650 default :
651 /* Update the error code */
652 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
653
654 /* Return error status */
655 status = HAL_ERROR;
656 break;
657 }
658 }
659 else
660 {
661 /* Update the error code */
662 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
663
664 /* Return error status */
665 status = HAL_ERROR;
666 }
667
668 /* Release Lock */
669 __HAL_UNLOCK(hsubghz);
670
671 return status;
672 }
673
674 /**
675 * @brief Register the channel activity detection status SUBGHZ Callback
676 * To be used instead of the weak HAL_SUBGHZ_AddrCallback() predefined callback
677 * @param hsubghz Pointer to a SUBGHZ_HandleTypeDef structure that contains
678 * the configuration information for the specified SUBGHZ.
679 * @param pCallback pointer to the CAD Status Callback function
680 * @retval HAL status
681 */
HAL_SUBGHZ_RegisterCadStatusCallback(SUBGHZ_HandleTypeDef * hsubghz,pSUBGHZ_CadStatusCallbackTypeDef pCallback)682 HAL_StatusTypeDef HAL_SUBGHZ_RegisterCadStatusCallback(SUBGHZ_HandleTypeDef *hsubghz,
683 pSUBGHZ_CadStatusCallbackTypeDef pCallback)
684 {
685 HAL_StatusTypeDef status = HAL_OK;
686
687 if (pCallback == NULL)
688 {
689 /* Update the error code */
690 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
691
692 return HAL_ERROR;
693 }
694 /* Process locked */
695 __HAL_LOCK(hsubghz);
696
697 if (HAL_SUBGHZ_STATE_READY == hsubghz->State)
698 {
699 hsubghz->CADStatusCallback = pCallback;
700 }
701 else
702 {
703 /* Update the error code */
704 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
705
706 /* Return error status */
707 status = HAL_ERROR;
708 }
709
710 /* Release Lock */
711 __HAL_UNLOCK(hsubghz);
712 return status;
713 }
714
715 /**
716 * @brief UnRegister the channel activity detection status SUBGHZ Callback
717 * @param hsubghz Pointer to a SUBGHZ_HandleTypeDef structure that contains
718 * the configuration information for the specified SUBGHZ.
719 * @retval HAL status
720 */
HAL_SUBGHZ_UnRegisterCadStatusCallback(SUBGHZ_HandleTypeDef * hsubghz)721 HAL_StatusTypeDef HAL_SUBGHZ_UnRegisterCadStatusCallback(SUBGHZ_HandleTypeDef *hsubghz)
722 {
723 HAL_StatusTypeDef status = HAL_OK;
724
725 /* Process locked */
726 __HAL_LOCK(hsubghz);
727
728 if (HAL_SUBGHZ_STATE_READY == hsubghz->State)
729 {
730 hsubghz->CADStatusCallback = HAL_SUBGHZ_CADStatusCallback; /* Legacy weak AddrCallback */
731 }
732 else
733 {
734 /* Update the error code */
735 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK;
736
737 /* Return error status */
738 status = HAL_ERROR;
739 }
740
741 /* Release Lock */
742 __HAL_UNLOCK(hsubghz);
743 return status;
744 }
745 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
746 /**
747 * @}
748 */
749
750 /** @defgroup SUBGHZ_Exported_Functions_Group2 IO operation functions
751 * @brief Data transfers functions
752 *
753 @verbatim
754 ==============================================================================
755 ##### IO operation functions #####
756 ===============================================================================
757 [..]
758 This subsection provides a set of functions allowing to manage the SUBGHZ
759 data transfers.
760
761 [..] The SUBGHZ supports Read and Write operation:
762
763 (#) There are four modes of transfer:
764 (++) Set operation: The Set Command operation is performed in polling mode.
765 The HAL status of command processing is returned by the same function
766 after finishing transfer.
767 (++) Get operation: The Get Status operation is performed using polling mode
768 These API update buffer in parameter to retrieve status of command.
769 These API return the HAL status
770 (++) Write operation: The write operation is performed in polling mode.
771 The HAL status of all data processing is returned by the same function
772 after finishing transfer.
773 (++) Read operation: The read operation is performed using polling mode
774 These APIs return the HAL status.
775
776 (#) Blocking mode functions are :
777 (++) HAL_SUBGHZ_ExecSetCmd(
778 (++) HAL_SUBGHZ_ExecGetCmd()
779 (++) HAL_SUBGHZ_WriteBuffer()
780 (++) HAL_SUBGHZ_ReadBuffer()
781 (++) HAL_SUBGHZ_WriteRegisters()
782 (++) HAL_SUBGHZ_ReadRegisters()
783 (++) HAL_SUBGHZ_WriteRegister()
784 (++) HAL_SUBGHZ_ReadRegister()
785
786 @endverbatim
787 * @{
788 */
789
790 /**
791 * @brief Write data buffer at an Address to configurate the peripheral
792 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
793 * the configuration information for the specified SUBGHZ.
794 * @param Address register to configurate
795 * @param pBuffer pointer to a data buffer
796 * @param Size amount of data to be sent
797 * @retval HAL status
798 */
HAL_SUBGHZ_WriteRegisters(SUBGHZ_HandleTypeDef * hsubghz,uint16_t Address,uint8_t * pBuffer,uint16_t Size)799 HAL_StatusTypeDef HAL_SUBGHZ_WriteRegisters(SUBGHZ_HandleTypeDef *hsubghz,
800 uint16_t Address,
801 uint8_t *pBuffer,
802 uint16_t Size)
803 {
804 HAL_StatusTypeDef status;
805
806 if (hsubghz->State == HAL_SUBGHZ_STATE_READY)
807 {
808 /* Process Locked */
809 __HAL_LOCK(hsubghz);
810
811 hsubghz->State = HAL_SUBGHZ_STATE_BUSY;
812
813 (void)SUBGHZ_CheckDeviceReady(hsubghz);
814
815 /* NSS = 0 */
816 LL_PWR_SelectSUBGHZSPI_NSS();
817
818 (void)SUBGHZSPI_Transmit(hsubghz, SUBGHZ_RADIO_WRITE_REGISTER);
819 (void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)((Address & 0xFF00U) >> 8U));
820 (void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)(Address & 0x00FFU));
821
822 for (uint16_t i = 0U; i < Size; i++)
823 {
824 (void)SUBGHZSPI_Transmit(hsubghz, pBuffer[i]);
825 }
826
827 /* NSS = 1 */
828 LL_PWR_UnselectSUBGHZSPI_NSS();
829
830 (void)SUBGHZ_WaitOnBusy(hsubghz);
831
832 if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE)
833 {
834 status = HAL_ERROR;
835 }
836 else
837 {
838 status = HAL_OK;
839 }
840
841 hsubghz->State = HAL_SUBGHZ_STATE_READY;
842
843 /* Process Unlocked */
844 __HAL_UNLOCK(hsubghz);
845
846 return status;
847 }
848 else
849 {
850 return HAL_BUSY;
851 }
852 }
853
854 /**
855 * @brief Read data register at an Address in the peripheral
856 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
857 * the configuration information for the specified SUBGHZ.
858 * @param Address register to configurate
859 * @param pBuffer pointer to a data buffer
860 * @param Size amount of data to be sent
861 * @retval HAL status
862 */
HAL_SUBGHZ_ReadRegisters(SUBGHZ_HandleTypeDef * hsubghz,uint16_t Address,uint8_t * pBuffer,uint16_t Size)863 HAL_StatusTypeDef HAL_SUBGHZ_ReadRegisters(SUBGHZ_HandleTypeDef *hsubghz,
864 uint16_t Address,
865 uint8_t *pBuffer,
866 uint16_t Size)
867 {
868 HAL_StatusTypeDef status;
869 uint8_t *pData = pBuffer;
870
871 if (hsubghz->State == HAL_SUBGHZ_STATE_READY)
872 {
873 /* Process Locked */
874 __HAL_LOCK(hsubghz);
875
876 (void)SUBGHZ_CheckDeviceReady(hsubghz);
877
878 /* NSS = 0 */
879 LL_PWR_SelectSUBGHZSPI_NSS();
880
881 (void)SUBGHZSPI_Transmit(hsubghz, SUBGHZ_RADIO_READ_REGISTER);
882 (void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)((Address & 0xFF00U) >> 8U));
883 (void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)(Address & 0x00FFU));
884 (void)SUBGHZSPI_Transmit(hsubghz, 0U);
885
886 for (uint16_t i = 0U; i < Size; i++)
887 {
888 (void)SUBGHZSPI_Receive(hsubghz, (pData));
889 pData++;
890 }
891
892 /* NSS = 1 */
893 LL_PWR_UnselectSUBGHZSPI_NSS();
894
895 (void)SUBGHZ_WaitOnBusy(hsubghz);
896
897 if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE)
898 {
899 status = HAL_ERROR;
900 }
901 else
902 {
903 status = HAL_OK;
904 }
905
906 hsubghz->State = HAL_SUBGHZ_STATE_READY;
907
908 /* Process Unlocked */
909 __HAL_UNLOCK(hsubghz);
910
911 return status;
912 }
913 else
914 {
915 return HAL_BUSY;
916 }
917 }
918
919 /**
920 * @brief Write one data at an Address to configurate the peripheral
921 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
922 * the configuration information for the specified SUBGHZ.
923 * @param Address register to configurate
924 * @param Value data
925 * @retval HAL status
926 */
HAL_SUBGHZ_WriteRegister(SUBGHZ_HandleTypeDef * hsubghz,uint16_t Address,uint8_t Value)927 HAL_StatusTypeDef HAL_SUBGHZ_WriteRegister(SUBGHZ_HandleTypeDef *hsubghz,
928 uint16_t Address,
929 uint8_t Value)
930 {
931 return (HAL_SUBGHZ_WriteRegisters(hsubghz, Address, &Value, 1U));
932 }
933
934 /**
935 * @brief Read data register at an Address in the peripheral
936 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
937 * the configuration information for the specified SUBGHZ.
938 * @param Address register to configurate
939 * @param pValue pointer to a data
940 * @retval HAL status
941 */
HAL_SUBGHZ_ReadRegister(SUBGHZ_HandleTypeDef * hsubghz,uint16_t Address,uint8_t * pValue)942 HAL_StatusTypeDef HAL_SUBGHZ_ReadRegister(SUBGHZ_HandleTypeDef *hsubghz,
943 uint16_t Address,
944 uint8_t *pValue)
945 {
946 return (HAL_SUBGHZ_ReadRegisters(hsubghz, Address, pValue, 1U));
947 }
948
949 /**
950 * @brief Send a command to configure the peripheral
951 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
952 * the configuration information for the specified SUBGHZ.
953 * @param Command configuration for peripheral
954 * @param pBuffer pointer to a data buffer
955 * @param Size amount of data to be sent
956 * @retval HAL status
957 */
HAL_SUBGHZ_ExecSetCmd(SUBGHZ_HandleTypeDef * hsubghz,SUBGHZ_RadioSetCmd_t Command,uint8_t * pBuffer,uint16_t Size)958 HAL_StatusTypeDef HAL_SUBGHZ_ExecSetCmd(SUBGHZ_HandleTypeDef *hsubghz,
959 SUBGHZ_RadioSetCmd_t Command,
960 uint8_t *pBuffer,
961 uint16_t Size)
962 {
963 HAL_StatusTypeDef status;
964
965 /* LORA Modulation not available on STM32WLx4xx devices */
966 assert_param(IS_SUBGHZ_MODULATION_SUPPORTED(Command, pBuffer[0U]));
967
968 if (hsubghz->State == HAL_SUBGHZ_STATE_READY)
969 {
970 /* Process Locked */
971 __HAL_LOCK(hsubghz);
972
973 /* Need to wakeup Radio if already in Sleep at startup */
974 (void)SUBGHZ_CheckDeviceReady(hsubghz);
975
976 if ((Command == RADIO_SET_SLEEP) || (Command == RADIO_SET_RXDUTYCYCLE))
977 {
978 hsubghz->DeepSleep = SUBGHZ_DEEP_SLEEP_ENABLE;
979 }
980 else
981 {
982 hsubghz->DeepSleep = SUBGHZ_DEEP_SLEEP_DISABLE;
983 }
984
985 /* NSS = 0 */
986 LL_PWR_SelectSUBGHZSPI_NSS();
987
988 (void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)Command);
989
990 for (uint16_t i = 0U; i < Size; i++)
991 {
992 (void)SUBGHZSPI_Transmit(hsubghz, pBuffer[i]);
993 }
994
995 /* NSS = 1 */
996 LL_PWR_UnselectSUBGHZSPI_NSS();
997
998 if (Command != RADIO_SET_SLEEP)
999 {
1000 (void)SUBGHZ_WaitOnBusy(hsubghz);
1001 }
1002
1003 if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE)
1004 {
1005 status = HAL_ERROR;
1006 }
1007 else
1008 {
1009 status = HAL_OK;
1010 }
1011
1012 hsubghz->State = HAL_SUBGHZ_STATE_READY;
1013
1014 /* Process Unlocked */
1015 __HAL_UNLOCK(hsubghz);
1016
1017 return status;
1018 }
1019 else
1020 {
1021 return HAL_BUSY;
1022 }
1023 }
1024
1025 /**
1026 * @brief Retrieve a status from the peripheral
1027 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1028 * the configuration information for the specified SUBGHZ.
1029 * @param Command configuration for peripheral
1030 * @param pBuffer pointer to a data buffer
1031 * @param Size amount of data to be sent
1032 * @retval HAL status
1033 */
HAL_SUBGHZ_ExecGetCmd(SUBGHZ_HandleTypeDef * hsubghz,SUBGHZ_RadioGetCmd_t Command,uint8_t * pBuffer,uint16_t Size)1034 HAL_StatusTypeDef HAL_SUBGHZ_ExecGetCmd(SUBGHZ_HandleTypeDef *hsubghz,
1035 SUBGHZ_RadioGetCmd_t Command,
1036 uint8_t *pBuffer,
1037 uint16_t Size)
1038 {
1039 HAL_StatusTypeDef status;
1040 uint8_t *pData = pBuffer;
1041
1042 if (hsubghz->State == HAL_SUBGHZ_STATE_READY)
1043 {
1044 /* Process Locked */
1045 __HAL_LOCK(hsubghz);
1046
1047 (void)SUBGHZ_CheckDeviceReady(hsubghz);
1048
1049 /* NSS = 0 */
1050 LL_PWR_SelectSUBGHZSPI_NSS();
1051
1052 (void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)Command);
1053
1054 /* Use to flush the Status (First byte) receive from SUBGHZ as not use */
1055 (void)SUBGHZSPI_Transmit(hsubghz, 0x00U);
1056
1057 for (uint16_t i = 0U; i < Size; i++)
1058 {
1059 (void)SUBGHZSPI_Receive(hsubghz, (pData));
1060 pData++;
1061 }
1062
1063 /* NSS = 1 */
1064 LL_PWR_UnselectSUBGHZSPI_NSS();
1065
1066 (void)SUBGHZ_WaitOnBusy(hsubghz);
1067
1068 if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE)
1069 {
1070 status = HAL_ERROR;
1071 }
1072 else
1073 {
1074 status = HAL_OK;
1075 }
1076
1077 hsubghz->State = HAL_SUBGHZ_STATE_READY;
1078
1079 /* Process Unlocked */
1080 __HAL_UNLOCK(hsubghz);
1081
1082 return status;
1083 }
1084 else
1085 {
1086 return HAL_BUSY;
1087 }
1088 }
1089
1090 /**
1091 * @brief Write data buffer inside payload of peripheral
1092 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1093 * the configuration information for the specified SUBGHZ.
1094 * @param Offset Offset inside payload
1095 * @param pBuffer pointer to a data buffer
1096 * @param Size amount of data to be sent
1097 * @retval HAL status
1098 */
HAL_SUBGHZ_WriteBuffer(SUBGHZ_HandleTypeDef * hsubghz,uint8_t Offset,uint8_t * pBuffer,uint16_t Size)1099 HAL_StatusTypeDef HAL_SUBGHZ_WriteBuffer(SUBGHZ_HandleTypeDef *hsubghz,
1100 uint8_t Offset,
1101 uint8_t *pBuffer,
1102 uint16_t Size)
1103 {
1104 HAL_StatusTypeDef status;
1105
1106 if (hsubghz->State == HAL_SUBGHZ_STATE_READY)
1107 {
1108 /* Process Locked */
1109 __HAL_LOCK(hsubghz);
1110
1111 (void)SUBGHZ_CheckDeviceReady(hsubghz);
1112
1113 /* NSS = 0 */
1114 LL_PWR_SelectSUBGHZSPI_NSS();
1115
1116 (void)SUBGHZSPI_Transmit(hsubghz, SUBGHZ_RADIO_WRITE_BUFFER);
1117 (void)SUBGHZSPI_Transmit(hsubghz, Offset);
1118
1119 for (uint16_t i = 0U; i < Size; i++)
1120 {
1121 (void)SUBGHZSPI_Transmit(hsubghz, pBuffer[i]);
1122 }
1123 /* NSS = 1 */
1124 LL_PWR_UnselectSUBGHZSPI_NSS();
1125
1126 (void)SUBGHZ_WaitOnBusy(hsubghz);
1127
1128 if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE)
1129 {
1130 status = HAL_ERROR;
1131 }
1132 else
1133 {
1134 status = HAL_OK;
1135 }
1136
1137 hsubghz->State = HAL_SUBGHZ_STATE_READY;
1138
1139 /* Process Unlocked */
1140 __HAL_UNLOCK(hsubghz);
1141
1142 return status;
1143 }
1144 else
1145 {
1146 return HAL_BUSY;
1147 }
1148 }
1149
1150 /**
1151 * @brief Read data buffer inside payload of peripheral
1152 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1153 * the configuration information for the specified SUBGHZ.
1154 * @param Offset Offset inside payload
1155 * @param pBuffer pointer to a data buffer
1156 * @param Size amount of data to be sent
1157 * @retval HAL status
1158 */
HAL_SUBGHZ_ReadBuffer(SUBGHZ_HandleTypeDef * hsubghz,uint8_t Offset,uint8_t * pBuffer,uint16_t Size)1159 HAL_StatusTypeDef HAL_SUBGHZ_ReadBuffer(SUBGHZ_HandleTypeDef *hsubghz,
1160 uint8_t Offset,
1161 uint8_t *pBuffer,
1162 uint16_t Size)
1163 {
1164 HAL_StatusTypeDef status;
1165 uint8_t *pData = pBuffer;
1166
1167 if (hsubghz->State == HAL_SUBGHZ_STATE_READY)
1168 {
1169 /* Process Locked */
1170 __HAL_LOCK(hsubghz);
1171
1172 (void)SUBGHZ_CheckDeviceReady(hsubghz);
1173
1174 /* NSS = 0 */
1175 LL_PWR_SelectSUBGHZSPI_NSS();
1176
1177 (void)SUBGHZSPI_Transmit(hsubghz, SUBGHZ_RADIO_READ_BUFFER);
1178 (void)SUBGHZSPI_Transmit(hsubghz, Offset);
1179 (void)SUBGHZSPI_Transmit(hsubghz, 0x00U);
1180
1181 for (uint16_t i = 0U; i < Size; i++)
1182 {
1183 (void)SUBGHZSPI_Receive(hsubghz, (pData));
1184 pData++;
1185 }
1186
1187 /* NSS = 1 */
1188 LL_PWR_UnselectSUBGHZSPI_NSS();
1189
1190 (void)SUBGHZ_WaitOnBusy(hsubghz);
1191
1192 if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE)
1193 {
1194 status = HAL_ERROR;
1195 }
1196 else
1197 {
1198 status = HAL_OK;
1199 }
1200
1201 hsubghz->State = HAL_SUBGHZ_STATE_READY;
1202
1203 /* Process Unlocked */
1204 __HAL_UNLOCK(hsubghz);
1205
1206 return status;
1207 }
1208 else
1209 {
1210 return HAL_BUSY;
1211 }
1212 }
1213
1214 /**
1215 * @brief Handle SUBGHZ interrupt request.
1216 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1217 * the configuration information for the specified SUBGHZ module.
1218 * @retval None
1219 */
HAL_SUBGHZ_IRQHandler(SUBGHZ_HandleTypeDef * hsubghz)1220 void HAL_SUBGHZ_IRQHandler(SUBGHZ_HandleTypeDef *hsubghz)
1221 {
1222 uint8_t tmpisr[2U] = {0U};
1223 uint16_t itsource;
1224
1225 /* Retrieve Interrupts from SUBGHZ Irq Register */
1226 (void)HAL_SUBGHZ_ExecGetCmd(hsubghz, RADIO_GET_IRQSTATUS, tmpisr, 2U);
1227 itsource = tmpisr[0U];
1228 itsource = (itsource << 8U) | tmpisr[1U];
1229
1230 /* Clear SUBGHZ Irq Register */
1231 (void)HAL_SUBGHZ_ExecSetCmd(hsubghz, RADIO_CLR_IRQSTATUS, tmpisr, 2U);
1232
1233 /* Packet transmission completed Interrupt */
1234 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_TX_CPLT) != RESET)
1235 {
1236 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1237 hsubghz->TxCpltCallback(hsubghz);
1238 #else
1239 HAL_SUBGHZ_TxCpltCallback(hsubghz);
1240 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1241 }
1242
1243 /* Packet received Interrupt */
1244 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_RX_CPLT) != RESET)
1245 {
1246 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1247 hsubghz->RxCpltCallback(hsubghz);
1248 #else
1249 HAL_SUBGHZ_RxCpltCallback(hsubghz);
1250 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1251 }
1252
1253 /* Preamble Detected Interrupt */
1254 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_PREAMBLE_DETECTED) != RESET)
1255 {
1256 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1257 hsubghz->PreambleDetectedCallback(hsubghz);
1258 #else
1259 HAL_SUBGHZ_PreambleDetectedCallback(hsubghz);
1260 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1261 }
1262
1263 /* Valid sync word detected Interrupt */
1264 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_SYNCWORD_VALID) != RESET)
1265 {
1266 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1267 hsubghz->SyncWordValidCallback(hsubghz);
1268 #else
1269 HAL_SUBGHZ_SyncWordValidCallback(hsubghz);
1270 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1271 }
1272
1273 /* Valid LoRa header received Interrupt */
1274 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_HEADER_VALID) != RESET)
1275 {
1276 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1277 hsubghz->HeaderValidCallback(hsubghz);
1278 #else
1279 HAL_SUBGHZ_HeaderValidCallback(hsubghz);
1280 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1281 }
1282
1283 /* LoRa header CRC error Interrupt */
1284 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_HEADER_ERROR) != RESET)
1285 {
1286 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1287 hsubghz->HeaderErrorCallback(hsubghz);
1288 #else
1289 HAL_SUBGHZ_HeaderErrorCallback(hsubghz);
1290 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1291 }
1292
1293 /* Wrong CRC received Interrupt */
1294 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_CRC_ERROR) != RESET)
1295 {
1296 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1297 hsubghz->CRCErrorCallback(hsubghz);
1298 #else
1299 HAL_SUBGHZ_CRCErrorCallback(hsubghz);
1300 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1301 }
1302
1303 /* Channel activity detection finished Interrupt */
1304 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_CAD_DONE) != RESET)
1305 {
1306 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1307 /* Channel activity Detected Interrupt */
1308 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_CAD_ACTIVITY_DETECTED) != RESET)
1309 {
1310 hsubghz->CADStatusCallback(hsubghz, HAL_SUBGHZ_CAD_DETECTED);
1311 }
1312 else
1313 {
1314 hsubghz->CADStatusCallback(hsubghz, HAL_SUBGHZ_CAD_CLEAR);
1315 }
1316 #else
1317 /* Channel activity Detected Interrupt */
1318 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_CAD_ACTIVITY_DETECTED) != RESET)
1319 {
1320 HAL_SUBGHZ_CADStatusCallback(hsubghz, HAL_SUBGHZ_CAD_DETECTED);
1321 }
1322 else
1323 {
1324 HAL_SUBGHZ_CADStatusCallback(hsubghz, HAL_SUBGHZ_CAD_CLEAR);
1325 }
1326 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1327 }
1328
1329 /* Rx or Tx Timeout Interrupt */
1330 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_RX_TX_TIMEOUT) != RESET)
1331 {
1332 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1333 hsubghz->RxTxTimeoutCallback(hsubghz);
1334 #else
1335 HAL_SUBGHZ_RxTxTimeoutCallback(hsubghz);
1336 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1337 }
1338
1339 /* LR_FHSS Hop interrupt */
1340 if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_LR_FHSS_HOP) != RESET)
1341 {
1342 #if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U)
1343 hsubghz->LrFhssHopCallback(hsubghz);
1344 #else
1345 HAL_SUBGHZ_LrFhssHopCallback(hsubghz);
1346 #endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */
1347 }
1348 }
1349
1350 /**
1351 * @brief Packet transmission completed callback.
1352 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1353 * the configuration information for SUBGHZ module.
1354 * @retval None
1355 */
HAL_SUBGHZ_TxCpltCallback(SUBGHZ_HandleTypeDef * hsubghz)1356 __weak void HAL_SUBGHZ_TxCpltCallback(SUBGHZ_HandleTypeDef *hsubghz)
1357 {
1358 /* Prevent unused argument(s) compilation warning */
1359 UNUSED(hsubghz);
1360
1361 /* NOTE : This function should not be modified, when the callback is needed,
1362 the HAL_SUBGHZ_TxCpltCallback should be implemented in the user file
1363 */
1364 }
1365
1366 /**
1367 * @brief Packet received callback.
1368 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1369 * the configuration information for SUBGHZ module.
1370 * @retval None
1371 */
HAL_SUBGHZ_RxCpltCallback(SUBGHZ_HandleTypeDef * hsubghz)1372 __weak void HAL_SUBGHZ_RxCpltCallback(SUBGHZ_HandleTypeDef *hsubghz)
1373 {
1374 /* Prevent unused argument(s) compilation warning */
1375 UNUSED(hsubghz);
1376
1377 /* NOTE : This function should not be modified, when the callback is needed,
1378 the HAL_SUBGHZ_RxCpltCallback should be implemented in the user file
1379 */
1380 }
1381
1382 /**
1383 * @brief Preamble Detected callback.
1384 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1385 * the configuration information for SUBGHZ module.
1386 * @retval None
1387 */
HAL_SUBGHZ_PreambleDetectedCallback(SUBGHZ_HandleTypeDef * hsubghz)1388 __weak void HAL_SUBGHZ_PreambleDetectedCallback(SUBGHZ_HandleTypeDef *hsubghz)
1389 {
1390 /* Prevent unused argument(s) compilation warning */
1391 UNUSED(hsubghz);
1392
1393 /* NOTE : This function should not be modified, when the callback is needed,
1394 the HAL_SUBGHZ_PreambleDetectedCallback should be implemented in the user file
1395 */
1396 }
1397
1398 /**
1399 * @brief Valid sync word detected callback.
1400 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1401 * the configuration information for SUBGHZ module.
1402 * @retval None
1403 */
HAL_SUBGHZ_SyncWordValidCallback(SUBGHZ_HandleTypeDef * hsubghz)1404 __weak void HAL_SUBGHZ_SyncWordValidCallback(SUBGHZ_HandleTypeDef *hsubghz)
1405 {
1406 /* Prevent unused argument(s) compilation warning */
1407 UNUSED(hsubghz);
1408
1409 /* NOTE : This function should not be modified, when the callback is needed,
1410 the HAL_SUBGHZ_SyncWordValidCallback should be implemented in the user file
1411 */
1412 }
1413
1414 /**
1415 * @brief Valid LoRa header received callback.
1416 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1417 * the configuration information for SUBGHZ module.
1418 * @retval None
1419 */
HAL_SUBGHZ_HeaderValidCallback(SUBGHZ_HandleTypeDef * hsubghz)1420 __weak void HAL_SUBGHZ_HeaderValidCallback(SUBGHZ_HandleTypeDef *hsubghz)
1421 {
1422 /* Prevent unused argument(s) compilation warning */
1423 UNUSED(hsubghz);
1424
1425 /* NOTE : This function should not be modified, when the callback is needed,
1426 the HAL_SUBGHZ_HeaderValidCallback should be implemented in the user file
1427 */
1428 }
1429
1430 /**
1431 * @brief LoRa header CRC error callback.
1432 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1433 * the configuration information for SUBGHZ module.
1434 * @retval None
1435 */
HAL_SUBGHZ_HeaderErrorCallback(SUBGHZ_HandleTypeDef * hsubghz)1436 __weak void HAL_SUBGHZ_HeaderErrorCallback(SUBGHZ_HandleTypeDef *hsubghz)
1437 {
1438 /* Prevent unused argument(s) compilation warning */
1439 UNUSED(hsubghz);
1440
1441 /* NOTE : This function should not be modified, when the callback is needed,
1442 the HAL_SUBGHZ_HeaderErrorCallback should be implemented in the user file
1443 */
1444 }
1445
1446 /**
1447 * @brief Wrong CRC received callback.
1448 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1449 * the configuration information for SUBGHZ module.
1450 * @retval None
1451 */
HAL_SUBGHZ_CRCErrorCallback(SUBGHZ_HandleTypeDef * hsubghz)1452 __weak void HAL_SUBGHZ_CRCErrorCallback(SUBGHZ_HandleTypeDef *hsubghz)
1453 {
1454 /* Prevent unused argument(s) compilation warning */
1455 UNUSED(hsubghz);
1456
1457 /* NOTE : This function should not be modified, when the callback is needed,
1458 the HAL_SUBGHZ_CRCErrorCallback should be implemented in the user file
1459 */
1460 }
1461
1462 /**
1463 * @brief Channel activity detection status callback.
1464 * @note Unified callback for CAD Done and CAD activity interrupts.
1465 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1466 * the configuration information for SUBGHZ module.
1467 * @param cadstatus reports whether activity is detected or not
1468 * @retval None
1469 */
HAL_SUBGHZ_CADStatusCallback(SUBGHZ_HandleTypeDef * hsubghz,HAL_SUBGHZ_CadStatusTypeDef cadstatus)1470 __weak void HAL_SUBGHZ_CADStatusCallback(SUBGHZ_HandleTypeDef *hsubghz,
1471 HAL_SUBGHZ_CadStatusTypeDef cadstatus)
1472 {
1473 /* Prevent unused argument(s) compilation warning */
1474 UNUSED(hsubghz);
1475
1476 UNUSED(cadstatus);
1477 /* NOTE : This function should not be modified, when the callback is needed,
1478 the HAL_SUBGHZ_CADStatusCallback should be implemented in the user file
1479 */
1480 }
1481
1482 /**
1483 * @brief Rx or Tx Timeout callback.
1484 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1485 * the configuration information for SUBGHZ module.
1486 * @retval None
1487 */
HAL_SUBGHZ_RxTxTimeoutCallback(SUBGHZ_HandleTypeDef * hsubghz)1488 __weak void HAL_SUBGHZ_RxTxTimeoutCallback(SUBGHZ_HandleTypeDef *hsubghz)
1489 {
1490 /* Prevent unused argument(s) compilation warning */
1491 UNUSED(hsubghz);
1492
1493 /* NOTE : This function should not be modified, when the callback is needed,
1494 the HAL_SUBGHZ_RxTxTimeoutCallback should be implemented in the user file
1495 */
1496 }
1497
1498 /**
1499 * @brief LR FHSS Hop callback.
1500 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1501 * the configuration information for SUBGHZ module.
1502 * @retval None
1503 */
HAL_SUBGHZ_LrFhssHopCallback(SUBGHZ_HandleTypeDef * hsubghz)1504 __weak void HAL_SUBGHZ_LrFhssHopCallback(SUBGHZ_HandleTypeDef *hsubghz)
1505 {
1506 /* Prevent unused argument(s) compilation warning */
1507 UNUSED(hsubghz);
1508
1509 /* NOTE : This function should not be modified, when the callback is needed,
1510 the HAL_SUBGHZ_LrFhssHopCallback should be implemented in the user file
1511 */
1512 }
1513 /**
1514 * @}
1515 */
1516
1517 /** @defgroup SUBGHZ_Exported_Functions_Group3 Peripheral State and Errors functions
1518 * @brief SUBGHZ control functions
1519 *
1520 @verbatim
1521 ===============================================================================
1522 ##### Peripheral State and Errors functions #####
1523 ===============================================================================
1524 [..]
1525 This subsection provides a set of functions allowing to control the SUBGHZ.
1526 (+) HAL_SUBGHZ_GetState() API can be helpful to check in run-time the state of the SUBGHZ peripheral
1527 (+) HAL_SUBGHZ_GetError() check in run-time Errors occurring during communication
1528 @endverbatim
1529 * @{
1530 */
1531
1532 /**
1533 * @brief Return the SUBGHZ handle state.
1534 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1535 * the handle information for SUBGHZ module.
1536 * @retval SUBGHZ state
1537 */
HAL_SUBGHZ_GetState(SUBGHZ_HandleTypeDef * hsubghz)1538 HAL_SUBGHZ_StateTypeDef HAL_SUBGHZ_GetState(SUBGHZ_HandleTypeDef *hsubghz)
1539 {
1540 /* Return SUBGHZ handle state */
1541 return hsubghz->State;
1542 }
1543
1544 /**
1545 * @brief Return the SUBGHZ error code.
1546 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1547 * the handle information for SUBGHZ module.
1548 * @retval SUBGHZ error code in bitmap format
1549 */
HAL_SUBGHZ_GetError(SUBGHZ_HandleTypeDef * hsubghz)1550 uint32_t HAL_SUBGHZ_GetError(SUBGHZ_HandleTypeDef *hsubghz)
1551 {
1552 /* Return SUBGHZ ErrorCode */
1553 return hsubghz->ErrorCode;
1554 }
1555
1556 /**
1557 * @}
1558 */
1559
1560 /**
1561 * @}
1562 */
1563
1564 /** @addtogroup SUBGHZ_Private_Functions
1565 * @brief Private functions
1566 * @{
1567 */
1568
1569 /**
1570 * @brief Initializes the SUBGHZSPI peripheral
1571 * @param BaudratePrescaler SPI Baudrate prescaler
1572 * @retval None
1573 */
SUBGHZSPI_Init(uint32_t BaudratePrescaler)1574 void SUBGHZSPI_Init(uint32_t BaudratePrescaler)
1575 {
1576 /* Check the parameters */
1577 assert_param(IS_SUBGHZ_ALL_INSTANCE(SUBGHZSPI));
1578
1579 /* Disable SUBGHZSPI Peripheral */
1580 CLEAR_BIT(SUBGHZSPI->CR1, SPI_CR1_SPE);
1581
1582 /*----------------------- SPI CR1 Configuration ----------------------------*
1583 * SPI Mode: Master *
1584 * Communication Mode: 2 lines (Full-Duplex) *
1585 * Clock polarity: Low *
1586 * phase: 1st Edge *
1587 * NSS management: Internal (Done with External bit inside PWR *
1588 * Communication speed: BaudratePrescaler *
1589 * First bit: MSB *
1590 * CRC calculation: Disable *
1591 *--------------------------------------------------------------------------*/
1592 WRITE_REG(SUBGHZSPI->CR1, (SPI_CR1_MSTR | SPI_CR1_SSI | BaudratePrescaler | SPI_CR1_SSM));
1593
1594 /*----------------------- SPI CR2 Configuration ----------------------------*
1595 * Data Size: 8bits *
1596 * TI Mode: Disable *
1597 * NSS Pulse: Disable *
1598 * Rx FIFO Threshold: 8bits *
1599 *--------------------------------------------------------------------------*/
1600 WRITE_REG(SUBGHZSPI->CR2, (SPI_CR2_FRXTH | SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2));
1601
1602 /* Enable SUBGHZSPI Peripheral */
1603 SET_BIT(SUBGHZSPI->CR1, SPI_CR1_SPE);
1604 }
1605
1606 /**
1607 * @brief DeInitializes the SUBGHZSPI peripheral
1608 * @retval None
1609 */
SUBGHZSPI_DeInit(void)1610 void SUBGHZSPI_DeInit(void)
1611 {
1612 /* Check the parameters */
1613 assert_param(IS_SUBGHZ_ALL_INSTANCE(SUBGHZSPI));
1614
1615 /* Disable SUBGHZSPI Peripheral */
1616 CLEAR_BIT(SUBGHZSPI->CR1, SPI_CR1_SPE);
1617 }
1618
1619 /**
1620 * @brief Transmit data through SUBGHZSPI peripheral
1621 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1622 * the handle information for SUBGHZ module.
1623 * @param Data data to transmit
1624 * @retval HAL status
1625 */
SUBGHZSPI_Transmit(SUBGHZ_HandleTypeDef * hsubghz,uint8_t Data)1626 HAL_StatusTypeDef SUBGHZSPI_Transmit(SUBGHZ_HandleTypeDef *hsubghz,
1627 uint8_t Data)
1628 {
1629 HAL_StatusTypeDef status = HAL_OK;
1630 __IO uint32_t count;
1631
1632 /* Handle Tx transmission from SUBGHZSPI peripheral to Radio ****************/
1633 /* Initialize Timeout */
1634 count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME;
1635
1636 /* Wait until TXE flag is set */
1637 do
1638 {
1639 if (count == 0U)
1640 {
1641 status = HAL_ERROR;
1642 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT;
1643 break;
1644 }
1645 count--;
1646 } while (READ_BIT(SUBGHZSPI->SR, SPI_SR_TXE) != (SPI_SR_TXE));
1647
1648 /* Transmit Data*/
1649 #if defined (__GNUC__)
1650 __IO uint8_t *spidr = ((__IO uint8_t *)&SUBGHZSPI->DR);
1651 *spidr = Data;
1652 #else
1653 *((__IO uint8_t *)&SUBGHZSPI->DR) = Data;
1654 #endif /* __GNUC__ */
1655
1656 /* Handle Rx transmission from SUBGHZSPI peripheral to Radio ****************/
1657 /* Initialize Timeout */
1658 count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME;
1659
1660 /* Wait until RXNE flag is set */
1661 do
1662 {
1663 if (count == 0U)
1664 {
1665 status = HAL_ERROR;
1666 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT;
1667 break;
1668 }
1669 count--;
1670 } while (READ_BIT(SUBGHZSPI->SR, SPI_SR_RXNE) != (SPI_SR_RXNE));
1671
1672 /* Flush Rx data */
1673 READ_REG(SUBGHZSPI->DR);
1674
1675 return status;
1676 }
1677
1678 /**
1679 * @brief Receive data through SUBGHZSPI peripheral
1680 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1681 * the handle information for SUBGHZ module.
1682 * @param pData pointer on data to receive
1683 * @retval HAL status
1684 */
SUBGHZSPI_Receive(SUBGHZ_HandleTypeDef * hsubghz,uint8_t * pData)1685 HAL_StatusTypeDef SUBGHZSPI_Receive(SUBGHZ_HandleTypeDef *hsubghz,
1686 uint8_t *pData)
1687 {
1688 HAL_StatusTypeDef status = HAL_OK;
1689 __IO uint32_t count;
1690
1691 /* Handle Tx transmission from SUBGHZSPI peripheral to Radio ****************/
1692 /* Initialize Timeout */
1693 count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME;
1694
1695 /* Wait until TXE flag is set */
1696 do
1697 {
1698 if (count == 0U)
1699 {
1700 status = HAL_ERROR;
1701 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT;
1702 break;
1703 }
1704 count--;
1705 } while (READ_BIT(SUBGHZSPI->SR, SPI_SR_TXE) != (SPI_SR_TXE));
1706
1707 /* Transmit Data*/
1708 #if defined (__GNUC__)
1709 __IO uint8_t *spidr = ((__IO uint8_t *)&SUBGHZSPI->DR);
1710 *spidr = SUBGHZ_DUMMY_DATA;
1711 #else
1712 *((__IO uint8_t *)&SUBGHZSPI->DR) = SUBGHZ_DUMMY_DATA;
1713 #endif /* __GNUC__ */
1714
1715 /* Handle Rx transmission from SUBGHZSPI peripheral to Radio ****************/
1716 /* Initialize Timeout */
1717 count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME;
1718
1719 /* Wait until RXNE flag is set */
1720 do
1721 {
1722 if (count == 0U)
1723 {
1724 status = HAL_ERROR;
1725 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT;
1726 break;
1727 }
1728 count--;
1729 } while (READ_BIT(SUBGHZSPI->SR, SPI_SR_RXNE) != (SPI_SR_RXNE));
1730
1731 /* Retrieve pData */
1732 *pData = (uint8_t)(READ_REG(SUBGHZSPI->DR));
1733
1734 return status;
1735 }
1736
1737 /**
1738 * @brief Check if peripheral is ready
1739 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1740 * the handle information for SUBGHZ module.
1741 * @retval HAL status
1742 */
SUBGHZ_CheckDeviceReady(SUBGHZ_HandleTypeDef * hsubghz)1743 HAL_StatusTypeDef SUBGHZ_CheckDeviceReady(SUBGHZ_HandleTypeDef *hsubghz)
1744 {
1745 __IO uint32_t count;
1746
1747 /* Wakeup radio in case of sleep mode: Select-Unselect radio */
1748 if (hsubghz->DeepSleep == SUBGHZ_DEEP_SLEEP_ENABLE)
1749 {
1750 /* Initialize NSS switch Delay */
1751 count = SUBGHZ_NSS_LOOP_TIME;
1752
1753 /* NSS = 0; */
1754 LL_PWR_SelectSUBGHZSPI_NSS();
1755
1756 /* Wait Radio wakeup */
1757 do
1758 {
1759 count--;
1760 } while (count != 0UL);
1761
1762 /* NSS = 1 */
1763 LL_PWR_UnselectSUBGHZSPI_NSS();
1764 }
1765 return (SUBGHZ_WaitOnBusy(hsubghz));
1766 }
1767
1768 /**
1769 * @brief Wait busy flag low from peripheral
1770 * @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains
1771 * the handle information for SUBGHZ module.
1772 * @retval HAL status
1773 */
SUBGHZ_WaitOnBusy(SUBGHZ_HandleTypeDef * hsubghz)1774 HAL_StatusTypeDef SUBGHZ_WaitOnBusy(SUBGHZ_HandleTypeDef *hsubghz)
1775 {
1776 HAL_StatusTypeDef status;
1777 __IO uint32_t count;
1778 uint32_t mask;
1779
1780 status = HAL_OK;
1781 count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_RFBUSY_LOOP_TIME;
1782
1783 /* Wait until Busy signal is set */
1784 do
1785 {
1786 mask = LL_PWR_IsActiveFlag_RFBUSYMS();
1787
1788 if (count == 0U)
1789 {
1790 status = HAL_ERROR;
1791 hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_RF_BUSY;
1792 break;
1793 }
1794 count--;
1795 } while ((LL_PWR_IsActiveFlag_RFBUSYS()& mask) == 1UL);
1796
1797 return status;
1798 }
1799 /**
1800 * @}
1801 */
1802
1803 #endif /* HAL_SUBGHZ_MODULE_ENABLED */
1804
1805 /**
1806 * @}
1807 */
1808
1809 /**
1810 * @}
1811 */
1812