diff --git a/CHANGELOG.md b/CHANGELOG.md index b63e790..dc45d80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.5.0] 2024-07-24 + +### Added + +- [radio] `lr11xx_radio_set_lna_mode` function to configure usage of antenna for LNA and corresponding helper functions `lr11xx_radio_set_rx_and_lna_mode` and `lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode` + ## [v2.4.1] 2023-11-16 ### Changed @@ -70,56 +76,56 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added -* [radio] `lr11xx_radio_set_lora_sync_timeout_with_mantissa_exponent()` function -* [radio] `LR11XX_RADIO_PKT_TYPE_BPSK` packet type, with `lr11xx_radio_set_bpsk_pkt_params` and `lr11xx_radio_set_bpsk_mod_params` functions -* [GNSS] `lr11xx_gnss_apply_mixer_cfg_workaround()` function -* [GNSS] Add function `lr11xx_gnss_read_gnss_rssi_test` to read RSSI on GNSS path -* [GNSS] Add function `lr11xx_gnss_read_freq_search_space` -* [GNSS] Add function `lr11xx_gnss_set_freq_search_space` -* [GNSS] Add function `lr11xx_gnss_get_nb_visible_satellites` -* [GNSS] Add function `lr11xx_gnss_get_visible_satellites` -* [GNSS] add structure `lr11xx_gnss_visible_satellite_t` to support `lr11xx_gnss_get_visible_satellites` function -* [lr-fhss] Add function `lr11xx_lr_fhss_get_bit_delay_in_us` to compute the delay between the last LR-FHSS bit sent and the TX done interrupt -* [radio] Add function `lr11xx_radio_set_lr_fhss_sync_word` to configure the LR-FHSS syncword -* [radio] Add function `lr11xx_radio_set_lr_fhss_mod_params` to configure the LR-FHSS modulation parameters -* [radio] Add helper function `lr11xx_radio_convert_nb_symb_to_mant_exp` to convert a number of symbols into mantissa/exponent representation -* [crypto] Add functions `lr11xx_crypto_check_encrypted_firmware_image` and `lr11xx_crypto_get_check_encrypted_firmware_image_result`; and helper function `lr11xx_crypto_check_encrypted_firmware_image_full` to check suitability of encrypted firmware image prior to actual flashing -* [ranging] Add `lr11xx_ranging_*` functions as part of new ranging component `lr11xx_ranging` +- [radio] `lr11xx_radio_set_lora_sync_timeout_with_mantissa_exponent()` function +- [radio] `LR11XX_RADIO_PKT_TYPE_BPSK` packet type, with `lr11xx_radio_set_bpsk_pkt_params` and `lr11xx_radio_set_bpsk_mod_params` functions +- [GNSS] `lr11xx_gnss_apply_mixer_cfg_workaround()` function +- [GNSS] Add function `lr11xx_gnss_read_gnss_rssi_test` to read RSSI on GNSS path +- [GNSS] Add function `lr11xx_gnss_read_freq_search_space` +- [GNSS] Add function `lr11xx_gnss_set_freq_search_space` +- [GNSS] Add function `lr11xx_gnss_get_nb_visible_satellites` +- [GNSS] Add function `lr11xx_gnss_get_visible_satellites` +- [GNSS] add structure `lr11xx_gnss_visible_satellite_t` to support `lr11xx_gnss_get_visible_satellites` function +- [lr-fhss] Add function `lr11xx_lr_fhss_get_bit_delay_in_us` to compute the delay between the last LR-FHSS bit sent and the TX done interrupt +- [radio] Add function `lr11xx_radio_set_lr_fhss_sync_word` to configure the LR-FHSS syncword +- [radio] Add function `lr11xx_radio_set_lr_fhss_mod_params` to configure the LR-FHSS modulation parameters +- [radio] Add helper function `lr11xx_radio_convert_nb_symb_to_mant_exp` to convert a number of symbols into mantissa/exponent representation +- [crypto] Add functions `lr11xx_crypto_check_encrypted_firmware_image` and `lr11xx_crypto_get_check_encrypted_firmware_image_result`; and helper function `lr11xx_crypto_check_encrypted_firmware_image_full` to check suitability of encrypted firmware image prior to actual flashing +- [ranging] Add `lr11xx_ranging_*` functions as part of new ranging component `lr11xx_ranging` ### Changed -* [GNSS] Call to `lr11xx_gnss_apply_mixer_cfg_workaround()` in `lr11xx_gnss_scan_autonomous()` and `lr11xx_gnss_scan_assisted()` (can be removed by defining `LR11XX_DISABLE_MIXER_CFG_WORKAROUND`) -* [system] Field `type` of `lr11xx_system_version_t` is now an enumerated type named `lr11xx_system_version_type_t` -* [system] Add IRQ raised on LoRa symbol received over-the-air -* [radio] `lr11xx_radio_set_lora_sync_timeout` takes argument `nb_symbol` as `uint16_t` -* [regmem] `lr11xx_regmem_write_regmem32` and `lr11xx_regmem_read_regmem32` test the number of words to write/read before actually requesting the chip, and raise an error status if it is higher than 64 +- [GNSS] Call to `lr11xx_gnss_apply_mixer_cfg_workaround()` in `lr11xx_gnss_scan_autonomous()` and `lr11xx_gnss_scan_assisted()` (can be removed by defining `LR11XX_DISABLE_MIXER_CFG_WORKAROUND`) +- [system] Field `type` of `lr11xx_system_version_t` is now an enumerated type named `lr11xx_system_version_type_t` +- [system] Add IRQ raised on LoRa symbol received over-the-air +- [radio] `lr11xx_radio_set_lora_sync_timeout` takes argument `nb_symbol` as `uint16_t` +- [regmem] `lr11xx_regmem_write_regmem32` and `lr11xx_regmem_read_regmem32` test the number of words to write/read before actually requesting the chip, and raise an error status if it is higher than 64 ## [v2.1.1] 2022-04-06 ### Fixed -* [radio] Order of the parameters in `lr11xx_radio_set_rssi_calibration()` function +- [radio] Order of the parameters in `lr11xx_radio_set_rssi_calibration()` function ## [v2.1.0] 2022-03-28 ### Added -* [radio] `lr11xx_radio_apply_high_acp_workaround()` function -* [radio] `lr11xx_radio_set_rssi_calibration()` function -* [radio] `LR11XX_RADIO_LORA_BW_200`, `LR11XX_RADIO_LORA_BW_400` and `LR11XX_RADIO_LORA_BW_800` entries to `lr11xx_radio_lora_bw_t` -* [radio] `LR11XX_RADIO_GFSK_PKT_VAR_LEN_SX128X_COMP` entry in `lr11xx_radio_gfsk_pkt_len_modes_t` to support compatibility with SX128x -* [radio] `LR11XX_RADIO_GFSK_DC_FREE_WHITENING_SX128X_COMP` entry in `lr11xx_radio_gfsk_dc_free_t` to support compatibility with SX128x -* [GNSS] `lr11xx_gnss_get_consumption` function -* [Wi-Fi] `lr11xx_wifi_get_consumption` function -* [Wi-Fi] `lr11xx_wifi_are_scan_mode_result_format_compatible` function +- [radio] `lr11xx_radio_apply_high_acp_workaround()` function +- [radio] `lr11xx_radio_set_rssi_calibration()` function +- [radio] `LR11XX_RADIO_LORA_BW_200`, `LR11XX_RADIO_LORA_BW_400` and `LR11XX_RADIO_LORA_BW_800` entries to `lr11xx_radio_lora_bw_t` +- [radio] `LR11XX_RADIO_GFSK_PKT_VAR_LEN_SX128X_COMP` entry in `lr11xx_radio_gfsk_pkt_len_modes_t` to support compatibility with SX128x +- [radio] `LR11XX_RADIO_GFSK_DC_FREE_WHITENING_SX128X_COMP` entry in `lr11xx_radio_gfsk_dc_free_t` to support compatibility with SX128x +- [GNSS] `lr11xx_gnss_get_consumption` function +- [Wi-Fi] `lr11xx_wifi_get_consumption` function +- [Wi-Fi] `lr11xx_wifi_are_scan_mode_result_format_compatible` function ### Changed -* [radio] Call to `lr11xx_radio_apply_high_acp_workaround()` in `lr11xx_radio_set_tx_with_timeout_in_rtc_step()`, `lr11xx_radio_set_rx_with_timeout_in_rtc_step()`, `lr11xx_radio_set_cad()` and `lr11xx_radio_set_tx_infinite_preamble()` (can be removed by defining `LR11XX_DISABLE_HIGH_ACP_WORKAROUND`) -* [Wi-Fi] Define type `lr11xx_wifi_country_code_str_t` for Wi-Fi country code data and update `lr11xx_wifi_extended_full_result_t` and `lr11xx_wifi_country_code_t` to use it. +- [radio] Call to `lr11xx_radio_apply_high_acp_workaround()` in `lr11xx_radio_set_tx_with_timeout_in_rtc_step()`, `lr11xx_radio_set_rx_with_timeout_in_rtc_step()`, `lr11xx_radio_set_cad()` and `lr11xx_radio_set_tx_infinite_preamble()` (can be removed by defining `LR11XX_DISABLE_HIGH_ACP_WORKAROUND`) +- [Wi-Fi] Define type `lr11xx_wifi_country_code_str_t` for Wi-Fi country code data and update `lr11xx_wifi_extended_full_result_t` and `lr11xx_wifi_country_code_t` to use it. ## [v1.0.0] Unreleased ### Added -* [all] Initial version - based on LR1110 driver v7.0.0 +- [all] Initial version - based on LR1110 driver v7.0.0 diff --git a/src/lr11xx_radio.c b/src/lr11xx_radio.c index ded213d..092801f 100644 --- a/src/lr11xx_radio.c +++ b/src/lr11xx_radio.c @@ -409,7 +409,22 @@ lr11xx_status_t lr11xx_radio_set_rx( const void* context, const uint32_t timeout return lr11xx_radio_set_rx_with_timeout_in_rtc_step( context, timeout_in_rtc_step ); } -lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step( const void* context, const uint32_t timeout ) +lr11xx_status_t lr11xx_radio_set_rx_and_lna_mode( const void* context, const uint32_t timeout_in_ms, + lr11xx_radio_lna_mode_t lna_mode ) +{ + const uint32_t timeout_in_rtc_step = lr11xx_radio_convert_time_in_ms_to_rtc_step( timeout_in_ms ); + + return lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode( context, timeout_in_rtc_step, lna_mode ); +} + +lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step( const void* context, const uint32_t timeout_in_ms ) +{ + return lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode( context, timeout_in_ms, + LR11XX_RADIO_LNA_MODE_DIFFERENTIAL_LF0 ); +} + +lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode( const void* context, const uint32_t timeout, + lr11xx_radio_lna_mode_t lna_mode ) { lr11xx_status_t status = LR11XX_STATUS_ERROR; const uint8_t cbuffer[LR11XX_RADIO_SET_RX_CMD_LENGTH] = { @@ -433,6 +448,17 @@ lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step( const void* contex { break; } + + if( ( lna_mode == LR11XX_RADIO_LNA_MODE_SINGLE_RFI_P_LF0 ) || + ( lna_mode == LR11XX_RADIO_LNA_MODE_SINGLE_RFI_N_LF0 ) ) + { + status = lr11xx_radio_set_lna_mode( context, lna_mode ); + if( status != LR11XX_STATUS_OK ) + { + break; + } + } + } while( 0 ); return status; @@ -1292,6 +1318,10 @@ uint16_t lr11xx_radio_convert_nb_symb_to_mant_exp( const uint16_t nb_symbol, uin return mant_loc << ( 2 * exp_loc + 1 ); } +lr11xx_status_t lr11xx_radio_set_lna_mode( const void* context, lr11xx_radio_lna_mode_t lna_config ) +{ + return lr11xx_regmem_write_regmem32_mask( context, 0x00F3008C, 0xF0, lna_config << 4 ); +} /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- diff --git a/src/lr11xx_radio.h b/src/lr11xx_radio.h index 0745c41..0392713 100644 --- a/src/lr11xx_radio.h +++ b/src/lr11xx_radio.h @@ -285,6 +285,33 @@ lr11xx_status_t lr11xx_radio_set_lora_public_network( const void* */ lr11xx_status_t lr11xx_radio_set_rx( const void* context, const uint32_t timeout_in_ms ); +/*! + * @brief Start RX operations with a timeout in millisecond and configure the LNA LF0 mode + * + * This command sets the LR11XX to RX mode and configures the LNA LF0 mode. The radio must have been configured before + * using this command with @ref lr11xx_radio_set_pkt_type + * + * This command must be issued only for sub-GHz RX operations as it configures the LNA LF0, which is only used for + * sub-GHz Rx operations. + * + * By default, the timeout parameter allows to return automatically to standby RC mode if no packets have been received + * after a certain amount of time. This behavior can be altered by @ref lr11xx_radio_set_rx_tx_fallback_mode and @ref + * lr11xx_radio_auto_tx_rx. + * + * @remark To set the radio in Rx continuous mode, the function @ref lr11xx_radio_set_rx_with_timeout_in_rtc_step has to + * be called with \p timeout_in_rtc_step set to 0xFFFFFF + * + * @param [in] context Chip implementation context + * @param [in] timeout_in_ms The timeout configuration for RX operation + * @param [in] lna_mode Path to use for reception + * + * @returns Operation status + * + * @see lr11xx_radio_set_pkt_type, lr11xx_radio_set_rx_tx_fallback_mode, lr11xx_radio_set_lna_mode + */ +lr11xx_status_t lr11xx_radio_set_rx_and_lna_mode( const void* context, const uint32_t timeout_in_ms, + lr11xx_radio_lna_mode_t lna_mode ); + /*! * @brief Start RX operations with a timeout in RTC step * @@ -318,6 +345,44 @@ lr11xx_status_t lr11xx_radio_set_rx( const void* context, const uint32_t timeout */ lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step( const void* context, const uint32_t timeout_in_rtc_step ); +/*! + * @brief Start RX operations with a timeout in RTC step and configure the LNA LF0 mode + * + * This command sets the LR11XX to RX mode and configures the LNA LF0 mode. The radio must have been configured before + * using this command with @ref lr11xx_radio_set_pkt_type It internally calls lr11xx_radio_set_lna_mode. This command + * must be issued only for sub-GHz RX operations as it configures the LNA LF0, which is only used for sub-GHz Rx + * operations. + * + * By default, the timeout parameter allows to return automatically to standby RC mode if no packets have been received + * after a certain amount of time. This behavior can be altered by @ref lr11xx_radio_set_rx_tx_fallback_mode and @ref + * lr11xx_radio_auto_tx_rx. + * + * The timeout duration is obtained by: + * \f$ timeout\_duration\_ms = timeout \times \frac{1}{32.768} \f$ + * + * Maximal timeout value is 0xFFFFFF, which gives a maximal timeout of 511 seconds. + * + * The timeout argument can also have the following special values: + * + * + *
Special values Meaning
0x000000 RX single: LR11XX stays in RX mode until a + * packet is received, then switch to standby RC mode
0xFFFFFF + * RX continuous: LR11XX stays in RX mode even after reception of a + * packet + *
+ * + * @param [in] context Chip implementation context + * @param [in] timeout_in_rtc_step The timeout configuration for RX operation + * @param [in] lna_mode Path to use for reception + * + * @returns Operation status + * + * @see lr11xx_radio_set_pkt_type, lr11xx_radio_set_rx_tx_fallback_mode + */ +lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode( const void* context, + const uint32_t timeout_in_rtc_step, + lr11xx_radio_lna_mode_t lna_mode ); + /*! * @brief Start TX operations * @@ -954,6 +1019,22 @@ lr11xx_status_t lr11xx_radio_apply_high_acp_workaround( const void* context ); */ uint16_t lr11xx_radio_convert_nb_symb_to_mant_exp( const uint16_t nb_symbol, uint8_t* mant, uint8_t* exp ); +/** + * @brief Configure LNA LF0 mode + * + * @remark This function shall be called after each call to lr11xx_radio_set_rx or + * lr11xx_radio_set_rx_with_timeout_in_rtc_step to be taken into account. Helper functions + * lr11xx_radio_set_rx_on_lna_path or lr11xx_radio_set_rx_with_timeout_in_rtc_step_on_lna_path can be used instead. + * + * @param [in] context Chip implementation context + * @param [in] lna_mode Value to put in the register, enum type + * + * @returns Operation status + * + * @see lr11xx_radio_set_rx_on_lna_path, lr11xx_radio_set_rx_with_timeout_in_rtc_step_on_lna_path + */ +lr11xx_status_t lr11xx_radio_set_lna_mode( const void* context, lr11xx_radio_lna_mode_t lna_mode ); + #ifdef __cplusplus } #endif diff --git a/src/lr11xx_radio_types.h b/src/lr11xx_radio_types.h index e3cc32e..4794f41 100644 --- a/src/lr11xx_radio_types.h +++ b/src/lr11xx_radio_types.h @@ -628,6 +628,18 @@ typedef struct lr11xx_radio_rssi_calibration_table_s int16_t gain_offset; //!< Used to set gain offset value for RSSI calibration } lr11xx_radio_rssi_calibration_table_t; +/*! + * @brief Values to use to setup LNA LF0 configuration + * + * LNA can be configured in either of the 3 modes: Single N, Single P or differential (which is default) + * + */ +typedef enum +{ + LR11XX_RADIO_LNA_MODE_SINGLE_RFI_N_LF0 = 1, //!< Use only RFI_N_LF0 antenna + LR11XX_RADIO_LNA_MODE_SINGLE_RFI_P_LF0 = 2, //!< Use only RFI_P_LF0 antenna + LR11XX_RADIO_LNA_MODE_DIFFERENTIAL_LF0 = 3 //!< Configure LNA LF0 in differential mode (default) +} lr11xx_radio_lna_mode_t; /* * ----------------------------------------------------------------------------- * --- PUBLIC FUNCTIONS PROTOTYPES --------------------------------------------- diff --git a/src/lr11xx_rttof.c b/src/lr11xx_rttof.c new file mode 100644 index 0000000..4d06b48 --- /dev/null +++ b/src/lr11xx_rttof.c @@ -0,0 +1,194 @@ +/** + * @file lr11xx_rttof.c + * + * @brief Round-Trip Time of Flight (RTToF) driver implementation for LR11XX + * + * The Clear BSD License + * Copyright Semtech Corporation 2022. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ + +#include +#include "lr11xx_rttof.h" +#include "lr11xx_hal.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ + +#define LR11XX_RTTOF_SET_ADDRESS_CMD_LENGTH ( 2 + 5 ) +#define LR11XX_RTTOF_SET_REQUEST_ADDRESS_CMD_LENGTH ( 2 + 4 ) +#define LR11XX_RTTOF_SET_RX_TX_DELAY_CMD_LENGTH ( 2 + 4 ) +#define LR11XX_RTTOF_SET_PARAMETERS_CMD_LENGTH ( 2 + 2 ) +#define LR11XX_RTTOF_GET_RESULT_CMD_LENGTH ( 2 + 1 ) + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/** + * @brief Operating codes for RTToF-related operations + */ +enum +{ + LR11XX_RTTOF_SET_ADDRESS = 0x021C, + LR11XX_RTTOF_SET_REQUEST_ADDRESS = 0x021D, + LR11XX_RTTOF_SET_RX_TX_DELAY = 0x021F, + LR11XX_RTTOF_SET_PARAMETERS = 0x0228, + LR11XX_RTTOF_GET_RESULT = 0x021E, +}; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTION DECLARATIONS ------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTION DEFINITIONS --------------------------------------------- + */ + +lr11xx_status_t lr11xx_rttof_set_address( const void* context, const uint32_t address, const uint8_t check_length ) +{ + const uint8_t cbuffer[LR11XX_RTTOF_SET_ADDRESS_CMD_LENGTH] = { + ( uint8_t )( LR11XX_RTTOF_SET_ADDRESS >> 8 ), + ( uint8_t )( LR11XX_RTTOF_SET_ADDRESS >> 0 ), + ( uint8_t )( address >> 24 ), + ( uint8_t )( address >> 16 ), + ( uint8_t )( address >> 8 ), + ( uint8_t )( address >> 0 ), + check_length, + }; + + return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_RTTOF_SET_ADDRESS_CMD_LENGTH, 0, 0 ); +} + +lr11xx_status_t lr11xx_rttof_set_request_address( const void* context, const uint32_t request_address ) +{ + const uint8_t cbuffer[LR11XX_RTTOF_SET_REQUEST_ADDRESS_CMD_LENGTH] = { + ( uint8_t )( LR11XX_RTTOF_SET_REQUEST_ADDRESS >> 8 ), + ( uint8_t )( LR11XX_RTTOF_SET_REQUEST_ADDRESS >> 0 ), + ( uint8_t )( request_address >> 24 ), + ( uint8_t )( request_address >> 16 ), + ( uint8_t )( request_address >> 8 ), + ( uint8_t )( request_address >> 0 ), + }; + + return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_RTTOF_SET_REQUEST_ADDRESS_CMD_LENGTH, 0, 0 ); +} + +lr11xx_status_t lr11xx_rttof_set_rx_tx_delay_indicator( const void* context, const uint32_t delay_indicator ) +{ + const uint8_t cbuffer[LR11XX_RTTOF_SET_RX_TX_DELAY_CMD_LENGTH] = { + ( uint8_t )( LR11XX_RTTOF_SET_RX_TX_DELAY >> 8 ), + ( uint8_t )( LR11XX_RTTOF_SET_RX_TX_DELAY >> 0 ), + ( uint8_t )( delay_indicator >> 24 ), + ( uint8_t )( delay_indicator >> 16 ), + ( uint8_t )( delay_indicator >> 8 ), + ( uint8_t )( delay_indicator >> 0 ), + }; + + return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_RTTOF_SET_RX_TX_DELAY_CMD_LENGTH, 0, 0 ); +} + +lr11xx_status_t lr11xx_rttof_set_parameters( const void* context, const uint8_t nb_symbols ) +{ + const uint8_t cbuffer[LR11XX_RTTOF_SET_PARAMETERS_CMD_LENGTH] = { ( uint8_t )( LR11XX_RTTOF_SET_PARAMETERS >> 8 ), + ( uint8_t )( LR11XX_RTTOF_SET_PARAMETERS >> 0 ), + 0x00, nb_symbols }; + + return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_RTTOF_SET_PARAMETERS_CMD_LENGTH, 0, 0 ); +} + +lr11xx_status_t lr11xx_rttof_get_raw_result( const void* context, const lr11xx_rttof_result_type_t type, + uint8_t result[LR11XX_RTTOF_RESULT_LENGTH] ) +{ + const uint8_t cbuffer[LR11XX_RTTOF_GET_RESULT_CMD_LENGTH] = { + ( uint8_t )( LR11XX_RTTOF_GET_RESULT >> 8 ), + ( uint8_t )( LR11XX_RTTOF_GET_RESULT >> 0 ), + ( uint8_t ) type, + }; + + return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_RTTOF_GET_RESULT_CMD_LENGTH, result, + LR11XX_RTTOF_RESULT_LENGTH ); +} + +int32_t lr11xx_rttof_distance_raw_to_meter( lr11xx_radio_lora_bw_t rttof_bw, + const uint8_t raw_distance_buf[LR11XX_RTTOF_RESULT_LENGTH] ) +{ + const uint8_t bitcnt = 24u; + uint8_t bw_scaling = 0u; + + const uint32_t raw_distance = + ( ( uint32_t ) raw_distance_buf[3] << 0 ) + ( ( uint32_t ) raw_distance_buf[2] << 8 ) + + ( ( uint32_t ) raw_distance_buf[1] << 16 ) + ( ( uint32_t ) raw_distance_buf[0] << 24 ); + + if( rttof_bw == LR11XX_RADIO_LORA_BW_500 ) + { + bw_scaling = 1u; + } + else if( rttof_bw == LR11XX_RADIO_LORA_BW_250 ) + { + bw_scaling = 2u; + } + else if( rttof_bw == LR11XX_RADIO_LORA_BW_125 ) + { + bw_scaling = 4u; + } + + int32_t retval = raw_distance; + if( raw_distance >= ( 1 << ( bitcnt - 1 ) ) ) + { + retval -= ( 1 << bitcnt ); + } + + return 300 * bw_scaling * retval / 4096; +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTION DEFINITIONS -------------------------------------------- + */ + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/lr11xx_rttof.h b/src/lr11xx_rttof.h new file mode 100644 index 0000000..535c721 --- /dev/null +++ b/src/lr11xx_rttof.h @@ -0,0 +1,201 @@ +/** + * @file lr11xx_rttof.h + * + * @brief Round-Trip Time of Flight (RTToF) driver definition for LR11XX + * + * The Clear BSD License + * Copyright Semtech Corporation 2022. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LR11XX_RTTOF_H +#define LR11XX_RTTOF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ + +#include +#include "lr11xx_rttof_types.h" +#include "lr11xx_radio_types.h" +#include "lr11xx_types.h" + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC MACROS ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC CONSTANTS -------------------------------------------------------- + */ + +/** + * @brief Length in byte of the RTToF result + */ +#define LR11XX_RTTOF_RESULT_LENGTH ( 4 ) + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC TYPES ------------------------------------------------------------ + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTION PROTOTYPES --------------------------------------------- + */ + +/** + * @brief Set the RTToF address for this subordinate device. + * + * @param [in] context Chip implementation context + * @param [in] address 32-bit subordinate address (default is 0x00000019) + * @param [in] check_length Number of bytes to be checked when comparing the device's + * address with request address value contained in received + * RTToF frames (valid range 1..4, default is 4) + * + * @returns Operation status + * + * @note The address set by this function is only used in subordinate mode, that is, + * when receiving RTToF requests. While processing received request packets, + * the RTToF subordinate compares @p check_length bytes (LSB first) of + * the request address with its own address. Packets with non-matching request + * addresses are discarded. + */ +lr11xx_status_t lr11xx_rttof_set_address( const void* context, const uint32_t address, const uint8_t check_length ); + +/** + * @brief Set the RTToF address used for requests sent in manager mode. + * + * @param [in] context Chip implementation context + * @param [in] request_address 32-bit request address (default is 0x00000019) + * + * @returns Operation status + * + * @note The request address set by this function is only used in manager mode, + * that is, when sending RTToF requests. The @p request_address is copied + * into the corresponding field in the next RTToF request sent. + */ +lr11xx_status_t lr11xx_rttof_set_request_address( const void* context, const uint32_t request_address ); + +/** + * @brief Set the transceiver RX/TX delay indicator to be compensated during RTToF. + * + * The transceiver hardware induces a delay depending on the physical layer + * configuration (bandwidth, spreading factor). To achieve the desired RTToF + * accuracy, this delay needs to be compensated by a calibration value. + * + * @param [in] context Chip implementation context + * @param [in] delay_indicator Delay value corresponding to the used bandwidth and spreading factor + * + * @returns lr11xx_status_t Operation status + * + * @note The same delay_indicator value needs to be configured in both manager and subordinate devices. + */ +lr11xx_status_t lr11xx_rttof_set_rx_tx_delay_indicator( const void* context, const uint32_t delay_indicator ); + +/** + * @brief Configure RTToF specific parameters. + * + * It is recommended to always call this command when configuring the RTToF operation with @p nb_symbols = 15. + * This value balances the RTToF accuracy and power consumption. + * + * @param [in] context Chip implementation context + * @param [in] nb_symbols Number of symbols contained in responses sent by subordinates + * + * @returns lr11xx_status_t Operation status + * + * @note The RTToF parameters need to be configured in both manager and subordinate devices. + */ +lr11xx_status_t lr11xx_rttof_set_parameters( const void* context, const uint8_t nb_symbols ); + +/** + * @brief Get the RTToF result on the manager device. + * + * Retrieve the RTToF result item corresponding to the given item type @p type. + * + * @param [in] context Chip implementation context + * @param [in] type Result item type to be retrieved + * @param [out] result Result data buffer + * + * @returns lr11xx_status_t Operation status + * + * @note This function is only available on devices in manager mode after + * the RTToF is terminated. + */ +lr11xx_status_t lr11xx_rttof_get_raw_result( const void* context, const lr11xx_rttof_result_type_t type, + uint8_t result[LR11XX_RTTOF_RESULT_LENGTH] ); + +/** + * @brief Convert the raw distance result obtained from the device to a distance result [m]. + * + * This function is meaningful only to convert a RTToF result obtained by calling @p lr11xx_rttof_get_raw_result + * with type set to @p LR11XX_RTTOF_RESULT_TYPE_RAW + * + * @param [in] rttof_bw Bandwidth used during RTToF + * @param [in] raw_distance_buf Buffer containing the raw distance result + * + * @returns int32_t Distance result [m] + * + * @see lr11xx_rttof_get_raw_result + * + * @note The caller must ensure that the @p rttof_bw parameter is one of the supported ones, + * i.e., #LR11XX_RADIO_LORA_BW_125, #LR11XX_RADIO_LORA_BW_250, #LR11XX_RADIO_LORA_BW_500. + */ +int32_t lr11xx_rttof_distance_raw_to_meter( lr11xx_radio_lora_bw_t rttof_bw, + const uint8_t raw_distance_buf[LR11XX_RTTOF_RESULT_LENGTH] ); + +/** + * @brief Convert the raw RSSI result obtained from the device to an RSSI result. + * + * This function is meaningful only to convert a RTToF result obtained by calling @p lr11xx_rttof_get_raw_result + * with type set to @p LR11XX_RTTOF_RESULT_TYPE_RSSI + * + * @param [in] raw_rssi_buf Buffer containing the raw RSSI result + * + * @returns int8_t RSSI result [dBm] + * + * @see lr11xx_rttof_get_raw_result + */ +static inline int8_t lr11xx_rttof_rssi_raw_to_value( const uint8_t raw_rssi_buf[LR11XX_RTTOF_RESULT_LENGTH] ) +{ + // Only the last byte is meaningful + return -( int8_t )( raw_rssi_buf[3] >> 1 ); +} + +#ifdef __cplusplus +} +#endif + +#endif // LR11XX_RTTOF_H + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/lr11xx_rttof_types.h b/src/lr11xx_rttof_types.h new file mode 100644 index 0000000..a046a47 --- /dev/null +++ b/src/lr11xx_rttof_types.h @@ -0,0 +1,82 @@ +/** + * @file lr11xx_rttof_types.h + * + * @brief Round-Trip Time of Flight (RTToF) driver types for LR11XX + * + * The Clear BSD License + * Copyright Semtech Corporation 2022. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LR11XX_RTTOF_TYPES_H +#define LR11XX_RTTOF_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC MACROS ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC CONSTANTS -------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC TYPES ------------------------------------------------------------ + */ + +/** + * @brief Round-Trip Time of Flight result types + */ +typedef enum lr11xx_rttof_result_type_e +{ + LR11XX_RTTOF_RESULT_TYPE_RAW = 0, ///< Raw distance result + LR11XX_RTTOF_RESULT_TYPE_RSSI, ///< RTToF RSSI +} lr11xx_rttof_result_type_t; + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTION PROTOTYPES --------------------------------------------- + */ + +#ifdef __cplusplus +} +#endif + +#endif // LR11XX_RTTOF_TYPES_H + +/* --- EOF ------------------------------------------------------------------ */