/*!
 * \file      lr1110_radio.h
 *
 * \brief     Radio driver definition for LR1110
 *
 * Revised BSD License
 * Copyright Semtech Corporation 2020. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted 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.
 *
 * 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 S.A. 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 __LR1110_RADIO_H__
#define __LR1110_RADIO_H__

/*
 * -----------------------------------------------------------------------------
 * --- DEPENDENCIES ------------------------------------------------------------
 */

#include "lr1110_radio_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * -----------------------------------------------------------------------------
 * --- PUBLIC MACROS -----------------------------------------------------------
 */

/*
 * -----------------------------------------------------------------------------
 * --- PUBLIC CONSTANTS --------------------------------------------------------
 */

/*
 * -----------------------------------------------------------------------------
 * --- PUBLIC TYPES ------------------------------------------------------------
 */

/*
 * -----------------------------------------------------------------------------
 * --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
 */

/*!
 * \brief Reset internal statistics of the received packets
 *
 * \see lr1110_radio_get_stats_gfsk, lr1110_radio_get_stats_lora
 */
void lr1110_radio_reset_stats( const void* radio );

/*!
 * \brief Get the internal statistics of the GFSK received packets
 *
 * Internal statistics are reset on Power on Reset, by entering sleep mode
 * without memory retention, or by calling \ref lr1110_radio_reset_stats.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [out] radio_stats The statistics structure of the received packets
 *
 * \see lr1110_radio_reset_stats
 */
void lr1110_radio_get_stats_gfsk( const void* radio, lr1110_radio_stats_gfsk_t* radio_stats );

/*!
 * \brief Get the internal statistics of the LoRa received packets
 *
 * Internal statistics are reset on Power on Reset, by entering sleep mode
 * without memory retention, or by calling \ref lr1110_radio_reset_stats.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [out] radio_stats The statistics structure of the received packets
 *
 * \see lr1110_radio_reset_stats
 */
void lr1110_radio_get_stats_lora( const void* radio, lr1110_radio_stats_lora_t* radio_stats );

/*!
 * \brief Get the packet type currently configured
 *
 * \param [in] radio Radio abstraction
 *
 * \param [out] packetType The packet type currently configured
 *
 * \see lr1110_radio_set_packet_type
 */
void lr1110_radio_get_packet_type( const void* radio, lr1110_radio_packet_types_t* packet_type );

/*!
 * \brief Get the length of last received packet, and the offset in the RX
 * internal buffer of the first byte of the received payload
 *
 * \param [out] rxBufferStatus The structure of RX buffer status
 */
void lr1110_radio_get_rxbuffer_status( const void* radio, lr1110_radio_rxbuffer_status_t* rxbuffer_status );

/*!
 * \brief Get the status of last GFSK received packet
 *
 * The value depends on the received packet type
 *
 * \param [in] radio Radio abstraction
 *
 * \param[out] packetStatus The last received packet status
 */
void lr1110_radio_get_packet_status_gfsk( const void* radio, lr1110_radio_packet_status_gfsk_t* packet_status );

/*!
 * \brief Get the status of last LoRa received packet
 *
 * The value depends on the received packet type
 *
 * \param [in] radio Radio abstraction
 *
 * \param[out] packetStatus The last received packet status
 */
void lr1110_radio_get_packet_status_lora( const void* radio, lr1110_radio_packet_status_lora_t* packet_status );

/*!
 * \brief Get the instantaneous RSSI.
 *
 * This command can be used during reception of a packet
 *
 * \param [in] radio Radio abstraction
 *
 * \param [out] rssi Instantaneous RSSI.
 */
void lr1110_radio_get_rssi_inst( const void* radio, int8_t* rssi_in_dbm );

/*!
 * \brief Set the GFSK modem sync word
 *
 * This command is used to set the GFSK nodem sync word. By default, the value
 * is 0x9723522556536564
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] gfsk_sync_word The sync word to be configured
 */
void lr1110_radio_set_gfsk_sync_word( const void* radio, const uint8_t* gfsk_sync_word );

/*!
 * \brief Set the LoRa modem sync word to private / public
 *
 * This command is used to select which LoRa network is selected
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] network_type The network type to be configured
 */
