mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-08-29 14:58:16 +00:00
lr20xx: bump vendored SDK to v2.0.2 and load the firmware Patch RAM
This commit is contained in:
@@ -140,3 +140,4 @@ handover_thinknode_m9.md
|
||||
|
||||
# Vendor reference docs (datasheets, errata). Local only — not ours to redistribute.
|
||||
/datasheets/
|
||||
LR2021_AUDIT_INDEX.md
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
License for the code produced by Semtech contained in this project
|
||||
------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
@@ -57,7 +57,7 @@ extern "C" {
|
||||
/**
|
||||
* @brief Value of driver version string
|
||||
*/
|
||||
#define LR20XX_DRIVER_VERSION "v1.3.4"
|
||||
#define LR20XX_DRIVER_VERSION "v2.0.2"
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
|
||||
@@ -67,7 +67,7 @@ extern "C" {
|
||||
typedef enum lr20xx_hal_status_e
|
||||
{
|
||||
LR20XX_HAL_STATUS_OK = 0,
|
||||
LR20XX_HAL_STATUS_ERROR = 3, /* Must match lr20xx_status_t ERROR value */
|
||||
LR20XX_HAL_STATUS_ERROR = 3,
|
||||
} lr20xx_hal_status_t;
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*!
|
||||
* @file lr20xx_patch.c
|
||||
*
|
||||
* @brief Implementation of patching commands for LR20XX
|
||||
*
|
||||
* The Clear BSD License
|
||||
* Copyright Semtech Corporation 2026. 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 <stdbool.h> // true, false
|
||||
|
||||
#include "lr20xx_patch.h"
|
||||
#include "lr20xx_regmem.h"
|
||||
#include "lr20xx_hal.h"
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE MACROS-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define LR20XX_PATCH_MAGIC_WORD_ADDRESS ( 0x800FF8 )
|
||||
#define LR20XX_PATCH_TYPE_VERSION_ADDRESS ( 0x800FFC )
|
||||
#define LR20XX_PATCH_MAGIC_WORD_EXPECTED ( 0x600DB002 )
|
||||
#define LR20XX_PRAM_BASE_ADDRESS ( 0x801000 )
|
||||
|
||||
#define LR20XX_PATCH_ENABLE_PRAM_CMD_LENGTH ( 2 + 1 )
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE CONSTANTS -------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE TYPES -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Operating codes for patch RAM related operations
|
||||
*/
|
||||
enum
|
||||
{
|
||||
LR20XX_PATCH_ENABLE_PRAM_OC = 0x012D,
|
||||
};
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE VARIABLES -------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
|
||||
*/
|
||||
|
||||
lr20xx_status_t lr20xx_patch_load_pram( const void* context, const uint32_t address, const uint32_t* buffer,
|
||||
const uint32_t length )
|
||||
{
|
||||
// The pram is written by blocks of 32 words
|
||||
const uint32_t n_32_word_blocks = length / 32u;
|
||||
|
||||
// Write all blocks of 32 words
|
||||
for( uint32_t index_32_word_block = 0; index_32_word_block < n_32_word_blocks; index_32_word_block++ )
|
||||
{
|
||||
const uint32_t* local_buffer = buffer + ( index_32_word_block * 32u );
|
||||
const uint32_t local_address = address + ( index_32_word_block * 32u * 4u );
|
||||
const lr20xx_status_t status = lr20xx_regmem_write_regmem32( context, local_address, local_buffer, 32u );
|
||||
if( status != LR20XX_STATUS_OK )
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there are remaining words to write and if so, write it in a single call
|
||||
const uint8_t n_remaining_words = ( uint8_t ) ( length - ( n_32_word_blocks * 32u ) );
|
||||
if( n_remaining_words > 0 )
|
||||
{
|
||||
const lr20xx_status_t status =
|
||||
lr20xx_regmem_write_regmem32( context, address + ( n_32_word_blocks * 32u * 4u ),
|
||||
buffer + ( n_32_word_blocks * 32u ), n_remaining_words );
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LR20XX_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_patch_enable_pram( const void* context )
|
||||
{
|
||||
const uint8_t cbuffer[LR20XX_PATCH_ENABLE_PRAM_CMD_LENGTH] = {
|
||||
( uint8_t ) ( LR20XX_PATCH_ENABLE_PRAM_OC >> 8 ),
|
||||
( uint8_t ) ( LR20XX_PATCH_ENABLE_PRAM_OC >> 0 ),
|
||||
0,
|
||||
};
|
||||
|
||||
return ( lr20xx_status_t ) lr20xx_hal_write( context, cbuffer, LR20XX_PATCH_ENABLE_PRAM_CMD_LENGTH, 0, 0 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_patch_get_version( const void* context, lr20xx_patch_version_t* pram_version )
|
||||
{
|
||||
// 1. Read the magic word register
|
||||
uint32_t magic_word_read = 0;
|
||||
const lr20xx_status_t magic_word_read_status =
|
||||
lr20xx_regmem_read_regmem32( context, LR20XX_PATCH_MAGIC_WORD_ADDRESS, &magic_word_read, 1 );
|
||||
if( magic_word_read_status == LR20XX_STATUS_OK )
|
||||
{
|
||||
// 2. If magic word register content match expectation, a PRAM is loaded
|
||||
if( magic_word_read == LR20XX_PATCH_MAGIC_WORD_EXPECTED )
|
||||
{
|
||||
// 3. Read the PRAM type and version register
|
||||
uint32_t pram_type_version_raw = 0;
|
||||
const lr20xx_status_t pram_type_version_read_status =
|
||||
lr20xx_regmem_read_regmem32( context, LR20XX_PATCH_TYPE_VERSION_ADDRESS, &pram_type_version_raw, 1 );
|
||||
if( pram_type_version_read_status == LR20XX_STATUS_OK )
|
||||
{
|
||||
pram_version->is_pram_loaded = true;
|
||||
pram_version->pram_type = ( uint8_t ) ( pram_type_version_raw >> 16 );
|
||||
pram_version->pram_version = ( uint8_t ) ( pram_type_version_raw >> 8 );
|
||||
}
|
||||
return pram_type_version_read_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
pram_version->is_pram_loaded = false;
|
||||
pram_version->pram_type = 0;
|
||||
pram_version->pram_version = 0;
|
||||
}
|
||||
}
|
||||
return magic_word_read_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
|
||||
*/
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
@@ -0,0 +1,128 @@
|
||||
/*!
|
||||
* @file lr20xx_patch.h
|
||||
*
|
||||
* @brief Patching commands for Lr20xx
|
||||
*
|
||||
* The Clear BSD License
|
||||
* Copyright Semtech Corporation 2026. 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 LR20XX_PATCH_H
|
||||
#define LR20XX_PATCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- DEPENDENCIES ------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "lr20xx_patch_types.h"
|
||||
#include "lr20xx_status.h"
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC MACROS -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC CONSTANTS --------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC TYPES ------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Transfer a Patch RAM (PRAM) into the chip
|
||||
*
|
||||
* This function is a helper function that execute several calls to @ref lr20xx_regmem_write_regmem32 in order to
|
||||
* transfer the complete PRAM.
|
||||
* After loading the PRAM with @ref lr20xx_patch_load_pram, it must be enabled by calling @ref lr20xx_patch_enable_pram.
|
||||
*
|
||||
* @note The helper functions @ref lr20xx_pram_load_pram_lr2021 and @ref lr20xx_pram_load_pram_lr20x2 handle the load
|
||||
* and enabling of the appropriate PRAM.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param address The base address in the chip memory where the PRAM is to be written
|
||||
* @param buffer Pointer to the buffer being the PRAM data to transfer. It is up to the caller to ensure it contains at
|
||||
* least @p length elements
|
||||
* @param length Number of elements fro @p buffer array to write
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_patch_enable_pram, lr20xx_regmem_write_regmem32, lr20xx_patch_get_version
|
||||
*/
|
||||
lr20xx_status_t lr20xx_patch_load_pram( const void* context, const uint32_t address, const uint32_t* buffer,
|
||||
const uint32_t length );
|
||||
|
||||
/**
|
||||
* @brief Enable Patch RAM (PRAM)
|
||||
*
|
||||
* This function must be called after @ref lr20xx_patch_load_pram to enable the PRAM usage.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_patch_load_pram, lr20xx_patch_get_version, lr20xx_pram_load_pram_lr2021, lr20xx_pram_load_pram_lr20x2
|
||||
*/
|
||||
lr20xx_status_t lr20xx_patch_enable_pram( const void* context );
|
||||
|
||||
/**
|
||||
* @brief Get Patch RAM (PRAM) version information
|
||||
*
|
||||
* This function can be called after @ref lr20xx_patch_load_pram to check that PRAM has been correctly loaded.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param pram_version The version information of the PRAM. Only valid if function returned with status @ref
|
||||
* LR20XX_STATUS_OK
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_patch_load_pram, lr20xx_patch_enable_pram, lr20xx_pram_load_pram_lr2021, lr20xx_pram_load_pram_lr20x2
|
||||
*/
|
||||
lr20xx_status_t lr20xx_patch_get_version( const void* context, lr20xx_patch_version_t* pram_version );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LR20XX_PATCH_H
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
@@ -0,0 +1,92 @@
|
||||
/*!
|
||||
* @file lr20xx_patch_types.h
|
||||
*
|
||||
* @brief Patch types driver definition for LR20XX
|
||||
*
|
||||
* The Clear BSD License
|
||||
* Copyright Semtech Corporation 2026. 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 LR20XX_PATCH_TYPES_H
|
||||
#define LR20XX_PATCH_TYPES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- DEPENDENCIES ------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC MACROS -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC CONSTANTS --------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC TYPES ------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief PRAM version information
|
||||
*
|
||||
* @ref lr20xx_patch_version_e::is_pram_loaded indicates if a PRAM is loaded.
|
||||
* If @ref lr20xx_patch_version_e::is_pram_loaded is true then lr20xx_patch_version_e::pram_type contains the type of
|
||||
* PRAM, and lr20xx_patch_version_e::pram_version contains the version of the loaded PRAM. If @ref
|
||||
* lr20xx_patch_version_e::is_pram_loaded is false, then value of fields lr20xx_patch_version_e::pram_type and
|
||||
* lr20xx_patch_version_e::pram_version are undefined, and should not be read.
|
||||
*/
|
||||
typedef struct lr20xx_patch_version_e
|
||||
{
|
||||
bool is_pram_loaded; //!< True if the PRAM is loaded, false otherwise
|
||||
uint8_t pram_type; //!< Type of the loaded PRAM, if lr20xx_patch_version_e::is_pram_loaded is true
|
||||
uint8_t pram_version; //!< Version of the loaded PRAM, if lr20xx_patch_version_e::is_pram_loaded is true
|
||||
} lr20xx_patch_version_t;
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LR20XX_PATCH_TYPES_H
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
@@ -0,0 +1,123 @@
|
||||
/*!
|
||||
* @file lr20xx_pram_lr2021.h
|
||||
*
|
||||
* @brief LR2021 firmware Patch RAM (PRAM) image
|
||||
*
|
||||
* The Clear BSD License
|
||||
* Copyright Semtech Corporation 2026. 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.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Vendored verbatim from Lora-net/usp, tag v1.1.2-feature-202604,
|
||||
* smtc_rac_lib/radio_drivers/lr20xx_driver/inc/lr20xx_pram_lr2021.h
|
||||
* (lr20xx_driver v2.0.2). Upstream ships this file with no per-file notice;
|
||||
* the header above is the standard Semtech Clear BSD notice carried by every
|
||||
* other file in that directory and reproduced here because the Clear BSD terms
|
||||
* require the copyright notice to be retained on redistribution. The array
|
||||
* contents below are byte-for-byte upstream.
|
||||
*
|
||||
* See LR20xx datasheet rev 2.1 section 22.3 for what the PRAM is and why it
|
||||
* must be loaded after every reset.
|
||||
*
|
||||
* NOTE: `pram_lr2021` and `pram_lr2021_size` are const definitions at file
|
||||
* scope, which in C have external linkage — include this header from exactly
|
||||
* one translation unit (lr20xx_lora.c) or the link will fail with duplicate
|
||||
* symbols.
|
||||
*/
|
||||
#ifndef LR20XX_PRAM_LR2021_H
|
||||
#define LR20XX_PRAM_LR2021_H
|
||||
#include <stdint.h>
|
||||
|
||||
const uint32_t pram_lr2021_size = 560;
|
||||
const uint32_t pram_lr2021[560] = {
|
||||
0x600db002, 0x31304, 0x10104c, 0x101018, 0x0, 0x0, 0x40c3c0f1, 0x88000, 0x212a,
|
||||
0xff82184, 0x212bb986, 0x40c30000, 0x9680080, 0x1800d981, 0xb90d0041, 0x8040c3, 0x794077f8, 0x7fe0c0d1,
|
||||
0x78e0720c, 0x45cbc2e4, 0x77f80080, 0x10011d00, 0x41c358bf, 0x18c00010, 0x8046cb, 0xe81a0968, 0xf80212b,
|
||||
0x2900000, 0x70148600, 0x41c3f2ac, 0x88000, 0x40202a, 0xff82084, 0x202bb886, 0xd9810040, 0x40a1b90d,
|
||||
0x1e007960, 0xf09c1041, 0x852f0b0e, 0x307208a, 0x146208a, 0x1041c3, 0xbe2134c, 0x1e00856f, 0x41c31001,
|
||||
0x120c0010, 0x856f0bd2, 0x41c3d83d, 0x11d80010, 0x856f0bc6, 0x41c3d835, 0x13940010, 0x856f0bba, 0x786208a,
|
||||
0x1041c3, 0xbae13b4, 0x208a856f, 0x41c30846, 0x14580010, 0x856f0b9e, 0x41c3d848, 0x143c0010, 0x856f0b92,
|
||||
0x41c3d847, 0x14240010, 0x856f0b86, 0x41c3d845, 0x15840010, 0x856f0b7a, 0x41c3d8e0, 0x15580010, 0x856f0b6e,
|
||||
0x41c3d8dc, 0x16080010, 0x856f0b62, 0x304208a, 0x1041c3, 0xb5615d0, 0x208a856f, 0x41c302c4, 0x16680010,
|
||||
0x856f0b46, 0x4c4208a, 0x1041c3, 0xb3a1640, 0x208a856f, 0x41c30484, 0x13740010, 0x856f0b2a, 0x186208a,
|
||||
0x1041c3, 0xb1e1470, 0xd882856f, 0x1041c3, 0xb121690, 0x208a856f, 0x41c30504, 0x184c0010, 0x856f0b02,
|
||||
0x87208a, 0x1041c3, 0xaf617f0, 0x208a856f, 0x41c30cc6, 0x18040010, 0x856f0ae6, 0xdc6208a, 0x1041c3,
|
||||
0xada15ac, 0xd8f6856f, 0x1040c3, 0x80401000, 0x40c38021, 0xff80080, 0xa021a040, 0x90a, 0xcf6,
|
||||
0xc6c4720c, 0x47cbc2e6, 0x20000f4, 0xb98dd9f0, 0x87c07960, 0x87004508, 0x120126ad, 0x10710e0d, 0x20120ad,
|
||||
0x95080d, 0x10940e0d, 0x510809, 0x8d2, 0xc6c640a1, 0x1cfcc2e6, 0xc1a1b6c8, 0x8044cb, 0x84800968,
|
||||
0x46484768, 0x43184528, 0x40c3ec0f, 0x77f80080, 0xec0b8080, 0x41a14063, 0x7c6042c1, 0x208c43e1, 0xc0408fc3,
|
||||
0x238cf443, 0xf227b7c2, 0xb2c1238c, 0x238cf229, 0xf22db682, 0x30310b63, 0x16004063, 0x807080, 0x7514600b,
|
||||
0xc040700c, 0x710cf22f, 0x11340d5b, 0x40c1c040, 0x45cb5839, 0x60500080, 0x734c712c, 0x5981a520, 0x10011d00,
|
||||
0x84ee89f, 0x720c0000, 0x40a1f01a, 0xc4641c1, 0x42e10020, 0x40a1f014, 0x9ee41c1, 0x42e10020, 0x40a1f00e,
|
||||
0xa4a41c1, 0x42e10020, 0x44cbf008, 0x24e00000, 0x42c141a1, 0x43e17c60, 0xc000c040, 0x7487780f, 0x341b1404,
|
||||
0x78e0c6c6, 0x42c3c2e2, 0x2400f2, 0x8040c3, 0x88000773, 0x710811, 0x250582a0, 0xf01f80, 0xf0270000,
|
||||
0xf441c3, 0x81000200, 0x1c2084, 0x8004208c, 0x43c3f405, 0xcccc0044, 0x43c3f004, 0xcccc002c, 0x8044cb,
|
||||
0xa460004c, 0x80001144, 0x2d0070d3, 0x25040000, 0xff0f1f80, 0xf788ffff, 0x797db894, 0xb897b896, 0xf003a420,
|
||||
0xa200b897, 0x70001600, 0x14400f4, 0xc6c25852, 0x1600c2e2, 0x80708d, 0x42c30773, 0xfdc00000, 0x16007a40,
|
||||
0x807081, 0x75300773, 0xffe20f6c, 0x40a14508, 0x78e0c6c2, 0x3e0817, 0x40c34408, 0x9680080, 0xb8028800,
|
||||
0x204f7885, 0x788f004c, 0x44cb, 0x7c00feb0, 0x8041c3, 0x89200773, 0x42c3e987, 0x2400f2, 0xb9ad8220,
|
||||
0x41c3a220, 0x101c0001, 0x78e07900, 0x40c3c0f1, 0x13b00001, 0x40c37840, 0x2400f2, 0xb98d8020, 0x7fe0c0d1,
|
||||
0xa020, 0x70811600, 0x2a10080, 0x837690a, 0x713400b5, 0xf341c3, 0x81000c14, 0x2822150, 0x180206c,
|
||||
0xf012085, 0x8105a100, 0x7f02084, 0xf2085, 0x8200a105, 0x1c0206c, 0x7fe0b880, 0x7de0a200, 0xf340c3,
|
||||
0x80200814, 0xb993b9d2, 0xb995b994, 0xa0207fe0, 0x40c3c0f1, 0x269c0000, 0xfa67840, 0x4300ffef, 0x7fe0c0d1,
|
||||
0x78e04060, 0xc1a1c3e2, 0x45cbc404, 0x27500000, 0xc4407d60, 0xffef0f86, 0x40604300, 0x78e0c7c2, 0x42c3c0f1,
|
||||
0x27b80000, 0xf727a40, 0x4300ffef, 0x7fe0c0d1, 0x78e04060, 0x43c3c0f1, 0x4f280000, 0x42c37b40, 0xd2400f3,
|
||||
0xb9dd8220, 0x7fe0c0d1, 0x78e0a220, 0x872c2e4, 0x454881ef, 0x88418521, 0x8840a940, 0xa9418521, 0x90218541,
|
||||
0xaa22793d, 0x85618824, 0x8042c3, 0x793d77fc, 0x8824ab23, 0x88058862, 0x4c2144, 0xb8046b32, 0x1032144,
|
||||
0x204485c1, 0x23050c01, 0x78250300, 0x8240ae04, 0x2a418501, 0xa8250401, 0x2012a41, 0xa8268501, 0xa8478501,
|
||||
0x1d00730c, 0xc6c41201, 0xcdec2e4, 0x4548802f, 0x85014608, 0xa8208e29, 0x85018e28, 0x8521a821, 0x781d9605,
|
||||
0x9606a902, 0x781d8521, 0x886f0d06, 0x8521a903, 0x9606a904, 0x20449625, 0x69120042, 0x20448521, 0x78450100,
|
||||
0x8e12a905, 0xa9068521, 0x40c38561, 0x78080080, 0x11c11d00, 0x8b458800, 0x79456833, 0xab25730c, 0x78e0c6c4,
|
||||
0xfd2c2e2, 0x4508838f, 0x40c3, 0x78408db8, 0xf340c3, 0x80200b74, 0x4012184, 0x411090f, 0x8ba8001,
|
||||
0x780f836f, 0xc6c2ad08, 0x43c3c2e2, 0x8eb80000, 0x45087b60, 0xf344cb, 0x84600b50, 0x10022578, 0x2304ba18,
|
||||
0xf8ff0f81, 0x7945ffff, 0xc6c2a420, 0x45cbc2e4, 0x14400f4, 0x40c3, 0x78609fec, 0x850085c0, 0x781178c2,
|
||||
0xa070d3, 0xd0c0001, 0xc6c4ffc6, 0x41c3c2e2, 0xa9680000, 0x82b7940, 0x45080131, 0x820f0aee, 0x111081f,
|
||||
0xf442c3, 0x82200144, 0x8040c3, 0x18007800, 0xa0210041, 0x180216c, 0x40a1a200, 0x78e0c6c2, 0x41c3c2e2,
|
||||
0xaad40000, 0x82b7940, 0x45080171, 0x820f0ab6, 0x111081f, 0xf442c3, 0x82200144, 0x8040c3, 0x18007800,
|
||||
0xa0210041, 0x180216c, 0x40a1a200, 0x78e0c6c2, 0x40c3c0f1, 0xb15c0000, 0x42c37840, 0x78000080, 0xe9098220,
|
||||
0x1a008221, 0x1e000001, 0xf47040, 0xc0d10144, 0x78e07ee0, 0x40c3c0f1, 0xb2b00000, 0x42c37840, 0x78000080,
|
||||
0xe9098220, 0x1a008221, 0x1e000001, 0xf47040, 0xc0d10144, 0x78e07ee0, 0x41c3c2e2, 0xb3dc0000, 0xa367940,
|
||||
0x827820f, 0x16000151, 0xf37000, 0x45cb0d3c, 0x77fc0080, 0xb0ab854, 0xa500802f, 0x85008030, 0xb94c790c,
|
||||
0xc6c2a520, 0x8041c3, 0x40c37800, 0x3930, 0x11900, 0xa1017fe0, 0x1cfcc2e6, 0xc1a3b6c8, 0x85b4528,
|
||||
0x716f01b4, 0x8d838d05, 0x8d648dc0, 0x8d428d21, 0x8f206d, 0xc041b8c0, 0x12002c40, 0x40c17b05, 0xdbec742,
|
||||
0x1c0082af, 0x26053081, 0xf415903e, 0x42c38d05, 0x83000f3, 0x78128220, 0xb9b9b818, 0x800212fc, 0xf802004,
|
||||
0x200, 0xb826038, 0x4100862f, 0x4063726f, 0x1404c0a3, 0xc6c6341b, 0xa76c2e6, 0x1048800f, 0x8a30080,
|
||||
0x244a0071, 0x41c37200, 0x6faa00b1, 0xf342c3, 0x40c30c18, 0x6faa004e, 0x501a04, 0x59c343c3, 0x1a04ae57,
|
||||
0x22500010, 0x1a040281, 0x820000d0, 0xff7d44cb, 0x43c3d5f7, 0x7f5dff7d, 0xf802004, 0xfffc07ff, 0xf802005,
|
||||
0x1f800, 0xa180a200, 0x8102a161, 0x9f4643c3, 0x206c0012, 0xb8850180, 0xa261a102, 0x800012f0, 0x43c370ad,
|
||||
0x18b00010, 0x180206c, 0x2045bd93, 0x23400300, 0x41a1020c, 0x10cf2d41, 0x80001af0, 0x2c020a8, 0x14c01401,
|
||||
0x4ce1301, 0xbe087825, 0x78c561f9, 0xc6c6a206, 0x40c3c0f1, 0x1ac00001, 0xf4e7840, 0xc0d1ffcf, 0x78e07ee0,
|
||||
0xc1a5c3e6, 0xc00a4608, 0x4328c40c, 0xc50bc10e, 0xc040c70d, 0x9fc3248c, 0x20ca4081, 0xe68b0321, 0xc541c144,
|
||||
0x100124ca, 0x145cb, 0x40c11e7c, 0xc7434161, 0xc4427d60, 0xe68a4508, 0xffef0f06, 0x106125ca, 0xc7c640a1,
|
||||
0x41c3c0f1, 0x60c90080, 0x1e008900, 0x807002, 0x11ff0584, 0x40c38081, 0x78080080, 0xb76a020, 0x730c84ef,
|
||||
0x884f0c0a, 0x7ee0c0d1, 0x2494e49, 0x1018c0, 0xfffff8d0, 0x800968, 0xfffff970, 0x8077f8, 0x14,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf7e41c09, 0x1f20201f,
|
||||
0xe10f0fe1, 0xf9fffff9
|
||||
};
|
||||
#endif // LR20XX_PRAM_LR2021_H
|
||||
@@ -49,13 +49,21 @@
|
||||
* --- PRIVATE MACROS-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* LR2021 internal RTC: 32.768kHz (datasheet §5.3) */
|
||||
/**
|
||||
* @brief Internal RTC frequency
|
||||
*/
|
||||
#define LR20XX_RTC_FREQ_IN_HZ ( 32768UL )
|
||||
|
||||
/* Front-end calibration granularity: 4MHz steps (LR2021 datasheet §5.5.1) */
|
||||
/*!
|
||||
* @brief Frequency step in Hz used to compute the front end calibration parameter
|
||||
*
|
||||
* @see lr20xx_radio_common_calibrate_front_end_helper
|
||||
*/
|
||||
#define LR20XX_RADIO_COMMON_FRONT_END_CALIBRATION_STEP_IN_HZ ( 4000000u )
|
||||
|
||||
/* LR2021 register: LQI (Link Quality Indicator) — Semtech SWDR001 register map */
|
||||
/**
|
||||
* Register address holding the LQI value
|
||||
*/
|
||||
#define LR20XX_RADIO_COMMON_REGISTER_LQI ( 0xF30C38 )
|
||||
|
||||
/*
|
||||
@@ -145,13 +153,27 @@ enum
|
||||
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
|
||||
*/
|
||||
|
||||
/* Serialize one RSSI calibration gain item; returns pointer past written data.
|
||||
* Caller ensures array has sufficient space. */
|
||||
/*!
|
||||
* @brief Serialize an RSSI calibration item into an array
|
||||
*
|
||||
* @param array Pointer to the array to write to. It is up to the caller to ensure the array is long enough to store the
|
||||
* serialized item
|
||||
* @param rssi_calibration_item Pointer to the RSSI calibration item to serialize. It is up to the caller to ensure it
|
||||
* points to an actual item.
|
||||
* @return uint8_t* Pointer to the next memory slot to write
|
||||
*/
|
||||
uint8_t* lr20xx_radio_common_serialize_rssi_calibration_item(
|
||||
uint8_t* array, const lr20xx_radio_common_rssi_calibration_gain_item_t* rssi_calibration_item );
|
||||
|
||||
/* Serialize a full RSSI calibration gain table; no-op if rssi_calibration_table is NULL.
|
||||
* Returns pointer past written data. */
|
||||
/**
|
||||
* @brief Serialize an RSSI calibration table into an array
|
||||
*
|
||||
* @param array Pointer to the array to write to. It is up to the caller to ensure the array is long enough to store the
|
||||
* serialized table
|
||||
* @param rssi_calibration_table Pointer to the calibration table to serialize. Can be NULL, in which case nothing is
|
||||
* written to the array
|
||||
* @return uint8_t* Pointer to the next memory slot to write
|
||||
*/
|
||||
uint8_t* lr20xx_radio_common_serialize_rssi_calibration_table(
|
||||
uint8_t* array, const lr20xx_radio_common_rssi_calibration_gain_table_t* rssi_calibration_table );
|
||||
|
||||
@@ -237,17 +259,7 @@ lr20xx_status_t lr20xx_radio_common_set_rx_path( const void* context, lr20xx_rad
|
||||
( uint8_t ) boost_mode,
|
||||
};
|
||||
|
||||
const lr20xx_status_t write_status =
|
||||
( lr20xx_status_t ) lr20xx_hal_write( context, cbuffer, LR20XX_RADIO_COMMON_SET_RX_PATH_CMD_LENGTH, 0, 0 );
|
||||
|
||||
if( write_status != LR20XX_STATUS_OK )
|
||||
{
|
||||
return write_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LR20XX_WORKAROUNDS_CONDITIONAL_APPLY_AUTOMATIC_DCDC_CONFIGURE( context );
|
||||
}
|
||||
return ( lr20xx_status_t ) lr20xx_hal_write( context, cbuffer, LR20XX_RADIO_COMMON_SET_RX_PATH_CMD_LENGTH, 0, 0 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_radio_common_set_pa_cfg( const void* context, const lr20xx_radio_common_pa_cfg_t* pa_cfg )
|
||||
@@ -330,17 +342,7 @@ lr20xx_status_t lr20xx_radio_common_set_pkt_type( const void* context, lr20xx_ra
|
||||
( uint8_t ) pkt_type,
|
||||
};
|
||||
|
||||
const lr20xx_status_t write_status =
|
||||
( lr20xx_status_t ) lr20xx_hal_write( context, cbuffer, LR20XX_RADIO_COMMON_SET_PKT_TYPE_CMD_LENGTH, 0, 0 );
|
||||
|
||||
if( write_status != LR20XX_STATUS_OK )
|
||||
{
|
||||
return write_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LR20XX_WORKAROUNDS_CONDITIONAL_APPLY_AUTOMATIC_DCDC_RESET( context );
|
||||
}
|
||||
return ( lr20xx_status_t ) lr20xx_hal_write( context, cbuffer, LR20XX_RADIO_COMMON_SET_PKT_TYPE_CMD_LENGTH, 0, 0 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_radio_common_get_pkt_type( const void* context, lr20xx_radio_common_pkt_type_t* pkt_type )
|
||||
|
||||
@@ -69,169 +69,577 @@ extern "C" {
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Calibrate front-end (ADC offset, poly-phase filter, image) from raw calibration values.
|
||||
* Must be called when chip is not in Rx/Tx. Up to 3 values; 0 calibrates at next 4MHz multiple of current RF freq.
|
||||
* RF ops should stay within 50MHz of a calibrated frequency. Errors readable via lr20xx_system_get_errors.
|
||||
/*!
|
||||
* @brief Executes front end calibration procedure on given raw frequencies and Rx path
|
||||
*
|
||||
* The front end calibration calibrates:
|
||||
* - the ADC offset
|
||||
* - the poly-phase filter
|
||||
* - the image
|
||||
* This function can be called only if the chip is neither in Rx nor Tx states.
|
||||
*
|
||||
* Upon completion, the chip will return to the same mode it was before calling this command.
|
||||
* Potential calibration issues can be read out with lr20xx_system_get_errors command.
|
||||
*
|
||||
* Up to three calibration configuration values can be given.
|
||||
* Only the provided and non-zero frequencies are calibrated.
|
||||
*
|
||||
* It is advised to configure calibration so that RF frequencies used during RF operations are at most 50MHz away from
|
||||
* a calibrated RF frequency.
|
||||
*
|
||||
* If no calibration configuration is given, then one front end calibration is executed on the next 4MHz multiple of the
|
||||
* currently configured RF frequency.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] front_end_calibration_values Array of front end calibration configuration. It is up to the caller to
|
||||
* ensure that it has at least n_rx_path_frequency elements.
|
||||
* @param [in] n_front_end_calibration_values Number of front end calibration values to consider. Valid values are [0:3]
|
||||
* included.
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_get_errors, lr20xx_radio_common_calibrate_front_end_helper
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_calibrate_front_end(
|
||||
const void* context, const lr20xx_radio_common_raw_front_end_calibration_value_t* front_end_calibration_values,
|
||||
uint8_t n_front_end_calibration_values );
|
||||
|
||||
/*
|
||||
* Helper: converts front_end_calibration_value_t structs to raw values and calls calibrate_front_end.
|
||||
* Each frequency is rounded up to the next 4MHz multiple.
|
||||
/*!
|
||||
* @brief Helper function to execute front end calibration procedure
|
||||
*
|
||||
* This function really is a helper function that converts the front end calibration structures in argument to the
|
||||
* corresponding raw values, and calls @ref lr20xx_radio_common_calibrate_front_end.
|
||||
* For each given front end calibration frequency, the actual calibration frequency used is the next frequency multiple
|
||||
* of 4MHz following the given frequency.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] front_end_calibration_structures Array of front end calibration configuration structures. It is up to the
|
||||
* user that it contains at least n_rx_path_frequency items.
|
||||
* @param [in] n_front_end_calibration_structures Number of front end calibration structures to consider. Valid values
|
||||
* are [0:3] included.
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_radio_common_calibrate_front_end
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_calibrate_front_end_helper(
|
||||
const void* context, const lr20xx_radio_common_front_end_calibration_value_t* front_end_calibration_structures,
|
||||
uint8_t n_front_end_calibration_structures );
|
||||
|
||||
/* Convert milliseconds to 32.768kHz RTC step count */
|
||||
/**
|
||||
* @brief Helper function that computes the number of RTC steps from a given time in millisecond
|
||||
*
|
||||
* @param [in] time_in_ms Time in millisecond
|
||||
*
|
||||
* @returns Number of RTC steps
|
||||
*/
|
||||
uint32_t lr20xx_radio_common_convert_time_in_ms_to_rtc_step( uint32_t time_in_ms );
|
||||
|
||||
/*!
|
||||
* @brief Set the RF frequency to be used
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] freq_in_hz RF frequency in Hertz
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rf_freq( const void* context, uint32_t freq_in_hz );
|
||||
|
||||
/*!
|
||||
* @brief Select the Rx path and set the boost mode
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rx_path Rx path to be used
|
||||
* @param [in] boost_mode Boost mode applied to selected Rx path
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rx_path( const void* context, lr20xx_radio_common_rx_path_t rx_path,
|
||||
lr20xx_radio_common_rx_path_boost_mode_t boost_mode );
|
||||
|
||||
/* Must be called before lr20xx_radio_common_set_tx_params */
|
||||
/*!
|
||||
* @brief Set the Power Amplifier configuration
|
||||
*
|
||||
* It must be called prior using @ref lr20xx_radio_common_set_tx_params.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] pa_cfg The structure for PA configuration
|
||||
*
|
||||
* @see lr20xx_radio_common_set_tx_params
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_pa_cfg( const void* context, const lr20xx_radio_common_pa_cfg_t* pa_cfg );
|
||||
|
||||
/*
|
||||
* Set TX output power (0.5dBm steps) and PA ramp time. Requires prior call to set_pa_cfg.
|
||||
* LF PA: power_half_dbm in [0xED, 0x2C] (-9.5 to +22dBm)
|
||||
* HF PA: power_half_dbm in [0xD9, 0x18] (-19.5 to +12dBm)
|
||||
/*!
|
||||
* @brief Set the parameters for TX power and power amplifier ramp time
|
||||
*
|
||||
* @ref lr20xx_radio_common_set_pa_cfg must be called prior calling lr20xx_radio_common_set_tx_params.
|
||||
*
|
||||
* The range of possible TX output power values depends on PA selected with @ref
|
||||
* lr20xx_radio_common_set_pa_cfg :
|
||||
* - for @ref LR20XX_RADIO_COMMON_PA_SEL_LF : power value goes from -9.5dBm to +22dBm
|
||||
* (ie. @p power_half_dbm from 0xED to 0x2C)
|
||||
* - for @ref LR20XX_RADIO_COMMON_PA_SEL_HF : power value goes from -19.5dBm to +12dBm
|
||||
* (ie. @p power_half_dbm from 0xD9 to 0x18)
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] power_half_dbm TX output power raw value, as 0.5dBm steps (so twice the value in dBm)
|
||||
* @param [in] ramp_time Ramping time configuration
|
||||
*
|
||||
* @see lr20xx_radio_common_set_pa_cfg
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_tx_params( const void* context, const int8_t power_half_dbm,
|
||||
const lr20xx_radio_common_ramp_time_t ramp_time );
|
||||
|
||||
/* Set RSSI calibration gain tables; NULL pointer skips that path */
|
||||
/*!
|
||||
* @brief Set RSSI calibration table(s)
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rssi_cal_table_lf Pointer to RSSI calibration table for low frequency path. Can be NULL, in which case
|
||||
* this path is not configured
|
||||
* @param [in] rssi_cal_table_hf Pointer to RSSI calibration table for high frequency path. Can be NULL, in which case
|
||||
* this path is not configured
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rssi_calibration(
|
||||
const void* context, const lr20xx_radio_common_rssi_calibration_gain_table_t* rssi_cal_table_lf,
|
||||
const lr20xx_radio_common_rssi_calibration_gain_table_t* rssi_cal_table_hf );
|
||||
|
||||
/*
|
||||
* Set chip mode after leaving Tx/Rx (successful, timeout, or CAD).
|
||||
* Applied on: TX done, RX done (non-continuous), RX duty cycle done, CAD exit, timeout, auto-Tx/Rx transitions.
|
||||
/*!
|
||||
* @brief Configure the chip mode shall be in after transmission or reception operation
|
||||
*
|
||||
* @remark The configured fallback mode is applied as soon as the chip leaves Tx / Rx mode:
|
||||
* - after a successful transmission
|
||||
* - after a successful reception if not set in continuous mode
|
||||
* - after a successful reception in duty cycle mode
|
||||
* - after a CAD operation (depending on configured exit mode)
|
||||
* - when a timeout occurs
|
||||
* - during automatic Tx/Rx (see @ref lr20xx_radio_common_configure_auto_tx_rx), both after the first Rx/Tx and the
|
||||
* second Tx/Rx
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] fallback_mode Chip mode to enter after transmission or reception operation
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rx_tx_fallback_mode( const void* context,
|
||||
const lr20xx_radio_common_fallback_modes_t fallback_mode );
|
||||
|
||||
/*
|
||||
* Set packet type; must precede any modulation configuration.
|
||||
* Automatically applies lr20xx_workarounds_dcdc_reset unless LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_RESET is defined.
|
||||
/*!
|
||||
* @brief Set the packet type to be used
|
||||
*
|
||||
* @remark This command has to be sent prior to any modulation related configuration command
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] pkt_type Packet type to be configured
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_pkt_type( const void* context, lr20xx_radio_common_pkt_type_t pkt_type );
|
||||
|
||||
/*!
|
||||
* @brief Get the packet type currently in use
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] pkt_type Packet type currently in use
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_get_pkt_type( const void* context, lr20xx_radio_common_pkt_type_t* pkt_type );
|
||||
|
||||
/*
|
||||
* Configure when the Rx timeout timer stops:
|
||||
* - false: on LoRa header / GFSK syncword detection
|
||||
* - true: on preamble detection
|
||||
/*!
|
||||
* @brief Set the event on which the Rx timeout is stopped
|
||||
*
|
||||
* Depending on the configuration, Rx timeout is stopped either on the detection of the following events:
|
||||
* - LoRa header detection (or Rx done in implicit mode) / GFSK syncword detection
|
||||
* - Preamble detection
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] is_stopped_on_preamble_detection If true, the timer stops on preamble detection
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rx_timeout_stop_event( const void* context,
|
||||
const bool is_stopped_on_preamble_detection );
|
||||
|
||||
/*!
|
||||
* @brief Reset internal Rx stats
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_reset_rx_stats( const void* context );
|
||||
|
||||
/*
|
||||
* Get instantaneous RSSI during active reception.
|
||||
* Full precision: RSSI_dBm = rssi_in_dbm - (half_dbm_count * 0.5); half_dbm_count may be NULL.
|
||||
/*!
|
||||
* @brief Get the instantaneous RSSI while the transceiver is in reception mode
|
||||
*
|
||||
* This command can be used during reception of a packet
|
||||
*
|
||||
* The instantaneous RSSI can be obtained with 0.5 dBm accuracy thanks to the output argument half_dbm_count, which is
|
||||
* either 0 or 1, using the following formula:
|
||||
*
|
||||
* RSSI = rssi_in_dbm - ( half_dbm_count * 0.5 )
|
||||
*
|
||||
* The pointer half_dbm_count can be NULL, in which case the value is not returned.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] rssi_in_dbm Instantaneous RSSI.
|
||||
* @param [out] half_dbm_count Count of 0.5 dBm to subtract to value in dBm. Can be NULL.
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_get_rssi_inst( const void* context, int16_t* rssi_in_dbm, uint8_t* half_dbm_count );
|
||||
|
||||
/*!
|
||||
* @brief Start RX operations with a timeout in millisecond
|
||||
*
|
||||
* @remark To set the radio in Rx continuous mode, refer to @ref lr20xx_radio_common_set_rx_with_timeout_in_rtc_step
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] timeout_in_ms Timeout configuration in millisecond for RX operation
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rx( const void* context, const uint32_t timeout_in_ms );
|
||||
|
||||
/*
|
||||
* Start RX with RTC step timeout. timeout_in_ms = steps / 32.768; max 0xFFFFFE (~511s).
|
||||
* 0x000000 = single RX (wait for packet); 0xFFFFFF = continuous RX.
|
||||
/*!
|
||||
* @brief Start RX operations with a timeout in RTC step
|
||||
*
|
||||
* The timeout duration is obtained by:
|
||||
* \f$ timeout\_duration\_ms = timeout\_in\_rtc\_step \times \frac{1}{32.768} \f$
|
||||
*
|
||||
* Maximal timeout value is 0xFFFFFE, which gives a maximal timeout of 511 seconds.
|
||||
*
|
||||
* The timeout argument can also have the following special values:
|
||||
* <table>
|
||||
* <tr><th> Special values </th><th> Meaning </th>
|
||||
* <tr><td> 0x000000 </td><td> RX single - transceiver stays in RX mode until a packet is received </td>
|
||||
* <tr><td> 0xFFFFFF </td><td> RX continuous - transceiver stays in RX mode even after reception of a packet </td>
|
||||
* </table>
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] timeout_in_rtc_step Timeout configuration in RTC step for RX operation
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rx_with_timeout_in_rtc_step( const void* context,
|
||||
const uint32_t timeout_in_rtc_step );
|
||||
|
||||
/* Start RX using timeout pre-configured by set_default_rx_tx_timeout[_in_rtc_step] */
|
||||
/*!
|
||||
* @brief Start RX operations with a pre-configured default timeout
|
||||
*
|
||||
* @remark The timeout has to be configured by calling either @ref lr20xx_radio_common_set_default_rx_tx_timeout or @ref
|
||||
* lr20xx_radio_common_set_default_rx_tx_timeout_in_rtc_step
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rx_with_default_timeout( const void* context );
|
||||
|
||||
/*!
|
||||
* @brief Start transmission operation with a timeout in millisecond
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] timeout_in_ms Timeout configuration in millisecond for RX operation
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_tx( const void* context, const uint32_t timeout_in_ms );
|
||||
|
||||
/* Start TX with RTC step timeout. timeout=0 disables timeout. Max 0xFFFFFF (~511s). */
|
||||
/*!
|
||||
* @brief Start transmission operation with a timeout in RTC step
|
||||
*
|
||||
* The timeout duration is obtained by:
|
||||
* \f$ timeout\_duration\_ms = timeout_in_rtc_step \times \frac{1}{32.768} \f$
|
||||
*
|
||||
* Maximal timeout value is 0xFFFFFF, which gives a maximal timeout of 511 seconds.
|
||||
*
|
||||
* If \p timeout_in_rtc_step is set to 0, then no timeout is used.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] timeout_in_rtc_step Timeout configuration in RTC step for TX operation
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_tx_with_timeout_in_rtc_step( const void* context,
|
||||
const uint32_t timeout_in_rtc_step );
|
||||
|
||||
/* Start TX using timeout pre-configured by set_default_rx_tx_timeout[_in_rtc_step] */
|
||||
/*!
|
||||
* @brief Start TX operations with a pre-configured default timeout
|
||||
*
|
||||
* @remark The timeout has to be configured by calling either @ref lr20xx_radio_common_set_default_rx_tx_timeout or @ref
|
||||
* lr20xx_radio_common_set_default_rx_tx_timeout_in_rtc_step
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_tx_with_default_timeout( const void* context );
|
||||
|
||||
/*!
|
||||
* @brief Set the transceiver into a Tx test mode.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] mode Test mode
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_tx_test_mode( const void* context, lr20xx_radio_common_tx_test_mode_t mode );
|
||||
|
||||
/* Select PA; set_pa_cfg must be called first */
|
||||
/*!
|
||||
* @brief Select the Power Amplifier to use
|
||||
*
|
||||
* @remark Configuration has to be applied first by calling @ref lr20xx_radio_common_set_pa_cfg
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] sel Power amplifier selection
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_select_pa( const void* context, lr20xx_radio_common_pa_selection_t sel );
|
||||
|
||||
/* Converts ms to RTC steps and calls set_rx_duty_cycle_with_timing_in_rtc_step */
|
||||
/*!
|
||||
* @brief Configure and start a Rx Duty Cycle operation with timings in millisecond
|
||||
*
|
||||
* @remark This function computes timings in RTC step from values given in millisecond and then calls @ref
|
||||
* lr20xx_radio_common_set_rx_duty_cycle_with_timing_in_rtc_step
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rx_period_in_ms Rx period in millisecond
|
||||
* @param [in] sleep_period_in_ms Sleep period in millisecond
|
||||
* @param [in] mode Operation mode used during Rx phase
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rx_duty_cycle( const void* context, const uint32_t rx_period_in_ms,
|
||||
const uint32_t sleep_period_in_ms,
|
||||
const lr20xx_radio_common_rx_duty_cycle_mode_t mode );
|
||||
|
||||
/*
|
||||
* Start RX duty cycle: Rx for rx_period, then sleep for sleep_period, repeat.
|
||||
* On activity detected: extend Rx timeout to (2*rx_period + sleep_period).
|
||||
* On packet received: return to fallback mode.
|
||||
* CAD mode (LoRa only): configure CAD params before calling.
|
||||
* To stop during sleep: call lr20xx_system_wakeup then lr20xx_system_set_standby_mode when BUSY goes low.
|
||||
/*!
|
||||
* @brief Configure and start a Rx Duty Cycle operation with timings in RTC step
|
||||
*
|
||||
* It executes the following steps:
|
||||
* 1. Reception - enters reception state for duration defined by @p rx_period_in_rtc_step:
|
||||
* - @p mode = LR20XX_RADIO_COMMON_RX_DUTY_CYCLE_MODE_RX: regular Rx mode
|
||||
* - @p mode = LR20XX_RADIO_COMMON_RX_DUTY_CYCLE_MODE_CAD (LoRa only) : CAD mode
|
||||
* 2. Depending on the over-the-air activity detection (either preamble detection or valid CAD):
|
||||
* - In case of positive over-the-air detection, the Rx period timeout is restarted with the value
|
||||
* \f$2 \times rx_period_in_rtc_step + sleep_period_in_rtc_step\f$
|
||||
* - else, the transceiver goes into sleep mode with retention for a duration defined by @p
|
||||
* sleep_period_in_rtc_step
|
||||
* 3. On wake-up, the transceiver restarts the process to step 1
|
||||
*
|
||||
* The loop described above is terminated in the following cases:
|
||||
* - a packet is received during a Rx window - the chip goes back to fallback mode configured with @ref
|
||||
* lr20xx_radio_common_set_rx_tx_fallback_mode
|
||||
* - a call to @ref lr20xx_system_set_standby_mode is done during a Rx window
|
||||
* - a call to @ref lr20xx_system_wakeup is done during a sleep phase - to prevent a possible race condition from
|
||||
* happening when the call is performed during the boot phase, it is recommended to call @ref
|
||||
* lr20xx_system_set_standby_mode when BUSY is going low
|
||||
*
|
||||
* @remark If @p mode is set to @ref LR20XX_RADIO_COMMON_RX_DUTY_CYCLE_MODE_CAD, CAD parameters have to be defined
|
||||
* before calling this function
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rx_period_in_rtc_step Rx period in RTC step
|
||||
* @param [in] sleep_period_in_rtc_step Sleep period in RTC step
|
||||
* @param [in] mode Operation mode used during Rx phase
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_rx_duty_cycle_with_timing_in_rtc_step(
|
||||
const void* context, const uint32_t rx_period_in_rtc_step, const uint32_t sleep_period_in_rtc_step,
|
||||
const lr20xx_radio_common_rx_duty_cycle_mode_t mode );
|
||||
|
||||
/*
|
||||
* Configure automatic Tx-after-Rx or Rx-after-Tx.
|
||||
* Set mode to Tx → auto-Rx fires; set mode to Rx → auto-Tx fires.
|
||||
* Between operations the chip enters fallback mode. Triggers once then auto-disables.
|
||||
* delay_in_tick must account for PA ramp, TCXO start, fallback mode switching.
|
||||
* Pass condition=LR20XX_RADIO_COMMON_AUTO_TX_RX_OFF to disable.
|
||||
/**
|
||||
* @brief Configure the automatic Tx operation after Rx, or automatic Rx operation after Tx
|
||||
*
|
||||
* This feature allows the chip to automatically execute a Tx operation after an Rx one; or to automatically execute an
|
||||
* Rx operation after a Tx one.
|
||||
*
|
||||
* The order of operation depends on the mode manually requested after issuing this command:
|
||||
* - If the radio is set to Tx mode, then an automatic Rx will be executed;
|
||||
* - If the radio is set to Rx mode, then an automatic Tx will be executed.
|
||||
*
|
||||
* This feature is similar to a call to @ref lr20xx_radio_common_set_tx_with_timeout_in_rtc_step (or @ref
|
||||
* lr20xx_radio_common_set_rx_with_timeout_in_rtc_step) after the given delay_in_tick. Therefore to fine tune the
|
||||
* instant of first bit automatically sent over-the-air (or reception window opening) other delays have to be taken into
|
||||
* account when determining the delay_in_tick value. For instance, but not limited to:
|
||||
* - PA ramp-up
|
||||
* - TCXO start time (if applicable)
|
||||
* - Configured fallback mode
|
||||
* - Radio state switching time
|
||||
*
|
||||
* When the automatic Tx/Rx is enabled, the chip is in the state configured by @ref
|
||||
* lr20xx_radio_common_set_rx_tx_fallback_mode between the end of Rx (or Tx) operation and the start of the next
|
||||
* automatic Tx (or Rx) operation.
|
||||
*
|
||||
* Calling @ref lr20xx_radio_common_configure_auto_tx_rx with condition being @ref LR20XX_RADIO_COMMON_AUTO_TX_RX_OFF
|
||||
* disables the automatic Tx or Rx behavior. Doing so after end of Rx (or Tx) operation and start of automatic Tx (or
|
||||
* Rx) also cancels the automatic Tx or Rx operation.
|
||||
*
|
||||
* Once the automatic operation triggers, the feature is automatically disabled. So that to engage again an automatic
|
||||
* operation after a manual one, the @ref lr20xx_radio_common_configure_auto_tx_rx must be called to enable it again.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param configuration The configuration of the automatic Tx/Rx
|
||||
*
|
||||
* @see lr20xx_radio_common_set_tx_with_timeout_in_rtc_step, lr20xx_radio_common_set_rx_with_timeout_in_rtc_step,
|
||||
* lr20xx_radio_common_set_rx_tx_fallback_mode
|
||||
*
|
||||
* @return lr20xx_status_t
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_configure_auto_tx_rx(
|
||||
const void* context, const lr20xx_radio_common_auto_tx_rx_configuration_t* configuration );
|
||||
|
||||
/*!
|
||||
* @brief Get the length in byte of the last received packet
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] pkt_len Length in byte of the last received packet
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_get_rx_packet_length( const void* context, uint16_t* pkt_len );
|
||||
|
||||
/*!
|
||||
* @brief Set default timeout values for RX and TX operations
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rx_timeout_in_ms Timeout configuration in millisecond for RX operation
|
||||
* @param [in] tx_timeout_in_ms Timeout configuration in millisecond for TX operation
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_default_rx_tx_timeout( const void* context, uint32_t rx_timeout_in_ms,
|
||||
uint32_t tx_timeout_in_ms );
|
||||
|
||||
/* Same special values apply as for set_rx/tx_with_timeout_in_rtc_step */
|
||||
/*!
|
||||
* @brief Set default timeout values for RX and TX operations
|
||||
*
|
||||
* @remark Special values defined for @ref lr20xx_radio_common_set_rx_with_timeout_in_rtc_step and @ref
|
||||
* lr20xx_radio_common_set_tx_with_timeout_in_rtc_step are also applicable here
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rx_timeout_in_rtc_step Timeout configuration in RTC step for RX operation
|
||||
* @param [in] tx_timeout_in_rtc_step Timeout configuration in RTC step for TX operation
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_default_rx_tx_timeout_in_rtc_step( const void* context,
|
||||
uint32_t rx_timeout_in_rtc_step,
|
||||
uint32_t tx_timeout_in_rtc_step );
|
||||
|
||||
/* Arm a 32MHz timestamp on the given radio event; read with get_elapsed_time_in_tick */
|
||||
/*!
|
||||
* @brief Set a timestamp source for a given configuration slot
|
||||
*
|
||||
* @remark This command configure a source linked to a radio event that will then be used by @ref
|
||||
* lr20xx_radio_common_get_elapsed_time_in_tick to compute the elapsed time
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] cfg_slot Configuration slot
|
||||
* @param [in] source Timestamp source
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_timestamp_source( const void* context,
|
||||
lr20xx_radio_common_timestamp_cfg_slot_t cfg_slot,
|
||||
lr20xx_radio_common_timestamp_source_t source );
|
||||
|
||||
/*
|
||||
* Read elapsed 32MHz ticks since the event configured in set_timestamp_source for cfg_slot.
|
||||
* Radio must not have entered sleep between the event and this call.
|
||||
/*!
|
||||
* @brief Get the elapsed time since radio event registered at given configuration slot
|
||||
*
|
||||
* @remark This is the time elapsed between the event configured with @ref lr20xx_radio_common_set_timestamp_source and
|
||||
* the NSS falling edge of this request
|
||||
*
|
||||
* @remark That radio must not be put in sleep mode between the configured event and the call to this function
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] cfg_slot Configuration slot
|
||||
* @param [out] elapsed_time_in_tick Elapsed time in 32MHz tick
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_get_elapsed_time_in_tick( const void* context,
|
||||
lr20xx_radio_common_timestamp_cfg_slot_t cfg_slot,
|
||||
uint32_t* elapsed_time_in_tick );
|
||||
|
||||
/* Start CCA (Clear Channel Assessment); duration in 32MHz steps */
|
||||
/*!
|
||||
* @brief Launch a CCA (Clear Channel Assessment) operation
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] duration CCA duration in 32MHz step
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_cca( const void* context, const uint32_t duration );
|
||||
|
||||
/*!
|
||||
* @brief Get the CCA values once the operation is over
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] cca_res Structure holding CCA result
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_get_cca_result( const void* context, lr20xx_radio_common_cca_res_t* cca_res );
|
||||
|
||||
/*!
|
||||
* @brief Set the gain to be used by the AGC (Automatic Gain Control)
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] gain Gain
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_agc_gain( const void* context, lr20xx_radio_common_gain_step_t gain );
|
||||
|
||||
/* Set non-LoRa CAD parameters; not applicable when packet type is LoRa */
|
||||
/*!
|
||||
* @brief Set non-LoRa CAD parameters
|
||||
*
|
||||
* @remark This command is not applicable if the packet type is set to LoRa
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] params CAD parameters
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_cad_params( const void* context,
|
||||
const lr20xx_radio_common_cad_params_t* params );
|
||||
|
||||
/*!
|
||||
* @brief Set the chip in non-LoRa CAD mode
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_set_cad( const void* context );
|
||||
|
||||
/*
|
||||
* Get LQI of last detected packet. Valid from preamble detection until next Rx call.
|
||||
* Applies to FSK-based modes: FSK, BLE, OQPSK-15.4, Wi-SUN, Wireless M-Bus, Z-Wave.
|
||||
/**
|
||||
* @brief Get the Link Quality Indicator (LQI) of latest detected packet
|
||||
*
|
||||
* This function is only valid if the latest received packet is an FSK based modulation:
|
||||
* - FSK
|
||||
* - Bluetooth_LE
|
||||
* - OQPSK 15.4
|
||||
* - Wi-SUN
|
||||
* - Wireless M-Bus
|
||||
* - Z-Wave
|
||||
*
|
||||
* The value returned corresponds to the latest detected packet. It is valid from the packet detection (corresponding to
|
||||
* @ref LR20XX_SYSTEM_IRQ_PREAMBLE_DETECTED raised if enabled) until next Rx attempt (through call to @ref
|
||||
* lr20xx_radio_common_set_rx or @ref lr20xx_radio_common_set_rx_with_timeout_in_rtc_step for instance).
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[out] lqi The LQI value
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_common_get_lqi( const void* context, lr20xx_radio_common_lqi_value_t* lqi );
|
||||
|
||||
|
||||
@@ -39,12 +39,19 @@
|
||||
|
||||
#include "lr20xx_radio_fifo.h"
|
||||
#include "lr20xx_hal.h"
|
||||
#include "lr20xx_regmem.h"
|
||||
#include "lr20xx_system.h"
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE MACROS-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define LR20XX_RADIO_FIFO_TX_FIFO_ADDRESS ( 0x00F3002C )
|
||||
#define LR20XX_RADIO_FIFO_TX_FIFO_SIZE_ADDRESS ( 0x00F30034 )
|
||||
#define LR20XX_RADIO_FIFO_RX_FIFO_ADDRESS ( 0x00F30028 )
|
||||
#define LR20XX_RADIO_FIFO_RX_FIFO_SIZE_ADDRESS ( 0x00F30030 )
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE CONSTANTS -------------------------------------------------------
|
||||
@@ -257,6 +264,52 @@ lr20xx_status_t lr20xx_radio_fifo_get_and_clear_irq_flags( const void* context,
|
||||
return status;
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_radio_fifo_configure_1024_byte_tx_fifo( const void* context )
|
||||
{
|
||||
const uint32_t tx_fifo_1024_memory_address = 0x00804000;
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32( context, LR20XX_RADIO_FIFO_TX_FIFO_ADDRESS, &tx_fifo_1024_memory_address, 1 ) );
|
||||
|
||||
const uint32_t tx_fifo_size = 0x000003FC;
|
||||
return lr20xx_regmem_write_regmem32( context, LR20XX_RADIO_FIFO_TX_FIFO_SIZE_ADDRESS, &tx_fifo_size, 1 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_radio_fifo_1024_byte_tx_fifo_store_retention_mem( const void* context,
|
||||
uint8_t retention_slot_address,
|
||||
uint8_t retention_slot_size )
|
||||
{
|
||||
// Store the registers configuration for the TX FIFOs location in retention
|
||||
RETURN_STATUS_ON_NOT_OK( lr20xx_system_add_register_to_retention_mem( context, retention_slot_address,
|
||||
LR20XX_RADIO_FIFO_TX_FIFO_ADDRESS ) );
|
||||
|
||||
// Store the registers configuration for the TX FIFOs size in retention
|
||||
return lr20xx_system_add_register_to_retention_mem( context, retention_slot_size,
|
||||
LR20XX_RADIO_FIFO_TX_FIFO_SIZE_ADDRESS );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_radio_fifo_configure_1024_byte_rx_fifo( const void* context )
|
||||
{
|
||||
const uint32_t rx_fifo_1024_memory_address = 0x00804400;
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32( context, LR20XX_RADIO_FIFO_RX_FIFO_ADDRESS, &rx_fifo_1024_memory_address, 1 ) );
|
||||
|
||||
const uint32_t rx_fifo_size = 0x000003E8;
|
||||
return lr20xx_regmem_write_regmem32( context, LR20XX_RADIO_FIFO_RX_FIFO_SIZE_ADDRESS, &rx_fifo_size, 1 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_radio_fifo_1024_byte_rx_fifo_store_retention_mem( const void* context,
|
||||
uint8_t retention_slot_address,
|
||||
uint8_t retention_slot_size )
|
||||
{
|
||||
// Store the registers configuration for the RX FIFOs location in retention
|
||||
RETURN_STATUS_ON_NOT_OK( lr20xx_system_add_register_to_retention_mem( context, retention_slot_address,
|
||||
LR20XX_RADIO_FIFO_RX_FIFO_ADDRESS ) );
|
||||
|
||||
// Store the registers configuration for the RX FIFOs size in retention
|
||||
return lr20xx_system_add_register_to_retention_mem( context, retention_slot_size,
|
||||
LR20XX_RADIO_FIFO_RX_FIFO_SIZE_ADDRESS );
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
|
||||
|
||||
@@ -68,33 +68,216 @@ extern "C" {
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Read data from RX First in First out (FiFo) radio memory
|
||||
*
|
||||
* The RX FiFo radio memory contains packet received or being received.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] buffer The buffer to be filled with data read from RX FiFo. It is up to the caller to ensure it is at
|
||||
* least @p length bytes long.
|
||||
* @param [in] length The number of bytes to read from RX FiFo
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_radio_fifo_write_tx
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_read_rx( const void* context, uint8_t* buffer, const uint16_t length );
|
||||
|
||||
/*!
|
||||
* @brief Write data to TX First in First out (FiFo) radio memory
|
||||
*
|
||||
* The TX FiFo radio memory contains packet to send.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] buffer The buffer to be written to TX FiFo. It is up to the caller to ensure it is at least
|
||||
* @p length bytes long.
|
||||
* @param [in] length The number of bytes to write to TX FiFo
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_radio_fifo_read_rx
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_write_tx( const void* context, const uint8_t* buffer, const uint16_t length );
|
||||
|
||||
/*!
|
||||
* @brief Clear Rx FIFO
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_clear_rx( const void* context );
|
||||
|
||||
/*!
|
||||
* @brief Clear Tx FIFO
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_clear_tx( const void* context );
|
||||
|
||||
/*!
|
||||
* @brief Get Rx FIFO level
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] fifo_level Rx FIFO level in byte
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_get_rx_level( const void* context, uint16_t* fifo_level );
|
||||
|
||||
/*!
|
||||
* @brief Get Tx FIFO level
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] fifo_level Tx FIFO level in byte
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_get_tx_level( const void* context, uint16_t* fifo_level );
|
||||
|
||||
/*
|
||||
* Configure FIFO threshold IRQs. Threshold IRQs fire on level crossing in the triggering direction;
|
||||
* clearing the IRQ flag does not re-fire until the threshold is crossed again.
|
||||
* rx_fifo_high_threshold: triggers THRESHOLD_HIGH when Rx level rises above this
|
||||
* rx_fifo_low_threshold: triggers THRESHOLD_LOW when Rx level falls below this
|
||||
* tx_fifo_high_threshold: triggers THRESHOLD_HIGH when Tx level rises above this
|
||||
* tx_fifo_low_threshold: triggers THRESHOLD_LOW when Tx level falls below this
|
||||
/*!
|
||||
* @brief Configure FIFO events and threshold levels triggering a FIFO interrupt in Rx and Tx
|
||||
*
|
||||
* @remark When configured, the FIFO interrupts are triggered if the FIFO level crosses the threshold in the correct
|
||||
* direction. Therefore if a threshold related IRQ is cleared, it will be raised again only if the FIFO level crosses
|
||||
* the threshold on the correct direction.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rx_fifo_irq_enable FIFO events triggering an interrupt in Rx
|
||||
* @param [in] tx_fifo_irq_enable FIFO events triggering an interrupt in Tx
|
||||
* @param [in] rx_fifo_high_threshold Rx FIFO threshold above which an interrupt (if
|
||||
* LR20XX_RADIO_FIFO_FLAG_THRESHOLD_HIGH is enabled) is triggered
|
||||
* @param [in] tx_fifo_low_threshold Tx FIFO threshold below which an interrupt (if
|
||||
* LR20XX_RADIO_FIFO_FLAG_THRESHOLD_LOW is enabled) is triggered
|
||||
* @param [in] rx_fifo_low_threshold Rx FIFO threshold below which an interrupt (if
|
||||
* LR20XX_RADIO_FIFO_FLAG_THRESHOLD_LOW is enabled) is triggered
|
||||
* @param [in] tx_fifo_high_threshold Tx FIFO threshold above which an interrupt (if
|
||||
* LR20XX_RADIO_FIFO_FLAG_THRESHOLD_HIGH is enabled) is triggered
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_cfg_irq( const void* context, lr20xx_radio_fifo_flag_t rx_fifo_irq_enable,
|
||||
lr20xx_radio_fifo_flag_t tx_fifo_irq_enable, uint16_t rx_fifo_high_threshold,
|
||||
uint16_t tx_fifo_low_threshold, uint16_t rx_fifo_low_threshold,
|
||||
uint16_t tx_fifo_high_threshold );
|
||||
|
||||
/*!
|
||||
* @brief Clear specific IRQ flags for both Rx and Tx FIFO
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rx_fifo_flags_to_clear Rx FIFO IRQ flags to clear
|
||||
* @param [in] tx_fifo_flags_to_clear Tx FIFO IRQ flags to clear
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_clear_irq_flags( const void* context, lr20xx_radio_fifo_flag_t rx_fifo_flags_to_clear,
|
||||
lr20xx_radio_fifo_flag_t tx_fifo_flags_to_clear );
|
||||
|
||||
/*!
|
||||
* @brief Get FIFO events triggering a FIFO interrupt in Rx and Tx
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] rx_fifo_flags FIFO events triggering an interrupt in Rx
|
||||
* @param [out] tx_fifo_flags FIFO events triggering an interrupt in Tx
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_get_irq( const void* context, lr20xx_radio_fifo_flag_t* rx_fifo_flags,
|
||||
lr20xx_radio_fifo_flag_t* tx_fifo_flags );
|
||||
|
||||
/*!
|
||||
* @brief Clear and return FiFo IRQ flags
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] rx_fifo_flags Rx FiFo flags
|
||||
* @param [out] tx_fifo_flags Tx FiFo flags
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_get_and_clear_irq_flags( const void* context, lr20xx_radio_fifo_flag_t* rx_fifo_flags,
|
||||
lr20xx_radio_fifo_flag_t* tx_fifo_flags );
|
||||
|
||||
/**
|
||||
* @brief Switch Tx FiFo to 1024-bytes FiFo
|
||||
*
|
||||
* This command switches the Tx FiFo from default 256-byte Tx FiFo to extended 1024-byte Tx FiFo.
|
||||
*
|
||||
* It modifies internal registers that are not maintained during sleep mode.
|
||||
* Refer to the function @ref lr20xx_radio_fifo_1024_byte_tx_fifo_store_retention_mem configures to configure the radio
|
||||
* so that it maintains the registers.
|
||||
*
|
||||
* Usage of 1024-byte Tx FiFo comes with a limitation when configuring the low thresholds IRQ with @ref
|
||||
* lr20xx_radio_fifo_cfg_irq.
|
||||
* Refer to @ref lr20xx_workarounds_1024_byte_fifo_cfg_irq for a workaround of this limitation.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] retention_slot_address Retention memory slot to store Tx FiFo address
|
||||
* @param [in] retention_slot_size Retention memory slot to store Tx FiFo size
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_radio_fifo_1024_byte_tx_fifo_store_retention_mem, lr20xx_radio_fifo_configure_1024_byte_rx_fifo,
|
||||
* lr20xx_workarounds_1024_byte_fifo_cfg_irq
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_configure_1024_byte_tx_fifo( const void* context );
|
||||
|
||||
/**
|
||||
* @brief Store the registers to configure the 1024 bytes Tx FiFo in retention memory
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] retention_slot_address Retention memory slot to store Tx FiFo address
|
||||
* @param [in] retention_slot_size Retention memory slot to store Tx FiFo size
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_system_add_register_to_retention_mem, lr20xx_radio_fifo_configure_1024_byte_tx_fifo
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_1024_byte_tx_fifo_store_retention_mem( const void* context,
|
||||
uint8_t retention_slot_address,
|
||||
uint8_t retention_slot_size );
|
||||
|
||||
/**
|
||||
* @brief Switch Rx FiFo to 1024-bytes FiFo
|
||||
*
|
||||
* This command switches the Rx FiFo from default 256-byte Rx FiFo to extended 1024-byte Rx FiFo.
|
||||
*
|
||||
* It modifies internal registers that are not maintained during sleep mode.
|
||||
* Refer to the function @ref lr20xx_radio_fifo_1024_byte_rx_fifo_store_retention_mem configures to configure the radio
|
||||
* so that it maintains the registers.
|
||||
*
|
||||
* Usage of 1024-byte Rx FiFo comes with a limitation when configuring the low thresholds IRQ with @ref
|
||||
* lr20xx_radio_fifo_cfg_irq.
|
||||
* Refer to @ref lr20xx_workarounds_1024_byte_fifo_cfg_irq for a workaround of this limitation.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] retention_slot_address Retention memory slot to store Rx FiFo address
|
||||
* @param [in] retention_slot_size Retention memory slot to store Rx FiFo size
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_radio_fifo_1024_byte_rx_fifo_store_retention_mem,
|
||||
* lr20xx_radio_fifo_configure_1024_byte_tx_fifo,lr20xx_workarounds_1024_byte_fifo_cfg_irq
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_configure_1024_byte_rx_fifo( const void* context );
|
||||
|
||||
/**
|
||||
* @brief Store the registers to configure the 1024 bytes Rx FiFo in retention memory
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] retention_slot_address Retention memory slot to store Rx FiFo address
|
||||
* @param [in] retention_slot_size Retention memory slot to store Rx FiFo size
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_system_add_register_to_retention_mem, lr20xx_radio_fifo_configure_1024_byte_rx_fifo
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_fifo_1024_byte_rx_fifo_store_retention_mem( const void* context,
|
||||
uint8_t retention_slot_address,
|
||||
uint8_t retention_slot_size );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -68,39 +68,124 @@ extern "C" {
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set FLRC modulation params. Not available on LR2022.
|
||||
* Applies lr20xx_workarounds_dcdc_configure automatically unless LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_CONFIGURE.
|
||||
/**
|
||||
* @brief Set the modulation parameters for FLRC packets
|
||||
*
|
||||
* @note This command is not available to LR2022
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] params Structure of FLRC modulation configuration
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_flrc_set_modulation_params( const void* context,
|
||||
const lr20xx_radio_flrc_mod_params_t* params );
|
||||
|
||||
/* Set FLRC packet params. Not available on LR2022. */
|
||||
/**
|
||||
* @brief Set the packet parameters for FLRC packets
|
||||
*
|
||||
* @note This command is not available to LR2022
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] params Structure of FLRC packet configuration
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_flrc_set_pkt_params( const void* context, const lr20xx_radio_flrc_pkt_params_t* params );
|
||||
|
||||
/*
|
||||
* Get FLRC Rx statistics. Not available on LR2022.
|
||||
* Stats reset on POR, retention-less sleep, or lr20xx_radio_common_reset_rx_stats.
|
||||
/**
|
||||
* @brief Get the internal statistics of received FLRC packets
|
||||
*
|
||||
* The internal statistics are reset on:
|
||||
* - Power On Reset (POR)
|
||||
* - sleep without memory retention
|
||||
* - call to lr20xx_radio_common_reset_rx_stats
|
||||
*
|
||||
* @note This command is not available to LR2022
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[out] statistics FLRC received packet statistics
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_common_reset_rx_stats
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_flrc_get_rx_stats( const void* context, lr20xx_radio_flrc_rx_stats_t* statistics );
|
||||
|
||||
/*
|
||||
* Get status of last FLRC received packet. Not available on LR2022.
|
||||
* rssi_sync/syncword_index available from SYNC_WORD_HEADER_VALID IRQ.
|
||||
* rssi_avg available from RX_DONE IRQ.
|
||||
/**
|
||||
* @brief Get the status of the last FLRC received packet
|
||||
*
|
||||
* Availability of the packet status fields depend on the IRQ as follows:
|
||||
* - Available from LR20XX_SYSTEM_IRQ_SYNC_WORD_HEADER_VALID:
|
||||
* - lr20xx_radio_flrc_pkt_status_t.rssi_sync_in_dbm
|
||||
* - lr20xx_radio_flrc_pkt_status_t.rssi_sync_half_dbm_count
|
||||
* - lr20xx_radio_flrc_pkt_status_t.syncword_index
|
||||
* - Available from LR20XX_SYSTEM_IRQ_RX_DONE:
|
||||
* - lr20xx_radio_flrc_pkt_status_t.rssi_avg_in_dbm
|
||||
* - lr20xx_radio_flrc_pkt_status_t.rssi_avg_half_dbm_count
|
||||
*
|
||||
* @note This command is not available to LR2022
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[out] pkt_status FLRC packet status structure
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_flrc_get_pkt_status( const void* context, lr20xx_radio_flrc_pkt_status_t* pkt_status );
|
||||
|
||||
/* Set 2-byte short syncword at syncword_index. Not available on LR2022. */
|
||||
/**
|
||||
* @brief Set a short syncword for FLRC packet
|
||||
*
|
||||
* A short syncword is a 2-bytes long syncword.
|
||||
*
|
||||
* Status is available only after the end of a packet reception.
|
||||
*
|
||||
* @note This command is not available to LR2022
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] syncword_index Syncword index to be configured
|
||||
* @param[in] short_syncword Syncword value to be configured. It is up to the caller to ensure @p short_syncword is at
|
||||
* least @ref LR20XX_RADIO_FLRC_SHORT_SYNCWORD_LENGTH bytes long
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_flrc_set_syncword
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_flrc_set_short_syncword(
|
||||
const void* context, uint8_t syncword_index,
|
||||
const uint8_t short_syncword[LR20XX_RADIO_FLRC_SHORT_SYNCWORD_LENGTH] );
|
||||
|
||||
/* Set 4-byte syncword at syncword_index. Not available on LR2022. */
|
||||
/**
|
||||
* @brief Set the syncword for FLRC packet
|
||||
*
|
||||
* Status is available only after the end of a packet reception.
|
||||
*
|
||||
* @note This command is not available to LR2022
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] syncword_index Syncword index to be configured
|
||||
* @param[in] syncword Syncword value to be configured. It is up to the caller to ensure @p short_syncword is at least
|
||||
* @ref LR20XX_RADIO_FLRC_SYNCWORD_LENGTH bytes long
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_flrc_set_short_syncword
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_flrc_set_syncword( const void* context, uint8_t syncword_index,
|
||||
const uint8_t syncword[LR20XX_RADIO_FLRC_SYNCWORD_LENGTH] );
|
||||
|
||||
/* Compute FLRC time-on-air in microseconds. Not available on LR2022. */
|
||||
/**
|
||||
* @brief Helper function to get the time-on-air of FLRC packet, in microseconds
|
||||
*
|
||||
* @note This command is not available to LR2022
|
||||
*
|
||||
* @param pkt_params The packet parameter configuration
|
||||
* @param mod_params The modulation parameter configuration
|
||||
*
|
||||
* @return Time-on-air of the packet in microsecond
|
||||
*
|
||||
* @see lr20xx_radio_flrc_set_modulation_params, lr20xx_radio_flrc_set_pkt_params
|
||||
*/
|
||||
uint32_t lr20xx_get_flrc_time_on_air_in_us( const lr20xx_radio_flrc_pkt_params_t* pkt_params,
|
||||
const lr20xx_radio_flrc_mod_params_t* mod_params );
|
||||
|
||||
|
||||
@@ -51,10 +51,16 @@ extern "C" {
|
||||
* --- PUBLIC MACROS -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*! @brief FLRC short syncword length in bytes */
|
||||
/**
|
||||
* @brief Length in bytes of the FLRC short syncword
|
||||
*
|
||||
*/
|
||||
#define LR20XX_RADIO_FLRC_SHORT_SYNCWORD_LENGTH ( 2 )
|
||||
|
||||
/*! @brief FLRC syncword length in bytes */
|
||||
/**
|
||||
* @brief Length in bytes of the FLRC syncword
|
||||
*
|
||||
*/
|
||||
#define LR20XX_RADIO_FLRC_SYNCWORD_LENGTH ( 4 )
|
||||
|
||||
/*
|
||||
@@ -179,8 +185,9 @@ typedef enum lr20xx_radio_flrc_crc_types_e
|
||||
LR20XX_RADIO_FLRC_CRC_4_BYTES = 0x03,
|
||||
} lr20xx_radio_flrc_crc_types_t;
|
||||
|
||||
/*!
|
||||
* @brief Modulation configuration for FLRC packet
|
||||
/**
|
||||
* @brief Modulation configuration for LoRa packet
|
||||
*
|
||||
*/
|
||||
typedef struct lr20xx_radio_flrc_mod_params_s
|
||||
{
|
||||
@@ -214,6 +221,7 @@ typedef struct lr20xx_radio_flrc_rx_stats_s
|
||||
uint16_t received_packets; //!< Number of received packets
|
||||
uint16_t crc_errors; //!< Number of received packets with CRC error
|
||||
uint16_t length_errors; //!< Number of received packets with length error
|
||||
uint16_t crc_ok; //!< Number of received packets with CRC ok
|
||||
} lr20xx_radio_flrc_rx_stats_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,7 +47,10 @@
|
||||
* --- PRIVATE MACROS-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define LR20XX_RADIO_LORA_CAD_SIDE_DETECTOR_CONFIGURATION_LENGTH ( 2u ) /* pnr_delta + det_peak */
|
||||
/**
|
||||
* @brief Length in byte of one side detector CAD configuration
|
||||
*/
|
||||
#define LR20XX_RADIO_LORA_CAD_SIDE_DETECTOR_CONFIGURATION_LENGTH ( 2u )
|
||||
|
||||
#define LR20XX_RADIO_LORA_SET_SIDE_DETECTOR_CONFIGURE_CAD_CMD_LENGTH ( 2 )
|
||||
#define LR20XX_RADIO_LORA_SET_MODULATION_PARAMS_CMD_LENGTH ( 2 + 2 )
|
||||
@@ -66,8 +69,8 @@
|
||||
#define LR20XX_RADIO_LORA_CONFIGURE_SIDE_DETECTOR_CAD_TEMP_LENGTH \
|
||||
( 3 * LR20XX_RADIO_LORA_CAD_SIDE_DETECTOR_CONFIGURATION_LENGTH )
|
||||
|
||||
#define LR20XX_RADIO_LORA_GET_RX_STATISTICS_RBUFFER_LENGTH ( 8 )
|
||||
#define LR20XX_RADIO_LORA_GET_PACKET_STATUS_RBUFFER_LENGTH ( 6 )
|
||||
#define LR20XX_RADIO_LORA_GET_RX_STATISTICS_RBUFFER_LENGTH ( 10 )
|
||||
#define LR20XX_RADIO_LORA_GET_PACKET_STATUS_RBUFFER_LENGTH ( 9 )
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
@@ -79,7 +82,9 @@
|
||||
* --- PRIVATE TYPES -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* LoRa radio command opcodes */
|
||||
/*!
|
||||
* @brief Operating codes for radio related operations
|
||||
*/
|
||||
enum
|
||||
{
|
||||
LR20XX_RADIO_LORA_SET_SIDE_DETECTOR_CONFIGURE_CAD_OC = 0x021E,
|
||||
@@ -113,11 +118,34 @@ typedef enum
|
||||
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
|
||||
*/
|
||||
|
||||
/* Send SET_LORA_SEARCH_SYMBOLS command with given n_symbols value and format byte */
|
||||
/**
|
||||
* @brief Helper function that abstract the call for lr20xx_radio_lora_set_lora_search_symbols_by_number and
|
||||
* lr20xx_radio_lora_set_lora_search_symbols_by_mantissa
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] n_symbols A byte representing the number of symbol. Meaning depends on format
|
||||
* @param[in] format The format that defines the meaning of n_symbols
|
||||
* @return lr20xx_status_t
|
||||
*/
|
||||
static lr20xx_status_t abstract_search_symbols( const void* context, uint8_t n_symbols, search_symbol_format_t format );
|
||||
/* Read 2 bytes MSB-first from buffer into uint16_t */
|
||||
|
||||
/**
|
||||
* @brief Read two bytes from buffer and convert it in 16 bits value MSB first
|
||||
*
|
||||
* @param buffer Pointer to location where to read 2 bytes. It is up to the caller to ensure there are at least two
|
||||
* bytes to read
|
||||
*
|
||||
* @return The MSB first value corresponding to the consecutive bytes read
|
||||
*/
|
||||
static uint16_t read_2_bytes_msbf( const uint8_t* buffer );
|
||||
/* Pack lr20xx_radio_lora_side_detector_cfg_t into a single command byte: sf[7:4] | ppm[3:2] | iq[1:0] */
|
||||
|
||||
/**
|
||||
* @brief Compute the byte representation of LoRa side detector configuration
|
||||
*
|
||||
* @param side_detector_cfg The LoRa side detector configuration
|
||||
*
|
||||
* @return uint8_t The byte representing the LoRa side detector configuration
|
||||
*/
|
||||
static uint8_t radio_lora_side_detector_cfg_to_byte( const lr20xx_radio_lora_side_detector_cfg_t* side_detector_cfg );
|
||||
|
||||
/*
|
||||
@@ -163,17 +191,8 @@ lr20xx_status_t lr20xx_radio_lora_set_modulation_params( const void*
|
||||
( uint8_t ) ( ( mod_params->cr << 4 ) + mod_params->ppm ),
|
||||
};
|
||||
|
||||
const lr20xx_status_t write_status = ( lr20xx_status_t ) lr20xx_hal_write(
|
||||
context, cbuffer, LR20XX_RADIO_LORA_SET_MODULATION_PARAMS_CMD_LENGTH, 0, 0 );
|
||||
|
||||
if( write_status != LR20XX_STATUS_OK )
|
||||
{
|
||||
return write_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LR20XX_WORKAROUNDS_CONDITIONAL_APPLY_AUTOMATIC_DCDC_CONFIGURE( context );
|
||||
}
|
||||
return ( lr20xx_status_t ) lr20xx_hal_write( context, cbuffer, LR20XX_RADIO_LORA_SET_MODULATION_PARAMS_CMD_LENGTH,
|
||||
0, 0 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_radio_lora_set_packet_params( const void* context,
|
||||
@@ -324,7 +343,8 @@ lr20xx_status_t lr20xx_radio_lora_get_rx_statistics( const void*
|
||||
statistics->n_received_packets = read_2_bytes_msbf( rbuffer + 0 );
|
||||
statistics->n_crc_errors = read_2_bytes_msbf( rbuffer + 2 );
|
||||
statistics->n_header_errors = read_2_bytes_msbf( rbuffer + 4 );
|
||||
statistics->n_false_synchronisation = read_2_bytes_msbf( rbuffer + 6 );
|
||||
statistics->n_header_valid = read_2_bytes_msbf( rbuffer + 6 );
|
||||
statistics->n_false_synchronisation = read_2_bytes_msbf( rbuffer + 8 );
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -355,6 +375,10 @@ lr20xx_status_t lr20xx_radio_lora_get_packet_status( const void*
|
||||
pkt_status->detector = ( rbuffer[5] >> 2 ) & 0x0F;
|
||||
pkt_status->rssi_pkt_half_dbm_count = ( rbuffer[5] >> 1 ) & 0x01;
|
||||
pkt_status->rssi_signal_pkt_half_dbm_count = ( rbuffer[5] >> 0 ) & 0x01;
|
||||
/* Extract 24-bit signed value and sign-extend to 32 bits */
|
||||
int32_t freq_offset_24 = ( ( rbuffer[6] << 16 ) | ( rbuffer[7] << 8 ) | rbuffer[8] ) & 0x00FFFFFF;
|
||||
/* Sign-extend: shift left 8 bits then arithmetic shift right 8 bits */
|
||||
pkt_status->freq_offset_hz = ( freq_offset_24 << 8 ) >> 8;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -535,20 +559,24 @@ uint32_t lr20xx_radio_lora_get_time_on_air_in_ms( const lr20xx_radio_lora_pkt_pa
|
||||
{
|
||||
uint32_t numerator = 1000U * lr20xx_radio_lora_get_time_on_air_numerator( pkt_p, mod_p );
|
||||
uint32_t denominator = lr20xx_radio_lora_get_bw_in_hz( mod_p->bw );
|
||||
// Perform integral ceil()
|
||||
return ( numerator + denominator - 1 ) / denominator;
|
||||
}
|
||||
|
||||
lr20xx_radio_lora_ppm_t lr20xx_radio_lora_get_recommended_ppm_offset( lr20xx_radio_lora_sf_t sf,
|
||||
lr20xx_radio_lora_bw_t bw )
|
||||
{
|
||||
// PPM offset is LR20XX_RADIO_LORA_PPM_1_4, except for the cases that follow
|
||||
lr20xx_radio_lora_ppm_t ppm_offset = LR20XX_RADIO_LORA_PPM_1_4;
|
||||
|
||||
if( ( sf != LR20XX_RADIO_LORA_SF11 ) && ( sf != LR20XX_RADIO_LORA_SF12 ) )
|
||||
{
|
||||
// 1. If sf is not SF11 nor SF12: no ppm offset
|
||||
ppm_offset = LR20XX_RADIO_LORA_NO_PPM;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2. Else it depends on the bandwidth
|
||||
switch( bw )
|
||||
{
|
||||
case LR20XX_RADIO_LORA_BW_1000:
|
||||
|
||||
@@ -68,113 +68,402 @@ extern "C" {
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set LoRa modulation params. Applies lr20xx_workarounds_dcdc_configure automatically unless
|
||||
* LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_CONFIGURE. For RTToF with fractional BW, also call
|
||||
* lr20xx_workarounds_rttof_results_deviation. See lr20xx_radio_lora_get_recommended_ppm_offset for PPM offset.
|
||||
/**
|
||||
* @brief Set the modulation parameters for LoRa packets
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] mod_params Structure of LoRa modulation configuration
|
||||
*
|
||||
* @note For RTToF operations with fractional bandwidth, the workaround @ref lr20xx_workarounds_rttof_results_deviation
|
||||
* shall be applied. Refer to its documentation for details.
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_lora_get_recommended_ppm_offset, lr20xx_workarounds_rttof_results_deviation
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_set_modulation_params( const void* context,
|
||||
const lr20xx_radio_lora_mod_params_t* mod_params );
|
||||
|
||||
/*
|
||||
* Set LoRa packet params. In LR20XX_RADIO_LORA_PKT_EXPLICIT mode: pld_len_in_bytes=0 accepts all lengths;
|
||||
* pld_len_in_bytes>0 accepts [1:pld_len_in_bytes], rejecting 0 or >pld_len_in_bytes with LORA_HEADER_ERROR IRQ.
|
||||
/**
|
||||
* @brief Set the packet parameters for LoRa packets
|
||||
*
|
||||
* The meaning of field pkt_params->pld_len_in_bytes depends on the packet mode selected:
|
||||
* - If LR20XX_RADIO_LORA_PKT_EXPLICIT:
|
||||
* - pld_len_in_bytes = 0 means that packets of all payload length will be accepted
|
||||
* - pld_len_in_bytes > 0 means that packet with payload length in range [1:pld_len_in_bytes] will be accepted.
|
||||
* Packet of payload length equals to 0 or strictly superior to pld_len_in_bytes will be rejected with IRQ
|
||||
* LR20XX_SYSTEM_IRQ_LORA_HEADER_ERROR
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] pkt_params Structure of LoRa packet configuration
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_set_packet_params( const void* context,
|
||||
const lr20xx_radio_lora_pkt_params_t* pkt_params );
|
||||
|
||||
/*
|
||||
* Configure preamble-absent Rx timeout in LoRa symbols. n_symbols=0 disables.
|
||||
* n_symbols>255 delegates to configure_timeout_by_mantissa_exponent_symbols via lr20xx_radio_convert_nb_symb_to_mant_exp.
|
||||
/**
|
||||
* @brief Configure a timeout given in number of LoRa symbols before stopping reception if no LoRa preamble symbols are
|
||||
* detected
|
||||
*
|
||||
* A timeout interrupt is triggered if no LoRa preamble symbol is detected during the given period.
|
||||
*
|
||||
* Setting @p n_symbols to 0 disables the mechanism.
|
||||
*
|
||||
* If @p n_symbols is higher than 255, this function automatically propagate call to @ref
|
||||
* lr20xx_radio_lora_configure_timeout_by_mantissa_exponent_symbols function, using @ref
|
||||
* lr20xx_radio_convert_nb_symb_to_mant_exp to compute mantissa, exponent components.
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] n_symbols The number of symbols to search for.
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_lora_configure_timeout_by_mantissa_exponent_symbols, lr20xx_radio_convert_nb_symb_to_mant_exp
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_configure_timeout_by_number_of_symbols( const void* context, uint16_t n_symbols );
|
||||
|
||||
/*
|
||||
* Configure preamble-absent Rx timeout via mantissa/exponent encoding: N = mant × 2^(2×exp+1).
|
||||
* mantissa in [0:31], exponent in [0:7]. N=0 disables.
|
||||
/**
|
||||
* @brief Configure a timeout given in number of LoRa symbols before stopping reception if no LoRa preamble symbols are
|
||||
* detected
|
||||
*
|
||||
* A timeout interrupt is triggered if no LoRa preamble symbol is detected during the given period.
|
||||
*
|
||||
* The number of symbol is computed as \f$ N_{symbols} = mantissa ^ {2 \times exponent + 1} \f$
|
||||
*
|
||||
* Setting @p mantissa and @p exponent to get a number of symbol equal to 0 disables the mechanism.
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] mantissa Mantissa - from 0 to 31 - to compute the number of symbols
|
||||
* @param[in] exponent Exponent - from 0 to 7 - to compute the number of symbols
|
||||
*
|
||||
* @return lr20xx_status_t
|
||||
*
|
||||
* @see lr20xx_radio_lora_configure_timeout_by_number_of_symbols, lr20xx_radio_convert_nb_symb_to_mant_exp
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_configure_timeout_by_mantissa_exponent_symbols( const void* context, uint8_t mantissa,
|
||||
uint8_t exponent );
|
||||
|
||||
/*
|
||||
* Compute mantissa/exponent [mant, exp] encoding for nb_symbol, finding the smallest N >= nb_symbol
|
||||
* where N = mant × 2^(2×exp+1). Returns the actual N value used.
|
||||
/**
|
||||
* @brief Helper function to get the mantissa and exponent for a given number of symbol
|
||||
*
|
||||
* @remark This function computes the [mantissa, exponent] duple which corresponds to \f$ nb\_of\_symb \f$ : the
|
||||
* smallest value verifying both following conditions:
|
||||
* - \f$ nb\_of\_symb >= nb\_symbol \f$; and
|
||||
* - \f$ nb\_of\_symb = mant * 2 ^ { 2 * exp + 1 } \f$
|
||||
*
|
||||
* @param [in] nb_symbol Number of symbols
|
||||
* @param [out] mant Mantissa computed from @p nb_symbol
|
||||
* @param [out] exp Exponent computed from @p nb_symbol
|
||||
*
|
||||
* @returns Number of symbols corresponding to the [mantissa, exponent] duple computed with the following formula:
|
||||
* \f$ nb\_of\_symb = mant * 2 ^ { 2 * exp + 1 } \f$
|
||||
*
|
||||
* @see lr20xx_radio_lora_configure_timeout_by_mantissa_exponent_symbols,
|
||||
* lr20xx_radio_lora_configure_timeout_by_number_of_symbols
|
||||
*/
|
||||
uint16_t lr20xx_radio_convert_nb_symb_to_mant_exp( const uint16_t nb_symbol, uint8_t* mant, uint8_t* exp );
|
||||
|
||||
/*
|
||||
* Set LoRa syncword. Default 0x12 (LoRaWAN private). 0x34 = LoRaWAN public.
|
||||
* Syncword is two 4-bit nibbles: syncword = ((block1 & 0x0F) << 4) | (block2 & 0x0F).
|
||||
* block1 must not be 0. With SX1276 compatibility disabled, blocks are 4-bit signed [-8:7];
|
||||
* with compatibility enabled they are 4-bit unsigned [0:15] matching SX127x.
|
||||
* Different syncwords reduce but do not guarantee rejection of foreign packets.
|
||||
/**
|
||||
* @brief Configure the LoRa syncword.
|
||||
*
|
||||
* Default value is 0x12.
|
||||
* Example of typical values:
|
||||
* - LoRaWAN public network: 0x34
|
||||
* - LoRaWAN private network: 0x12
|
||||
*
|
||||
* The syncword here should be understood as the concatenation of two 4 bits blocks as follows:
|
||||
* @code{.c}
|
||||
* uint8_t sync_block_1 = BLOCK_1;
|
||||
* uint8_t sync_block_2 = BLOCK_2;
|
||||
* uint8_t syncword = ((sync_block_1 & 0x0F) << 4) | (sync_block_2 & 0x0F);
|
||||
* @endcode
|
||||
*
|
||||
* Here are some recommendations for syncword selection:
|
||||
* - @p sync_block_1 must not be 0. So that syncword 0x0x must not be used;
|
||||
* - avoid reusing a block value from another network
|
||||
*
|
||||
* Note that using different syncwords does not guarantee packet rejection. Receiver is just less likely to accept frame
|
||||
* of different syncword.
|
||||
*
|
||||
* The following table indicates the compatible block values with other chips. Note that the block values are to be
|
||||
* compared as signed integer when evaluating compatibility.
|
||||
* A line indicates a set of values that are compatible together depending on other chips.
|
||||
* Column <tt>SX126x/LR11xx/LR20xx syncword</tt> indicates block values used
|
||||
* with @ref lr20xx_radio_lora_set_syncword function and SX1276 LoRa compatibility disabled (@ref
|
||||
* lr20xx_workarounds_lora_disable_sx1276_compatibility_mode); the column <tt>LR20xx syncword SX127x compatibility</tt>
|
||||
* indicates block values used with @ref lr20xx_radio_lora_set_syncword and with SX1276 LoRa compatibility enabled
|
||||
* (@ref lr20xx_workarounds_lora_enable_sx1276_compatibility_mode).
|
||||
*
|
||||
* | SX126x/LR11xx/LR20xx syncword | LR20xx syncword SX127x compatibility | SX127x |
|
||||
* | ----------------------------- | ------------------------------------ | --------------- |
|
||||
* | 4 bits signed | 4 bits unsigned | 4 bits unsigned |
|
||||
* | -8 | | |
|
||||
* | -7 | | |
|
||||
* | -6 | | |
|
||||
* | -5 | | |
|
||||
* | -4 | | |
|
||||
* | -3 | | |
|
||||
* | -2 | | |
|
||||
* | -1 | | |
|
||||
* | 0 | 0 | 0 |
|
||||
* | 1 | 1 | 1 |
|
||||
* | 2 | 2 | 2 |
|
||||
* | 3 | 3 | 3 |
|
||||
* | 4 | 4 | 4 |
|
||||
* | 5 | 5 | 5 |
|
||||
* | 6 | 6 | 6 |
|
||||
* | 7 | 7 | 7 |
|
||||
* | | 8 | 8 |
|
||||
* | | 9 | 9 |
|
||||
* | | 10 | 10 |
|
||||
* | | 11 | 11 |
|
||||
* | | 12 | 12 |
|
||||
* | | 13 | 13 |
|
||||
* | | 14 | 14 |
|
||||
* | | 15 | 15 |
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] syncword The syncword to configure
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see LR20XX_RADIO_LORA_SYNCWORD_LORAWAN_PUBLIC_NETWORK,
|
||||
* LR20XX_RADIO_LORA_SYNCWORD_LORAWAN_PRIVATE_NETWORK
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_set_syncword( const void* context, uint8_t syncword );
|
||||
|
||||
/**
|
||||
* @brief Configure the Channel Activity Detection (CAD) operation
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] cad_params Structure of CAD parameter configuration
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_lora_set_cad
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_configure_cad_params( const void* context,
|
||||
const lr20xx_radio_lora_cad_params_t* cad_params );
|
||||
|
||||
/*
|
||||
* Start CAD. Raises CAD_DONE IRQ; also raises CAD_DETECTED if signal found. Depending on cad_params exit_mode,
|
||||
* chip either returns to fallback or starts the configured exit operation (RX or TX), whose IRQ fires after CAD IRQ.
|
||||
/**
|
||||
* @brief Start Channel Activity Detection (CAD) operation
|
||||
*
|
||||
* The CAD operation is a special mode of operation where the chip is looking for the presence of LoRa preamble symbols
|
||||
* or for any Lora signal, depending on the setting in the @ref lr20xx_radio_lora_configure_cad_params command.
|
||||
*
|
||||
* At the end of the CAD operation a LR20XX_SYSTEM_IRQ_CAD_DONE is generated. If the CAD operation detects a signal, it
|
||||
* also generates a LR20XX_SYSTEM_IRQ_CAD_DETECTED.
|
||||
*
|
||||
* Depending on the CAD configuration, the chip may either go back to the configured fallback mode, or enter the
|
||||
* configured exit mode.
|
||||
*
|
||||
* If the exit mode is a radio operation the corresponding IRQ the CAD related IRQ(s) comes at the end CAD operation,
|
||||
* and radio operations IRQ(s) of exit modes comes at the end of this radio operation.
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_lora_configure_cad_params
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_set_cad( const void* context );
|
||||
|
||||
/* Get Rx statistics. Reset on POR, retentionless sleep, or lr20xx_radio_common_reset_rx_stats */
|
||||
/**
|
||||
* @brief Get the internal statistics of received packets
|
||||
*
|
||||
* The internal statistics are reset on:
|
||||
* - Power On Reset (POR)
|
||||
* - sleep without memory retention
|
||||
* - call to lr20xx_radio_common_reset_rx_stats
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[out] statistics Pointer to a structure of statistic to populate with internal statistics
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_common_reset_rx_stats
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_get_rx_statistics( const void* context,
|
||||
lr20xx_radio_lora_rx_statistics_t* statistics );
|
||||
|
||||
/*
|
||||
* Get last received LoRa packet status. Valid after RX_DONE or CAD_DONE, until next set_packet_params call.
|
||||
* CRC/CR: from received header in EXPLICIT mode; from receiver config in IMPLICIT mode.
|
||||
/**
|
||||
* @brief Get the status of the last received LoRa packet
|
||||
*
|
||||
* Status is valid only after the end of a packet reception or CAD done and until the next LoRa packet configuration.
|
||||
*
|
||||
* CRC and coding rate source depends on the packet mode configured on the receiver:
|
||||
* - If LR20XX_RADIO_LORA_PKT_EXPLICIT: it is obtained from the received payload
|
||||
* - If LR20XX_RADIO_LORA_PKT_IMPLICIT: it is obtained from the receiver configuration
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[out] pkt_status Pointer to a structure of packet status to populate
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_get_packet_status( const void* context,
|
||||
lr20xx_radio_lora_packet_status_t* pkt_status );
|
||||
|
||||
/*
|
||||
* Configure LoRa address filtering. address_offset: payload byte offset of address field (header not counted).
|
||||
* address_length in [0:8]; 0 disables filtering.
|
||||
/**
|
||||
* @brief Set the address for filtering in reception
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] address_offset Offset in byte of the address field in the payload (header not counted)
|
||||
* @param[in] address_length Address length in byte - in [0:8], 0 disables LoRa address filtering
|
||||
* @param[in] address Address
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_set_address( const void* context, uint8_t address_offset, uint8_t address_length,
|
||||
const uint8_t* address );
|
||||
|
||||
/*
|
||||
* Configure LoRa intra-packet frequency hopping. For SX1276 compatibility, call
|
||||
* lr20xx_workarounds_lora_freq_hop_enable_sx1276_compatibility_mode after this.
|
||||
/**
|
||||
* @brief Configure LoRa intra-packet frequency hopping
|
||||
*
|
||||
* If the intra-packet frequency hopping must be compatible with SX1276, then the workaround @ref
|
||||
* lr20xx_workarounds_lora_freq_hop_enable_sx1276_compatibility_mode must be called after calling @ref
|
||||
* lr20xx_radio_lora_set_freq_hop.
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] cfg Frequency hopping configuration
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_workarounds_lora_freq_hop_enable_sx1276_compatibility_mode
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_set_freq_hop( const void* context, const lr20xx_radio_lora_hopping_cfg_t* cfg );
|
||||
|
||||
/* Configure up to 3 CAD side detectors (additional SF detectors for CAD). n_side_detector_cad_configurations in [0:3] */
|
||||
/**
|
||||
* @brief Configure the LoRa Channel Activity Detection (CAD) side detectors
|
||||
*
|
||||
* Up to three CAD side detectors can be configured.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param side_detector_cad_configurations Array of side detector CAD configurations
|
||||
* @param n_side_detector_cad_configurations Number of CAD side detector configurations in @p
|
||||
* side_detector_cad_configurations. It is up to the caller to ensure that @p side_detector_cad_configurations contains
|
||||
* at least @p n_side_detector_cad_configurations elements
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_configure_side_detector_cad(
|
||||
const void* context, const lr20xx_radio_lora_side_detector_cad_configuration_t* side_detector_cad_configurations,
|
||||
uint8_t n_side_detector_cad_configurations );
|
||||
|
||||
/*
|
||||
* Configure up to 3 LoRa side detectors (multi-SF Rx on same BW). n_side_detector_cfgs=0 or set_modulation_params
|
||||
* disables all. Constraints: Rx-SF < side-SF; CAD-SF > side-SF; BW>=500 limits to 2 (or 1 if main SF>=SF10);
|
||||
* all SFs distinct; max SF spread = 4. Demodulated SF readable via get_packet_status after RX_DONE.
|
||||
/**
|
||||
* @brief Configure LoRa side detectors
|
||||
*
|
||||
* The side detectors allow to receive on multiple spreading factors, but on the same bandwidth as main detector. Up to
|
||||
* three side detectors can be configured.
|
||||
*
|
||||
* To disable all side detectors, there are 2 options:
|
||||
* - call this command with @p n_side_detector_cfgs set to 0.
|
||||
* - call @ref lr20xx_radio_lora_set_modulation_params
|
||||
*
|
||||
* Once a packet is received, it is possible to know which SF has been demodulated thanks to @ref
|
||||
* lr20xx_radio_lora_get_packet_status.
|
||||
*
|
||||
* Specificities related to the side detector configuration:
|
||||
* - For normal Rx operations, the SF configured with @ref lr20xx_radio_lora_set_modulation_params must be lower than
|
||||
* the SF of the side detectors
|
||||
* - For CAD operations, the SF configured with @ref lr20xx_radio_lora_set_modulation_params must be higher than the
|
||||
* SF of the side detectors
|
||||
* - With BW set to @ref LR20XX_RADIO_LORA_BW_500 or higher, maximum 2 side detectors are allowed except if the SF
|
||||
* configured with @ref lr20xx_radio_lora_set_modulation_params is @ref LR20XX_RADIO_LORA_SF10 or higher where only 1
|
||||
* side detector is allowed
|
||||
* - All SF must be different
|
||||
* - Difference between the highest and the lowest SF must be less than or equal to 4
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] side_detector_cfgs Array of side detector configuration to set. It is up to the caller to ensure
|
||||
* there are at least @p n_side_detector_cfgs
|
||||
* @param[in] n_side_detector_cfgs Number of side detector to configure. Un-configured side detectors are
|
||||
* disabled. Value must be in range [0:3] included.
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_configure_side_detectors(
|
||||
const void* context, const lr20xx_radio_lora_side_detector_cfg_t* side_detector_cfgs,
|
||||
uint8_t n_side_detector_cfgs );
|
||||
|
||||
/* Set syncwords for up to 3 side detectors. n_syncword in [0:3]; unconfigured syncwords use default */
|
||||
/**
|
||||
* @brief Configure the LoRa syncwords for side detectors
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] syncword Array of side detector syncword to set. It is up to the caller to ensure there are at least @p
|
||||
* n_syncword
|
||||
* @param[in] n_syncword Number of side detector syncword configure. Un-configured syncword are set to a default value.
|
||||
* Value must be in range [0:3] included.
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_lora_set_side_detector_syncwords( const void* context, const uint8_t* syncword,
|
||||
uint8_t n_syncword );
|
||||
|
||||
/* Time-on-air numerator (divide by BW in Hz to get seconds) */
|
||||
/**
|
||||
* @brief Compute the numerator for LoRa time-on-air computation.
|
||||
*
|
||||
* @remark To get the actual time-on-air in seconds, this value has to be divided by the LoRa bandwidth in Hertz.
|
||||
*
|
||||
* @param [in] pkt_p Pointer to the structure holding the LoRa packet parameters
|
||||
* @param [in] mod_p Pointer to the structure holding the LoRa modulation parameters
|
||||
*
|
||||
* @returns LoRa time-on-air numerator
|
||||
*/
|
||||
uint32_t lr20xx_radio_lora_get_time_on_air_numerator( const lr20xx_radio_lora_pkt_params_t* pkt_p,
|
||||
const lr20xx_radio_lora_mod_params_t* mod_p );
|
||||
|
||||
/**
|
||||
* @brief Get the actual value in Hertz of a given LoRa bandwidth
|
||||
*
|
||||
* @param [in] bw LoRa bandwidth parameter
|
||||
*
|
||||
* @returns Actual LoRa bandwidth in Hertz
|
||||
*/
|
||||
uint32_t lr20xx_radio_lora_get_bw_in_hz( lr20xx_radio_lora_bw_t bw );
|
||||
|
||||
/*!
|
||||
* @brief Get the time on air in ms for LoRa transmission
|
||||
*
|
||||
* @param [in] pkt_p Pointer to a structure holding the LoRa packet parameters
|
||||
* @param [in] mod_p Pointer to a structure holding the LoRa modulation parameters
|
||||
*
|
||||
* @returns Time-on-air value in ms for LoRa transmission
|
||||
*/
|
||||
uint32_t lr20xx_radio_lora_get_time_on_air_in_ms( const lr20xx_radio_lora_pkt_params_t* pkt_p,
|
||||
const lr20xx_radio_lora_mod_params_t* mod_p );
|
||||
|
||||
/*
|
||||
* Recommended ppm_offset for given SF/BW:
|
||||
* NO_PPM: SF<11, or BW>=500, or BW=250+SF11
|
||||
* PPM_1_4: SF11/12 at BW<=406 (SX128x compat), BW=250+SF12, or SF12 at other narrow BWs
|
||||
* See lr20xx_radio_lora_set_modulation_params.
|
||||
/**
|
||||
* @brief Helper function to compute recommended ppm offset value from SF and BW
|
||||
*
|
||||
* This helper function provides recommended PPM offset configuration based on the following rules
|
||||
* - @ref LR20XX_RADIO_LORA_NO_PPM for all spreading factors, except for @ref LR20XX_RADIO_LORA_SF11 and @ref
|
||||
* LR20XX_RADIO_LORA_SF12
|
||||
* - @ref LR20XX_RADIO_LORA_PPM_1_4 for bandwidths @ref LR20XX_RADIO_LORA_BW_812, @ref LR20XX_RADIO_LORA_BW_406 and
|
||||
* @ref LR20XX_RADIO_LORA_BW_203 to ensure SX128x compatibility
|
||||
* - @ref LR20XX_RADIO_LORA_NO_PPM for bandwidths @ref LR20XX_RADIO_LORA_BW_1000 and @ref LR20XX_RADIO_LORA_BW_500
|
||||
* - @ref LR20XX_RADIO_LORA_NO_PPM for bandwidth @ref LR20XX_RADIO_LORA_BW_250 and spreading factor @ref
|
||||
* LR20XX_RADIO_LORA_SF11
|
||||
* - @ref LR20XX_RADIO_LORA_PPM_1_4 for bandwidth @ref LR20XX_RADIO_LORA_BW_250 and spreading factor @ref
|
||||
* LR20XX_RADIO_LORA_SF12
|
||||
* - @ref LR20XX_RADIO_LORA_PPM_1_4 otherwise
|
||||
*
|
||||
* | Bandwidths | @ref LR20XX_RADIO_LORA_SF12 | @ref LR20XX_RADIO_LORA_SF11 | other spreading factors |
|
||||
* | -- | -- | -- | -- |
|
||||
* | @ref LR20XX_RADIO_LORA_BW_1000 | @ref LR20XX_RADIO_LORA_NO_PPM |||
|
||||
* | @ref LR20XX_RADIO_LORA_BW_500 | @ref LR20XX_RADIO_LORA_NO_PPM |||
|
||||
* | @ref LR20XX_RADIO_LORA_BW_250 | @ref LR20XX_RADIO_LORA_PPM_1_4 | @ref LR20XX_RADIO_LORA_NO_PPM ||
|
||||
* | @ref LR20XX_RADIO_LORA_BW_812 | @ref LR20XX_RADIO_LORA_PPM_1_4 || @ref LR20XX_RADIO_LORA_NO_PPM |
|
||||
* | @ref LR20XX_RADIO_LORA_BW_406 | @ref LR20XX_RADIO_LORA_PPM_1_4 || @ref LR20XX_RADIO_LORA_NO_PPM |
|
||||
* | @ref LR20XX_RADIO_LORA_BW_203 | @ref LR20XX_RADIO_LORA_PPM_1_4 || @ref LR20XX_RADIO_LORA_NO_PPM |
|
||||
* | other bandwidths | @ref LR20XX_RADIO_LORA_PPM_1_4 || @ref LR20XX_RADIO_LORA_NO_PPM |
|
||||
*
|
||||
* @param sf Spreading factor
|
||||
* @param bw Bandwidth
|
||||
*
|
||||
* @return The recommended PPM offset configuration for the given spreading factor and bandwidth
|
||||
*
|
||||
* @see lr20xx_radio_lora_set_modulation_params
|
||||
*/
|
||||
lr20xx_radio_lora_ppm_t lr20xx_radio_lora_get_recommended_ppm_offset( lr20xx_radio_lora_sf_t sf,
|
||||
lr20xx_radio_lora_bw_t bw );
|
||||
|
||||
@@ -52,10 +52,14 @@ extern "C" {
|
||||
* --- PUBLIC MACROS -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*! @brief LoRa syncword for LoRaWAN public networks */
|
||||
/**
|
||||
* @brief LoRa syncword value for LoRaWAN public networks
|
||||
*/
|
||||
#define LR20XX_RADIO_LORA_SYNCWORD_LORAWAN_PUBLIC_NETWORK ( 0x34 )
|
||||
|
||||
/*! @brief LoRa syncword for LoRaWAN private networks */
|
||||
/**
|
||||
* @brief LoRa syncword value for LoRaWAN private networks
|
||||
*/
|
||||
#define LR20XX_RADIO_LORA_SYNCWORD_LORAWAN_PRIVATE_NETWORK ( 0x12 )
|
||||
|
||||
/*
|
||||
@@ -174,7 +178,6 @@ typedef enum
|
||||
//!< mode. Otherwise it enters in fallback mode
|
||||
LR20XX_RADIO_LORA_CAD_EXIT_MODE_TX = 0x10, //!< If the CAD operation does not detect an activity, the chip enters
|
||||
//!< in TX mode. Otherwise it enters in fallback mode
|
||||
//!< (0x10, not 0x02: register encoding gap in LR2021 datasheet)
|
||||
} lr20xx_radio_lora_cad_exit_mode_t;
|
||||
|
||||
/**
|
||||
@@ -264,6 +267,7 @@ typedef struct lr20xx_radio_lora_rx_statistics_s
|
||||
uint16_t n_crc_errors; //!< Number of received packets with CRC error
|
||||
uint16_t n_header_errors; //!< Number of received packets with header error (Rx configured in
|
||||
//!< LR20XX_RADIO_LORA_PKT_EXPLICIT and header CRC check failed)
|
||||
uint16_t n_header_valid; //!< Number of detected header valid
|
||||
uint16_t n_false_synchronisation; //!< Number of false synchronisation (preamble detected but syncword not
|
||||
//!< detected, probably preamble detected on noise)
|
||||
} lr20xx_radio_lora_rx_statistics_t;
|
||||
@@ -285,6 +289,7 @@ typedef struct lr20xx_radio_lora_packet_status_s
|
||||
//!< Equivalent to rssi_pkt_in_dbm if snr_pkt_raw is positive, to rssi_pkt_in_dbm
|
||||
//!< + (snr_pkt_raw/4) if snr_pkt_raw is negative
|
||||
uint8_t rssi_signal_pkt_half_dbm_count; //!< Count of 0.5 dBm to subtract to rssi_signal_pkt_in_dbm value in dBm
|
||||
int32_t freq_offset_hz; //!< Frequency offset of the last packet received in Hz
|
||||
} lr20xx_radio_lora_packet_status_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -68,44 +68,163 @@ extern "C" {
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set OOK modulation params.
|
||||
* Applies lr20xx_workarounds_dcdc_configure automatically unless LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_CONFIGURE.
|
||||
/**
|
||||
* @brief Set the modulation parameters for OOK packets
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] params Structure of OOK modulation configuration
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_set_modulation_params( const void* context,
|
||||
const lr20xx_radio_ook_mod_params_t* params );
|
||||
|
||||
/* Set OOK packet params. Note: explicit header + CRC disabled causes incorrect reception. */
|
||||
/**
|
||||
* @brief Set the packet parameters for OOK packets
|
||||
*
|
||||
* The OOK packet configuration with header explicit and CRC disabled is known to generate incorrect packet reception.
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] params Structure of the OOK packet parameter to configure
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_set_packet_params( const void* context, const lr20xx_radio_ook_pkt_params_t* params );
|
||||
|
||||
/**
|
||||
* @brief Set the CRC configuration for OOK packets
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] crc_polynomial Polynomial to use for CRC LFSR
|
||||
* @param[in] crc_seed LFSR initial value
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_set_crc_params( const void* context, uint32_t crc_polynomial, uint32_t crc_seed );
|
||||
|
||||
/*
|
||||
* Set OOK syncword. syncword is a 32-bit value stored MSB-first in 4 bytes; nb_bits LSBs are used.
|
||||
* bit_order controls OTA transmission order (LSBF or MSBF).
|
||||
* Example: syncword=0x0000AA67, nb_bits=12 → bits 0xA67 (12 LSBs).
|
||||
/**
|
||||
* @brief Set the syncword for OOK packets
|
||||
*
|
||||
* The argument \p syncword is a 4-byte array. However, it should be understood as 32-bit variable, where Most
|
||||
* Significant Bit is the MSB of syncword[0] and Least Significant Bit is LSB of syncword[3].
|
||||
*
|
||||
* For instance:
|
||||
*
|
||||
* @code{.c}
|
||||
* syncword = 0x0000AA67
|
||||
* nb_bits = 12
|
||||
* @endcode
|
||||
*
|
||||
* Then, syncword in bits is:
|
||||
*
|
||||
* @verbatim
|
||||
* 0...0 01010101 01100111
|
||||
* ^ ^ ^
|
||||
* MSB nb_bit'th LSB
|
||||
* @endverbatim
|
||||
*
|
||||
* Then, the bit stream sent over the air will be
|
||||
* - if \p bit_order == LR20XX_RADIO_OOK_SYNCWORD_LSBF:
|
||||
* @verbatim
|
||||
* 111001101010
|
||||
* @endverbatim
|
||||
* - if \p bit_order == LR20XX_RADIO_OOK_SYNCWORD_MSBF:
|
||||
* @verbatim
|
||||
* 010101100111
|
||||
* @endverbatim
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] syncword Array holding the syncword value. It is up to the caller that this array holds at least
|
||||
* LR20XX_RADIO_OOK_SYNCWORD_LENGTH bytes, even if nb_bits is not 32
|
||||
* @param[in] nb_bits The number of significant bits in syncword to use for syncword. The significant bits are taken as
|
||||
* Least Significant Bits of \p syncword argument. Value in range of [0:32]
|
||||
* @param[in] bit_order The order of transmission of the selected bits of syncword over-the-air
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_set_syncword( const void* context,
|
||||
const uint8_t syncword[LR20XX_RADIO_OOK_SYNCWORD_LENGTH],
|
||||
uint8_t nb_bits, lr20xx_radio_ook_syncword_bit_order_t bit_order );
|
||||
|
||||
/**
|
||||
* @brief Set the node and broadcast addresses for OOK packets
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] node_address Node address
|
||||
* @param[in] broadcast_address Broadcast address
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_set_addresses( const void* context, uint8_t node_address, uint8_t broadcast_address );
|
||||
|
||||
/* Get OOK Rx statistics; reset on POR, retention-less sleep, or lr20xx_radio_common_reset_rx_stats */
|
||||
/**
|
||||
* @brief Get the internal statistics of received OOK packets
|
||||
*
|
||||
* The internal statistics are reset on:
|
||||
* - Power On Reset (POR)
|
||||
* - sleep without memory retention
|
||||
* - call to lr20xx_radio_common_reset_rx_stats
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[out] statistics Pointer to a structure of statistic to populate with internal statistics
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*
|
||||
* @see lr20xx_radio_common_reset_rx_stats
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_get_rx_statistics( const void* context, lr20xx_radio_ook_rx_statistics_t* statistics );
|
||||
|
||||
/*
|
||||
* Get status of last received OOK packet.
|
||||
* rssi_on/syncword available from SYNC_WORD_HEADER_VALID IRQ.
|
||||
* rssi_avg/addr_match available from RX_DONE IRQ.
|
||||
/**
|
||||
* @brief Get the status of the last received OOK packet
|
||||
*
|
||||
* Availability of the packet status fields depend on the IRQ as follows:
|
||||
* - Available from LR20XX_SYSTEM_IRQ_SYNC_WORD_HEADER_VALID:
|
||||
* - lr20xx_radio_ook_packet_status_t.rssi_on_in_dbm
|
||||
* - lr20xx_radio_ook_packet_status_t.rssi_on_half_dbm_count
|
||||
* - Available from LR20XX_SYSTEM_IRQ_RX_DONE:
|
||||
* - lr20xx_radio_ook_packet_status_t.rssi_avg_in_dbm
|
||||
* - lr20xx_radio_ook_packet_status_t.rssi_avg_half_dbm_count
|
||||
* - lr20xx_radio_ook_packet_status_t.is_addr_match_broadcast
|
||||
* - lr20xx_radio_ook_packet_status_t.is_addr_match_node
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[out] pkt_status Pointer to a structure of packet status to populate
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_get_packet_status( const void* context, lr20xx_radio_ook_packet_status_t* pkt_status );
|
||||
|
||||
/**
|
||||
* @brief Configure the Rx detector OOK packet
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] rx_detector Rx detector configuration
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_set_rx_detector( const void* context,
|
||||
const lr20xx_radio_ook_rx_detector_t* rx_detector );
|
||||
|
||||
/**
|
||||
* @brief Set whitening parameters for OOK packet
|
||||
*
|
||||
* @param[in] context Chip implementation context
|
||||
* @param[in] params Whitening parameters
|
||||
*
|
||||
* @return lr20xx_status_t Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_radio_ook_set_whitening_params( const void* context,
|
||||
const lr20xx_radio_ook_whitening_params_t* params );
|
||||
|
||||
/**
|
||||
* @brief Get the time on air in ms for OOK transmission
|
||||
*
|
||||
* @param [in] pkt_p Pointer to a structure holding the OOK packet parameters
|
||||
* @param [in] mod_p Pointer to a structure holding the OOK modulation parameters
|
||||
* @param [in] syncword_len_in_bit Syncword length in bit
|
||||
*
|
||||
* @returns Time-on-air value in ms for OOK transmission
|
||||
*/
|
||||
uint32_t lr20xx_radio_ook_get_time_on_air_in_ms( const lr20xx_radio_ook_pkt_params_t* pkt_p,
|
||||
const lr20xx_radio_ook_mod_params_t* mod_p,
|
||||
uint8_t syncword_len_in_bit );
|
||||
|
||||
@@ -53,7 +53,10 @@ extern "C" {
|
||||
* --- PUBLIC MACROS -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*! @brief OOK syncword length in bytes */
|
||||
/**
|
||||
* @brief Length in bytes of the OOK syncword
|
||||
*
|
||||
*/
|
||||
#define LR20XX_RADIO_OOK_SYNCWORD_LENGTH ( 4 )
|
||||
|
||||
/*
|
||||
@@ -238,7 +241,7 @@ typedef struct
|
||||
} lr20xx_radio_ook_rx_detector_t;
|
||||
|
||||
/**
|
||||
* @brief Whitening configuration for OOK packet
|
||||
* @brief Rx detector configuration for OOK packet
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
* --- DEPENDENCIES ------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "lr20xx_regmem.h"
|
||||
#include "lr20xx_hal.h"
|
||||
|
||||
@@ -54,7 +55,6 @@
|
||||
#define LR20XX_REGMEM_WRITE_REGMEM32_MASK_CMD_LENGTH ( 2 + 3 + 4 + 4 )
|
||||
#define LR20XX_REGMEM_READ_REGMEM32_CMD_LENGTH ( 2 + 3 + 1 )
|
||||
|
||||
/* 32 words × 4 bytes = 128 bytes max payload; 256 provides headroom */
|
||||
#define LR20XX_REGMEM_BUFFER_SIZE_MAX ( 256 )
|
||||
|
||||
/*
|
||||
@@ -82,25 +82,66 @@ enum
|
||||
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
|
||||
*/
|
||||
|
||||
/* @warning caller must ensure cbuffer is sized for opcode + 3-byte address */
|
||||
/*!
|
||||
* @brief Helper function that fill both cbuffer with opcode and memory address
|
||||
*
|
||||
* It is typically used in read/write regmem32 functions.
|
||||
*
|
||||
* @warning It is up to the caller to ensure cbuffer is big enough to contain opcode and address!
|
||||
*/
|
||||
static void lr20xx_regmem_fill_cbuffer_opcode_address( uint8_t* cbuffer, uint16_t opcode, uint32_t address );
|
||||
|
||||
/* @warning caller must ensure cbuffer is sized for opcode + 3-byte address + length byte */
|
||||
/*!
|
||||
* @brief Helper function that fill both cbuffer with opcode memory address, and data length to read
|
||||
*
|
||||
* It is typically used in read functions.
|
||||
*
|
||||
* @warning It is up to the caller to ensure cbuffer is big enough to contain opcode and address!
|
||||
*/
|
||||
static void lr20xx_regmem_fill_cbuffer_opcode_address_length( uint8_t* cbuffer, uint16_t opcode, uint32_t address,
|
||||
uint8_t length );
|
||||
|
||||
/* @warning caller must ensure cdata is sized for data_length × 4 bytes */
|
||||
/*!
|
||||
* @brief Helper function that fill both cbuffer with data
|
||||
*
|
||||
* It is typically used in write write regmem32 functions.
|
||||
*
|
||||
* @warning It is up to the caller to ensure cdata is big enough to contain all data!
|
||||
*/
|
||||
static void lr20xx_regmem_fill_cdata( uint8_t* cdata, const uint32_t* data, uint8_t data_length );
|
||||
|
||||
/* @warning caller must ensure cbuffer and cdata are appropriately sized */
|
||||
/*!
|
||||
* @brief Helper function that fill both cbuffer and cdata buffers with opcode, memory address and data
|
||||
*
|
||||
* It is typically used to factorize and write regmem32 operations. Behind the scene it calls the other helpers
|
||||
* lr20xx_regmem_fill_cbuffer_opcode_address and lr20xx_regmem_fill_cdata.
|
||||
*
|
||||
* @warning It is up to the caller to ensure cbuffer and cdata are big enough to contain their respective information!
|
||||
*/
|
||||
static void lr20xx_regmem_fill_cbuffer_cdata_opcode_address_data( uint8_t* cbuffer, uint8_t* cdata, uint16_t opcode,
|
||||
uint32_t address, const uint32_t* data,
|
||||
uint8_t data_length );
|
||||
|
||||
/* @warning caller must ensure raw_buffer is at least out_buffer_length × 4 bytes */
|
||||
/*!
|
||||
* @brief Helper function that convert an array of uint8_t into an array of uint32_t
|
||||
*
|
||||
* Typically used in the read function returning uint32_t array.
|
||||
*
|
||||
* @warning It is up to the caller to ensure the raw_buffer is of length at least "out_buffer_length *
|
||||
* sizeof(uint32_t)"!
|
||||
*/
|
||||
static void lr20xx_regmem_fill_out_buffer_from_raw_buffer( uint32_t* out_buffer, const uint8_t* raw_buffer,
|
||||
uint8_t out_buffer_length );
|
||||
|
||||
/**
|
||||
* @brief Check buffer length is appropriate for read/write regmem32 operations
|
||||
*
|
||||
* @param buffer_length The buffer length
|
||||
* @return true The buffer length is correct for the operation
|
||||
* @return false The buffer length is incorrect and the operation should not be executed
|
||||
*/
|
||||
static inline bool lr20xx_regmem_buffer_length_is_correct( uint8_t buffer_length );
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
|
||||
@@ -112,7 +153,7 @@ lr20xx_status_t lr20xx_regmem_write_regmem32( const void* context, const uint32_
|
||||
uint8_t cbuffer[LR20XX_REGMEM_WRITE_REGMEM32_CMD_LENGTH];
|
||||
uint8_t cdata[LR20XX_REGMEM_BUFFER_SIZE_MAX];
|
||||
|
||||
if( length > LR20XX_REGMEM_MAX_WRITE_READ_WORDS )
|
||||
if( !lr20xx_regmem_buffer_length_is_correct( length ) )
|
||||
{
|
||||
return LR20XX_STATUS_ERROR;
|
||||
}
|
||||
@@ -149,7 +190,7 @@ lr20xx_status_t lr20xx_regmem_read_regmem32( const void* context, const uint32_t
|
||||
{
|
||||
uint8_t cbuffer[LR20XX_REGMEM_READ_REGMEM32_CMD_LENGTH];
|
||||
|
||||
if( length > LR20XX_REGMEM_MAX_WRITE_READ_WORDS )
|
||||
if( !lr20xx_regmem_buffer_length_is_correct( length ) )
|
||||
{
|
||||
return LR20XX_STATUS_ERROR;
|
||||
}
|
||||
@@ -223,4 +264,9 @@ void lr20xx_regmem_fill_out_buffer_from_raw_buffer( uint32_t* out_buffer, const
|
||||
}
|
||||
}
|
||||
|
||||
bool lr20xx_regmem_buffer_length_is_correct( uint8_t buffer_length )
|
||||
{
|
||||
return buffer_length <= LR20XX_REGMEM_MAX_WRITE_READ_WORDS;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
|
||||
@@ -52,7 +52,9 @@ extern "C" {
|
||||
* --- PUBLIC MACROS -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*! @brief Max words per regmem32 read/write (LR2021 datasheet §5.4.3) */
|
||||
/*!
|
||||
* @brief Maximum number of words that can be written to / read from a LR20XX chip with regmem32 commands
|
||||
*/
|
||||
#define LR20XX_REGMEM_MAX_WRITE_READ_WORDS 32
|
||||
|
||||
/*
|
||||
@@ -79,7 +81,7 @@ extern "C" {
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] address The register memory address to start writing operation (only the 3 bytes LSB are relevant)
|
||||
* @param [in] buffer The buffer of words to write into memory. Its size must be enough to contain length words.
|
||||
* @param [in] length Number of words to write into memory
|
||||
* @param [in] length Number of words to write into memory. Must be inferior or equal to 32.
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
@@ -109,7 +111,7 @@ lr20xx_status_t lr20xx_regmem_write_regmem32_mask( const void* context, const ui
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] address The register memory address to start reading operation (only the 3 bytes LSB are relevant)
|
||||
* @param [in] length Number of words to read from memory
|
||||
* @param [in] length Number of words to read from memory. Must be inferior or equal to 32.
|
||||
* @param [out] buffer Pointer to a words array to be filled with content from memory. Its size must be enough to
|
||||
* contain at least length words.
|
||||
*
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
typedef enum lr20xx_status_e
|
||||
{
|
||||
LR20XX_STATUS_OK = 0,
|
||||
LR20XX_STATUS_ERROR = 3, /* Must match lr20xx_hal_status_t ERROR value */
|
||||
LR20XX_STATUS_ERROR = 3,
|
||||
} lr20xx_status_t;
|
||||
|
||||
/*
|
||||
|
||||
@@ -78,12 +78,35 @@
|
||||
#define LR20XX_SYSTEM_SET_TEMP_COMP_CFG_CMD_LENGTH ( 2 + 1 )
|
||||
#define LR20XX_SYSTEM_SET_NTC_PARAMS_CMD_LENGTH ( 2 + 5 )
|
||||
|
||||
#define LR20XX_SYSTEM_GET_STATUS_DIRECT_READ_LENGTH ( 6 ) /* stat1 + stat2 + 4-byte IRQ mask */
|
||||
#define LR20XX_SYSTEM_VERSION_LENGTH ( 2 ) /* major + minor */
|
||||
#define LR20XX_SYSTEM_ERRORS_LENGTH ( 2 ) /* 16-bit error bitmask */
|
||||
#define LR20XX_SYSTEM_RANDOM_NUMBER_LENGTH ( 4 ) /* 32-bit random number */
|
||||
#define LR20XX_SYSTEM_MEASURE_LENGTH ( 2 ) /* vbat / temp measurement */
|
||||
#define LR20XX_SYSTEM_INTERRUPTS_LENGTH ( 4 ) /* 32-bit IRQ mask */
|
||||
/*!
|
||||
* @brief Length in byte of the status returned by the transceiver
|
||||
*/
|
||||
#define LR20XX_SYSTEM_GET_STATUS_DIRECT_READ_LENGTH ( 6 )
|
||||
|
||||
/*!
|
||||
* @brief Length in byte of the version returned by the transceiver
|
||||
*/
|
||||
#define LR20XX_SYSTEM_VERSION_LENGTH ( 2 )
|
||||
|
||||
/*!
|
||||
* @brief Length in byte of the error list returned by the transceiver
|
||||
*/
|
||||
#define LR20XX_SYSTEM_ERRORS_LENGTH ( 2 )
|
||||
|
||||
/*!
|
||||
* @brief Length in byte of the random number returned by the transceiver
|
||||
*/
|
||||
#define LR20XX_SYSTEM_RANDOM_NUMBER_LENGTH ( 4 )
|
||||
|
||||
/*!
|
||||
* @brief Length in byte of the measure (temperature or voltage) returned by the transceiver
|
||||
*/
|
||||
#define LR20XX_SYSTEM_MEASURE_LENGTH ( 2 )
|
||||
|
||||
/*!
|
||||
* @brief Length in byte of the interrupt flags returned by the transceiver
|
||||
*/
|
||||
#define LR20XX_SYSTEM_INTERRUPTS_LENGTH ( 4 )
|
||||
|
||||
static const lr20xx_system_dio_t dio_list[] = {
|
||||
LR20XX_SYSTEM_DIO_5, LR20XX_SYSTEM_DIO_6, LR20XX_SYSTEM_DIO_7, LR20XX_SYSTEM_DIO_8,
|
||||
@@ -95,7 +118,9 @@ static const lr20xx_system_dio_t dio_list[] = {
|
||||
* --- PRIVATE TYPES -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* System command opcodes */
|
||||
/*!
|
||||
* @brief Operating codes for system related operations
|
||||
*/
|
||||
enum
|
||||
{
|
||||
LR20XX_SYSTEM_GET_STATUS_OC = 0x0100,
|
||||
@@ -135,9 +160,24 @@ enum
|
||||
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
|
||||
*/
|
||||
|
||||
/* Parse stat1 byte into stat1 struct; no-op if stat1 is NULL */
|
||||
/*!
|
||||
* @brief Fill stat1 structure with data from stat1_byte
|
||||
*
|
||||
* @remark If \p stat1 is NULL, the function does not perform any operation
|
||||
*
|
||||
* @param [in] stat1_byte stat1 byte
|
||||
* @param [out] stat1 stat1 structure
|
||||
*/
|
||||
static void lr20xx_system_convert_stat1_byte_to_enum( uint8_t stat1_byte, lr20xx_system_stat1_t* stat1 );
|
||||
/* Parse stat2 byte into stat2 struct; no-op if stat2 is NULL */
|
||||
|
||||
/*!
|
||||
* @brief Fill stat2 structure with data from stat2_byte
|
||||
*
|
||||
* @remark If \p stat2 is NULL, the function does not perform any operation
|
||||
*
|
||||
* @param [in] stat2_byte stat2 byte
|
||||
* @param [out] stat2 stat2 structure
|
||||
*/
|
||||
static void lr20xx_system_convert_stat2_byte_to_enum( uint8_t stat2_byte, lr20xx_system_stat2_t* stat2 );
|
||||
|
||||
/*
|
||||
@@ -428,7 +468,7 @@ lr20xx_status_t lr20xx_system_get_temp( const void* context, lr20xx_system_value
|
||||
|
||||
if( status == LR20XX_STATUS_OK )
|
||||
{
|
||||
*temp = ( uint16_t ) ( ( ( ( uint16_t ) rbuffer[0] << 8 ) + ( uint16_t ) rbuffer[1] ) >> 3 ); /* 3 LSBs are status bits, not measurement data */
|
||||
*temp = ( uint16_t ) ( ( ( ( uint16_t ) rbuffer[0] << 8 ) + ( uint16_t ) rbuffer[1] ) >> 3 );
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -464,8 +504,8 @@ lr20xx_status_t lr20xx_system_set_sleep_mode( const void* context, const lr20xx_
|
||||
const uint8_t cbuffer[LR20XX_SYSTEM_SET_SLEEP_MODE_CMD_LENGTH] = {
|
||||
( uint8_t ) ( LR20XX_SYSTEM_SET_SLEEP_MODE_OC >> 8 ),
|
||||
( uint8_t ) ( LR20XX_SYSTEM_SET_SLEEP_MODE_OC >> 0 ),
|
||||
( uint8_t ) ( ( ( sleep_cfg->is_ram_retention_enabled == true ) ? 0x02 : 0x00 ) + /* bit[1]: RAM retention */
|
||||
( ( sleep_cfg->is_clk_32k_enabled == true ) ? 0x01 : 0x00 ) ), /* bit[0]: 32kHz clock */
|
||||
( uint8_t ) ( ( ( sleep_cfg->is_ram_retention_enabled == true ) ? 0x02 : 0x00 ) +
|
||||
( ( sleep_cfg->is_clk_32k_enabled == true ) ? 0x01 : 0x00 ) ),
|
||||
( uint8_t ) ( sleep_time >> 24 ),
|
||||
( uint8_t ) ( sleep_time >> 16 ),
|
||||
( uint8_t ) ( sleep_time >> 8 ),
|
||||
|
||||
@@ -68,147 +68,471 @@ extern "C" {
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Reset the radio
|
||||
*
|
||||
* @param [in] context Chip implementation context.
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_reset( const void* context );
|
||||
|
||||
/*!
|
||||
* @brief Wake the radio up from sleep mode.
|
||||
*
|
||||
* @param [in] context Chip implementation context.
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_wakeup( const void* context );
|
||||
|
||||
/*
|
||||
* Return stat1, stat2, and irq_status. Any pointer may be NULL.
|
||||
* Implemented as a bare SPI read (NOP bytes on MOSI); does NOT execute the GetStatus command.
|
||||
* The LR20XX prefixes every SPI read response with stat1/stat2/irq_status automatically.
|
||||
* Reset status in stat2 is NOT cleared by this call — use lr20xx_system_clear_reset_status_info.
|
||||
/*!
|
||||
* @brief Return stat1, stat2, and irq_status
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] stat1 Pointer to a variable for holding stat1. Can be NULL.
|
||||
* @param [out] stat2 Pointer to a variable for holding stat2. Can be NULL.
|
||||
* @param [out] irq_status Pointer to a variable for holding irq_status. Can be NULL.
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @remark To simplify system integration, this function does not actually execute the GetStatus command, which would
|
||||
* require bidirectional SPI communication. It obtains the stat1, stat2, and irq_status values by performing an ordinary
|
||||
* SPI read (which is required to send null/NOP bytes on the MOSI line). This is possible since the LR20XX returns these
|
||||
* values automatically whenever a read that does not directly follow a response-carrying command is performed.
|
||||
* Unlike with the GetStatus command, however, the reset status information is NOT cleared by this command. The function
|
||||
* @ref lr20xx_system_clear_reset_status_info may be used for this purpose when necessary.
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_get_status( const void* context, lr20xx_system_stat1_t* stat1,
|
||||
lr20xx_system_stat2_t* stat2, lr20xx_system_irq_mask_t* irq_status );
|
||||
|
||||
/*!
|
||||
* @brief Clear the reset status information stored in stat2
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_clear_reset_status_info( const void* context );
|
||||
|
||||
/*
|
||||
* Read firmware version. Expected: LR2021 = major 0x01 / minor 0x18; LR2022 = major 0x02 / minor 0x00.
|
||||
/*!
|
||||
* @brief Return the version of the system
|
||||
*
|
||||
* The following table provides expected version per LR20xx derivatives:
|
||||
*
|
||||
* | Derivative | Version major | Version minor |
|
||||
* | ---------- | ------------- | ------------- |
|
||||
* | LR2021 | 0x01 | 0x18 |
|
||||
* | LR2022 | 0x02 | 0x00 |
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] version Pointer to the structure holding the system version
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_get_version( const void* context, lr20xx_system_version_t* version );
|
||||
|
||||
/*
|
||||
* Return system error flags. Remediation: calibration errors → retry RC calibration;
|
||||
* XOSC errors → hardware issue, reset; PLL lock errors → run PLL calibration or change frequency.
|
||||
/*!
|
||||
* @brief Return the system errors
|
||||
*
|
||||
* Errors may be fixed following:
|
||||
* - calibration error can be fixed by attempting another RC calibration;
|
||||
* - XOsc related errors may be due to hardware problems, can be fixed by reset;
|
||||
* - PLL lock related errors can be due to not-locked PLL, or by attempting to use an out-of-band frequency, can be
|
||||
* fixed by executing a PLL calibration, or by using other frequencies.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [out] errors Pointer to a value holding error flags
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_calibrate, lr20xx_radio_common_calibrate_front_end, lr20xx_system_clear_errors
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_get_errors( const void* context, lr20xx_system_errors_t* errors );
|
||||
|
||||
/*!
|
||||
* @brief Clear all error flags pending.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_get_errors
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_clear_errors( const void* context );
|
||||
|
||||
/* Return number of available DIOs (valid range for lr20xx_system_dio_get_nth) */
|
||||
/**
|
||||
* @brief Returns the number of available DIOs
|
||||
*
|
||||
* @remark Also is the valid range for lr20xx_system_dio_get_nth.
|
||||
*
|
||||
* @return uint8_t the number of valid DIOs.
|
||||
*
|
||||
* @see lr20xx_system_dio_get_nth
|
||||
*/
|
||||
uint8_t lr20xx_system_dio_get_count( void );
|
||||
|
||||
/* Return nth DIO enum value; returns false if nth >= dio_count */
|
||||
/**
|
||||
* @brief Returns the nth value from the enum lr20xx_system_dio_t
|
||||
*
|
||||
* @param [in] nth from 0 to lr20xx_system_dio_get_count() - 1
|
||||
* @param [out] dio Pointer to a value holding the corresponding DIO enum
|
||||
* @return true if nth is a valid number, false otherwise
|
||||
*
|
||||
* @see lr20xx_system_dio_get_count, lr20xx_system_dio_t
|
||||
*/
|
||||
bool lr20xx_system_dio_get_nth( uint8_t nth, lr20xx_system_dio_t* dio );
|
||||
|
||||
/*
|
||||
* Configure DIO function and drive mode. DIO state is re-evaluated on command.
|
||||
* drive applied on sleep entry (if func != NONE); reset to NONE (or PULL_UP for DIO5/6) on wake without retention.
|
||||
* TX/RX_TRIGGER uses the default timeout configured via set_default_rx_tx_timeout.
|
||||
* LF_CLK_OUT only valid on DIO7–DIO11.
|
||||
* DIO5/DIO6 must be set to FUNC_NONE if connected to external components that could toggle them during cold-start.
|
||||
/*!
|
||||
* @brief Configure the function and the drive mode of a given DIO
|
||||
*
|
||||
* @remark @p drive is applied when entering sleep mode if @p func is not @ref LR20XX_SYSTEM_DIO_FUNC_NONE.
|
||||
* When leaving sleep mode without retention, @p drive is reset to @ref LR20XX_SYSTEM_DIO_DRIVE_NONE (except for @p dio
|
||||
* LR20XX_SYSTEM_DIO_5 and LR20XX_SYSTEM_DIO_6 where @p drive is reset to LR20XX_SYSTEM_DIO_DRIVE_PULL_UP).
|
||||
*
|
||||
* @remark The state of @p dio is reevaluated when sending this command
|
||||
*
|
||||
* @remark When @p func is set to either LR20XX_SYSTEM_DIO_FUNC_TX_TRIGGER or LR20XX_SYSTEM_DIO_FUNC_RX_TRIGGER, default
|
||||
* timeout set through @ref lr20xx_radio_common_set_default_rx_tx_timeout or @ref
|
||||
* lr20xx_radio_common_set_default_rx_tx_timeout_in_rtc_step is used when radio operation is triggered
|
||||
*
|
||||
* @remark On @ref LR20XX_SYSTEM_DIO_5, only @ref LR20XX_SYSTEM_DIO_DRIVE_PULL_UP for @p drive
|
||||
*
|
||||
* @remark Function @ref LR20XX_SYSTEM_DIO_FUNC_LF_CLK_OUT can only be used if @p dio is one of:
|
||||
* - LR20XX_SYSTEM_DIO_7
|
||||
* - LR20XX_SYSTEM_DIO_8
|
||||
* - LR20XX_SYSTEM_DIO_9
|
||||
* - LR20XX_SYSTEM_DIO_10
|
||||
* - LR20XX_SYSTEM_DIO_11
|
||||
*
|
||||
* @ref LR20XX_SYSTEM_DIO_5 and @ref LR20XX_SYSTEM_DIO_6 must be configured explicitly to function @ref
|
||||
* LR20XX_SYSTEM_DIO_FUNC_NONE if they are connected to an external component that could toggle their state between a
|
||||
* cold start or a start without retention and the configuration of a function.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] dio DIO pin
|
||||
* @param [in] func DIO pin function
|
||||
* @param [in] drive DIO pin drive
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_dio_function( const void* context, lr20xx_system_dio_t dio,
|
||||
lr20xx_system_dio_func_t func, lr20xx_system_dio_drive_t drive );
|
||||
|
||||
/* Set RF switch configuration for a DIO; DIO state re-evaluated on command */
|
||||
/*!
|
||||
* @brief Set the RF switch configurations for a given DIO
|
||||
*
|
||||
* @remark The state of @p dio is reevaluated when sending this command
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] dio DIO pin
|
||||
* @param [in] rf_switch_cfg Pointer to a structure that holds the RF switch configuration for @p dio
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_dio_rf_switch_cfg( const void* context, lr20xx_system_dio_t dio,
|
||||
const lr20xx_system_dio_rf_switch_cfg_t rf_switch_cfg );
|
||||
|
||||
/*
|
||||
* Map IRQs to a DIO. Each IRQ can only be mapped to one DIO at a time (last write wins).
|
||||
* DIO state re-evaluated on command.
|
||||
/*!
|
||||
* @brief Set the interrupt configurations for a given DIO
|
||||
*
|
||||
* It is not possible to set the same IRQ on multiple DIOs. Only the last mapping for each IRQ is take into account.
|
||||
*
|
||||
* @remark The state of \p dio is reevaluated when sending this command
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] dio DIO pin
|
||||
* @param [in] irq_cfg Interrupt mask for \p dio
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_dio_irq_cfg( const void* context, lr20xx_system_dio_t dio,
|
||||
const lr20xx_system_irq_mask_t irq_cfg );
|
||||
|
||||
/*!
|
||||
* @brief Clear requested bits in the internal pending interrupt register
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] irqs_to_clear Variable that holds the interrupts to be cleared
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_get_and_clear_irq_status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_clear_irq_status( const void* context, const lr20xx_system_irq_mask_t irqs_to_clear );
|
||||
|
||||
/* Atomically clear and return pending IRQ flags */
|
||||
/**
|
||||
* @brief This helper function clears any radio irq status flags that are set and returns the flags that were cleared.
|
||||
*
|
||||
* @param [in] context Chip implementation context.
|
||||
* @param [out] irq Pointer to a variable for holding the system interrupt status.
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_clear_irq_status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_get_and_clear_irq_status( const void* context, lr20xx_system_irq_mask_t* irq );
|
||||
|
||||
/*
|
||||
* Select LF clock source. When switching to LR20XX_SYSTEM_LFCLK_EXT, the external clock must already be running
|
||||
* and must remain running. Call lr20xx_system_calibrate after changing LF clock source.
|
||||
/*!
|
||||
* @brief Configure the source of the Low Frequency Clock (LF_CLK)
|
||||
*
|
||||
* When switching LF CLK to external source (@ref LR20XX_SYSTEM_LFCLK_EXT), the external clock source must be already
|
||||
* running, and shall keep running afterwards.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] lfclock_cfg Low frequency clock configuration
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_calibrate, lr20xx_radio_common_calibrate_front_end, lr20xx_system_set_dio_function
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_cfg_lfclk( const void* context, const lr20xx_system_lfclk_cfg_t lfclock_cfg );
|
||||
|
||||
/*
|
||||
* Set HF clock output scaling on the DIO configured with LR20XX_SYSTEM_DIO_FUNC_HF_CLK_OUT.
|
||||
/*!
|
||||
* @brief Configure the High Frequency clock scaling on the output
|
||||
*
|
||||
* This command sets the HF clock scaling on the DIO configured with functionality
|
||||
* LR20XX_SYSTEM_DIO_FUNC_HF_CLK_OUT through lr20xx_system_set_dio_function
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] hf_clk_scaling High frequency output scaling
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_set_dio_function
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_cfg_clk_output( const void* context, lr20xx_system_hf_clk_scaling_t hf_clk_scaling );
|
||||
|
||||
/*
|
||||
* Configure TCXO supply voltage and start delay. start_delay_in_32mhz_step is a gating timeout in 32MHz ticks
|
||||
* (1 tick = 31.25ns); max value 0xFFFFFFFF. Set to 0 to disable TCXO mode.
|
||||
* If TCXO does not start within the delay, LR20XX_SYSTEM_ERRORS_HF_XOSC_START_MASK is set (check get_errors).
|
||||
* If 32MHz RC is uncalibrated, actual start time may be up to 2x the configured delay.
|
||||
/*!
|
||||
* @brief Enable the usage of a TCXO as HF clock and configure supply voltage & start delay
|
||||
*
|
||||
* \p start_delay_in_32mhz_step is the time the firmware waits before going into RF mode, expressed in number of 32MHz
|
||||
* clock ticks.
|
||||
* The timeout duration is given by: \f$ start\_delay\_in\_ns = start\_delay\_in\_32mhz\_step \times 31.25 \f$
|
||||
*
|
||||
* The TCXO mode can be disabled by setting \p start_delay_in_32mhz_step to 0.
|
||||
*
|
||||
* In the situation where the TCXO has not started within \p start_delay_in_32mhz_step then the error bit
|
||||
* LR20XX_SYSTEM_ERRORS_HF_XOSC_START_MASK will be set. It can be checked with a call to \p lr20xx_system_get_errors.
|
||||
*
|
||||
* It must be noted that the TCXO start time duration can last twice the duration of \p start_delay_in_32mhz_step
|
||||
* lr20xx_system_calibrate if the internal 32MHz RC clock source is not calibrated. Refer to \p lr20xx_system_calibrate
|
||||
* for details.
|
||||
*
|
||||
* The maximum value for \p start_delay_in_32mhz_step is 0xFFFFFFFF.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] supply_voltage Supply voltage value
|
||||
* @param [in] start_delay_in_32mhz_step Gating time before which the radio starts its RF operation
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_calibrate, lr20xx_radio_common_calibrate_front_end, lr20xx_system_get_errors
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_tcxo_mode( const void* context,
|
||||
const lr20xx_system_tcxo_supply_voltage_t supply_voltage,
|
||||
const uint32_t start_delay_in_32mhz_step );
|
||||
|
||||
/* Set regulator mode; controls whether DCDC is enabled in STANDBY_XOSC, FS, RX, TX modes */
|
||||
/*!
|
||||
* @brief Configure the regulator mode to be used in specific modes
|
||||
*
|
||||
* \p reg_mode defines if the DC-DC converter is switched on in the following modes: STANDBY XOSC, FS, RX, TX.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] reg_mode Regulator mode configuration
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_reg_mode( const void* context, const lr20xx_system_reg_mode_t reg_mode );
|
||||
|
||||
/*
|
||||
* Calibrate selected blocks (bitmask of lr20xx_system_calibration_e). Can be called from any mode.
|
||||
* Chip returns to STANDBY_RC on exit. Errors readable via lr20xx_system_get_errors.
|
||||
* Run at boot; re-run AAF_MASK if temperature changes by >20°C; MU_MASK needs boot calibration only.
|
||||
/*!
|
||||
* @brief Calibrate the requested blocks
|
||||
*
|
||||
* This function can be called in any mode of the chip.
|
||||
*
|
||||
* The chip will return to standby RC mode on exit. Potential calibration issues can be read out with
|
||||
* lr20xx_system_get_errors command.
|
||||
*
|
||||
* The calibration should be executed at boot. The calibration can then be executed again:
|
||||
* - @ref lr20xx_system_calibration_e::LR20XX_SYSTEM_CALIB_AAF_MASK : should be calibrated again for a temperature
|
||||
* change superior to 20 degree Celsius
|
||||
* - @ref lr20xx_system_calibration_e::LR20XX_SYSTEM_CALIB_MU_MASK : initial calibration is enough
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] blocks_to_calibrate Blocks to be calibrated - bitfield built with lr20xx_system_calibration_e
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_get_errors
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_calibrate( const void* context,
|
||||
const lr20xx_system_calibration_mask_t blocks_to_calibrate );
|
||||
|
||||
/*
|
||||
* Read supply voltage. RAW format: Vbat_V = (vbat/8192 × 5 - 1) × Vana (Vana typ. 1.35V; vbat is 13-bit).
|
||||
* UNIT format: result in mV.
|
||||
/*!
|
||||
* @brief Get the value of the power supply voltage
|
||||
*
|
||||
* If @p format is set to LR20XX_SYSTEM_VALUE_FORMAT_RAW, Vbat value (in [V]) is a function of Vana (typ. 1.35V) and can
|
||||
* be obtained using the following formula: \f$ Vbat_{V} = (\frac{vbat}{8192} \times 5 - 1) \times Vana \f$ where vbat
|
||||
* is a 13-bit long value
|
||||
*
|
||||
* If @p format is set to LR20XX_SYSTEM_VALUE_FORMAT_UNIT, the power supply voltage is given in [mV]
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] format Format of the returned value of @p vbat
|
||||
* @param [in] res Resolution of the measure of @p vbat
|
||||
* @param [out] vbat A pointer to the @p vbat value
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_get_vbat( const void* context, lr20xx_system_value_format_t format,
|
||||
lr20xx_system_meas_res_t res, uint16_t* vbat );
|
||||
|
||||
/*
|
||||
* Read internal junction temperature. RAW format: Temp_°C = (temp[12:0]/8192 × Vana - Vbe25) × 1000/VbeSlope + 25
|
||||
* (Vana typ. 1.35V, Vbe25 typ. 0.7295V, VbeSlope typ. -1.7mV/°C). UNIT format: °C in 13.5sb (integer + fractional).
|
||||
* Configure TCXO with set_tcxo_mode before calling if TCXO is used.
|
||||
/*!
|
||||
* @brief Get the value of the internal junction temperature
|
||||
*
|
||||
* If @p format is set to LR20XX_SYSTEM_VALUE_FORMAT_RAW, the temperature (in [°C]) is a function of Vana (typ. 1.35V),
|
||||
* Vbe25 (Vbe voltage @ 25°C, typ. 0.7295V) and VbeSlope (typ. -1.7mV/°C) using the following formula:
|
||||
* \f$ Temperature_{°C} = (\frac{temp(12:0)}{8192} \times Vana - Vbe25) \times \frac{1000}{VbeSlope} + 25 \f$ where
|
||||
* temp{12:0} is the value corresponding to the 12 LSBs of the output argument of @ref lr20xx_system_get_temp
|
||||
*
|
||||
* If @p format is set to LR20XX_SYSTEM_VALUE_FORMAT_UNIT, the temperature is given in [°C] in 13.5sb format, the first
|
||||
* byte returned contains the integer part, the second the fractional part.
|
||||
*
|
||||
* @remark If a TCXO is used, make sure to configure it with @ref lr20xx_system_set_tcxo_mode before calling this
|
||||
* function
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] format Format of the returned value of @p temp
|
||||
* @param [in] res Resolution of the measure
|
||||
* @param [in] src Temperature source
|
||||
* @param [out] temp A pointer to the @p temp value
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_get_temp( const void* context, lr20xx_system_value_format_t format,
|
||||
lr20xx_system_meas_res_t res, lr20xx_system_temp_src_t src, uint16_t* temp );
|
||||
|
||||
/*
|
||||
* Read a 32-bit random number. Not suitable for cryptographic use. Radio must be in standby mode.
|
||||
/*!
|
||||
* @brief Read and return a 32-bit random number
|
||||
*
|
||||
* This random number generator is not suitable for cryptographic operations.
|
||||
* It can be called during any mode without perturbation on ongoing Rx or Tx operation.
|
||||
*
|
||||
* @remark Radio operating mode must be set into standby.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] source Select source of entropy for random number generator
|
||||
* @param [out] random_number 32-bit random number
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_get_random_number( const void* context,
|
||||
lr20xx_system_random_entropy_source_bitmask_t source,
|
||||
uint32_t* random_number );
|
||||
|
||||
/* Enter sleep mode; sleep_time in LF clock steps (0 = sleep until wakeup pin) */
|
||||
/*!
|
||||
* @brief Switch the transceiver into sleep mode with the request configuration
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] sleep_cfg Sleep configuration
|
||||
* @param [in] sleep_time Sleep time in LF clock steps
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_sleep_mode( const void* context, const lr20xx_system_sleep_cfg_t* sleep_cfg,
|
||||
const uint32_t sleep_time );
|
||||
|
||||
/*!
|
||||
* @brief Switch the transceiver into the requested stand-by mode
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] standby_mode Requested stand-by mode
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_standby_mode( const void* context, const lr20xx_system_standby_mode_t standby_mode );
|
||||
|
||||
/*!
|
||||
* @brief Switch the transceiver into the Frequency Synthesis (FS) mode
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_fs_mode( const void* context );
|
||||
|
||||
/*
|
||||
* Add a register to the sleep retention list. slot in [0:31]; address must be word-aligned (only 3 LSBs significant).
|
||||
* Up to 32 additional registers beyond the hardware defaults can be retained across retentionless sleep.
|
||||
/*!
|
||||
* @brief Add a register to be saved in retention memory
|
||||
*
|
||||
* @remark This command is used when a register is not added by default to the retention memory. It gives the
|
||||
* possibility to store up to 32 additional registers when entering sleep mode.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] slot Index in the storage list. Allowed values [0:31]
|
||||
* @param [in] address Address of the register to be added to the list. Only the 3 LSBs are significant. Address must be
|
||||
* word-aligned
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_system_set_sleep_mode
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_add_register_to_retention_mem( const void* context, uint8_t slot, uint32_t address );
|
||||
|
||||
/*!
|
||||
* @brief Configure the low battery detector
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] is_enabled Low battery detector activation
|
||||
* @param [in] trim Trimming value defining the threshold used to trigger a low battery interrupt
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_lbd_cfg( const void* context, bool is_enabled, lr20xx_system_lbd_trim_t trim );
|
||||
|
||||
/*
|
||||
* Configure internal XTAL trim capacitors and post-ready wait time. XTA: 11.3pF + xta×0.47pF (max 47 steps = 33.39pF).
|
||||
* XTB: 10.1pF + xtb×0.47pF (max 47 steps = 32.19pF). wait_time_us is an additional delay after XTAL readiness.
|
||||
/*!
|
||||
* @brief Configure the internal trimming capacitor values and XTAL start time
|
||||
*
|
||||
* @remark The device is fitted with internal programmable capacitors connected independently to the pins XTA and XTB of
|
||||
* the device. Each capacitor can be controlled independently in steps of 0.47 pF added to the minimal value of 11.3pF
|
||||
* for XTA and 10.1pF for XTB.
|
||||
*
|
||||
* The maximal capacitor value corresponds to 47 LSB steps added to the corresponding minimal value, so it is 33.39pF
|
||||
* for XTA and 32.19pF for XTB.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] xta Value for the trimming capacitor connected to XTA pin
|
||||
* @param [in] xtb Value for the trimming capacitor connected to XTB pin
|
||||
* @param [in] wait_time_us Additional wait time after XTAL readiness in microsecond
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_configure_xosc( const void* context, uint8_t xta, uint8_t xtb, uint8_t wait_time_us );
|
||||
|
||||
/*
|
||||
* Configure TX heating compensation for XTAL 32MHz (not TCXO). Fails if TCXO is configured.
|
||||
* Set is_ntc_en if an external NTC temperature sensor is present.
|
||||
/*!
|
||||
* @brief Set the temperature compensation configuration
|
||||
*
|
||||
* This command configures the heating compensation during Tx operations when XTAL 32MHz is used.
|
||||
* This command will fail if a TCXO is configured.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] mode Temperature compensation mode
|
||||
* @param [in] is_ntc_en Indicate if an external temperature sensor is available
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_temp_comp_cfg( const void* context, lr20xx_system_temp_comp_mode_t mode,
|
||||
bool is_ntc_en );
|
||||
|
||||
/* Set NTC parameters: ntc_r_ratio is 10.9b resistance bias ratio at 25°C; ntc_beta in units of 2K */
|
||||
/*!
|
||||
* @brief Set Negative Temperature Coefficient parameters
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] ntc_r_ratio Resistance bias ratio (10.9b) - ratio between resistance bias and NTC resistance at 25°C
|
||||
* @param [in] ntc_beta Beta coefficient (unit is 2 Kelvin)
|
||||
* @param [in] delay First order time delay coefficient
|
||||
*
|
||||
* @returns Operation status
|
||||
*/
|
||||
lr20xx_status_t lr20xx_system_set_ntc_params( const void* context, uint16_t ntc_r_ratio, uint16_t ntc_beta,
|
||||
uint8_t delay );
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ typedef struct lr20xx_system_version_s
|
||||
} lr20xx_system_version_t;
|
||||
|
||||
/**
|
||||
* @brief Sleep mode configuration
|
||||
* @brief Version structure definition
|
||||
*/
|
||||
typedef struct lr20xx_system_sleep_cfg_s
|
||||
{
|
||||
@@ -345,8 +345,9 @@ typedef enum
|
||||
*/
|
||||
typedef enum lr20xx_system_reg_mode_e
|
||||
{
|
||||
LR20XX_SYSTEM_REG_MODE_LDO = 0x00, //!< (Default) Only use the Low-Dropout Regulator
|
||||
LR20XX_SYSTEM_REG_MODE_DCDC = 0x02, //!< Switch on the DC-to-DC regulator in applicable chip modes
|
||||
LR20XX_SYSTEM_REG_MODE_LDO = 0x00, //!< (Default) Only use the Low-Dropout Regulator
|
||||
LR20XX_SYSTEM_REG_MODE_DCDC =
|
||||
0x02, //!< Switch on the DC-to-DC regulator in applicable chip modes (a.k.a. SIMO converter)
|
||||
} lr20xx_system_reg_mode_t;
|
||||
|
||||
/**
|
||||
@@ -394,7 +395,12 @@ typedef enum lr20xx_system_temp_src_e
|
||||
LR20XX_SYSTEM_TEMP_SRC_NTC = 0x02,
|
||||
} lr20xx_system_temp_src_t;
|
||||
|
||||
/** @brief Entropy source selection for random number generator (default: PLL | ADC) */
|
||||
/**
|
||||
* @brief Select the entropy source to enable for random number generator
|
||||
*
|
||||
* It is advised to enable both PLL and ADC entropy sources.
|
||||
* By default PLL and ADC are used as entropy sources.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LR20XX_SYSTEM_RANDOM_ENTROPY_SOURCE_PLL = 0x01, //!< PLL is used as entropy source. The chip automatically goes to
|
||||
@@ -403,7 +409,11 @@ typedef enum
|
||||
//!< FS mode when needed, and goes back to original mode afterward.
|
||||
} lr20xx_system_random_entropy_source_t;
|
||||
|
||||
/** @brief Bitmask of lr20xx_system_random_entropy_source_t values */
|
||||
/**
|
||||
* @brief Bit mask of entropy source to enable.
|
||||
*
|
||||
* The values are from @ref lr20xx_system_random_entropy_source_t.
|
||||
*/
|
||||
typedef uint8_t lr20xx_system_random_entropy_source_bitmask_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,56 +45,33 @@
|
||||
#include "lr20xx_system.h"
|
||||
#include "lr20xx_radio_ook.h"
|
||||
#include "lr20xx_radio_common.h"
|
||||
#include "lr20xx_radio_fifo.h"
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PRIVATE MACROS-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Semtech SWDR001 workaround register addresses and field masks */
|
||||
#define LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_SYNCWORDS ( 7 ) /* Semtech SWDR001 prescribed value */
|
||||
#define LR20XX_WORKAROUND_BLUETOOTH_LE_2MBPS_PREAMBLE_LENGTH_BUFFER_LENGTH ( 7 ) /* Semtech SWDR001 prescribed value */
|
||||
|
||||
#define LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_FREQUENCY_DRIFT_REGISTER_ADDRESS ( 0x00F30C28 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_FREQUENCY_DRIFT_REGISTER_MASK ( 0x1F << 5 )
|
||||
#define LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_FREQUENCY_DRIFT_VALUE ( 30 << 5 ) /* Semtech SWDR001 prescribed value; field occupies bits[9:5] */
|
||||
|
||||
#define LR20XX_WORKAROUND_LORA_SX1276_COMPATIBILITY_REGISTER_ADDRESS ( 0x00F30A14 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_LORA_SX1276_COMPATIBILITY_REGISTER_ADDRESS ( 0x00F30A14 )
|
||||
#define LR20XX_WORKAROUND_LORA_SX1276_COMPATIBILITY_REGISTER_MASK ( 3 << 18 )
|
||||
|
||||
#define LR20XX_WORKAROUND_LORA_FREQ_HOP_SX1276_COMPATIBILITY_REGISTER_ADDRESS ( 0x00F30A24 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_LORA_FREQ_HOP_SX1276_COMPATIBILITY_REGISTER_ADDRESS ( 0x00F30A24 )
|
||||
#define LR20XX_WORKAROUND_LORA_FREQ_HOP_SX1276_COMPATIBILITY_REGISTER_MASK ( 1 << 18 )
|
||||
|
||||
#define LR20XX_WORKAROUND_OOK_DETECTION_THRESHOLD_REGISTER_ADDRESS ( 0x00F30E14 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_OOK_DETECTION_THRESHOLD_REGISTER_ADDRESS ( 0x00F30E14 )
|
||||
#define LR20XX_WORKAROUND_OOK_DETECTION_THRESHOLD_REGISTER_MASK ( 0x7F << 20 )
|
||||
|
||||
#define LR20XX_WORKAROUND_RTTOF_RF_FREQ_ADDRESS ( 0x00F40144 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_RTTOF_RF_FREQ_MASK ( 0x7F ) /* 7-bit PLL step fractional part */
|
||||
|
||||
#define LR20XX_WORKAROUND_RTTOF_RSSI_MAX_GAIN_REGISTER_ADDRESS ( 0x00F301A4 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_RTTOF_RSSI_POWER_OFFSET_REGISTER_ADDRESS ( 0x00F30128 ) /* Semtech SWDR001 */
|
||||
|
||||
#define LR20XX_WORKAROUND_DCDC_ADC_CTRL_REGISTER_ADDRESS ( 0x00F40200 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_DCDC_RX_PATH_REGISTER_ADDRESS ( 0x00F40430 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_DCDC_SWITCHER_REGISTER_ADDRESS ( 0x00F20024 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_DCDC_SWITCHER_RISE_REGISTER_MASK ( 0xF << 20 )
|
||||
#define LR20XX_WORKAROUND_DCDC_SWITCHER_FALL_REGISTER_MASK ( 0xF << 16 )
|
||||
#define LR20XX_WORKAROUND_DCDC_FREQ_LF_REGISTER_ADDRESS ( 0x80004C ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_DCDC_RF_FREQ_ADDRESS ( LR20XX_WORKAROUND_RTTOF_RF_FREQ_ADDRESS )
|
||||
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_CHANNEL_FILTER_ADDRESS ( 0xF3013C ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_CHANNEL_FILTER_ADDRESS ( 0xF3013C )
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_CHANNEL_FILTER_MASK ( 0x38 )
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_CHANNEL_FILTER_VALUE ( 0x30 ) /* Semtech SWDR001 prescribed value; within mask 0x38 */
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_CHANNEL_FILTER_VALUE ( 0x30 )
|
||||
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_DCC_ADDRESS ( 0xF30134 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_DCC_ADDRESS ( 0xF30134 )
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_DCC_MASK ( 0x1B )
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_DCC_MANAGER_VALUE ( 0x08 ) /* Semtech SWDR001 prescribed value; within mask 0x1B */
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_DCC_SUBORDINATE_VALUE ( 0x0A ) /* Semtech SWDR001 prescribed value; within mask 0x1B */
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_DCC_MANAGER_VALUE ( 0x08 )
|
||||
#define LR20XX_WORKAROUND_RESULT_DEVIATION_DCC_SUBORDINATE_VALUE ( 0x0A )
|
||||
|
||||
#define LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_ADDRESS ( 0x00F30B50 ) /* Semtech SWDR001 */
|
||||
#define LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_MASK ( 0x7 << 24 )
|
||||
#define LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_SET_VALUE ( 0x0 << 24 )
|
||||
#define LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_RESET_VALUE ( 0x1 << 24 )
|
||||
#define LR20XX_WORKAROUND_CFG_IRQ_RX_FIFO_THRESHOLDS_REGISTER ( 0xF2A098 )
|
||||
#define LR20XX_WORKAROUND_CFG_IRQ_TX_FIFO_THRESHOLDS_REGISTER ( 0xF2A09C )
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
@@ -116,73 +93,42 @@
|
||||
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
|
||||
*/
|
||||
|
||||
/* Write SX1276 LoRa compatibility field; value=true enables */
|
||||
/**
|
||||
* @brief Helper function to write the appropriate field to store LoRa SX1276 compatibility parameter
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param value True to enable the compatibility mode, false to disable it
|
||||
* @return Operation status
|
||||
*/
|
||||
static lr20xx_status_t lr20xx_workaround_lora_sx1276_compatibility_write_value( const void* context, bool value );
|
||||
|
||||
/* Write SX1276 frequency-hopping compatibility field; value=true enables */
|
||||
/**
|
||||
* @brief Helper function to write the appropriate field to store LoRa frequency hopping SX1276 compatibility parameter
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param value True to enable the compatibility mode, false to disable it
|
||||
* @return Operation status
|
||||
*/
|
||||
static lr20xx_status_t lr20xx_workaround_lora_frequency_hopping_sx1276_compatibility_write_value( const void* context,
|
||||
bool value );
|
||||
|
||||
/* Read SF bits from SX1276 compatibility register; used only when disabling the mode */
|
||||
/**
|
||||
* @brief Read the configured SF value configured
|
||||
*
|
||||
* This command is to be used only when disabling the SX1276 LoRa compatibility mode.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param [out] sf The configure SF
|
||||
*
|
||||
* @return Operation status
|
||||
*/
|
||||
static lr20xx_status_t lr20xx_workaround_lora_sx1276_compatibility_read_sf_value( const void* context, uint8_t* sf );
|
||||
|
||||
/* Read RTToF max gain (10-bit) and 6-bit signed power offset from hardware registers */
|
||||
static lr20xx_status_t lr20xx_workarounds_rttof_rssi_computation_get_gain_power( const void* context,
|
||||
uint16_t* max_gain,
|
||||
int16_t* power_offset );
|
||||
|
||||
/* Apply RTToF RSSI correction formula (Semtech SWDR001) to a raw RSSI byte */
|
||||
static uint8_t lr20xx_workarounds_rttof_rssi_computation_apply_correction( uint16_t max_gain, int16_t power_offset,
|
||||
uint8_t raw_rssi );
|
||||
|
||||
/* Write DCDC LF switching frequency register (frequency in Hz) */
|
||||
static lr20xx_status_t lr20xx_workaround_dcdc_set_frequency( const void* context, uint32_t frequency );
|
||||
|
||||
/* Read current RF frequency from PLL register; used only in DCDC workaround context */
|
||||
static lr20xx_status_t lr20xx_workaround_dcdc_get_rf_frequency( const void* context, uint32_t* frequency );
|
||||
|
||||
/* Convert raw PLL step count to Hz: step_hz = 15625/2^14 ≈ 0.9537Hz */
|
||||
static uint32_t pll_step_to_hz( uint32_t pll_steps );
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
|
||||
*/
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_bluetooth_le_phy_coded_syncwords( const void* context )
|
||||
{
|
||||
const uint8_t cbuffer[LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_SYNCWORDS] = { 0x02, 0x30, 0x01, 0x20,
|
||||
0x00, 0x09, 0x00 };
|
||||
|
||||
return ( lr20xx_status_t ) lr20xx_hal_write( context, cbuffer, LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_SYNCWORDS,
|
||||
0, 0 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_bluetooth_le_phy_coded_frequency_drift( const void* context )
|
||||
{
|
||||
return lr20xx_regmem_write_regmem32_mask( context,
|
||||
LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_FREQUENCY_DRIFT_REGISTER_ADDRESS,
|
||||
LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_FREQUENCY_DRIFT_REGISTER_MASK,
|
||||
LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_FREQUENCY_DRIFT_VALUE );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_bluetooth_le_phy_coded_frequency_drift_store_retention_mem( const void* context,
|
||||
uint8_t slot )
|
||||
{
|
||||
return lr20xx_system_add_register_to_retention_mem(
|
||||
context, slot, LR20XX_WORKAROUND_BLUETOOTH_LE_PHY_CODED_FREQUENCY_DRIFT_REGISTER_ADDRESS );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_bluetooth_le_2mbps_preamble_length( const void* context )
|
||||
{
|
||||
const uint8_t cbuffer[LR20XX_WORKAROUND_BLUETOOTH_LE_2MBPS_PREAMBLE_LENGTH_BUFFER_LENGTH] = { 0x02, 0x30, 0x01,
|
||||
0x21, 0x00, 0x07,
|
||||
0x00 };
|
||||
|
||||
return ( lr20xx_status_t ) lr20xx_hal_write(
|
||||
context, cbuffer, LR20XX_WORKAROUND_BLUETOOTH_LE_2MBPS_PREAMBLE_LENGTH_BUFFER_LENGTH, 0, 0 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_lora_enable_sx1276_compatibility_mode( const void* context )
|
||||
{
|
||||
return lr20xx_workaround_lora_sx1276_compatibility_write_value( context, true );
|
||||
@@ -190,10 +136,11 @@ lr20xx_status_t lr20xx_workarounds_lora_enable_sx1276_compatibility_mode( const
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_lora_disable_sx1276_compatibility_mode( const void* context )
|
||||
{
|
||||
// 1. Get the currently configured SF value
|
||||
uint8_t sf = 0;
|
||||
const lr20xx_status_t get_sf_status = lr20xx_workaround_lora_sx1276_compatibility_read_sf_value( context, &sf );
|
||||
|
||||
/* SF6 requires compatibility mode even when "disabling" (SX1276 SF6 implicit-only constraint) */
|
||||
// 2. Modify the compatibility mode value depending on currently configured SF
|
||||
if( get_sf_status == LR20XX_STATUS_OK )
|
||||
{
|
||||
return lr20xx_workaround_lora_sx1276_compatibility_write_value( context, ( ( sf <= 6 ) ? true : false ) );
|
||||
@@ -230,7 +177,6 @@ lr20xx_status_t lr20xx_workarounds_lora_freq_hop_sx1276_compatibility_mode_store
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_ook_set_detection_threshold_level( const void* context, int16_t threshold_level_db )
|
||||
{
|
||||
/* Register field is biased: +10 dB hardware offset + 64 to map signed dBm to unsigned field (Semtech SWDR001) */
|
||||
const int threshold_db = threshold_level_db + 10 + 64;
|
||||
return lr20xx_regmem_write_regmem32_mask(
|
||||
context, LR20XX_WORKAROUND_OOK_DETECTION_THRESHOLD_REGISTER_ADDRESS,
|
||||
@@ -426,92 +372,6 @@ int16_t lr20xx_workarounds_ook_get_default_detection_threshold_level( lr20xx_rad
|
||||
}
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_truncate_pll_freq_step( const void* context )
|
||||
{
|
||||
return lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_RTTOF_RF_FREQ_ADDRESS,
|
||||
LR20XX_WORKAROUND_RTTOF_RF_FREQ_MASK, 0 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_rssi_computation( const void* context, uint8_t rssi1_raw_value,
|
||||
uint8_t rssi2_raw_value, uint8_t* rssi1_raw_fixed,
|
||||
uint8_t* rssi2_raw_fixed )
|
||||
{
|
||||
uint16_t max_gain = 0;
|
||||
int16_t power_offset = 0;
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_workarounds_rttof_rssi_computation_get_gain_power( context, &max_gain, &power_offset ) );
|
||||
( *rssi1_raw_fixed ) =
|
||||
lr20xx_workarounds_rttof_rssi_computation_apply_correction( max_gain, power_offset, rssi1_raw_value );
|
||||
if( rssi2_raw_fixed != 0 )
|
||||
{
|
||||
( *rssi2_raw_fixed ) =
|
||||
lr20xx_workarounds_rttof_rssi_computation_apply_correction( max_gain, power_offset, rssi2_raw_value );
|
||||
}
|
||||
|
||||
return LR20XX_STATUS_OK;
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_dcdc_reset( const void* context )
|
||||
{
|
||||
/* Rise/fall timing fields (bits 23:20 and 19:16): default values 15,15 per Semtech SWDR001 */
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_DCDC_SWITCHER_REGISTER_ADDRESS,
|
||||
LR20XX_WORKAROUND_DCDC_SWITCHER_RISE_REGISTER_MASK, 15 << 20 ) );
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_DCDC_SWITCHER_REGISTER_ADDRESS,
|
||||
LR20XX_WORKAROUND_DCDC_SWITCHER_FALL_REGISTER_MASK, 15 << 16 ) );
|
||||
return lr20xx_workaround_dcdc_set_frequency( context, 2800000 ); /* 2.8MHz default switching frequency */
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_dcdc_configure( const void* context )
|
||||
{
|
||||
uint32_t adc_ctrl_raw = 0;
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_read_regmem32( context, LR20XX_WORKAROUND_DCDC_ADC_CTRL_REGISTER_ADDRESS, &adc_ctrl_raw, 1 ) );
|
||||
const uint32_t ana_dec = ( adc_ctrl_raw >> 8 ) & 0x7;
|
||||
|
||||
uint32_t rx_path_raw = 0;
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_read_regmem32( context, LR20XX_WORKAROUND_DCDC_RX_PATH_REGISTER_ADDRESS, &rx_path_raw, 1 ) );
|
||||
const bool is_rx_hf = ( ( rx_path_raw & 0x3 ) == 1 );
|
||||
|
||||
/* Rise=11,Fall=13 for narrow-band LF RX path; Rise=15,Fall=15 otherwise — Semtech SWDR001 */
|
||||
if( ( is_rx_hf == false ) && ( ( ana_dec == 1 ) || ( ana_dec == 2 ) ) )
|
||||
{
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_DCDC_SWITCHER_REGISTER_ADDRESS,
|
||||
LR20XX_WORKAROUND_DCDC_SWITCHER_RISE_REGISTER_MASK, 11 << 20 ) );
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_DCDC_SWITCHER_REGISTER_ADDRESS,
|
||||
LR20XX_WORKAROUND_DCDC_SWITCHER_FALL_REGISTER_MASK, 13 << 16 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_DCDC_SWITCHER_REGISTER_ADDRESS,
|
||||
LR20XX_WORKAROUND_DCDC_SWITCHER_RISE_REGISTER_MASK, 15 << 20 ) );
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_DCDC_SWITCHER_REGISTER_ADDRESS,
|
||||
LR20XX_WORKAROUND_DCDC_SWITCHER_FALL_REGISTER_MASK, 15 << 16 ) );
|
||||
}
|
||||
|
||||
/* ana_dec==1: 4.3MHz switching; otherwise: 2.8MHz — Semtech SWDR001 */
|
||||
if( ana_dec == 1 )
|
||||
{
|
||||
return lr20xx_workaround_dcdc_set_frequency( context, 4300000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return lr20xx_workaround_dcdc_set_frequency( context, 2800000 );
|
||||
}
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_dcdc_store_retention_mem( const void* context, uint8_t slot )
|
||||
{
|
||||
return lr20xx_system_add_register_to_retention_mem( context, slot,
|
||||
LR20XX_WORKAROUND_DCDC_SWITCHER_REGISTER_ADDRESS );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_results_deviation( const void* context, bool is_manager )
|
||||
{
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
@@ -533,24 +393,30 @@ lr20xx_status_t lr20xx_workarounds_rttof_results_deviation_store_retention_mem(
|
||||
LR20XX_WORKAROUND_RESULT_DEVIATION_DCC_ADDRESS );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_extended_stuck_second_request_enable( const void* context )
|
||||
lr20xx_status_t lr20xx_workarounds_1024_byte_fifo_cfg_irq(
|
||||
const void* context, lr20xx_radio_fifo_flag_t rx_fifo_irq_enable, lr20xx_radio_fifo_flag_t tx_fifo_irq_enable,
|
||||
uint16_t rx_fifo_high_threshold, uint16_t tx_fifo_low_threshold, uint16_t rx_fifo_low_threshold,
|
||||
uint16_t tx_fifo_high_threshold )
|
||||
{
|
||||
return lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_ADDRESS,
|
||||
LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_MASK,
|
||||
LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_SET_VALUE );
|
||||
RETURN_STATUS_ON_NOT_OK( lr20xx_radio_fifo_cfg_irq( context, rx_fifo_irq_enable, tx_fifo_irq_enable,
|
||||
rx_fifo_high_threshold, 0, 0, tx_fifo_high_threshold ) );
|
||||
|
||||
const uint32_t rx_threshold_raw = ( uint32_t ) rx_fifo_low_threshold + ( rx_fifo_high_threshold << 16u );
|
||||
const uint32_t tx_threshold_raw = ( uint32_t ) tx_fifo_low_threshold + ( tx_fifo_high_threshold << 16u );
|
||||
RETURN_STATUS_ON_NOT_OK( lr20xx_regmem_write_regmem32(
|
||||
context, LR20XX_WORKAROUND_CFG_IRQ_RX_FIFO_THRESHOLDS_REGISTER, &rx_threshold_raw, 1 ) );
|
||||
return lr20xx_regmem_write_regmem32( context, LR20XX_WORKAROUND_CFG_IRQ_TX_FIFO_THRESHOLDS_REGISTER,
|
||||
&tx_threshold_raw, 1 );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_extended_stuck_second_request_disable( const void* context )
|
||||
lr20xx_status_t lr20xx_workarounds_1024_byte_fifo_cfg_irq_store_retention_mem( const void* context,
|
||||
uint8_t retention_slot_rx_thresholds,
|
||||
uint8_t retention_slot_tx_thresholds )
|
||||
{
|
||||
return lr20xx_regmem_write_regmem32_mask( context, LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_ADDRESS,
|
||||
LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_MASK,
|
||||
LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_RESET_VALUE );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_extended_stuck_second_request_store_retention_mem( const void* context,
|
||||
uint8_t slot )
|
||||
{
|
||||
return lr20xx_system_add_register_to_retention_mem( context, slot, LR20XX_WORKAROUND_RTTOF_EXTENDED_STUCK_ADDRESS );
|
||||
RETURN_STATUS_ON_NOT_OK( lr20xx_system_add_register_to_retention_mem(
|
||||
context, retention_slot_rx_thresholds, LR20XX_WORKAROUND_CFG_IRQ_RX_FIFO_THRESHOLDS_REGISTER ) );
|
||||
return lr20xx_system_add_register_to_retention_mem( context, retention_slot_tx_thresholds,
|
||||
LR20XX_WORKAROUND_CFG_IRQ_TX_FIFO_THRESHOLDS_REGISTER );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -580,61 +446,9 @@ lr20xx_status_t lr20xx_workaround_lora_sx1276_compatibility_read_sf_value( const
|
||||
context, LR20XX_WORKAROUND_LORA_SX1276_COMPATIBILITY_REGISTER_ADDRESS, &raw_register_value, 1 );
|
||||
if( read_status == LR20XX_STATUS_OK )
|
||||
{
|
||||
*sf = raw_register_value & 0x0f; /* SF is stored in bits [3:0] */
|
||||
*sf = raw_register_value & 0x0f;
|
||||
}
|
||||
return read_status;
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_rssi_computation_get_gain_power( const void* context, uint16_t* max_gain,
|
||||
int16_t* power_offset )
|
||||
{
|
||||
uint32_t max_gain_raw = 0;
|
||||
RETURN_STATUS_ON_NOT_OK( lr20xx_regmem_read_regmem32(
|
||||
context, LR20XX_WORKAROUND_RTTOF_RSSI_MAX_GAIN_REGISTER_ADDRESS, &max_gain_raw, 1 ) );
|
||||
( *max_gain ) = ( uint16_t ) ( max_gain_raw & 0x03FF ); /* 10-bit gain field */
|
||||
|
||||
uint32_t power_offset_raw = 0;
|
||||
RETURN_STATUS_ON_NOT_OK( lr20xx_regmem_read_regmem32(
|
||||
context, LR20XX_WORKAROUND_RTTOF_RSSI_POWER_OFFSET_REGISTER_ADDRESS, &power_offset_raw, 1 ) );
|
||||
/* 6-bit two's-complement field at bit[11:6]: sign-extend by subtracting 64 if > 31 */
|
||||
const int16_t power_offset_raw_value = ( power_offset_raw >> 6 ) & 0x3F;
|
||||
( *power_offset ) = ( int16_t ) ( ( ( power_offset_raw_value ) > 32 ) ? ( power_offset_raw_value - ( int16_t ) 64 )
|
||||
: power_offset_raw_value );
|
||||
return LR20XX_STATUS_OK;
|
||||
}
|
||||
|
||||
uint8_t lr20xx_workarounds_rttof_rssi_computation_apply_correction( uint16_t max_gain, int16_t power_offset,
|
||||
uint8_t raw_rssi )
|
||||
{
|
||||
/* 208 = RSSI register bias per Semtech SWDR001 RSSI correction formula */
|
||||
return ( uint8_t ) ( 208 + ( max_gain >> 1 ) + power_offset - ( raw_rssi << 1 ) );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workaround_dcdc_set_frequency( const void* context, uint32_t frequency )
|
||||
{
|
||||
/* 1.048576 = 2^20 / 1e6: converts Hz to LF register units (Semtech SWDR001) */
|
||||
const uint32_t freq_lf = ( uint32_t ) ( ( float ) frequency * 1.048576f );
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_write_regmem32( context, LR20XX_WORKAROUND_DCDC_FREQ_LF_REGISTER_ADDRESS, &freq_lf, 1 ) );
|
||||
uint32_t rf_frequency = 0;
|
||||
RETURN_STATUS_ON_NOT_OK( lr20xx_workaround_dcdc_get_rf_frequency( context, &rf_frequency ) );
|
||||
return lr20xx_radio_common_set_rf_freq( context, rf_frequency );
|
||||
}
|
||||
|
||||
lr20xx_status_t lr20xx_workaround_dcdc_get_rf_frequency( const void* context, uint32_t* frequency )
|
||||
{
|
||||
uint32_t raw_rf_freq = 0;
|
||||
RETURN_STATUS_ON_NOT_OK(
|
||||
lr20xx_regmem_read_regmem32( context, LR20XX_WORKAROUND_DCDC_RF_FREQ_ADDRESS, &raw_rf_freq, 1 ) );
|
||||
*frequency = pll_step_to_hz( raw_rf_freq );
|
||||
return LR20XX_STATUS_OK;
|
||||
}
|
||||
|
||||
uint32_t pll_step_to_hz( uint32_t pll_steps )
|
||||
{
|
||||
const uint_least64_t numerator = ( ( uint_least64_t ) pll_steps * ( uint_least64_t ) 15625ULL );
|
||||
const uint_least64_t denominator = ( ( uint_least64_t ) ( 1 << 14 ) ); /* PLL step = 15625/2^14 Hz */
|
||||
return ( uint32_t ) ( ( numerator + denominator - 1 ) / denominator );
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
|
||||
@@ -48,31 +48,13 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
#include "lr20xx_status.h"
|
||||
#include "lr20xx_radio_fsk_common_types.h"
|
||||
#include "lr20xx_radio_fifo_types.h"
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC MACROS -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_RESET
|
||||
#define LR20XX_WORKAROUNDS_CONDITIONAL_APPLY_AUTOMATIC_DCDC_RESET( cont ) lr20xx_workarounds_dcdc_reset( cont )
|
||||
#else
|
||||
#define LR20XX_WORKAROUNDS_CONDITIONAL_APPLY_AUTOMATIC_DCDC_RESET( cont ) LR20XX_STATUS_OK
|
||||
#endif // LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_RESET
|
||||
|
||||
#ifndef LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_CONFIGURE
|
||||
#define LR20XX_WORKAROUNDS_CONDITIONAL_APPLY_AUTOMATIC_DCDC_CONFIGURE( cont ) lr20xx_workarounds_dcdc_configure( cont )
|
||||
#else
|
||||
#define LR20XX_WORKAROUNDS_CONDITIONAL_APPLY_AUTOMATIC_DCDC_CONFIGURE( cont ) LR20XX_STATUS_OK
|
||||
#endif // LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_CONFIGURE
|
||||
|
||||
#ifndef LR20XX_WORKAROUND_DISABLE_AUTOMATIC_BLE_2MBPS_PREAMBLE_LENGTH
|
||||
#define LR20XX_WORKAROUND_CONDITIONAL_APPLY_BLE_2MBPS_PREAMBLE_LENGTH( cont ) \
|
||||
lr20xx_workarounds_bluetooth_le_2mbps_preamble_length( cont )
|
||||
#else
|
||||
#define LR20XX_WORKAROUND_CONDITIONAL_APPLY_BLE_2MBPS_PREAMBLE_LENGTH( cont ) LR20XX_STATUS_OK
|
||||
#endif // LR20XX_WORKAROUND_DISABLE_AUTOMATIC_BLE_2MBPS_PREAMBLE_LENGTH
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* --- PUBLIC CONSTANTS --------------------------------------------------------
|
||||
@@ -88,110 +70,234 @@ extern "C" {
|
||||
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
|
||||
*/
|
||||
|
||||
/* Call after lr20xx_radio_bluetooth_le_set_pkt_params when PHY is LE_CODED_125KB or LE_CODED_500KB */
|
||||
lr20xx_status_t lr20xx_workarounds_bluetooth_le_phy_coded_syncwords( const void* context );
|
||||
|
||||
/* Call after lr20xx_radio_bluetooth_le_set_pkt_params when PHY is LE_CODED_125KB or LE_CODED_500KB */
|
||||
lr20xx_status_t lr20xx_workarounds_bluetooth_le_phy_coded_frequency_drift( const void* context );
|
||||
|
||||
/* Persist BLE coded-PHY frequency drift register across sleep; slot in [0:31] */
|
||||
lr20xx_status_t lr20xx_workarounds_bluetooth_le_phy_coded_frequency_drift_store_retention_mem( const void* context,
|
||||
uint8_t slot );
|
||||
|
||||
/*
|
||||
* Fix incorrect default preamble length for BLE 2Mbps mode.
|
||||
* Call after lr20xx_radio_bluetooth_le_set_modulation_params when PHY is LE_2M.
|
||||
* Applied automatically unless LR20XX_WORKAROUND_DISABLE_AUTOMATIC_BLE_2MBPS_PREAMBLE_LENGTH is defined.
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_bluetooth_le_2mbps_preamble_length( const void* context );
|
||||
|
||||
/*
|
||||
* Enable SX1276 LoRa compatibility: SF6 implicit mode and syncword nibbles > 7 for all SF.
|
||||
* Call after lr20xx_radio_lora_set_modulation_params.
|
||||
/**
|
||||
* @brief Enable LoRa compatibility mode with SX1276
|
||||
*
|
||||
* If the SX1276 LoRa compatibility is required, this workaround must be called after calling @ref
|
||||
* lr20xx_radio_lora_set_modulation_params.
|
||||
*
|
||||
* SX1276 LoRa compatibility mode allows:
|
||||
* - transmission to, and reception from, SX1276 LoRa packets at SF6 only in implicit mode (@ref
|
||||
* LR20XX_RADIO_LORA_PKT_IMPLICIT); and
|
||||
* - syncword nibbles greater than 7 for all SF.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_workarounds_lora_disable_sx1276_compatibility_mode,
|
||||
* lr20xx_workarounds_lora_sx1276_compatibility_mode_store_retention_mem
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_lora_enable_sx1276_compatibility_mode( const void* context );
|
||||
|
||||
/* Disable SX1276 LoRa compatibility; may be called before or after lr20xx_radio_lora_set_modulation_params */
|
||||
/**
|
||||
* @brief Disable the LoRa compatibility mode with SX1276
|
||||
*
|
||||
* To disable the SX1276 LoRa compatibility mode, this workaround can be call either before or after @ref
|
||||
* lr20xx_radio_lora_set_modulation_params.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_workarounds_lora_enable_sx1276_compatibility_mode,
|
||||
* lr20xx_workarounds_lora_sx1276_compatibility_mode_store_retention_mem
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_lora_disable_sx1276_compatibility_mode( const void* context );
|
||||
|
||||
/* Persist SX1276 LoRa compatibility register across sleep; slot in [0:31] */
|
||||
/**
|
||||
* @brief Store the LoRa SX1276 compatibility mode in retention memory
|
||||
*
|
||||
* Calling this function allows to store the SX1276 LoRa compatible state during sleep mode.
|
||||
* This helper function internally calls @ref lr20xx_system_add_register_to_retention_mem with the appropriate register
|
||||
* address.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param slot Index in the storage list. Allowed values [0:31]
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_system_add_register_to_retention_mem, lr20xx_workarounds_lora_enable_sx1276_compatibility_mode,
|
||||
* lr20xx_workarounds_lora_disable_sx1276_compatibility_mode
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_lora_sx1276_compatibility_mode_store_retention_mem( const void* context,
|
||||
uint8_t slot );
|
||||
|
||||
/* Enable SX1276 freq-hopping compatibility; call after lr20xx_radio_lora_set_freq_hop */
|
||||
/**
|
||||
* @brief Enable the SX1276 compatibility mode for LoRa intra-packet frequency hopping
|
||||
*
|
||||
* If the LoRa intra-packet frequency hopping compatible with SX1276 is required, this function must be called after
|
||||
* @ref lr20xx_radio_lora_set_freq_hop.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_radio_lora_set_freq_hop, lr20xx_workarounds_lora_freq_hop_disable_sx1276_compatibility_mode,
|
||||
* lr20xx_workarounds_lora_freq_hop_sx1276_compatibility_mode_store_retention_mem
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_lora_freq_hop_enable_sx1276_compatibility_mode( const void* context );
|
||||
|
||||
/* Disable SX1276 freq-hopping compatibility */
|
||||
/**
|
||||
* @brief Disable the SX1276 compatibility mode for LoRa intra-packet frequency hopping
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_radio_lora_set_freq_hop, lr20xx_workarounds_lora_freq_hop_enable_sx1276_compatibility_mode,
|
||||
* lr20xx_workarounds_lora_freq_hop_sx1276_compatibility_mode_store_retention_mem
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_lora_freq_hop_disable_sx1276_compatibility_mode( const void* context );
|
||||
|
||||
/* Persist SX1276 freq-hopping compatibility register across sleep; slot in [0:31] */
|
||||
/**
|
||||
* @brief Store the SX1276 compatibility mode for LoRa intra-packet frequency hopping in retention memory
|
||||
*
|
||||
* Calling this function allows to store the SX1276 LoRa intra-packet frequency hopping compatible state during sleep
|
||||
* mode. This helper function internally calls @ref lr20xx_system_add_register_to_retention_mem with the appropriate
|
||||
* register address.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param slot Index in the storage list. Allowed values [0:31]
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_system_add_register_to_retention_mem, lr20xx_workarounds_lora_freq_hop_enable_sx1276_compatibility_mode,
|
||||
* lr20xx_workarounds_lora_freq_hop_disable_sx1276_compatibility_mode
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_lora_freq_hop_sx1276_compatibility_mode_store_retention_mem( const void* context,
|
||||
uint8_t slot );
|
||||
|
||||
/*
|
||||
* Override OOK detection threshold. The default chip-computed value may be too conservative, raising PER.
|
||||
* Set to the noise floor (from lr20xx_radio_common_get_rssi_inst) if it exceeds the default.
|
||||
* Call after lr20xx_radio_ook_set_modulation_params. threshold_level_db in dBm.
|
||||
/**
|
||||
* @brief Override the OOK detection threshold level
|
||||
*
|
||||
* The OOK detection threshold level is automatically computed by the LR20xx depending on the modulation parameters.
|
||||
* However the computed value may be too conservative which increase the packet error rate.
|
||||
* The detection threshold level can be therefore modified with this function. The threshold to provide is typically the
|
||||
* noise level returned by @ref lr20xx_radio_common_get_rssi_inst using the same modulation parameters, if it is higher
|
||||
* than the LR20xx default computed value.
|
||||
*
|
||||
* Refer to @ref lr20xx_workarounds_ook_get_default_detection_threshold_level to obtain the default computed values
|
||||
* depending on modulation bandwidth.
|
||||
*
|
||||
* This function should be called after @ref lr20xx_radio_ook_set_modulation_params.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param threshold_level_db The threshold level to set, in dB
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_radio_ook_set_modulation_params, lr20xx_radio_common_get_rssi_inst,
|
||||
* lr20xx_workarounds_ook_get_default_detection_threshold_level
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_ook_set_detection_threshold_level( const void* context, int16_t threshold_level_db );
|
||||
|
||||
/*
|
||||
* Return default OOK detection threshold (dBm) for the given bandwidth.
|
||||
* Returns 0 for unknown bandwidth values.
|
||||
/**
|
||||
* @brief Helper function that returns default OOK detection threshold level
|
||||
*
|
||||
* This helper function helps to determine if the workaround @ref lr20xx_workarounds_ook_set_detection_threshold_level
|
||||
* is to be applied.
|
||||
*
|
||||
* @param bw The bandwidth for which the detection threshold is to be computed
|
||||
*
|
||||
* @return The default OOK detection threshold level, or 0 if the bandwidth @p bw is unknown
|
||||
*
|
||||
* @see lr20xx_workarounds_ook_set_detection_threshold_level
|
||||
*
|
||||
*/
|
||||
int16_t lr20xx_workarounds_ook_get_default_detection_threshold_level( lr20xx_radio_fsk_common_bw_t bw );
|
||||
|
||||
/*
|
||||
* Truncate internal PLL frequency to the nearest 122Hz multiple for RTToF accuracy.
|
||||
* Call after lr20xx_radio_common_set_rf_freq for RTToF ranging; adjusts RF freq by ≤122Hz.
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_truncate_pll_freq_step( const void* context );
|
||||
|
||||
/*
|
||||
* Correct RTToF raw RSSI values using gain/offset read from hardware registers.
|
||||
* raw = -(rssi_dB * 2); rssi_dB = -(raw / 2).
|
||||
* rssi2_raw_fixed may be null for single-RSSI (normal) results.
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_rssi_computation( const void* context, uint8_t rssi1_raw_value,
|
||||
uint8_t rssi2_raw_value, uint8_t* rssi1_raw_fixed,
|
||||
uint8_t* rssi2_raw_fixed );
|
||||
|
||||
/*
|
||||
* Reset DCDC switcher to default timing.
|
||||
* Required after lr20xx_radio_common_set_pkt_type when: sub-GHz RX + DCDC regulator mode.
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_dcdc_reset( const void* context );
|
||||
|
||||
/*
|
||||
* Configure DCDC switcher timing based on current RX path.
|
||||
* Required after any of: fsk/flrc/ook/lora set_modulation_params, z_wave_set_params, set_rx_path;
|
||||
* when: sub-GHz RX + DCDC regulator mode.
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_dcdc_configure( const void* context );
|
||||
|
||||
/* Persist DCDC switcher register across sleep; slot in [0:31] */
|
||||
lr20xx_status_t lr20xx_workarounds_dcdc_store_retention_mem( const void* context, uint8_t slot );
|
||||
|
||||
/*
|
||||
* Reduce RTToF result deviation on fractional bandwidths (BW_812/406/203/101).
|
||||
* Call after lr20xx_radio_lora_set_modulation_params; reset by subsequent set_modulation_params.
|
||||
* is_manager: true for RTToF manager role, false for subordinate.
|
||||
/**
|
||||
* @brief Apply workaround to reduce standard deviation of RTToF results with fractional bandwidths
|
||||
*
|
||||
* This workaround reduces the standard deviation of observed RTToF result on the following bandwiths:
|
||||
* - @ref LR20XX_RADIO_LORA_BW_812
|
||||
* - @ref LR20XX_RADIO_LORA_BW_406
|
||||
* - @ref LR20XX_RADIO_LORA_BW_203
|
||||
* - @ref LR20XX_RADIO_LORA_BW_101
|
||||
* The workaround must be called only on these bandwidths, after calling @ref lr20xx_radio_lora_set_modulation_params.
|
||||
*
|
||||
* Note that a call to @ref lr20xx_radio_lora_set_modulation_params reset the changes executed by this workaround.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param is_manager True if the device operate as manager, false if it operates as subordinate
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_radio_lora_set_modulation_params
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_results_deviation( const void* context, bool is_manager );
|
||||
|
||||
/* Persist RTToF deviation workaround registers (two slots) across sleep; slots in [0:31] */
|
||||
/**
|
||||
* @brief Store the registers for RTToF results deviation workaround in retention memory
|
||||
*
|
||||
* Calling this function allows to store the RTToF results deviation workaround registers during sleep mode. This helper
|
||||
* function internally calls @ref lr20xx_system_add_register_to_retention_mem with the appropriate register address.
|
||||
*
|
||||
* The @ref lr20xx_workarounds_rttof_results_deviation workaround addresses two registers, hence the two configurable
|
||||
* slots.
|
||||
*
|
||||
* @param context Chip implementation context
|
||||
* @param slot_1 Index in the storage list. Allowed values [0:31]
|
||||
* @param slot_2 Index in the storage list. Allowed values [0:31]
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_system_add_register_to_retention_mem, lr20xx_workarounds_rttof_results_deviation
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_results_deviation_store_retention_mem( const void* context, uint8_t slot_1,
|
||||
uint8_t slot_2 );
|
||||
|
||||
/* Enable RTToF extended-mode workaround; required when using LR20XX_RTTOF_MODE_EXTENDED */
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_extended_stuck_second_request_enable( const void* context );
|
||||
/*!
|
||||
* @brief Workaround helper to configure FIFO events and threshold levels with 1024-byte Tx/Rx FiFos
|
||||
*
|
||||
* This workaround wraps @ref lr20xx_radio_fifo_cfg_irq when using 1024-byte Rx/Tx FiFos to allow settings @p
|
||||
* tx_fifo_low_threshold and @p rx_fifo_low_threshold to value superior to 256.
|
||||
*
|
||||
* This workaround configures registers that are not maintained in memory during sleep mode. Call @ref
|
||||
* lr20xx_workarounds_1024_byte_fifo_cfg_irq_store_retention_mem to register these registers as maintained during sleep
|
||||
* mode.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] rx_fifo_irq_enable FIFO events triggering an interrupt in Rx
|
||||
* @param [in] tx_fifo_irq_enable FIFO events triggering an interrupt in Tx
|
||||
* @param [in] rx_fifo_high_threshold Rx FIFO threshold above which an interrupt (if
|
||||
* LR20XX_RADIO_FIFO_FLAG_THRESHOLD_HIGH is enabled) is triggered
|
||||
* @param [in] tx_fifo_low_threshold Tx FIFO threshold below which an interrupt (if LR20XX_RADIO_FIFO_FLAG_THRESHOLD_LOW
|
||||
* is enabled) is triggered
|
||||
* @param [in] rx_fifo_low_threshold Rx FIFO threshold below which an interrupt (if LR20XX_RADIO_FIFO_FLAG_THRESHOLD_LOW
|
||||
* is enabled) is triggered
|
||||
* @param [in] tx_fifo_high_threshold Tx FIFO threshold above which an interrupt (if
|
||||
* LR20XX_RADIO_FIFO_FLAG_THRESHOLD_HIGH is enabled) is triggered
|
||||
*
|
||||
* @returns Operation status
|
||||
*
|
||||
* @see lr20xx_radio_fifo_cfg_irq, lr20xx_radio_fifo_configure_1024_byte_tx_fifo,
|
||||
* lr20xx_radio_fifo_configure_1024_byte_rx_fifo
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_1024_byte_fifo_cfg_irq(
|
||||
const void* context, lr20xx_radio_fifo_flag_t rx_fifo_irq_enable, lr20xx_radio_fifo_flag_t tx_fifo_irq_enable,
|
||||
uint16_t rx_fifo_high_threshold, uint16_t tx_fifo_low_threshold, uint16_t rx_fifo_low_threshold,
|
||||
uint16_t tx_fifo_high_threshold );
|
||||
|
||||
/* Disable RTToF extended-mode workaround when switching back to LR20XX_RTTOF_MODE_NORMAL */
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_extended_stuck_second_request_disable( const void* context );
|
||||
|
||||
/* Persist RTToF extended-mode workaround register across sleep; slot in [0:31] */
|
||||
lr20xx_status_t lr20xx_workarounds_rttof_extended_stuck_second_request_store_retention_mem( const void* context,
|
||||
uint8_t slot );
|
||||
/**
|
||||
* @brief Store the registers to configure the 1024 bytes Tx/Rx FiFos threshold related IRQs in retention memory
|
||||
*
|
||||
* Calling this function allows to store the workaround registers for IRQ FiFo configuration with 1024-byte Tx/Rx FiFos
|
||||
* during sleep mode. This helper function internally calls @ref lr20xx_system_add_register_to_retention_mem with the
|
||||
* appropriate register address.
|
||||
*
|
||||
* @param [in] context Chip implementation context
|
||||
* @param [in] retention_slot_rx_thresholds Retention memory slot to store Rx FiFo thresholds
|
||||
* @param [in] retention_slot_tx_thresholds Retention memory slot to store Tx FiFo thresholds
|
||||
*
|
||||
* @return Operation status
|
||||
*
|
||||
* @see lr20xx_system_add_register_to_retention_mem, lr20xx_workarounds_1024_byte_fifo_cfg_irq
|
||||
*/
|
||||
lr20xx_status_t lr20xx_workarounds_1024_byte_fifo_cfg_irq_store_retention_mem( const void* context,
|
||||
uint8_t retention_slot_rx_thresholds,
|
||||
uint8_t retention_slot_tx_thresholds );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
zephyr_library()
|
||||
zephyr_library_compile_definitions(LR20XX_DISABLE_WARNINGS)
|
||||
# We run in LDO mode (not DCDC) — disable automatic DCDC workarounds
|
||||
# that the SDK injects after set_pkt_type, set_rx_path, set_modulation_params.
|
||||
# Per lr20xx_workarounds.h, these are only needed when REG_MODE_DCDC is used.
|
||||
zephyr_library_compile_definitions(LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_RESET)
|
||||
zephyr_library_compile_definitions(LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_CONFIGURE)
|
||||
# The two LR20XX_WORKAROUNDS_DISABLE_AUTOMATIC_DCDC_* defines that used to live
|
||||
# here are gone: SDK v2.0.2 deleted lr20xx_workarounds_dcdc_reset/_configure and
|
||||
# the macros that injected them after set_pkt_type / set_rx_path /
|
||||
# set_modulation_params. That workaround now lives in the Patch RAM, which this
|
||||
# driver loads on every reset. Nothing references the defines any more.
|
||||
|
||||
zephyr_library_sources(lr20xx_lora.c)
|
||||
|
||||
@@ -20,6 +20,12 @@ zephyr_library_sources(${LR20XX_SDK_DIR}/lr20xx_system.c)
|
||||
zephyr_library_sources(${LR20XX_SDK_DIR}/lr20xx_regmem.c)
|
||||
zephyr_library_sources(${LR20XX_SDK_DIR}/lr20xx_workarounds.c)
|
||||
zephyr_library_sources(${LR20XX_SDK_DIR}/lr20xx_driver_version.c)
|
||||
# Firmware Patch RAM loader (DS rev 2.1 section 22.3). The image itself lives in
|
||||
# lr20xx_pram_lr2021.h, included by lr20xx_lora.c. lr20xx_pram_load.c is
|
||||
# deliberately not vendored: it only dispatches between the LR2021 and
|
||||
# LR2012/LR2022 images, and pulling it in would drag 2 KB of LR20x2 patch data
|
||||
# into a driver that binds to semtech,lr2021 only.
|
||||
zephyr_library_sources(${LR20XX_SDK_DIR}/lr20xx_patch.c)
|
||||
|
||||
zephyr_library_include_directories(${LR20XX_SDK_DIR})
|
||||
zephyr_library_add_dependencies(offsets_h)
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
#include "lr20xx_system_types.h"
|
||||
#include "lr20xx_workarounds.h"
|
||||
#include "lr20xx_regmem.h"
|
||||
#include "lr20xx_patch.h"
|
||||
/* Defines the PRAM image itself (pram_lr2021 / pram_lr2021_size). In C these
|
||||
* are const objects at file scope and therefore have external linkage, so this
|
||||
* header must be included from exactly one translation unit — this one. */
|
||||
#include "lr20xx_pram_lr2021.h"
|
||||
|
||||
LOG_MODULE_REGISTER(lr20xx_lora, CONFIG_LORA_LOG_LEVEL);
|
||||
|
||||
@@ -384,6 +389,80 @@ static void lr20xx_get_pa_cfg_for_power(int8_t power_dbm,
|
||||
|
||||
static lr20xx_status_t lr20xx_calibrate_front_end(void *ctx, uint32_t freq_hz);
|
||||
|
||||
/* ── Firmware Patch RAM (PRAM) ──────────────────────────────────────── */
|
||||
|
||||
/* Base address the patch image is written to — DS §22.3.1, and the same value
|
||||
* lr20xx_patch.c uses internally (it does not export it). */
|
||||
#define LR20XX_PRAM_BASE_ADDRESS 0x801000
|
||||
|
||||
/* Load and activate the firmware Patch RAM.
|
||||
*
|
||||
* DS §22.3: "using the chip without the PRAM can create performance issues and
|
||||
* unexpected bugs. The use of the PRAM is therefore highly recommended", and
|
||||
* §22: "Most of the workarounds are implemented in the Firmware Patch RAM".
|
||||
* Semtech's own driver confirms the relationship — v2.0.2 added PRAM support and
|
||||
* deleted its BLE, RTToF and DC-DC workaround functions in the same release,
|
||||
* because the patch supersedes them.
|
||||
*
|
||||
* The image is volatile: lost on reset and on cold start, preserved by sleep
|
||||
* with retention (§22.3). Every sleep this driver issues sets retention
|
||||
* (lr20xx_reset_agc), and duty-cycle sleep is retention by definition (§6.3.8),
|
||||
* so the reset paths are the only places it has to be (re)loaded. Costs 2240
|
||||
* bytes of flash and +80 nA of retention sleep current.
|
||||
*
|
||||
* Best-effort: a chip without the patch still works, so a failure here is a
|
||||
* warning, not a reason to fail init. */
|
||||
static void lr20xx_load_pram(struct lr20xx_data *data)
|
||||
{
|
||||
void *ctx = &data->hal_ctx;
|
||||
lr20xx_system_version_t chip = { 0 };
|
||||
lr20xx_patch_version_t pram = { 0 };
|
||||
lr20xx_status_t rc;
|
||||
|
||||
/* DS §22.3.1: "There is one dedicated to the LR2021 and another one for
|
||||
* the LR2012/LR2022. The GetVersion(...) API indicates which PRAM is
|
||||
* needed." Per DS Table 6-40 the LR2021 answers 0x01/0x18; the other two
|
||||
* answer 0x02/0x00 and want lr20xx_pram_lr20x2.h, which is not vendored
|
||||
* because this driver only binds to semtech,lr2021. Read the version
|
||||
* here rather than taking it from the caller so both reset paths get the
|
||||
* same check. */
|
||||
if (lr20xx_system_get_version(ctx, &chip) != LR20XX_STATUS_OK) {
|
||||
LOG_WRN("PRAM: get_version failed — skipping patch load");
|
||||
return;
|
||||
}
|
||||
if (chip.major != 0x01 || chip.minor != 0x18) {
|
||||
LOG_WRN("PRAM: chip reports FW %u.%u, not the LR2021's 1.24 — "
|
||||
"no matching patch image vendored, skipping",
|
||||
chip.major, chip.minor);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = lr20xx_patch_load_pram(ctx, LR20XX_PRAM_BASE_ADDRESS, pram_lr2021,
|
||||
pram_lr2021_size);
|
||||
if (rc != LR20XX_STATUS_OK) {
|
||||
LOG_ERR("PRAM: load failed (rc=%d) — running unpatched", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = lr20xx_patch_enable_pram(ctx);
|
||||
if (rc != LR20XX_STATUS_OK) {
|
||||
LOG_ERR("PRAM: enable failed (rc=%d) — running unpatched", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reads back the magic word at 0x800FF8 (DS §22.3.2) — the only proof
|
||||
* the chip actually took the patch, so it is worth the two extra reads
|
||||
* on a path that runs once per reset. */
|
||||
if (lr20xx_patch_get_version(ctx, &pram) != LR20XX_STATUS_OK ||
|
||||
!pram.is_pram_loaded) {
|
||||
LOG_ERR("PRAM: magic word absent after load — running unpatched");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INF("PRAM loaded: type=0x%02x version=0x%02x (%u words)",
|
||||
pram.pram_type, pram.pram_version, pram_lr2021_size);
|
||||
}
|
||||
|
||||
/* ── Hardware reset (BUSY stuck recovery) ───────────────────────────── */
|
||||
|
||||
static void lr20xx_hardware_reset(struct lr20xx_data *data,
|
||||
@@ -395,7 +474,15 @@ static void lr20xx_hardware_reset(struct lr20xx_data *data,
|
||||
|
||||
lr20xx_hal_reset(ctx);
|
||||
|
||||
/* SIMO workaround skipped — LDO mode (see DS §22.6) */
|
||||
/* The reset wiped the patch — DS §22.3: "The PRAM is lost after a reset
|
||||
* or a cold start", and §22.3.1 requires it be reloaded "after a reset,
|
||||
* as part of the reset sequence". */
|
||||
lr20xx_load_pram(data);
|
||||
|
||||
/* SIMO workaround skipped — LDO mode. (The citation here used to be
|
||||
* "DS §22.6"; rev 2.1 has no such section — §22 ends at 22.3. The
|
||||
* conclusion still holds via Table 6-26: simo_usage 0x00 SIMO_OFF is the
|
||||
* reset default and we never issue SetRegMode.) */
|
||||
|
||||
if (cfg->tcxo_voltage_mv > 0) {
|
||||
/* Timeout in RTC ticks (30.52 µs/tick) */
|
||||
@@ -1992,6 +2079,13 @@ static int lr20xx_hw_init(struct lr20xx_data *data,
|
||||
ver.major, ver.minor);
|
||||
}
|
||||
|
||||
/* Patch the firmware before anything is configured or calibrated — DS
|
||||
* §22.3.1: load "after a reset, as part of the reset sequence". The
|
||||
* TCXO→XTAL fallback below re-enters this function, which resets the chip
|
||||
* again and so reaches this point again; that is required, since the
|
||||
* reset drops the patch. */
|
||||
lr20xx_load_pram(data);
|
||||
|
||||
DUMP_CHIP_STATE(data, "post-reset");
|
||||
|
||||
/* SIMO DC-DC workaround REMOVED — datasheet §22.6 says it's only
|
||||
|
||||
Reference in New Issue
Block a user