You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1811 lines
56 KiB
1811 lines
56 KiB
/******************************************************************************* |
|
* @file stm32wlxx_hal_subghz.c |
|
* @author MCD Application Team |
|
* @brief SUBGHZ HAL module driver. |
|
* This file provides firmware functions to manage the following |
|
* functionalities of the SUBGHZ peripheral: |
|
* + Initialization and de-initialization functions |
|
* + IO operation functions |
|
* + Peripheral State and Errors functions |
|
* |
|
****************************************************************************** |
|
* @attention |
|
* |
|
* Copyright (c) 2020 STMicroelectronics. |
|
* All rights reserved. |
|
* |
|
* This software is licensed under terms that can be found in the LICENSE file |
|
* in the root directory of this software component. |
|
* If no LICENSE file comes with this software, it is provided AS-IS. |
|
* |
|
****************************************************************************** |
|
@verbatim |
|
============================================================================== |
|
##### How to use this driver ##### |
|
============================================================================== |
|
[..] |
|
The SUBGHZ HAL driver can be used as follows: |
|
|
|
(#) Declare a SUBGHZ_HandleTypeDef handle structure, for example: |
|
SUBGHZ_HandleTypeDef hUserSubghz; |
|
|
|
(#) Initialize the SUBGHZ low level resources by implementing the @ref HAL_SUBGHZ_MspInit() API: |
|
(##) PWR configuration |
|
(+++) Enable the SUBGHZSPI interface clock |
|
(+++) Enable wakeup signal of the Radio peripheral |
|
(##) NVIC configuration: |
|
(+++) Enable the NVIC Radio IRQ ITs for CPU1 (EXTI 44) |
|
(+++) Configure the Radio interrupt priority |
|
|
|
(#) Initialize the SUBGHZ handle and SUBGHZSPI SPI registers by calling the @ref HAL_SUBGHZ_Init(&hUserSubghz), |
|
configures also the low level Hardware (GPIO, CLOCK, NVIC...etc) by calling |
|
the customized @ref HAL_SUBGHZ_MspInit() API. |
|
|
|
(#) For SUBGHZ IO operations, polling operation modes is available within this driver : |
|
|
|
*** Polling mode IO operation *** |
|
===================================== |
|
[..] |
|
(+) Set and execute a command in blocking mode using @ref HAL_SUBGHZ_ExecSetCmd() |
|
(+) Get a status blocking mode using @ref HAL_SUBGHZ_ExecGetCmd() |
|
(+) Write a Data Buffer in blocking mode using @ref HAL_SUBGHZ_WriteBuffer() |
|
(+) Read a Data Buffer in blocking mode using @ref HAL_SUBGHZ_ReadBuffer() |
|
(+) Write Registers (more than 1 byte) in blocking mode using @ref HAL_SUBGHZ_WriteRegisters() |
|
(+) Read Registers (more than 1 byte) in blocking mode using @ref HAL_SUBGHZ_ReadRegisters() |
|
(+) Write Register (1 byte) in blocking mode using @ref HAL_SUBGHZ_WriteRegister() |
|
(+) Read Register (1 byte) in blocking mode using @ref HAL_SUBGHZ_ReadRegister() |
|
|
|
*** SUBGHZ HAL driver macros list *** |
|
===================================== |
|
[..] |
|
(+) @ref __HAL_SUBGHZ_RESET_HANDLE_STATE: Reset the SUBGHZ handle state |
|
|
|
#if defined(GENERATOR_CALLBACK_REGISTERING_PRESENT) |
|
*** SUBGHZ Callback registration *** |
|
===================================== |
|
|
|
[..] |
|
The compilation flag USE_HAL_SUBGHZ_REGISTER_CALLBACKS when set to 1 |
|
allows the user to configure dynamically the driver callbacks. |
|
Use Functions @ref HAL_SUBGHZ_RegisterCallback() or @ref HAL_SUBGHZ_RegisterAddrCallback() |
|
to register an interrupt callback. |
|
|
|
[..] |
|
Function @ref HAL_SUBGHZ_RegisterCallback() allows to register following callbacks: |
|
(+) TxCpltCallback : callback for Tx Completed. |
|
(+) RxCpltCallback : callback for Rx Completed. |
|
(+) PreambleDetectedCallback : callback for Preamble detected. |
|
(+) SyncWordValidCallback : callback for Synchro word valid. |
|
(+) HeaderValidCallback : callback for Header valid. |
|
(+) HeaderErrorCallback : callback for Header error. |
|
(+) CRCErrorCallback : callback for CRC Error. |
|
(+) RxTxTimeoutCallback : callback for Rx Tx Timeout. |
|
(+) MspInitCallback : callback for Msp Init. |
|
(+) MspDeInitCallback : callback for Msp DeInit. |
|
(+) LrFhssHopCallback : callback for LoRa Frequency Hopping Spread Spectrum Hopping. |
|
This function takes as parameters the HAL peripheral handle, the Callback ID |
|
and a pointer to the user callback function. |
|
[..] |
|
For specific callback CADStatusCallback use dedicated register callbacks : |
|
@ref HAL_SUBGHZ_RegisterCadStatusCallback(). |
|
[..] |
|
Use function @ref HAL_SUBGHZ_UnRegisterCallback to reset a callback to the default |
|
weak function. |
|
@ref HAL_SUBGHZ_UnRegisterCallback takes as parameters the HAL peripheral handle, |
|
and the Callback ID. |
|
This function allows to reset following callbacks: |
|
(+) TxCpltCallback : callback for Tx Completed. |
|
(+) RxCpltCallback : callback for Rx Completed. |
|
(+) PreambleDetectedCallback : callback for Preamble detected. |
|
(+) SyncWordValidCallback : callback for Synchro word valid. |
|
(+) HeaderValidCallback : callback for Header valid. |
|
(+) HeaderErrorCallback : callback for Header error. |
|
(+) CRCErrorCallback : callback for CRC Error. |
|
(+) RxTxTimeoutCallback : callback for Rx Tx Timeout. |
|
(+) MspInitCallback : callback for Msp Init. |
|
(+) MspDeInitCallback : callback for Msp DeInit. |
|
(+) LrFhssHopCallback : callback for LoRa Frequency Hopping Spread Spectrum Hopping. |
|
[..] |
|
For specific callback CADStatusCallback use dedicated register callbacks : |
|
@ref HAL_SUBGHZ_UnRegisterCadStatusCallback(). |
|
[..] |
|
MspInit and MspDeInit functions are reset to the legacy weak functions in the |
|
@ref HAL_SUBGHZ_Init()/ @ref HAL_SUBGHZ_DeInit() only when these callbacks are null |
|
(not registered beforehand). |
|
If MspInit or MspDeInit are not null, the @ref HAL_SUBGHZ_Init()/ @ref HAL_SUBGHZ_DeInit() |
|
keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. |
|
|
|
[..] |
|
Callbacks for MspInit/MspDeInit functions can be registered/unregistered |
|
in @ref HAL_SUBGHZ_STATE_READY or @ref HAL_SUBGHZ_STATE_RESET state, |
|
thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. |
|
Then, the user first registers the MspInit/MspDeInit user callbacks |
|
using @ref HAL_SUBGHZ_RegisterCallback() before calling @ref HAL_SUBGHZ_DeInit() |
|
or @ref HAL_SUBGHZ_Init() function. |
|
|
|
[..] |
|
When the compilation flag USE_HAL_SUBGHZ_REGISTER_CALLBACKS is set to 0 or |
|
not defined, the callback registration feature is not available and all callbacks |
|
are set to the corresponding weak functions. |
|
#endif |
|
*/ |
|
|
|
/* Includes ------------------------------------------------------------------*/ |
|
#include "stm32wlxx_hal.h" |
|
|
|
/** @addtogroup STM32WLxx_HAL_Driver |
|
* @{ |
|
*/ |
|
|
|
/** @defgroup SUBGHZ SUBGHZ |
|
* @brief SUBGHZ HAL module driver |
|
* @{ |
|
*/ |
|
#ifdef HAL_SUBGHZ_MODULE_ENABLED |
|
|
|
/* Private typedef -----------------------------------------------------------*/ |
|
/* Private defines -----------------------------------------------------------*/ |
|
/** @defgroup SUBGHZ_Private_Constants SUBGHZ Private Constants |
|
* @{ |
|
*/ |
|
#define SUBGHZ_DEFAULT_TIMEOUT 100U /* HAL Timeout in ms */ |
|
#define SUBGHZ_DUMMY_DATA 0xFFU /* SUBGHZSPI Dummy Data use for Tx */ |
|
#define SUBGHZ_DEEP_SLEEP_ENABLE 1U /* SUBGHZ Radio in Deep Sleep */ |
|
#define SUBGHZ_DEEP_SLEEP_DISABLE 0U /* SUBGHZ Radio not in Deep Sleep */ |
|
|
|
/* SystemCoreClock dividers. Corresponding to time execution of while loop. */ |
|
#define SUBGHZ_DEFAULT_LOOP_TIME ((SystemCoreClock*28U)>>19U) |
|
#define SUBGHZ_RFBUSY_LOOP_TIME ((SystemCoreClock*24U)>>20U) |
|
#define SUBGHZ_NSS_LOOP_TIME ((SystemCoreClock*24U)>>16U) |
|
/** |
|
* @} |
|
*/ |
|
|
|
/* Private macros ------------------------------------------------------------*/ |
|
/* Private variables ---------------------------------------------------------*/ |
|
/* Private function prototypes -----------------------------------------------*/ |
|
/** @defgroup SUBGHZ_Private_Functions SUBGHZ Private Functions |
|
* @{ |
|
*/ |
|
void SUBGHZSPI_Init(uint32_t BaudratePrescaler); |
|
void SUBGHZSPI_DeInit(void); |
|
HAL_StatusTypeDef SUBGHZSPI_Transmit(SUBGHZ_HandleTypeDef *hsubghz, uint8_t Data); |
|
HAL_StatusTypeDef SUBGHZSPI_Receive(SUBGHZ_HandleTypeDef *hsubghz, uint8_t *pData); |
|
HAL_StatusTypeDef SUBGHZ_WaitOnBusy(SUBGHZ_HandleTypeDef *hsubghz); |
|
HAL_StatusTypeDef SUBGHZ_CheckDeviceReady(SUBGHZ_HandleTypeDef *hsubghz); |
|
/** |
|
* @} |
|
*/ |
|
|
|
/* Exported functions --------------------------------------------------------*/ |
|
/** @defgroup SUBGHZ_Exported_Functions SUBGHZ Exported Functions |
|
* @{ |
|
*/ |
|
|
|
/** @defgroup SUBGHZ_Exported_Functions_Group1 Initialization and de-initialization functions |
|
* @brief Initialization and Configuration functions |
|
* |
|
@verbatim |
|
=============================================================================== |
|
##### Initialization and de-initialization functions ##### |
|
=============================================================================== |
|
[..] This subsection provides a set of functions allowing to initialize and |
|
de-initialize the SUBGHZ peripheral: |
|
|
|
(+) User must implement HAL_SUBGHZ_MspInit() function in which he configures |
|
all related peripherals resources (CLOCK, GPIO, IT and NVIC ). |
|
|
|
(+) Call the function HAL_SUBGHZ_Init() to configure SUBGHZSPI peripheral |
|
and initialize SUBGHZ Handle. |
|
|
|
(+) Call the function HAL_SUBGHZ_DeInit() to restore the default configuration |
|
of the SUBGHZ peripheral. |
|
|
|
@endverbatim |
|
* @{ |
|
*/ |
|
|
|
/** |
|
* @brief Initialize the SUBGHZ according to the specified parameters |
|
* in the SUBGHZ_HandleTypeDef and initialize the associated handle. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @note In case of exiting from Standby mode, before calling this function, |
|
* set the state to HAL_SUBGHZ_STATE_RESET_RF_READY with __HAL_SUBGHZ_RESET_HANDLE_STATE_RF_READY |
|
* to avoid the reset of Radio peripheral. |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_Init(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
HAL_StatusTypeDef status; |
|
__IO uint32_t count; |
|
HAL_SUBGHZ_StateTypeDef subghz_state; |
|
|
|
/* Check the hsubghz handle allocation */ |
|
if (hsubghz == NULL) |
|
{ |
|
status = HAL_ERROR; |
|
return status; |
|
} |
|
else |
|
{ |
|
status = HAL_OK; |
|
} |
|
|
|
assert_param(IS_SUBGHZSPI_BAUDRATE_PRESCALER(hsubghz->Init.BaudratePrescaler)); |
|
|
|
subghz_state = hsubghz->State; |
|
if ((subghz_state == HAL_SUBGHZ_STATE_RESET) || |
|
(subghz_state == HAL_SUBGHZ_STATE_RESET_RF_READY)) |
|
{ |
|
/* Allocate lock resource and initialize it */ |
|
hsubghz->Lock = HAL_UNLOCKED; |
|
|
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1) |
|
/* Init the SUBGHZ Legacy weak Callback settings */ |
|
hsubghz->TxCpltCallback = HAL_SUBGHZ_TxCpltCallback; |
|
hsubghz->RxCpltCallback = HAL_SUBGHZ_RxCpltCallback; |
|
hsubghz->PreambleDetectedCallback = HAL_SUBGHZ_PreambleDetectedCallback; |
|
hsubghz->SyncWordValidCallback = HAL_SUBGHZ_SyncWordValidCallback; |
|
hsubghz->HeaderValidCallback = HAL_SUBGHZ_HeaderValidCallback; |
|
hsubghz->HeaderErrorCallback = HAL_SUBGHZ_HeaderErrorCallback; |
|
hsubghz->CRCErrorCallback = HAL_SUBGHZ_CRCErrorCallback; |
|
hsubghz->CADStatusCallback = HAL_SUBGHZ_CADStatusCallback; |
|
hsubghz->RxTxTimeoutCallback = HAL_SUBGHZ_RxTxTimeoutCallback; |
|
hsubghz->LrFhssHopCallback = HAL_SUBGHZ_LrFhssHopCallback; |
|
|
|
if (hsubghz->MspInitCallback == NULL) |
|
{ |
|
hsubghz->MspInitCallback = HAL_SUBGHZ_MspInit; /* Legacy weak MspInit */ |
|
} |
|
|
|
/* Init the low level hardware : GPIO, CLOCK, NVIC... */ |
|
hsubghz->MspInitCallback(hsubghz); |
|
#else |
|
/* Init the low level hardware : GPIO, CLOCK, NVIC... */ |
|
HAL_SUBGHZ_MspInit(hsubghz); |
|
#endif /* USE_HAL_ SUBGHZ_REGISTER_CALLBACKS */ |
|
|
|
#if defined(CM0PLUS) |
|
/* Enable EXTI 44 : Radio IRQ ITs for CPU2 */ |
|
LL_C2_EXTI_EnableIT_32_63(LL_EXTI_LINE_44); |
|
#else |
|
/* Enable EXTI 44 : Radio IRQ ITs for CPU1 */ |
|
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_44); |
|
#endif /* CM0PLUS */ |
|
} |
|
|
|
if (subghz_state == HAL_SUBGHZ_STATE_RESET) |
|
{ |
|
/* Reinitialize Radio peripheral only if SUBGHZ is in full RESET state */ |
|
hsubghz->State = HAL_SUBGHZ_STATE_BUSY; |
|
|
|
/* De-asserts the reset signal of the Radio peripheral */ |
|
LL_RCC_RF_DisableReset(); |
|
|
|
/* Verify that Radio in reset status flag is set */ |
|
count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME; |
|
|
|
do |
|
{ |
|
if (count == 0U) |
|
{ |
|
status = HAL_ERROR; |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT; |
|
break; |
|
} |
|
count--; |
|
} while (LL_RCC_IsRFUnderReset() != 0UL); |
|
|
|
/* Asserts the reset signal of the Radio peripheral */ |
|
LL_PWR_UnselectSUBGHZSPI_NSS(); |
|
|
|
#if defined(CM0PLUS) |
|
/* Enable wakeup signal of the Radio peripheral */ |
|
LL_C2_PWR_SetRadioBusyTrigger(LL_PWR_RADIO_BUSY_TRIGGER_WU_IT); |
|
#else |
|
/* Enable wakeup signal of the Radio peripheral */ |
|
LL_PWR_SetRadioBusyTrigger(LL_PWR_RADIO_BUSY_TRIGGER_WU_IT); |
|
#endif /* CM0PLUS */ |
|
} |
|
|
|
/* Clear Pending Flag */ |
|
LL_PWR_ClearFlag_RFBUSY(); |
|
|
|
if (status == HAL_OK) |
|
{ |
|
/* Initialize SUBGHZSPI Peripheral */ |
|
SUBGHZSPI_Init(hsubghz->Init.BaudratePrescaler); |
|
|
|
hsubghz->DeepSleep = SUBGHZ_DEEP_SLEEP_ENABLE; |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_NONE; |
|
} |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_READY; |
|
|
|
return status; |
|
} |
|
|
|
/** |
|
* @brief De-Initialize the SUBGHZ peripheral. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_DeInit(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
HAL_StatusTypeDef status; |
|
__IO uint32_t count; |
|
|
|
/* Check the SUBGHZ handle allocation */ |
|
if (hsubghz == NULL) |
|
{ |
|
status = HAL_ERROR; |
|
return status; |
|
} |
|
else |
|
{ |
|
status = HAL_OK; |
|
} |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_BUSY; |
|
|
|
/* DeInitialize SUBGHZSPI Peripheral */ |
|
SUBGHZSPI_DeInit(); |
|
|
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1) |
|
if (hsubghz->MspDeInitCallback == NULL) |
|
{ |
|
hsubghz->MspDeInitCallback = HAL_SUBGHZ_MspDeInit; /* Legacy weak MspDeInit */ |
|
} |
|
|
|
/* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ |
|
hsubghz->MspDeInitCallback(hsubghz); |
|
#else |
|
/* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ |
|
HAL_SUBGHZ_MspDeInit(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
|
|
#if defined(CM0PLUS) |
|
/* Disable EXTI 44 : Radio IRQ ITs for CPU2 */ |
|
LL_C2_EXTI_DisableIT_32_63(LL_EXTI_LINE_44); |
|
|
|
/* Disable wakeup signal of the Radio peripheral */ |
|
LL_C2_PWR_SetRadioBusyTrigger(LL_PWR_RADIO_BUSY_TRIGGER_NONE); |
|
#else |
|
/* Disable EXTI 44 : Radio IRQ ITs for CPU1 */ |
|
LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_44); |
|
|
|
/* Disable wakeup signal of the Radio peripheral */ |
|
LL_PWR_SetRadioBusyTrigger(LL_PWR_RADIO_BUSY_TRIGGER_NONE); |
|
#endif /* CM0PLUS */ |
|
|
|
/* Clear Pending Flag */ |
|
LL_PWR_ClearFlag_RFBUSY(); |
|
|
|
/* Re-asserts the reset signal of the Radio peripheral */ |
|
LL_RCC_RF_EnableReset(); |
|
|
|
/* Verify that Radio in reset status flag is set */ |
|
count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME; |
|
|
|
do |
|
{ |
|
if (count == 0U) |
|
{ |
|
status = HAL_ERROR; |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT; |
|
break; |
|
} |
|
count--; |
|
} while (LL_RCC_IsRFUnderReset() != 1UL); |
|
|
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_NONE; |
|
hsubghz->State = HAL_SUBGHZ_STATE_RESET; |
|
|
|
/* Release Lock */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
|
|
/** |
|
* @brief Initialize the SUBGHZ MSP. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_MspInit(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_MspInit should be implemented in the user file |
|
*/ |
|
|
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
} |
|
|
|
/** |
|
* @brief De-Initialize the SUBGHZ MSP. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_MspDeInit(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_MspDeInit should be implemented in the user file |
|
*/ |
|
|
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
} |
|
|
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1) |
|
/** |
|
* @brief Register a User SUBGHZ Callback |
|
* To be used instead of the weak predefined callback |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param CallbackID ID of the callback to be registered |
|
* @param pCallback pointer to the Callback function |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_RegisterCallback(SUBGHZ_HandleTypeDef *hsubghz, |
|
HAL_SUBGHZ_CallbackIDTypeDef CallbackID, |
|
pSUBGHZ_CallbackTypeDef pCallback) |
|
{ |
|
HAL_StatusTypeDef status = HAL_OK; |
|
|
|
if (pCallback == NULL) |
|
{ |
|
/* Update the error code */ |
|
hsubghz->ErrorCode |= HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
return HAL_ERROR; |
|
} |
|
|
|
/* Process locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
if (HAL_SUBGHZ_STATE_READY == hsubghz->State) |
|
{ |
|
switch (CallbackID) |
|
{ |
|
case HAL_SUBGHZ_TX_COMPLETE_CB_ID : |
|
hsubghz->TxCpltCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_RX_COMPLETE_CB_ID : |
|
hsubghz->RxCpltCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_PREAMBLE_DETECTED_CB_ID : |
|
hsubghz->PreambleDetectedCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_SYNCWORD_VALID_CB_ID : |
|
hsubghz->SyncWordValidCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_HEADER_VALID_CB_ID : |
|
hsubghz->HeaderValidCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_HEADER_ERROR_CB_ID : |
|
hsubghz->HeaderErrorCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_CRC_ERROR_CB_ID : |
|
hsubghz->CRCErrorCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_RX_TX_TIMEOUT_CB_ID : |
|
hsubghz->RxTxTimeoutCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_MSPINIT_CB_ID : |
|
hsubghz->MspInitCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_MSPDEINIT_CB_ID : |
|
hsubghz->MspDeInitCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_LR_FHSS_HOP_CB_ID : |
|
hsubghz->LrFhssHopCallback = pCallback; |
|
break; |
|
|
|
default : |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
/* Return error status */ |
|
status = HAL_ERROR; |
|
break; |
|
} |
|
} |
|
else if (HAL_SUBGHZ_STATE_RESET == hsubghz->State) |
|
{ |
|
switch (CallbackID) |
|
{ |
|
case HAL_SUBGHZ_MSPINIT_CB_ID : |
|
hsubghz->MspInitCallback = pCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_MSPDEINIT_CB_ID : |
|
hsubghz->MspDeInitCallback = pCallback; |
|
break; |
|
|
|
default : |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
/* Return error status */ |
|
status = HAL_ERROR; |
|
break; |
|
} |
|
} |
|
else |
|
{ |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
/* Return error status */ |
|
status = HAL_ERROR; |
|
} |
|
|
|
/* Release Lock */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
|
|
/** |
|
* @brief Unregister an SUBGHZ Callback |
|
* SUBGHZ callback is redirected to the weak predefined callback |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param CallbackID ID of the callback to be unregistered |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_UnRegisterCallback(SUBGHZ_HandleTypeDef *hsubghz, |
|
HAL_SUBGHZ_CallbackIDTypeDef CallbackID) |
|
{ |
|
HAL_StatusTypeDef status = HAL_OK; |
|
|
|
/* Process locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
if (HAL_SUBGHZ_STATE_READY == hsubghz->State) |
|
{ |
|
/* call legacy weak callback function */ |
|
switch (CallbackID) |
|
{ |
|
case HAL_SUBGHZ_TX_COMPLETE_CB_ID : |
|
hsubghz->TxCpltCallback = HAL_SUBGHZ_TxCpltCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_RX_COMPLETE_CB_ID : |
|
hsubghz->RxCpltCallback = HAL_SUBGHZ_RxCpltCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_PREAMBLE_DETECTED_CB_ID : |
|
hsubghz->PreambleDetectedCallback = HAL_SUBGHZ_PreambleDetectedCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_SYNCWORD_VALID_CB_ID : |
|
hsubghz->SyncWordValidCallback = HAL_SUBGHZ_SyncWordValidCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_HEADER_VALID_CB_ID : |
|
hsubghz->HeaderValidCallback = HAL_SUBGHZ_HeaderValidCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_HEADER_ERROR_CB_ID : |
|
hsubghz->HeaderErrorCallback = HAL_SUBGHZ_HeaderErrorCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_CRC_ERROR_CB_ID : |
|
hsubghz->CRCErrorCallback = HAL_SUBGHZ_CRCErrorCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_RX_TX_TIMEOUT_CB_ID : |
|
hsubghz->RxTxTimeoutCallback = HAL_SUBGHZ_RxTxTimeoutCallback; |
|
break; |
|
|
|
case HAL_SUBGHZ_MSPINIT_CB_ID : |
|
hsubghz->MspInitCallback = HAL_SUBGHZ_MspInit; |
|
break; |
|
|
|
case HAL_SUBGHZ_MSPDEINIT_CB_ID : |
|
hsubghz->MspDeInitCallback = HAL_SUBGHZ_MspDeInit; |
|
break; |
|
|
|
case HAL_SUBGHZ_LR_FHSS_HOP_CB_ID : |
|
hsubghz->LrFhssHopCallback = HAL_SUBGHZ_LrFhssHopCallback; |
|
break; |
|
|
|
default : |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
/* Return error status */ |
|
status = HAL_ERROR; |
|
break; |
|
} |
|
} |
|
else if (HAL_SUBGHZ_STATE_RESET == hsubghz->State) |
|
{ |
|
switch (CallbackID) |
|
{ |
|
case HAL_SUBGHZ_MSPINIT_CB_ID : |
|
hsubghz->MspInitCallback = HAL_SUBGHZ_MspInit; |
|
break; |
|
|
|
case HAL_SUBGHZ_MSPDEINIT_CB_ID : |
|
hsubghz->MspDeInitCallback = HAL_SUBGHZ_MspDeInit; |
|
break; |
|
|
|
default : |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
/* Return error status */ |
|
status = HAL_ERROR; |
|
break; |
|
} |
|
} |
|
else |
|
{ |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
/* Return error status */ |
|
status = HAL_ERROR; |
|
} |
|
|
|
/* Release Lock */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
|
|
/** |
|
* @brief Register the channel activity detection status SUBGHZ Callback |
|
* To be used instead of the weak HAL_SUBGHZ_AddrCallback() predefined callback |
|
* @param hsubghz Pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param pCallback pointer to the CAD Status Callback function |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_RegisterCadStatusCallback(SUBGHZ_HandleTypeDef *hsubghz, |
|
pSUBGHZ_CadStatusCallbackTypeDef pCallback) |
|
{ |
|
HAL_StatusTypeDef status = HAL_OK; |
|
|
|
if (pCallback == NULL) |
|
{ |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
return HAL_ERROR; |
|
} |
|
/* Process locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
if (HAL_SUBGHZ_STATE_READY == hsubghz->State) |
|
{ |
|
hsubghz->CADStatusCallback = pCallback; |
|
} |
|
else |
|
{ |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
/* Return error status */ |
|
status = HAL_ERROR; |
|
} |
|
|
|
/* Release Lock */ |
|
__HAL_UNLOCK(hsubghz); |
|
return status; |
|
} |
|
|
|
/** |
|
* @brief UnRegister the channel activity detection status SUBGHZ Callback |
|
* @param hsubghz Pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_UnRegisterCadStatusCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
HAL_StatusTypeDef status = HAL_OK; |
|
|
|
/* Process locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
if (HAL_SUBGHZ_STATE_READY == hsubghz->State) |
|
{ |
|
hsubghz->CADStatusCallback = HAL_SUBGHZ_CADStatusCallback; /* Legacy weak AddrCallback */ |
|
} |
|
else |
|
{ |
|
/* Update the error code */ |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_INVALID_CALLBACK; |
|
|
|
/* Return error status */ |
|
status = HAL_ERROR; |
|
} |
|
|
|
/* Release Lock */ |
|
__HAL_UNLOCK(hsubghz); |
|
return status; |
|
} |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
/** |
|
* @} |
|
*/ |
|
|
|
/** @defgroup SUBGHZ_Exported_Functions_Group2 IO operation functions |
|
* @brief Data transfers functions |
|
* |
|
@verbatim |
|
============================================================================== |
|
##### IO operation functions ##### |
|
=============================================================================== |
|
[..] |
|
This subsection provides a set of functions allowing to manage the SUBGHZ |
|
data transfers. |
|
|
|
[..] The SUBGHZ supports Read and Write operation: |
|
|
|
(#) There are four modes of transfer: |
|
(++) Set operation: The Set Command operation is performed in polling mode. |
|
The HAL status of command processing is returned by the same function |
|
after finishing transfer. |
|
(++) Get operation: The Get Status operation is performed using polling mode |
|
These API update buffer in parameter to retrieve status of command. |
|
These API return the HAL status |
|
(++) Write operation: The write operation is performed in polling mode. |
|
The HAL status of all data processing is returned by the same function |
|
after finishing transfer. |
|
(++) Read operation: The read operation is performed using polling mode |
|
These APIs return the HAL status. |
|
|
|
(#) Blocking mode functions are : |
|
(++) HAL_SUBGHZ_ExecSetCmd( |
|
(++) HAL_SUBGHZ_ExecGetCmd() |
|
(++) HAL_SUBGHZ_WriteBuffer() |
|
(++) HAL_SUBGHZ_ReadBuffer() |
|
(++) HAL_SUBGHZ_WriteRegisters() |
|
(++) HAL_SUBGHZ_ReadRegisters() |
|
(++) HAL_SUBGHZ_WriteRegister() |
|
(++) HAL_SUBGHZ_ReadRegister() |
|
|
|
@endverbatim |
|
* @{ |
|
*/ |
|
|
|
/** |
|
* @brief Write data buffer at an Address to configurate the peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param Address register to configurate |
|
* @param pBuffer pointer to a data buffer |
|
* @param Size amount of data to be sent |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_WriteRegisters(SUBGHZ_HandleTypeDef *hsubghz, |
|
uint16_t Address, |
|
uint8_t *pBuffer, |
|
uint16_t Size) |
|
{ |
|
HAL_StatusTypeDef status; |
|
|
|
if (hsubghz->State == HAL_SUBGHZ_STATE_READY) |
|
{ |
|
/* Process Locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_BUSY; |
|
|
|
(void)SUBGHZ_CheckDeviceReady(hsubghz); |
|
|
|
/* NSS = 0 */ |
|
LL_PWR_SelectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZSPI_Transmit(hsubghz, SUBGHZ_RADIO_WRITE_REGISTER); |
|
(void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)((Address & 0xFF00U) >> 8U)); |
|
(void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)(Address & 0x00FFU)); |
|
|
|
for (uint16_t i = 0U; i < Size; i++) |
|
{ |
|
(void)SUBGHZSPI_Transmit(hsubghz, pBuffer[i]); |
|
} |
|
|
|
/* NSS = 1 */ |
|
LL_PWR_UnselectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZ_WaitOnBusy(hsubghz); |
|
|
|
if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE) |
|
{ |
|
status = HAL_ERROR; |
|
} |
|
else |
|
{ |
|
status = HAL_OK; |
|
} |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_READY; |
|
|
|
/* Process Unlocked */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
else |
|
{ |
|
return HAL_BUSY; |
|
} |
|
} |
|
|
|
/** |
|
* @brief Read data register at an Address in the peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param Address register to configurate |
|
* @param pBuffer pointer to a data buffer |
|
* @param Size amount of data to be sent |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_ReadRegisters(SUBGHZ_HandleTypeDef *hsubghz, |
|
uint16_t Address, |
|
uint8_t *pBuffer, |
|
uint16_t Size) |
|
{ |
|
HAL_StatusTypeDef status; |
|
uint8_t *pData = pBuffer; |
|
|
|
if (hsubghz->State == HAL_SUBGHZ_STATE_READY) |
|
{ |
|
/* Process Locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
(void)SUBGHZ_CheckDeviceReady(hsubghz); |
|
|
|
/* NSS = 0 */ |
|
LL_PWR_SelectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZSPI_Transmit(hsubghz, SUBGHZ_RADIO_READ_REGISTER); |
|
(void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)((Address & 0xFF00U) >> 8U)); |
|
(void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)(Address & 0x00FFU)); |
|
(void)SUBGHZSPI_Transmit(hsubghz, 0U); |
|
|
|
for (uint16_t i = 0U; i < Size; i++) |
|
{ |
|
(void)SUBGHZSPI_Receive(hsubghz, (pData)); |
|
pData++; |
|
} |
|
|
|
/* NSS = 1 */ |
|
LL_PWR_UnselectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZ_WaitOnBusy(hsubghz); |
|
|
|
if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE) |
|
{ |
|
status = HAL_ERROR; |
|
} |
|
else |
|
{ |
|
status = HAL_OK; |
|
} |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_READY; |
|
|
|
/* Process Unlocked */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
else |
|
{ |
|
return HAL_BUSY; |
|
} |
|
} |
|
|
|
/** |
|
* @brief Write one data at an Address to configurate the peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param Address register to configurate |
|
* @param Value data |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_WriteRegister(SUBGHZ_HandleTypeDef *hsubghz, |
|
uint16_t Address, |
|
uint8_t Value) |
|
{ |
|
return (HAL_SUBGHZ_WriteRegisters(hsubghz, Address, &Value, 1U)); |
|
} |
|
|
|
/** |
|
* @brief Read data register at an Address in the peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param Address register to configurate |
|
* @param pValue pointer to a data |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_ReadRegister(SUBGHZ_HandleTypeDef *hsubghz, |
|
uint16_t Address, |
|
uint8_t *pValue) |
|
{ |
|
return (HAL_SUBGHZ_ReadRegisters(hsubghz, Address, pValue, 1U)); |
|
} |
|
|
|
/** |
|
* @brief Send a command to configure the peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param Command configuration for peripheral |
|
* @param pBuffer pointer to a data buffer |
|
* @param Size amount of data to be sent |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_ExecSetCmd(SUBGHZ_HandleTypeDef *hsubghz, |
|
SUBGHZ_RadioSetCmd_t Command, |
|
uint8_t *pBuffer, |
|
uint16_t Size) |
|
{ |
|
HAL_StatusTypeDef status; |
|
|
|
/* LORA Modulation not available on STM32WLx4xx devices */ |
|
assert_param(IS_SUBGHZ_MODULATION_SUPPORTED(Command, pBuffer[0U])); |
|
|
|
if (hsubghz->State == HAL_SUBGHZ_STATE_READY) |
|
{ |
|
/* Process Locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
/* Need to wakeup Radio if already in Sleep at startup */ |
|
(void)SUBGHZ_CheckDeviceReady(hsubghz); |
|
|
|
if ((Command == RADIO_SET_SLEEP) || (Command == RADIO_SET_RXDUTYCYCLE)) |
|
{ |
|
hsubghz->DeepSleep = SUBGHZ_DEEP_SLEEP_ENABLE; |
|
} |
|
else |
|
{ |
|
hsubghz->DeepSleep = SUBGHZ_DEEP_SLEEP_DISABLE; |
|
} |
|
|
|
/* NSS = 0 */ |
|
LL_PWR_SelectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)Command); |
|
|
|
for (uint16_t i = 0U; i < Size; i++) |
|
{ |
|
(void)SUBGHZSPI_Transmit(hsubghz, pBuffer[i]); |
|
} |
|
|
|
/* NSS = 1 */ |
|
LL_PWR_UnselectSUBGHZSPI_NSS(); |
|
|
|
if (Command != RADIO_SET_SLEEP) |
|
{ |
|
(void)SUBGHZ_WaitOnBusy(hsubghz); |
|
} |
|
|
|
if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE) |
|
{ |
|
status = HAL_ERROR; |
|
} |
|
else |
|
{ |
|
status = HAL_OK; |
|
} |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_READY; |
|
|
|
/* Process Unlocked */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
else |
|
{ |
|
return HAL_BUSY; |
|
} |
|
} |
|
|
|
/** |
|
* @brief Retrieve a status from the peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param Command configuration for peripheral |
|
* @param pBuffer pointer to a data buffer |
|
* @param Size amount of data to be sent |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_ExecGetCmd(SUBGHZ_HandleTypeDef *hsubghz, |
|
SUBGHZ_RadioGetCmd_t Command, |
|
uint8_t *pBuffer, |
|
uint16_t Size) |
|
{ |
|
HAL_StatusTypeDef status; |
|
uint8_t *pData = pBuffer; |
|
|
|
if (hsubghz->State == HAL_SUBGHZ_STATE_READY) |
|
{ |
|
/* Process Locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
(void)SUBGHZ_CheckDeviceReady(hsubghz); |
|
|
|
/* NSS = 0 */ |
|
LL_PWR_SelectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZSPI_Transmit(hsubghz, (uint8_t)Command); |
|
|
|
/* Use to flush the Status (First byte) receive from SUBGHZ as not use */ |
|
(void)SUBGHZSPI_Transmit(hsubghz, 0x00U); |
|
|
|
for (uint16_t i = 0U; i < Size; i++) |
|
{ |
|
(void)SUBGHZSPI_Receive(hsubghz, (pData)); |
|
pData++; |
|
} |
|
|
|
/* NSS = 1 */ |
|
LL_PWR_UnselectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZ_WaitOnBusy(hsubghz); |
|
|
|
if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE) |
|
{ |
|
status = HAL_ERROR; |
|
} |
|
else |
|
{ |
|
status = HAL_OK; |
|
} |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_READY; |
|
|
|
/* Process Unlocked */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
else |
|
{ |
|
return HAL_BUSY; |
|
} |
|
} |
|
|
|
/** |
|
* @brief Write data buffer inside payload of peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param Offset Offset inside payload |
|
* @param pBuffer pointer to a data buffer |
|
* @param Size amount of data to be sent |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_WriteBuffer(SUBGHZ_HandleTypeDef *hsubghz, |
|
uint8_t Offset, |
|
uint8_t *pBuffer, |
|
uint16_t Size) |
|
{ |
|
HAL_StatusTypeDef status; |
|
|
|
if (hsubghz->State == HAL_SUBGHZ_STATE_READY) |
|
{ |
|
/* Process Locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
(void)SUBGHZ_CheckDeviceReady(hsubghz); |
|
|
|
/* NSS = 0 */ |
|
LL_PWR_SelectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZSPI_Transmit(hsubghz, SUBGHZ_RADIO_WRITE_BUFFER); |
|
(void)SUBGHZSPI_Transmit(hsubghz, Offset); |
|
|
|
for (uint16_t i = 0U; i < Size; i++) |
|
{ |
|
(void)SUBGHZSPI_Transmit(hsubghz, pBuffer[i]); |
|
} |
|
/* NSS = 1 */ |
|
LL_PWR_UnselectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZ_WaitOnBusy(hsubghz); |
|
|
|
if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE) |
|
{ |
|
status = HAL_ERROR; |
|
} |
|
else |
|
{ |
|
status = HAL_OK; |
|
} |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_READY; |
|
|
|
/* Process Unlocked */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
else |
|
{ |
|
return HAL_BUSY; |
|
} |
|
} |
|
|
|
/** |
|
* @brief Read data buffer inside payload of peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ. |
|
* @param Offset Offset inside payload |
|
* @param pBuffer pointer to a data buffer |
|
* @param Size amount of data to be sent |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef HAL_SUBGHZ_ReadBuffer(SUBGHZ_HandleTypeDef *hsubghz, |
|
uint8_t Offset, |
|
uint8_t *pBuffer, |
|
uint16_t Size) |
|
{ |
|
HAL_StatusTypeDef status; |
|
uint8_t *pData = pBuffer; |
|
|
|
if (hsubghz->State == HAL_SUBGHZ_STATE_READY) |
|
{ |
|
/* Process Locked */ |
|
__HAL_LOCK(hsubghz); |
|
|
|
(void)SUBGHZ_CheckDeviceReady(hsubghz); |
|
|
|
/* NSS = 0 */ |
|
LL_PWR_SelectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZSPI_Transmit(hsubghz, SUBGHZ_RADIO_READ_BUFFER); |
|
(void)SUBGHZSPI_Transmit(hsubghz, Offset); |
|
(void)SUBGHZSPI_Transmit(hsubghz, 0x00U); |
|
|
|
for (uint16_t i = 0U; i < Size; i++) |
|
{ |
|
(void)SUBGHZSPI_Receive(hsubghz, (pData)); |
|
pData++; |
|
} |
|
|
|
/* NSS = 1 */ |
|
LL_PWR_UnselectSUBGHZSPI_NSS(); |
|
|
|
(void)SUBGHZ_WaitOnBusy(hsubghz); |
|
|
|
if (hsubghz->ErrorCode != HAL_SUBGHZ_ERROR_NONE) |
|
{ |
|
status = HAL_ERROR; |
|
} |
|
else |
|
{ |
|
status = HAL_OK; |
|
} |
|
|
|
hsubghz->State = HAL_SUBGHZ_STATE_READY; |
|
|
|
/* Process Unlocked */ |
|
__HAL_UNLOCK(hsubghz); |
|
|
|
return status; |
|
} |
|
else |
|
{ |
|
return HAL_BUSY; |
|
} |
|
} |
|
|
|
/** |
|
* @brief Handle SUBGHZ interrupt request. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for the specified SUBGHZ module. |
|
* @retval None |
|
*/ |
|
void HAL_SUBGHZ_IRQHandler(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
uint8_t tmpisr[2U] = {0U}; |
|
uint16_t itsource; |
|
|
|
/* Retrieve Interrupts from SUBGHZ Irq Register */ |
|
(void)HAL_SUBGHZ_ExecGetCmd(hsubghz, RADIO_GET_IRQSTATUS, tmpisr, 2U); |
|
itsource = tmpisr[0U]; |
|
itsource = (itsource << 8U) | tmpisr[1U]; |
|
|
|
/* Clear SUBGHZ Irq Register */ |
|
(void)HAL_SUBGHZ_ExecSetCmd(hsubghz, RADIO_CLR_IRQSTATUS, tmpisr, 2U); |
|
|
|
/* Packet transmission completed Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_TX_CPLT) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->TxCpltCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_TxCpltCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* Packet received Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_RX_CPLT) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->RxCpltCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_RxCpltCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* Preamble Detected Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_PREAMBLE_DETECTED) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->PreambleDetectedCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_PreambleDetectedCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* Valid sync word detected Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_SYNCWORD_VALID) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->SyncWordValidCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_SyncWordValidCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* Valid LoRa header received Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_HEADER_VALID) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->HeaderValidCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_HeaderValidCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* LoRa header CRC error Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_HEADER_ERROR) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->HeaderErrorCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_HeaderErrorCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* Wrong CRC received Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_CRC_ERROR) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->CRCErrorCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_CRCErrorCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* Channel activity detection finished Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_CAD_DONE) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
/* Channel activity Detected Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_CAD_ACTIVITY_DETECTED) != RESET) |
|
{ |
|
hsubghz->CADStatusCallback(hsubghz, HAL_SUBGHZ_CAD_DETECTED); |
|
} |
|
else |
|
{ |
|
hsubghz->CADStatusCallback(hsubghz, HAL_SUBGHZ_CAD_CLEAR); |
|
} |
|
#else |
|
/* Channel activity Detected Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_CAD_ACTIVITY_DETECTED) != RESET) |
|
{ |
|
HAL_SUBGHZ_CADStatusCallback(hsubghz, HAL_SUBGHZ_CAD_DETECTED); |
|
} |
|
else |
|
{ |
|
HAL_SUBGHZ_CADStatusCallback(hsubghz, HAL_SUBGHZ_CAD_CLEAR); |
|
} |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* Rx or Tx Timeout Interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_RX_TX_TIMEOUT) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->RxTxTimeoutCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_RxTxTimeoutCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
|
|
/* LR_FHSS Hop interrupt */ |
|
if (SUBGHZ_CHECK_IT_SOURCE(itsource, SUBGHZ_IT_LR_FHSS_HOP) != RESET) |
|
{ |
|
#if (USE_HAL_SUBGHZ_REGISTER_CALLBACKS == 1U) |
|
hsubghz->LrFhssHopCallback(hsubghz); |
|
#else |
|
HAL_SUBGHZ_LrFhssHopCallback(hsubghz); |
|
#endif /* USE_HAL_SUBGHZ_REGISTER_CALLBACKS */ |
|
} |
|
} |
|
|
|
/** |
|
* @brief Packet transmission completed callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_TxCpltCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_TxCpltCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief Packet received callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_RxCpltCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_RxCpltCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief Preamble Detected callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_PreambleDetectedCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_PreambleDetectedCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief Valid sync word detected callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_SyncWordValidCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_SyncWordValidCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief Valid LoRa header received callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_HeaderValidCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_HeaderValidCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief LoRa header CRC error callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_HeaderErrorCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_HeaderErrorCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief Wrong CRC received callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_CRCErrorCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_CRCErrorCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief Channel activity detection status callback. |
|
* @note Unified callback for CAD Done and CAD activity interrupts. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @param cadstatus reports whether activity is detected or not |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_CADStatusCallback(SUBGHZ_HandleTypeDef *hsubghz, |
|
HAL_SUBGHZ_CadStatusTypeDef cadstatus) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
UNUSED(cadstatus); |
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_CADStatusCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief Rx or Tx Timeout callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_RxTxTimeoutCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_RxTxTimeoutCallback should be implemented in the user file |
|
*/ |
|
} |
|
|
|
/** |
|
* @brief LR FHSS Hop callback. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the configuration information for SUBGHZ module. |
|
* @retval None |
|
*/ |
|
__weak void HAL_SUBGHZ_LrFhssHopCallback(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Prevent unused argument(s) compilation warning */ |
|
UNUSED(hsubghz); |
|
|
|
/* NOTE : This function should not be modified, when the callback is needed, |
|
the HAL_SUBGHZ_LrFhssHopCallback should be implemented in the user file |
|
*/ |
|
} |
|
/** |
|
* @} |
|
*/ |
|
|
|
/** @defgroup SUBGHZ_Exported_Functions_Group3 Peripheral State and Errors functions |
|
* @brief SUBGHZ control functions |
|
* |
|
@verbatim |
|
=============================================================================== |
|
##### Peripheral State and Errors functions ##### |
|
=============================================================================== |
|
[..] |
|
This subsection provides a set of functions allowing to control the SUBGHZ. |
|
(+) HAL_SUBGHZ_GetState() API can be helpful to check in run-time the state of the SUBGHZ peripheral |
|
(+) HAL_SUBGHZ_GetError() check in run-time Errors occurring during communication |
|
@endverbatim |
|
* @{ |
|
*/ |
|
|
|
/** |
|
* @brief Return the SUBGHZ handle state. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @retval SUBGHZ state |
|
*/ |
|
HAL_SUBGHZ_StateTypeDef HAL_SUBGHZ_GetState(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Return SUBGHZ handle state */ |
|
return hsubghz->State; |
|
} |
|
|
|
/** |
|
* @brief Return the SUBGHZ error code. |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @retval SUBGHZ error code in bitmap format |
|
*/ |
|
uint32_t HAL_SUBGHZ_GetError(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
/* Return SUBGHZ ErrorCode */ |
|
return hsubghz->ErrorCode; |
|
} |
|
|
|
/** |
|
* @} |
|
*/ |
|
|
|
/** |
|
* @} |
|
*/ |
|
|
|
/** @addtogroup SUBGHZ_Private_Functions |
|
* @brief Private functions |
|
* @{ |
|
*/ |
|
|
|
/** |
|
* @brief Initializes the SUBGHZSPI peripheral |
|
* @param BaudratePrescaler SPI Baudrate prescaler |
|
* @retval None |
|
*/ |
|
void SUBGHZSPI_Init(uint32_t BaudratePrescaler) |
|
{ |
|
/* Check the parameters */ |
|
assert_param(IS_SUBGHZ_ALL_INSTANCE(SUBGHZSPI)); |
|
|
|
/* Disable SUBGHZSPI Peripheral */ |
|
CLEAR_BIT(SUBGHZSPI->CR1, SPI_CR1_SPE); |
|
|
|
/*----------------------- SPI CR1 Configuration ----------------------------* |
|
* SPI Mode: Master * |
|
* Communication Mode: 2 lines (Full-Duplex) * |
|
* Clock polarity: Low * |
|
* phase: 1st Edge * |
|
* NSS management: Internal (Done with External bit inside PWR * |
|
* Communication speed: BaudratePrescaler * |
|
* First bit: MSB * |
|
* CRC calculation: Disable * |
|
*--------------------------------------------------------------------------*/ |
|
WRITE_REG(SUBGHZSPI->CR1, (SPI_CR1_MSTR | SPI_CR1_SSI | BaudratePrescaler | SPI_CR1_SSM)); |
|
|
|
/*----------------------- SPI CR2 Configuration ----------------------------* |
|
* Data Size: 8bits * |
|
* TI Mode: Disable * |
|
* NSS Pulse: Disable * |
|
* Rx FIFO Threshold: 8bits * |
|
*--------------------------------------------------------------------------*/ |
|
WRITE_REG(SUBGHZSPI->CR2, (SPI_CR2_FRXTH | SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2)); |
|
|
|
/* Enable SUBGHZSPI Peripheral */ |
|
SET_BIT(SUBGHZSPI->CR1, SPI_CR1_SPE); |
|
} |
|
|
|
/** |
|
* @brief DeInitializes the SUBGHZSPI peripheral |
|
* @retval None |
|
*/ |
|
void SUBGHZSPI_DeInit(void) |
|
{ |
|
/* Check the parameters */ |
|
assert_param(IS_SUBGHZ_ALL_INSTANCE(SUBGHZSPI)); |
|
|
|
/* Disable SUBGHZSPI Peripheral */ |
|
CLEAR_BIT(SUBGHZSPI->CR1, SPI_CR1_SPE); |
|
} |
|
|
|
/** |
|
* @brief Transmit data through SUBGHZSPI peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @param Data data to transmit |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef SUBGHZSPI_Transmit(SUBGHZ_HandleTypeDef *hsubghz, |
|
uint8_t Data) |
|
{ |
|
HAL_StatusTypeDef status = HAL_OK; |
|
__IO uint32_t count; |
|
|
|
/* Handle Tx transmission from SUBGHZSPI peripheral to Radio ****************/ |
|
/* Initialize Timeout */ |
|
count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME; |
|
|
|
/* Wait until TXE flag is set */ |
|
do |
|
{ |
|
if (count == 0U) |
|
{ |
|
status = HAL_ERROR; |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT; |
|
break; |
|
} |
|
count--; |
|
} while (READ_BIT(SUBGHZSPI->SR, SPI_SR_TXE) != (SPI_SR_TXE)); |
|
|
|
/* Transmit Data*/ |
|
#if defined (__GNUC__) |
|
__IO uint8_t *spidr = ((__IO uint8_t *)&SUBGHZSPI->DR); |
|
*spidr = Data; |
|
#else |
|
*((__IO uint8_t *)&SUBGHZSPI->DR) = Data; |
|
#endif /* __GNUC__ */ |
|
|
|
/* Handle Rx transmission from SUBGHZSPI peripheral to Radio ****************/ |
|
/* Initialize Timeout */ |
|
count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME; |
|
|
|
/* Wait until RXNE flag is set */ |
|
do |
|
{ |
|
if (count == 0U) |
|
{ |
|
status = HAL_ERROR; |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT; |
|
break; |
|
} |
|
count--; |
|
} while (READ_BIT(SUBGHZSPI->SR, SPI_SR_RXNE) != (SPI_SR_RXNE)); |
|
|
|
/* Flush Rx data */ |
|
READ_REG(SUBGHZSPI->DR); |
|
|
|
return status; |
|
} |
|
|
|
/** |
|
* @brief Receive data through SUBGHZSPI peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @param pData pointer on data to receive |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef SUBGHZSPI_Receive(SUBGHZ_HandleTypeDef *hsubghz, |
|
uint8_t *pData) |
|
{ |
|
HAL_StatusTypeDef status = HAL_OK; |
|
__IO uint32_t count; |
|
|
|
/* Handle Tx transmission from SUBGHZSPI peripheral to Radio ****************/ |
|
/* Initialize Timeout */ |
|
count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME; |
|
|
|
/* Wait until TXE flag is set */ |
|
do |
|
{ |
|
if (count == 0U) |
|
{ |
|
status = HAL_ERROR; |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT; |
|
break; |
|
} |
|
count--; |
|
} while (READ_BIT(SUBGHZSPI->SR, SPI_SR_TXE) != (SPI_SR_TXE)); |
|
|
|
/* Transmit Data*/ |
|
#if defined (__GNUC__) |
|
__IO uint8_t *spidr = ((__IO uint8_t *)&SUBGHZSPI->DR); |
|
*spidr = SUBGHZ_DUMMY_DATA; |
|
#else |
|
*((__IO uint8_t *)&SUBGHZSPI->DR) = SUBGHZ_DUMMY_DATA; |
|
#endif /* __GNUC__ */ |
|
|
|
/* Handle Rx transmission from SUBGHZSPI peripheral to Radio ****************/ |
|
/* Initialize Timeout */ |
|
count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_DEFAULT_LOOP_TIME; |
|
|
|
/* Wait until RXNE flag is set */ |
|
do |
|
{ |
|
if (count == 0U) |
|
{ |
|
status = HAL_ERROR; |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_TIMEOUT; |
|
break; |
|
} |
|
count--; |
|
} while (READ_BIT(SUBGHZSPI->SR, SPI_SR_RXNE) != (SPI_SR_RXNE)); |
|
|
|
/* Retrieve pData */ |
|
*pData = (uint8_t)(READ_REG(SUBGHZSPI->DR)); |
|
|
|
return status; |
|
} |
|
|
|
/** |
|
* @brief Check if peripheral is ready |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef SUBGHZ_CheckDeviceReady(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
__IO uint32_t count; |
|
|
|
/* Wakeup radio in case of sleep mode: Select-Unselect radio */ |
|
if (hsubghz->DeepSleep == SUBGHZ_DEEP_SLEEP_ENABLE) |
|
{ |
|
/* Initialize NSS switch Delay */ |
|
count = SUBGHZ_NSS_LOOP_TIME; |
|
|
|
/* NSS = 0; */ |
|
LL_PWR_SelectSUBGHZSPI_NSS(); |
|
|
|
/* Wait Radio wakeup */ |
|
do |
|
{ |
|
count--; |
|
} while (count != 0UL); |
|
|
|
/* NSS = 1 */ |
|
LL_PWR_UnselectSUBGHZSPI_NSS(); |
|
} |
|
return (SUBGHZ_WaitOnBusy(hsubghz)); |
|
} |
|
|
|
/** |
|
* @brief Wait busy flag low from peripheral |
|
* @param hsubghz pointer to a SUBGHZ_HandleTypeDef structure that contains |
|
* the handle information for SUBGHZ module. |
|
* @retval HAL status |
|
*/ |
|
HAL_StatusTypeDef SUBGHZ_WaitOnBusy(SUBGHZ_HandleTypeDef *hsubghz) |
|
{ |
|
HAL_StatusTypeDef status; |
|
__IO uint32_t count; |
|
uint32_t mask; |
|
|
|
status = HAL_OK; |
|
count = SUBGHZ_DEFAULT_TIMEOUT * SUBGHZ_RFBUSY_LOOP_TIME; |
|
|
|
/* Wait until Busy signal is set */ |
|
do |
|
{ |
|
mask = LL_PWR_IsActiveFlag_RFBUSYMS(); |
|
|
|
if (count == 0U) |
|
{ |
|
status = HAL_ERROR; |
|
hsubghz->ErrorCode = HAL_SUBGHZ_ERROR_RF_BUSY; |
|
break; |
|
} |
|
count--; |
|
} while ((LL_PWR_IsActiveFlag_RFBUSYS()& mask) == 1UL); |
|
|
|
return status; |
|
} |
|
/** |
|
* @} |
|
*/ |
|
|
|
#endif /* HAL_SUBGHZ_MODULE_ENABLED */ |
|
|
|
/** |
|
* @} |
|
*/ |
|
|
|
/** |
|
* @} |
|
*/
|
|
|