void lr1110_radio_set_lora_sync_word( const void* radio, const lr1110_radio_lora_network_type_t network_type );

/*!
 * \brief Start RX operations
 *
 * This command sets the LR1110 to RX mode. The radio must have been
 * configured before using this command with \ref lr1110_radio_set_packet_type
 *
 * By default, the timeout parameter allows to return automatically to standby
 * RC mode if no packets have been received after a certain amount of time.
 * This behavior can be altered by \ref lr1110_radio_set_rx_tx_fallback_mode and
 * \ref AutoTxRx.
 *
 * The timeout duration is obtained by:
 * \f$ timeout\_duration\_ms = timeout \times \frac{1}{32.768} \f$
 *
 * Maximal timeout value is 0xFFFFFF, which gives a maximal timeout of 511
 * seconds.
 *
 * The timeout argument can also have the following special values:
 * <table>
 * <tr><th> Special values </th><th> Meaning </th>
 * <tr><td> 0x000000 </td><td> RX single: LR1110 stays in RX mode until a
 * packet is received, then switch to standby RC mode <tr><td> 0xFFFFFF
 * </td><td> RX continuous: LR1110 stays in RX mode even after reception of a
 * packet
 * </table>
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] timeout The timeout configuration for RX operation
 *
 * \see lr1110_radio_set_packet_type, lr1110_radio_set_rx_tx_fallback_mode
 */
void lr1110_radio_set_rx( const void* radio, const uint32_t timeout );

/*!
 * \brief Start TX operations
 *
 * This command sets the LR1110 to TX mode. The radio must have been
 * configured before using this command with \ref lr1110_radio_set_packet_type
 *
 * By default, the timeout parameter allows to return automatically to standby
 * RC mode if the packet has not been completely transmitted after a certain
 * amount of time.
 * This behavior can be altered by \ref lr1110_radio_set_rx_tx_fallback_mode and
 * \ref AutoTxRx.
 *
 * The timeout duration is obtained by:
 * \f$ timeout\_duration\_ms = timeout \times \frac{1}{32.768} \f$
 *
 * Maximal value is 0xFFFFFF.
 *
 * If the timeout argument is 0, then no timeout is used.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] timeout The timeout configuration for TX operation
 *
 * \see lr1110_radio_set_packet_type, lr1110_radio_set_rx_tx_fallback_mode
 */
void lr1110_radio_set_tx( const void* radio, const uint32_t timeout );

/*!
 * \brief Set the frequency for future radio operations.
 *
 * This commands does not set frequency for Wi-Fi and GNSS scan operations.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] frequency The frequency in Hz to set for radio operations
 */
void lr1110_radio_set_rf_frequency( const void* radio, const uint32_t frequency );

/*!
 * \brief Configure automatic TX after RX or automatic RX after TX
 *
 * After issuing this command, using the command \ref SetTx will make the
 * LR1110 doing the following:
 *   - Enter TX mode as usual
 *   - Enter configurable Intermediary mode during configurable delay
 *   - Enter RX mode
 *
 * Similarly, after a \ref SetRx command, the LR1110 will do the following:
 *   - Enter RX mode as usual
 *   - Enter configurable Intermediary mode during configurable delay
 *   - Enter TX mode
 *
 * In case delay is 0, the LR1110 does not enter Intermediary mode and
 * directly enter the following mode.
 *
 * To disable this behavior, use this method with delay 0xFFFFFFFF.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] delay Time to spend in Intermediary mode expressed as steps of
 * \f$\frac{1}{32.768 KHz}\f$ steps. Value 0xFFFFFF disable \ref AutoTxRx
 *
 * \param [in] intermediaryMode The mode the LR1110 enters after first mode
 * completion during delay time
 *
 * \param [in] timeout The timeout duration of the automatic RX or TX,
 * expressed as steps of \f$ \frac{1}{32.768KHz} \f$
 */
void lr1110_radio_auto_tx_rx( const void* radio, const uint32_t delay,
                              const lr1110_radio_intermediary_mode_t intermediary_mode, const uint32_t timeout );

/*!
 * \brief Set Channel Activity Detection configuration
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] cad_params The structure defining CAD configuration
 */
void lr1110_radio_set_cad_params( const void* radio, const lr1110_radio_cad_params_t* cad_params );

/*!
 * \brief Set the packet type
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] packet_type Packet type to set
 *
 * \see lr1110_radio_get_packet_type
 */
void lr1110_radio_set_packet_type( const void* radio, const lr1110_radio_packet_types_t packet_type );

/*!
 * \brief Set the modulation parameters for GFSK packets
 *
 * The command \ref lr1110_radio_set_packet_type must be called prior this one.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] modulation_params The structure of modulation configuration
 *
 * \see lr1110_radio_set_packet_type
 */
void lr1110_radio_set_modulation_param_gfsk( const void*                                 radio,
                                             const lr1110_radio_modulation_param_gfsk_t* modulation_params );

/*!
 * \brief Set the modulation parameters for LoRa packets
 *
 * The command \ref lr1110_radio_set_packet_type must be called prior this one.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] modulation_params The structure of modulation configuration
 *
 * \see lr1110_radio_set_packet_type
 */
void lr1110_radio_set_modulation_param_lora( const void*                                 radio,
                                             const lr1110_radio_modulation_param_lora_t* modulation_params );

/*!
 * \brief Set the packet parameters for GFSK packets
 *
 * The command \ref lr1110_radio_set_packet_type must be called prior this one.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] packet_params The structure of packet configuration
 *
 * \see lr1110_radio_set_packet_type, lr1110_radio_set_modulation_param_gfsk
 */
void lr1110_radio_set_packet_param_gfsk( const void* radio, const lr1110_radio_packet_param_gfsk_t* packet_params );

/*!
 * \brief Set the packet parameters for LoRa packets
 *
 * The command \ref lr1110_radio_set_packet_type must be called prior this one.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] packetParam The structure of packet configuration
 *
 * \see lr1110_radio_set_packet_type, lr1110_radio_set_modulation_param_lora
 */
void lr1110_radio_set_packet_param_lora( const void* radio, const lr1110_radio_packet_param_lora_t* packet_params );

/*!
 * \brief Set the parameters for TX power and power amplifier ramp time
 *
 * The command \ref lr1110_radio_set_pa_config must be called prior calling
 * lr1110_radio_set_tx_params.
 *
 * The range of possible TX output power values depends on PA selected with
 * \ref lr1110_radio_set_pa_config :
 *   - for LPA: power value goes from -17dBm to +14dBm (ie. from 0xEF to
 * 0x0E)
 *   - for HPA: power value goes from -9dBm to +22dBm (ie. from 0xF7 to
 * 0x16)
 *
 * Moreover, to use TX output power value higher than +10dBm, the
 * \ref REGPASUPPLY_VBAT supply must have been selected with \ref
 * lr1110_radio_set_pa_config.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] power The TX output power in dBm
 *
 * \param [in] rampTime The ramping time configuration for the PA
 */
void lr1110_radio_set_tx_params( const void* radio, const int8_t power, const lr1110_radio_ramp_time_t ramp_time );

/*!
 * \brief Sets the Node and Broadcast address used for GFSK
 *
 * This setting is used only when filtering is enabled.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] nodeAddress The address used as filter
 *
 * \param [in] broadcastAddress The address used as filter
 */
void lr1110_radio_set_packet_address( const void* radio, const uint8_t node_address, const uint8_t broadcast_address );

/*!
 * \brief Alter the chip mode after successfull transmission or reception
 * operation
 *
 * This setting is not used during Rx Duty Cycle mode or Auto Tx Rx.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] fallback_mode The chip mode to enter after transmission or
 * reception.
 *
 * \TODO: Is it only for successfull Tx/Rx (CER-641)
 */
void lr1110_radio_set_rx_tx_fallback_mode( const void* radio, const lr1110_radio_rx_tx_fallback_mode_t fallback_mode );

/*!
 * \brief Configure and start a Rx Duty Cycle operation
 *
 * It executes the following steps:
 *     1. Reception: enters reception state for duration defined by rx_period
 *         - If mode is LR1110_RADIO_RX_DUTY_CYCLE_MODE_RX: it is standard RX mode
 *         - If mode is LR1110_RADIO_RX_DUTY_CYCLE_MODE_CAD (only in LoRa) : it is CAD operation
 *     2. Depending on the over-the-air activity detection:
 *         - In case of positive over-the-air detection, the rx_period timeout is recomputed to the value
 *           \f$2 \times rx\_period + sleep\_period\f$
 *         - If no air activity is detected, the LR1110 goes back to sleep mode with retention for a duration defined by
 * sleep_period
 *     3. On wake-up, the LR1110 restarts the process with the reception state.
 *
 * \note If mode is configured to \ref LR1110_RADIO_RX_DUTY_CYCLE_MODE_CAD, then the CAD configuration used in step 1. is the
 * one set from the last call to \ref lr1110_radio_set_cad_params.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] rx_period The length of Rx period
 *
 * \param [in] sleep_period The length of sleep period
 *
 * \param [in] mode The operation mode during Rx phase
 *
 * \see lr1110_radio_set_cad_params
 */
void lr1110_radio_set_rx_dutycycle( const void* radio, const uint32_t rx_period, const uint32_t sleep_period,
                                    const lr1110_radio_rx_duty_cycle_mode_t mode );

/*!
 * \brief Set the Power Amplifier configuration
 *
 * It must be called prior using \ref lr1110_radio_set_tx_params.
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] pa_config The structure for PA configuration
 */
void lr1110_radio_set_pa_config( const void* radio, const lr1110_radio_pa_config_t* pa_config );

/*!
 * \brief Define on which event the Rx timeout shall be stopped
 *
 * The two options are:
 *   - Syncword / Header detection
 *   - Preamble detection
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] stop_timeout_on_preamble The choice of the event to be taken into
 * account
 */
void lr1110_radio_stop_timeout_on_preamble( const void* radio, const bool stop_timeout_on_preamble );

/*!
 * \brief Start the CAD mode
 *
 * The LoRa packet type shall be selected before this function is called. The
 * fallback mode is configured with lr1110_radio_set_cad_params.
 *
 * \param [in] radio Radio abstraction
 *
 * \see lr1110_radio_set_cad_params, lr1110_radio_set_packet_type
 */
void lr1110_radio_set_cad( const void* radio );

/*!
 * \brief Set the device into Tx continuous wave (RF tone).
 *
 * A packet type shall be selected before this function is called.
 *
 * \param [in] radio Radio abstraction
 *
 * \see lr1110_radio_set_packet_type
 */
void lr1110_radio_set_tx_cw( const void* radio );

/*!
 * \brief Set the device into Tx continuous preamble (modulated signal).
 *
 * \param [in] radio Radio abstraction
 */
void lr1110_radio_set_tx_infinite_preamble( const void* radio );

/*!
 * \brief Configure the LoRa modem to issue a RX timeout after an exact number
 * of symbols given in parameter if no LoRa modulation is detected
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] nb_symbol number of symbols to compute the timeout
 */
void lr1110_radio_set_lora_sync_timeout( const void* radio, const uint8_t nb_symbol );

/*!
 * \brief Configure the seed and the polynomial used to compute CRC in GFSK
 * packet
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] seed Seed used to compute the CRC value
 *
 * \param [in] polynomial Polynomial used to compute the CRC value
 */
void lr1110_radio_set_gfsk_crc_params( const void* radio, const uint32_t seed, const uint32_t polynomial );

/*!
 * \brief Configure the whitening seed used in GFSK packet
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] whitening Whitening value
 */
void lr1110_radio_set_gfsk_whitening_params( const void* radio, const uint16_t whitening );

/*!
 * \brief Configure the boost mode in reception
 *
 * \param [in] radio Radio abstraction
 *
 * \param [in] enable_boost_mode Boost mode activation
 */
void lr1110_radio_set_rx_boosted( const void* radio, const bool enable_boost_mode );

/*!
 * \brief Gets the radio bandwidth parameter related to a given bandwith in Hz
 *
 * \param [in] bw_in_hz Requested GFSK Rx bandwidth
 *
 * \param [out] bw_parameter Radio parameter immediately above requested
 * bw_in_hz
 */
void lr1110_radio_get_gfsk_rx_bandwidth( uint32_t bw_in_hz, lr1110_radio_gfsk_rx_bw_t* bw_parameter );

#ifdef __cplusplus
}
#endif

#endif  // __LR1110_RADIO_H__

/* --- EOF ------------------------------------------------------------------ */
