diff --git a/src/apps/ping-pong/B-L072Z-LRWAN1/main.c b/src/apps/ping-pong/B-L072Z-LRWAN1/main.c index 4ef59bb11..a007c210d 100644 --- a/src/apps/ping-pong/B-L072Z-LRWAN1/main.c +++ b/src/apps/ping-pong/B-L072Z-LRWAN1/main.c @@ -31,350 +31,543 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include +#include #include "board.h" -#include "gpio.h" #include "delay.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 470000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_CN779 ) +#if defined( USE_MODEM_LORA ) -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 + +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on + +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; + +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Application context + */ +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; -States_t State = LOWPOWER; +/*! + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ /*! - * Radio events function pointer + * \brief Tx done interrupt callback */ -static RadioEvents_t RadioEvents; +static void irq_tx_done( void ); /*! - * LED GPIO pins objects + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters */ -extern Gpio_t Led1; -extern Gpio_t Led2; +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Rx error interrupt callback */ -void OnTxDone( void ); +static void irq_rx_error( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioWrite( &Led1, GpioRead( &Led1 ) ^ 1 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - GpioWrite( &Led2, 1 ); // Set LED off - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioWrite( &Led1, GpioRead( &Led1 ) ^ 1 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - GpioWrite( &Led2, GpioRead( &Led2 ) ^ 1 ); - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/ping-pong/NAMote72/main.c b/src/apps/ping-pong/NAMote72/main.c index 49e36d7ab..a007c210d 100644 --- a/src/apps/ping-pong/NAMote72/main.c +++ b/src/apps/ping-pong/NAMote72/main.c @@ -31,343 +31,543 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include -#include "board-config.h" +#include #include "board.h" -#include "gpio.h" #include "delay.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_US915 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_RU864 ) +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#define RF_FREQUENCY 864000000 // Hz +#elif defined( USE_MODEM_FSK ) -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 + +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false + +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true + +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 + +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on + +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; + +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Application context + */ +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; -States_t State = LOWPOWER; +/*! + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ /*! - * Radio events function pointer + * \brief Tx done interrupt callback */ -static RadioEvents_t RadioEvents; +static void irq_tx_done( void ); /*! - * LED GPIO pins objects + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters */ -extern Gpio_t Led1; -extern Gpio_t Led2; +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Rx error interrupt callback */ -void OnTxDone( void ); +static void irq_rx_error( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioWrite( &Led1, GpioRead( &Led1 ) ^ 1 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - GpioWrite( &Led2, 1 ); // Set LED off - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioWrite( &Led1, GpioRead( &Led1 ) ^ 1 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - GpioWrite( &Led2, GpioRead( &Led2 ) ^ 1 ); - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/ping-pong/NucleoL073/main.c b/src/apps/ping-pong/NucleoL073/main.c index 1b3dd48a4..a007c210d 100644 --- a/src/apps/ping-pong/NucleoL073/main.c +++ b/src/apps/ping-pong/NucleoL073/main.c @@ -31,354 +31,543 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include +#include #include "board.h" -#include "gpio.h" #include "delay.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 470000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_CN779 ) +#if defined( USE_MODEM_LORA ) -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -States_t State = LOWPOWER; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; /*! - * Radio events function pointer + * \brief Application context */ -static RadioEvents_t RadioEvents; +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; -extern Gpio_t Led2; /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Tx done interrupt callback */ -void OnTxDone( void ); +static void irq_tx_done( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/*! + * \brief Rx error interrupt callback + */ +static void irq_rx_error( void ); + +/*! + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.Init( &RadioEvents ); - - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioToggle( &Led1 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - GpioToggle( &Led2 ); // Set LED off - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioToggle( &Led1 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - GpioToggle( &Led2 ); - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ + +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/ping-pong/NucleoL152/main.c b/src/apps/ping-pong/NucleoL152/main.c index 1b3dd48a4..a007c210d 100644 --- a/src/apps/ping-pong/NucleoL152/main.c +++ b/src/apps/ping-pong/NucleoL152/main.c @@ -31,354 +31,543 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include +#include #include "board.h" -#include "gpio.h" #include "delay.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 470000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_CN779 ) +#if defined( USE_MODEM_LORA ) -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -States_t State = LOWPOWER; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; /*! - * Radio events function pointer + * \brief Application context */ -static RadioEvents_t RadioEvents; +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; -extern Gpio_t Led2; /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Tx done interrupt callback */ -void OnTxDone( void ); +static void irq_tx_done( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/*! + * \brief Rx error interrupt callback + */ +static void irq_rx_error( void ); + +/*! + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.Init( &RadioEvents ); - - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioToggle( &Led1 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - GpioToggle( &Led2 ); // Set LED off - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioToggle( &Led1 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - GpioToggle( &Led2 ); - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ + +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/ping-pong/NucleoL476/main.c b/src/apps/ping-pong/NucleoL476/main.c index 1b3dd48a4..a007c210d 100644 --- a/src/apps/ping-pong/NucleoL476/main.c +++ b/src/apps/ping-pong/NucleoL476/main.c @@ -31,354 +31,543 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include +#include #include "board.h" -#include "gpio.h" #include "delay.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 470000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_CN779 ) +#if defined( USE_MODEM_LORA ) -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -States_t State = LOWPOWER; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; /*! - * Radio events function pointer + * \brief Application context */ -static RadioEvents_t RadioEvents; +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; -extern Gpio_t Led2; /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Tx done interrupt callback */ -void OnTxDone( void ); +static void irq_tx_done( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/*! + * \brief Rx error interrupt callback + */ +static void irq_rx_error( void ); + +/*! + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.Init( &RadioEvents ); - - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioToggle( &Led1 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - GpioToggle( &Led2 ); // Set LED off - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioToggle( &Led1 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - GpioToggle( &Led2 ); - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ + +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/ping-pong/SAMR34/main.c b/src/apps/ping-pong/SAMR34/main.c index 4cbb607cf..1336bed2a 100644 --- a/src/apps/ping-pong/SAMR34/main.c +++ b/src/apps/ping-pong/SAMR34/main.c @@ -31,350 +31,547 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include +#include #include "board.h" -#include "gpio.h" #include "delay.h" #include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 470000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_CN779 ) +#if defined( USE_MODEM_LORA ) -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 + +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on + +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; + +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Application context + */ +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; -States_t State = LOWPOWER; +/*! + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ /*! - * Radio events function pointer + * \brief Tx done interrupt callback */ -static RadioEvents_t RadioEvents; +static void irq_tx_done( void ); /*! - * LED GPIO pins objects + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters */ -extern Gpio_t Led1; +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Rx error interrupt callback */ -void OnTxDone( void ); +static void irq_rx_error( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { // Tick the RTC to execute callback in context of the main loop (in stead of the IRQ) TimerProcess( ); - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioWrite( &Led1, GpioRead( &Led1 ) ^ 1 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioWrite( &Led1, GpioRead( &Led1 ) ^ 1 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/ping-pong/SKiM880B/main.c b/src/apps/ping-pong/SKiM880B/main.c index f9b04058a..a007c210d 100644 --- a/src/apps/ping-pong/SKiM880B/main.c +++ b/src/apps/ping-pong/SKiM880B/main.c @@ -31,342 +31,543 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include +#include #include "board.h" -#include "gpio.h" #include "delay.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_US915 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_RU864 ) +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#define RF_FREQUENCY 864000000 // Hz +#elif defined( USE_MODEM_FSK ) -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 + +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false + +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true + +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 + +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on + +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; + +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Application context + */ +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; -States_t State = LOWPOWER; +/*! + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ /*! - * Radio events function pointer + * \brief Tx done interrupt callback */ -static RadioEvents_t RadioEvents; +static void irq_tx_done( void ); /*! - * LED GPIO pins objects + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters */ -extern Gpio_t Led3; -extern Gpio_t Led4; +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Rx error interrupt callback */ -void OnTxDone( void ); +static void irq_rx_error( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioToggle( &Led4 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - GpioToggle( &Led3 ); // Set LED off - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioToggle( &Led4 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - GpioToggle( &Led3 ); - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/ping-pong/SKiM881AXL/main.c b/src/apps/ping-pong/SKiM881AXL/main.c index f9b04058a..a007c210d 100644 --- a/src/apps/ping-pong/SKiM881AXL/main.c +++ b/src/apps/ping-pong/SKiM881AXL/main.c @@ -31,342 +31,543 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include +#include #include "board.h" -#include "gpio.h" #include "delay.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_US915 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_RU864 ) +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#define RF_FREQUENCY 864000000 // Hz +#elif defined( USE_MODEM_FSK ) -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 + +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false + +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true + +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 + +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on + +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; + +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Application context + */ +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; -States_t State = LOWPOWER; +/*! + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ /*! - * Radio events function pointer + * \brief Tx done interrupt callback */ -static RadioEvents_t RadioEvents; +static void irq_tx_done( void ); /*! - * LED GPIO pins objects + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters */ -extern Gpio_t Led3; -extern Gpio_t Led4; +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Rx error interrupt callback */ -void OnTxDone( void ); +static void irq_rx_error( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioToggle( &Led4 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - GpioToggle( &Led3 ); // Set LED off - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioToggle( &Led4 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - GpioToggle( &Led3 ); - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/ping-pong/SKiM980A/main.c b/src/apps/ping-pong/SKiM980A/main.c index f9b04058a..a007c210d 100644 --- a/src/apps/ping-pong/SKiM980A/main.c +++ b/src/apps/ping-pong/SKiM980A/main.c @@ -31,342 +31,543 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include +#include #include "board.h" -#include "gpio.h" #include "delay.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/*! + * \brief Application states definition + */ +typedef enum app_states_e +{ + APP_STATE_LOW_POWER, + APP_STATE_RX, + APP_STATE_RX_TIMEOUT, + APP_STATE_RX_ERROR, + APP_STATE_TX, + APP_STATE_TX_TIMEOUT, +} app_states_t; -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief Application context definition + */ +typedef struct app_context_s +{ + app_states_t state; + bool is_master; + uint16_t buffer_size_in_bytes; + uint8_t* buffer; +} app_context_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +/*! + * \brief RF frequency + */ +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF7 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_US915 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_RU864 ) +/*! + * \brief LoRa tx timeout + */ +#define LORA_TX_TIMEOUT_IN_MS 4000 -#define RF_FREQUENCY 864000000 // Hz +#elif defined( USE_MODEM_FSK ) -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#define TX_OUTPUT_POWER 14 // dBm +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 + +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false + +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true + +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_FDEV 25000 // Hz -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -typedef enum -{ - LOWPOWER, - RX, - RX_TIMEOUT, - RX_ERROR, - TX, - TX_TIMEOUT, -}States_t; +/*! + * \brief Maximum application data buffer size + * + * \remark Please do not change this value + */ +#define PING_PONG_APP_DATA_MAX_SIZE 255 + +/*! + * \brief Application payload length + * + * \remark Please change this value in order to test different payload lengths + */ +#define APP_PLD_LEN_IN_BYTES 64 +// clang-format on + +/*! + * \brief Ping message string + */ +const uint8_t app_ping_msg[] = "PING"; + +/*! + * \brief Pong message string + */ +const uint8_t app_pong_msg[] = "PONG"; -#define RX_TIMEOUT_VALUE 1000 -#define BUFFER_SIZE 64 // Define the payload size here +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ -const uint8_t PingMsg[] = "PING"; -const uint8_t PongMsg[] = "PONG"; +/*! + * \brief Application data buffer + */ +static uint8_t app_data_buffer[PING_PONG_APP_DATA_MAX_SIZE]; -uint16_t BufferSize = BUFFER_SIZE; -uint8_t Buffer[BUFFER_SIZE]; +/*! + * \brief Application context + */ +static app_context_t app_context = { + .state = APP_STATE_LOW_POWER, + .is_master = true, + .buffer_size_in_bytes = APP_PLD_LEN_IN_BYTES, + .buffer = app_data_buffer, +}; -States_t State = LOWPOWER; +/*! + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; -int8_t RssiValue = 0; -int8_t SnrValue = 0; +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ /*! - * Radio events function pointer + * \brief Tx done interrupt callback */ -static RadioEvents_t RadioEvents; +static void irq_tx_done( void ); /*! - * LED GPIO pins objects + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters */ -extern Gpio_t Led3; -extern Gpio_t Led4; +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); /*! - * \brief Function to be executed on Radio Tx Done event + * \brief Rx error interrupt callback */ -void OnTxDone( void ); +static void irq_rx_error( void ); /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Tx timeout interrupt callback */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +static void irq_tx_timeout( void ); /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Rx timeout interrupt callback */ -void OnTxTimeout( void ); +static void irq_rx_timeout( void ); /*! - * \brief Function executed on Radio Rx Timeout event + * \brief Print the provided buffer in HEX + * + * \param [in] buffer Buffer to be printed + * \param [in] size Buffer size to be printed */ -void OnRxTimeout( void ); +static void print_hex_buffer( uint8_t* buffer, uint8_t size ); /*! - * \brief Function executed on Radio Rx Error event + * \brief Build message to be transmitted + * + * \param [in] is_ping_msg Indicate if it is a PING or PONG message + * \param [out] buffer Buffer to be filled + * \param [in] size_in_bytes Buffer size to be filled */ -void OnRxError( void ); +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ); -/** - * Main application entry point. +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/*! + * \brief Main application entry point. */ int main( void ) { - bool isMaster = true; - uint8_t i; - // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization - RadioEvents.TxDone = OnTxDone; - RadioEvents.RxDone = OnRxDone; - RadioEvents.TxTimeout = OnTxTimeout; - RadioEvents.RxTimeout = OnRxTimeout; - RadioEvents.RxError = OnRxError; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_done = irq_tx_done; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; + radio_irq_callbacks.loramac_radio_irq_rx_error = irq_rx_error; + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + radio_irq_callbacks.loramac_radio_irq_rx_timeout = irq_rx_timeout; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, - LORA_SPREADING_FACTOR, LORA_CODINGRATE, - LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, BUFFER_SIZE ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = LORA_TX_TIMEOUT_IN_MS, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, - FSK_DATARATE, 0, - FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, - true, 0, 0, 0, 3000 ); - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0,false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, BUFFER_SIZE ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = APP_PLD_LEN_IN_BYTES, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + .tx_timeout_in_ms = GFSK_TX_TIMEOUT_IN_MS, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { - switch( State ) + switch( app_context.state ) { - case RX: - if( isMaster == true ) + case APP_STATE_RX: + if( app_context.is_master == true ) { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_pong_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PONG - GpioToggle( &Led4 ); - + printf( "[APP] pong message received\n" ); // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) - { // A master already exists then become a slave - isMaster = false; - GpioToggle( &Led3 ); // Set LED off - Radio.Rx( RX_TIMEOUT_VALUE ); + else if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) + { // A master already exists then become a slave + app_context.is_master = false; + printf( "[APP] ping-pong slave mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - else // valid reception but neither a PING or a PONG message - { // Set device as master ans start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but neither a PING or a PONG message + { // Set device as master ans start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } else { - if( BufferSize > 0 ) + if( app_context.buffer_size_in_bytes > 0 ) { - if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) + if( strncmp( ( const char* ) app_context.buffer, ( const char* ) app_ping_msg, 4 ) == 0 ) { - // Indicates on a LED that the received frame is a PING - GpioToggle( &Led4 ); - + printf( "[APP] ping message received\n" ); // Send the reply to the PONG string - Buffer[0] = 'P'; - Buffer[1] = 'O'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - // We fill the buffer with numbers for the payload - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( false, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] pong message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } - else // valid reception but not a PING as expected - { // Set device as master and start again - isMaster = true; - Radio.Rx( RX_TIMEOUT_VALUE ); + else // valid reception but not a PING as expected + { // Set device as master and start again + app_context.is_master = true; + printf( "[APP] ping-pong master mode\n" ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } } } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX: - // Indicates on a LED that we have sent a PING [Master] - // Indicates on a LED that we have sent a PONG [Slave] - GpioToggle( &Led3 ); - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + if( app_context.is_master == true ) + { + printf( "[APP] ping message transmitted\n" ); + } + else + { + printf( "[APP] pong message transmitted\n" ); + } + app_context.state = APP_STATE_LOW_POWER; break; - case RX_TIMEOUT: - case RX_ERROR: - if( isMaster == true ) + case APP_STATE_RX_TIMEOUT: + case APP_STATE_RX_ERROR: + if( app_context.is_master == true ) { // Send the next PING frame - Buffer[0] = 'P'; - Buffer[1] = 'I'; - Buffer[2] = 'N'; - Buffer[3] = 'G'; - for( i = 4; i < BufferSize; i++ ) - { - Buffer[i] = i - 4; - } + app_build_message( true, app_context.buffer, app_context.buffer_size_in_bytes ); DelayMs( 1 ); - Radio.Send( Buffer, BufferSize ); + printf( "[APP] ping message transmission\n" ); + loramac_radio_transmit( app_context.buffer, app_context.buffer_size_in_bytes ); } else { - Radio.Rx( RX_TIMEOUT_VALUE ); + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); } - State = LOWPOWER; + app_context.state = APP_STATE_LOW_POWER; break; - case TX_TIMEOUT: - Radio.Rx( RX_TIMEOUT_VALUE ); - State = LOWPOWER; + case APP_STATE_TX_TIMEOUT: + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); + app_context.state = APP_STATE_LOW_POWER; break; - case LOWPOWER: + case APP_STATE_LOW_POWER: default: // Set low power break; } - BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ +static void irq_tx_done( void ) +{ + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX; +} + +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) +{ + loramac_radio_set_sleep( ); + + memcpy( app_context.buffer, params->buffer, params->size_in_bytes ); + + app_context.buffer_size_in_bytes = params->size_in_bytes; + +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif + if( app_context.buffer[1] == 'I' ) + { + printf( "P I N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else if( app_context.buffer[1] == 'O' ) + { + printf( "P O N G " ); + print_hex_buffer( app_context.buffer + 4, params->size_in_bytes ); + } + else + { + print_hex_buffer( app_context.buffer, params->size_in_bytes ); } + app_context.state = APP_STATE_RX; } -void OnTxDone( void ) +static void irq_rx_error( void ) { - Radio.Sleep( ); - State = TX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_ERROR; } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_tx_timeout( void ) { - Radio.Sleep( ); - BufferSize = size; - memcpy( Buffer, payload, BufferSize ); - RssiValue = rssi; - SnrValue = snr; - State = RX; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_TX_TIMEOUT; } -void OnTxTimeout( void ) +static void irq_rx_timeout( void ) { - Radio.Sleep( ); - State = TX_TIMEOUT; + loramac_radio_set_sleep( ); + app_context.state = APP_STATE_RX_TIMEOUT; } -void OnRxTimeout( void ) +static void print_hex_buffer( uint8_t* buffer, uint8_t size ) { - Radio.Sleep( ); - State = RX_TIMEOUT; + uint8_t newline = 0; + + for( uint8_t i = 0; i < size; i++ ) + { + if( newline != 0 ) + { + printf( "\n" ); + newline = 0; + } + printf( "%02X ", buffer[i] ); + if( ( ( i + 1 ) % 16 ) == 0 ) + { + newline = 1; + } + } + printf( "\n" ); } -void OnRxError( void ) +static void app_build_message( bool is_ping_msg, uint8_t* buffer, uint8_t size_in_bytes ) { - Radio.Sleep( ); - State = RX_ERROR; + uint8_t app_msg_size; + + if( is_ping_msg == true ) + { + app_msg_size = sizeof( app_ping_msg ); + memcpy( buffer, app_ping_msg, app_msg_size ); + } + else + { + app_msg_size = sizeof( app_pong_msg ); + memcpy( buffer, app_pong_msg, app_msg_size ); + } + // Fill remaining buffer bytes + for( uint8_t i = app_msg_size; i < size_in_bytes; i++ ) + { + buffer[i] = i - app_msg_size; + } } + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/src/apps/rx-sensi/B-L072Z-LRWAN1/main.c b/src/apps/rx-sensi/B-L072Z-LRWAN1/main.c index 0a1aeba7e..5485679e0 100644 --- a/src/apps/rx-sensi/B-L072Z-LRWAN1/main.c +++ b/src/apps/rx-sensi/B-L072Z-LRWAN1/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,100 +36,172 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) - -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#define RF_FREQUENCY 915000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) - -#define RF_FREQUENCY 470000000 // Hz - +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 + +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -138,46 +210,57 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 1 - ledState ^= 1; - GpioWrite( &Led1, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/rx-sensi/NAMote72/main.c b/src/apps/rx-sensi/NAMote72/main.c index 8062417da..5485679e0 100644 --- a/src/apps/rx-sensi/NAMote72/main.c +++ b/src/apps/rx-sensi/NAMote72/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,93 +36,172 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#include "board-config.h" +#include #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 #elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 915000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_CN779 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) + +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -131,46 +210,57 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.Init( &RadioEvents ); - - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 1 - ledState ^= 1; - GpioWrite( &Led1, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/rx-sensi/NucleoL073/main.c b/src/apps/rx-sensi/NucleoL073/main.c index 935367cc0..5485679e0 100644 --- a/src/apps/rx-sensi/NucleoL073/main.c +++ b/src/apps/rx-sensi/NucleoL073/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,100 +36,172 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) - -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#define RF_FREQUENCY 915000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) - -#define RF_FREQUENCY 470000000 // Hz - +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 + +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -138,51 +210,57 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 1 - ledState ^= 1; - GpioWrite( &Led1, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/rx-sensi/NucleoL152/main.c b/src/apps/rx-sensi/NucleoL152/main.c index 935367cc0..5485679e0 100644 --- a/src/apps/rx-sensi/NucleoL152/main.c +++ b/src/apps/rx-sensi/NucleoL152/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,100 +36,172 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) - -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#define RF_FREQUENCY 915000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) - -#define RF_FREQUENCY 470000000 // Hz - +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 + +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -138,51 +210,57 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 1 - ledState ^= 1; - GpioWrite( &Led1, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/rx-sensi/NucleoL476/main.c b/src/apps/rx-sensi/NucleoL476/main.c index 935367cc0..5485679e0 100644 --- a/src/apps/rx-sensi/NucleoL476/main.c +++ b/src/apps/rx-sensi/NucleoL476/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,100 +36,172 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) - -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#define RF_FREQUENCY 915000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) - -#define RF_FREQUENCY 470000000 // Hz - +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 + +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -138,51 +210,57 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; - - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 1 - ledState ^= 1; - GpioWrite( &Led1, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/rx-sensi/SAMR34/main.c b/src/apps/rx-sensi/SAMR34/main.c index 3cf01aff4..ed3c764d0 100644 --- a/src/apps/rx-sensi/SAMR34/main.c +++ b/src/apps/rx-sensi/SAMR34/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,100 +36,173 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "board.h" -#include "gpio.h" #include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) - -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#elif defined( REGION_AU915 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ -#define RF_FREQUENCY 915000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 +#elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 #elif defined( REGION_CN470 ) - -#define RF_FREQUENCY 470000000 // Hz - +#define RF_FREQ_IN_HZ 470000000 #elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 779000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_EU433 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 433000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 + +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led1; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -138,49 +211,59 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.Init( &RadioEvents ); - - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { // Tick the RTC to execute callback in context of the main loop (in stead of the IRQ) TimerProcess( ); - BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 1 - ledState ^= 1; - GpioWrite( &Led1, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/rx-sensi/SKiM880B/main.c b/src/apps/rx-sensi/SKiM880B/main.c index 6ea8f40a6..5485679e0 100644 --- a/src/apps/rx-sensi/SKiM880B/main.c +++ b/src/apps/rx-sensi/SKiM880B/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,92 +36,172 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 #elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 915000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_CN779 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) + +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led4; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -130,46 +210,57 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.Init( &RadioEvents ); - - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 4 - ledState ^= 1; - GpioWrite( &Led4, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/rx-sensi/SKiM881AXL/main.c b/src/apps/rx-sensi/SKiM881AXL/main.c index 6ea8f40a6..5485679e0 100644 --- a/src/apps/rx-sensi/SKiM881AXL/main.c +++ b/src/apps/rx-sensi/SKiM881AXL/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,92 +36,172 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 #elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 915000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_CN779 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) + +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led4; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -130,46 +210,57 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.Init( &RadioEvents ); - - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 4 - ledState ^= 1; - GpioWrite( &Led4, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/rx-sensi/SKiM980A/main.c b/src/apps/rx-sensi/SKiM980A/main.c index 6ea8f40a6..5485679e0 100644 --- a/src/apps/rx-sensi/SKiM980A/main.c +++ b/src/apps/rx-sensi/SKiM980A/main.c @@ -3,10 +3,10 @@ * * \brief Radio sensitivity test * - * \remark When LED1 stops blinking LoRa packets aren't received any more and - * the sensitivity level has been reached. - * By reading the RF generator output power we can estimate the board - * sensitivity + * \remark When messages stop being displayed on the uart, RF packets aren't + * received any more and the sensitivity level has been reached. + * By reading the RF generator output power we can estimate the board + * sensitivity * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -36,92 +36,172 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" -#if defined( REGION_AS923 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ -#define RF_FREQUENCY 923000000 // Hz +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off +#if defined( REGION_AS923 ) +#define RF_FREQ_IN_HZ 923000000 #elif defined( REGION_AU915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_CN470 ) +#define RF_FREQ_IN_HZ 470000000 +#elif defined( REGION_CN779 ) +#define RF_FREQ_IN_HZ 779000000 +#elif defined( REGION_EU433 ) +#define RF_FREQ_IN_HZ 433000000 +#elif defined( REGION_EU868 ) +#define RF_FREQ_IN_HZ 868000000 +#elif defined( REGION_KR920 ) +#define RF_FREQ_IN_HZ 920000000 +#elif defined( REGION_IN865 ) +#define RF_FREQ_IN_HZ 865000000 +#elif defined( REGION_US915 ) +#define RF_FREQ_IN_HZ 915000000 +#elif defined( REGION_RU864 ) +#define RF_FREQ_IN_HZ 864000000 +#else +#error "Please select a region under compiler options." +#endif -#define RF_FREQUENCY 915000000 // Hz +#if defined( USE_MODEM_LORA ) -#elif defined( REGION_CN779 ) +/*! + * \brief LoRa modulation spreading factor + */ +#define LORA_SF RAL_LORA_SF10 -#define RF_FREQUENCY 779000000 // Hz +/*! + * \brief LoRa modulation bandwidth + */ +#define LORA_BW RAL_LORA_BW_125_KHZ -#elif defined( REGION_EU868 ) +/*! + * \brief LoRa modulation coding rate + */ +#define LORA_CR RAL_LORA_CR_4_5 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief LoRa preamble length + */ +#define LORA_PREAMBLE_LEN_IN_SYMB 8 -#elif defined( REGION_KR920 ) +/*! + * \brief LoRa is packet length fixed or variable + */ +#define LORA_IS_PKT_LEN_FIXED false -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief LoRa is packet crc on or off + */ +#define LORA_IS_CRC_ON true -#elif defined( REGION_IN865 ) +/*! + * \brief LoRa is IQ inversion on or off + */ +#define LORA_IS_INVERT_IQ_ON false -#define RF_FREQUENCY 865000000 // Hz +/*! + * \brief LoRa rx synchronization timeout + */ +#define LORA_RX_SYNC_TIMEOUT_IN_SYMB 6 -#elif defined( REGION_US915 ) +#elif defined( USE_MODEM_FSK ) + +/*! + * \brief GFSK bitrate + */ +#define GFSK_BR_IN_BPS 50000 -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief GFSK frequency deviation + */ +#define GFSK_FDEV_IN_HZ 25000 -#elif defined( REGION_RU864 ) +/*! + * \brief GFSK bandwidth double sided + */ +#define GFSK_BW_DSB_IN_HZ 100000 -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief GFSK preable length + */ +#define GFSK_PREABLE_LEN_IN_BITS 40 -#else - #error "Please define a frequency band in the compiler options." -#endif +/*! + * \brief GFSK sync word length + */ +#define GFSK_SYNC_WORD_LEN_IN_BITS 24 -#if defined( USE_MODEM_LORA ) +/*! + * \brief GFSK is packet length fixed or variable + */ +#define GFSK_IS_PKT_LEN_FIXED false -#define LORA_BANDWIDTH 0 // [0: 125 kHz, - // 1: 250 kHz, - // 2: 500 kHz, - // 3: Reserved] -#define LORA_SPREADING_FACTOR 10 // [SF7..SF12] -#define LORA_CODINGRATE 1 // [1: 4/5, - // 2: 4/6, - // 3: 4/7, - // 4: 4/8] -#define LORA_SYMBOL_TIMEOUT 5 // Symbols -#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx -#define LORA_FIX_LENGTH_PAYLOAD_ON false -#define LORA_IQ_INVERSION_ON false +/*! + * \brief GFSK is packet crc on or off + */ +#define GFSK_IS_CRC_ON true -#elif defined( USE_MODEM_FSK ) +/*! + * \brief GFSK rx synchronization timeout + */ +#define GFSK_RX_SYNC_TIMEOUT_IN_SYMB 6 -#define FSK_DATARATE 50000 // bps -#define FSK_BANDWIDTH 50000 // Hz -#define FSK_AFC_BANDWIDTH 83333 // Hz -#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx -#define FSK_FIX_LENGTH_PAYLOAD_ON false +/*! + * \brief GFSK tx timeout + */ +#define GFSK_TX_TIMEOUT_IN_MS 4000 #else - #error "Please define a modem in the compiler options." +#error "Please select a modem under compiler options." #endif -/*! - * Radio events function pointer +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static RadioEvents_t RadioEvents; /*! - * LED GPIO pins objects + * \brief Radio interrupt callbacks + */ +static loramac_radio_irq_t radio_irq_callbacks; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -extern Gpio_t Led4; /*! - * \brief Function to be executed on Radio Rx Done event + * \brief Rx done interrupt callback + * + * \param [out] params Pointer to the received parameters + */ +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); /*! - * Main application entry point. + * \brief Main application entry point. */ int main( void ) { @@ -130,46 +210,57 @@ int main( void ) BoardInitPeriph( ); // Radio initialization - RadioEvents.RxDone = OnRxDone; + radio_irq_callbacks.loramac_radio_irq_rx_done = irq_rx_done; - Radio.Init( &RadioEvents ); - - Radio.SetChannel( RF_FREQUENCY ); + loramac_radio_init( &radio_irq_callbacks ); #if defined( USE_MODEM_LORA ) - - Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, - LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, - LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, - 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); - - Radio.SetMaxPayloadLength( MODEM_LORA, 255 ); - + loramac_radio_lora_cfg_params_t lora_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .sf = LORA_SF, + .bw = LORA_BW, + .cr = LORA_CR, + .preamble_len_in_symb = LORA_PREAMBLE_LEN_IN_SYMB, + .is_pkt_len_fixed = LORA_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = LORA_IS_CRC_ON, + .invert_iq_is_on = LORA_IS_INVERT_IQ_ON, + .rx_sync_timeout_in_symb = LORA_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_lora_set_cfg( &lora_params ); #elif defined( USE_MODEM_FSK ) - - Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, - 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, - 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, - 0, 0, false, true ); - - Radio.SetMaxPayloadLength( MODEM_FSK, 255 ); - -#else - #error "Please define a frequency band in the compiler options." + loramac_radio_gfsk_cfg_params_t gfsk_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .br_in_bps = GFSK_BR_IN_BPS, + .fdev_in_hz = GFSK_FDEV_IN_HZ, + .bw_dsb_in_hz = GFSK_BW_DSB_IN_HZ, + .preamble_len_in_bits = GFSK_PREABLE_LEN_IN_BITS, + .sync_word_len_in_bits = GFSK_SYNC_WORD_LEN_IN_BITS, + .is_pkt_len_fixed = GFSK_IS_PKT_LEN_FIXED, + .pld_len_in_bytes = 255, + .is_crc_on = GFSK_IS_CRC_ON, + .rx_sync_timeout_in_symb = GFSK_RX_SYNC_TIMEOUT_IN_SYMB, + .is_rx_continuous = true, + }; + loramac_radio_gfsk_set_cfg( &gfsk_params ); #endif - Radio.Rx( 0 ); // Continuous Rx + loramac_radio_set_rx( RAL_RX_TIMEOUT_CONTINUOUS_MODE ); while( 1 ) { BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } -void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +static void irq_rx_done( loramac_radio_irq_rx_done_params_t* params ) { - static uint8_t ledState = 1; - // Toggle LED 4 - ledState ^= 1; - GpioWrite( &Led4, ledState ); +#if defined( USE_MODEM_LORA ) + printf( "[IRQ] rx done rssi: %4d dBm, snr: %4d dB\n", params->rssi_in_dbm, params->snr_in_db ); +#elif defined( USE_MODEM_FSK ) + printf( "[IRQ] rx done rssi: %4d dBm\n", params->rssi_in_dbm ); +#endif } diff --git a/src/apps/tx-cw/B-L072Z-LRWAN1/main.c b/src/apps/tx-cw/B-L072Z-LRWAN1/main.c index e42b4fbdd..906e51bb2 100644 --- a/src/apps/tx-cw/B-L072Z-LRWAN1/main.c +++ b/src/apps/tx-cw/B-L072Z-LRWAN1/main.c @@ -31,124 +31,186 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_CN470 ) -#define RF_FREQUENCY 470000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 -#elif defined( REGION_CN779 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#define RF_FREQUENCY 779000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +#elif defined( REGION_CN779 ) -#elif defined( REGION_EU433 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 -#define RF_FREQUENCY 433000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_EU868 ) +#elif defined( REGION_EU433 ) -#define RF_FREQUENCY 868000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 -#elif defined( REGION_KR920 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#define RF_FREQUENCY 920000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +#elif defined( REGION_EU868 ) -#elif defined( REGION_IN865 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 -#define RF_FREQUENCY 865000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_US915 ) +#elif defined( REGION_KR920 ) -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 -#elif defined( REGION_RU864 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 864000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +#elif defined( REGION_IN865 ) -#else +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 - #error "Please define a frequency band in the compiler options." +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#endif -#define TX_TIMEOUT 65535 // seconds (MAX value) +#elif defined( REGION_US915 ) -static TimerEvent_t Led1Timer; -volatile bool Led1TimerEvent = false; +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -static TimerEvent_t Led2Timer; -volatile bool Led2TimerEvent = false; +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -static TimerEvent_t Led3Timer; -volatile bool Led3TimerEvent = false; +#elif defined( REGION_RU864 ) /*! - * Radio events function pointer + * \brief RF frequency */ -static RadioEvents_t RadioEvents; +#define RF_FREQ_IN_HZ 864000000 /*! - * LED GPIO pins objects + * \brief RF transmission output power */ -extern Gpio_t Led1; -extern Gpio_t Led2; -extern Gpio_t Led3; +#define TX_RF_PWR_IN_DBM 14 + +#else +#error "Please select a region under compiler options." +#endif /*! - * \brief Function executed on Led 1 Timeout event + * \brief Tx timeout */ -void OnLed1TimerEvent( void* context ) -{ - Led1TimerEvent = true; -} +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on -/*! - * \brief Function executed on Led 2 Timeout event +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -void OnLed2TimerEvent( void* context ) -{ - Led2TimerEvent = true; -} /*! - * \brief Function executed on Led 3 Timeout event + * \brief Radio interrupt callbacks */ -void OnLed3TimerEvent( void* context ) -{ - Led3TimerEvent = true; -} +static loramac_radio_irq_t radio_irq_callbacks; /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Tx timeout interrupt callback */ -void OnRadioTxTimeout( void ) +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -156,59 +218,23 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led1Timer, OnLed1TimerEvent ); - TimerSetValue( &Led1Timer, 90 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 90 ); - - TimerInit( &Led3Timer, OnLed3TimerEvent ); - TimerSetValue( &Led3Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { - if( Led1TimerEvent == true ) - { - Led1TimerEvent = false; - - // Switch LED 1 OFF - GpioWrite( &Led1, 1 ); - // Switch LED 2 ON - GpioWrite( &Led2, 0 ); - TimerStart( &Led2Timer ); - } - - if( Led2TimerEvent == true ) - { - Led2TimerEvent = false; - - // Switch LED 2 OFF - GpioWrite( &Led2, 1 ); - // Switch LED 3 ON - GpioWrite( &Led3, 0 ); - TimerStart( &Led3Timer ); - } - - if( Led3TimerEvent == true ) - { - Led3TimerEvent = false; - - // Switch LED 3 OFF - GpioWrite( &Led3, 1 ); - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - } + BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } diff --git a/src/apps/tx-cw/NAMote72/main.c b/src/apps/tx-cw/NAMote72/main.c index 41426ed46..906e51bb2 100644 --- a/src/apps/tx-cw/NAMote72/main.c +++ b/src/apps/tx-cw/NAMote72/main.c @@ -31,109 +31,186 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#include "board-config.h" + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -#elif defined( REGION_CN779 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 779000000 // Hz +#elif defined( REGION_CN470 ) -#elif defined( REGION_EU868 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_KR920 ) +#elif defined( REGION_CN779 ) -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 -#elif defined( REGION_IN865 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 865000000 // Hz +#elif defined( REGION_EU433 ) -#elif defined( REGION_US915 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_RU864 ) +#elif defined( REGION_EU868 ) -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 -#else +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 - #error "Please define a frequency band in the compiler options." +#elif defined( REGION_KR920 ) -#endif +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 -#define TX_OUTPUT_POWER 20 // 20 dBm -#define TX_TIMEOUT 65535 // seconds (MAX value) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -static TimerEvent_t Led1Timer; -volatile bool Led1TimerEvent = false; +#elif defined( REGION_IN865 ) -static TimerEvent_t Led2Timer; -volatile bool Led2TimerEvent = false; +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 -static TimerEvent_t Led3Timer; -volatile bool Led3TimerEvent = false; +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 + +#elif defined( REGION_US915 ) /*! - * Radio events function pointer + * \brief RF frequency */ -static RadioEvents_t RadioEvents; +#define RF_FREQ_IN_HZ 915000000 /*! - * LED GPIO pins objects + * \brief RF transmission output power */ -extern Gpio_t Led1; -extern Gpio_t Led2; -extern Gpio_t Led3; +#define TX_RF_PWR_IN_DBM 14 + +#elif defined( REGION_RU864 ) /*! - * \brief Function executed on Led 1 Timeout event + * \brief RF frequency */ -void OnLed1TimerEvent( void* context ) -{ - Led1TimerEvent = true; -} +#define RF_FREQ_IN_HZ 864000000 /*! - * \brief Function executed on Led 2 Timeout event + * \brief RF transmission output power */ -void OnLed2TimerEvent( void* context ) -{ - Led2TimerEvent = true; -} +#define TX_RF_PWR_IN_DBM 14 + +#else +#error "Please select a region under compiler options." +#endif /*! - * \brief Function executed on Led 3 Timeout event + * \brief Tx timeout + */ +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -void OnLed3TimerEvent( void* context ) -{ - Led3TimerEvent = true; -} /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Radio interrupt callbacks */ -void OnRadioTxTimeout( void ) +static loramac_radio_irq_t radio_irq_callbacks; + +/*! + * \brief Tx timeout interrupt callback + */ +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -141,59 +218,23 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led1Timer, OnLed1TimerEvent ); - TimerSetValue( &Led1Timer, 90 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 90 ); - - TimerInit( &Led3Timer, OnLed3TimerEvent ); - TimerSetValue( &Led3Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { - if( Led1TimerEvent == true ) - { - Led1TimerEvent = false; - - // Switch LED 1 OFF - GpioWrite( &Led1, 1 ); - // Switch LED 2 ON - GpioWrite( &Led2, 0 ); - TimerStart( &Led2Timer ); - } - - if( Led2TimerEvent == true ) - { - Led2TimerEvent = false; - - // Switch LED 2 OFF - GpioWrite( &Led2, 1 ); - // Switch LED 3 ON - GpioWrite( &Led3, 0 ); - TimerStart( &Led3Timer ); - } - - if( Led3TimerEvent == true ) - { - Led3TimerEvent = false; - - // Switch LED 3 OFF - GpioWrite( &Led3, 1 ); - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - } + BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } diff --git a/src/apps/tx-cw/NucleoL073/main.c b/src/apps/tx-cw/NucleoL073/main.c index bccc8c134..906e51bb2 100644 --- a/src/apps/tx-cw/NucleoL073/main.c +++ b/src/apps/tx-cw/NucleoL073/main.c @@ -31,112 +31,186 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_CN470 ) -#define RF_FREQUENCY 470000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 #elif defined( REGION_CN779 ) -#define RF_FREQUENCY 779000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_EU433 ) -#define RF_FREQUENCY 433000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm - -#elif defined( REGION_EU868 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 -#define RF_FREQUENCY 868000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_KR920 ) +#elif defined( REGION_EU868 ) -#define RF_FREQUENCY 920000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 -#elif defined( REGION_IN865 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 865000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +#elif defined( REGION_KR920 ) -#elif defined( REGION_US915 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_RU864 ) +#elif defined( REGION_IN865 ) -#define RF_FREQUENCY 864000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 -#else +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 - #error "Please define a frequency band in the compiler options." +#elif defined( REGION_US915 ) -#endif -#define TX_TIMEOUT 10 // seconds (MAX value) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -static TimerEvent_t Led1Timer; -volatile bool Led1TimerEvent = false; +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -static TimerEvent_t Led2Timer; -volatile bool Led2TimerEvent = false; +#elif defined( REGION_RU864 ) /*! - * Radio events function pointer + * \brief RF frequency */ -static RadioEvents_t RadioEvents; +#define RF_FREQ_IN_HZ 864000000 /*! - * LED GPIO pins objects + * \brief RF transmission output power */ -extern Gpio_t Led1; -extern Gpio_t Led2; +#define TX_RF_PWR_IN_DBM 14 + +#else +#error "Please select a region under compiler options." +#endif /*! - * \brief Function executed on Led 1 Timeout event + * \brief Tx timeout + */ +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -void OnLed1TimerEvent( void* context ) -{ - Led1TimerEvent = true; -} /*! - * \brief Function executed on Led 2 Timeout event + * \brief Radio interrupt callbacks */ -void OnLed2TimerEvent( void* context ) -{ - Led2TimerEvent = true; -} +static loramac_radio_irq_t radio_irq_callbacks; /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Tx timeout interrupt callback */ -void OnRadioTxTimeout( void ) +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -144,50 +218,23 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led1Timer, OnLed1TimerEvent ); - TimerSetValue( &Led1Timer, 90 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { + BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } - if( Led1TimerEvent == true ) - { - Led1TimerEvent = false; - - // Switch LED 1 OFF - GpioWrite( &Led1, 1 ); - // Switch LED 2 ON - GpioWrite( &Led2, 0 ); - TimerStart( &Led2Timer ); - } - - if( Led2TimerEvent == true ) - { - Led2TimerEvent = false; - - // Switch LED 2 OFF - GpioWrite( &Led2, 1 ); - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - } + loramac_radio_irq_process( ); } } diff --git a/src/apps/tx-cw/NucleoL152/main.c b/src/apps/tx-cw/NucleoL152/main.c index bccc8c134..906e51bb2 100644 --- a/src/apps/tx-cw/NucleoL152/main.c +++ b/src/apps/tx-cw/NucleoL152/main.c @@ -31,112 +31,186 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_CN470 ) -#define RF_FREQUENCY 470000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 #elif defined( REGION_CN779 ) -#define RF_FREQUENCY 779000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_EU433 ) -#define RF_FREQUENCY 433000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm - -#elif defined( REGION_EU868 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 -#define RF_FREQUENCY 868000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_KR920 ) +#elif defined( REGION_EU868 ) -#define RF_FREQUENCY 920000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 -#elif defined( REGION_IN865 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 865000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +#elif defined( REGION_KR920 ) -#elif defined( REGION_US915 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_RU864 ) +#elif defined( REGION_IN865 ) -#define RF_FREQUENCY 864000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 -#else +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 - #error "Please define a frequency band in the compiler options." +#elif defined( REGION_US915 ) -#endif -#define TX_TIMEOUT 10 // seconds (MAX value) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -static TimerEvent_t Led1Timer; -volatile bool Led1TimerEvent = false; +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -static TimerEvent_t Led2Timer; -volatile bool Led2TimerEvent = false; +#elif defined( REGION_RU864 ) /*! - * Radio events function pointer + * \brief RF frequency */ -static RadioEvents_t RadioEvents; +#define RF_FREQ_IN_HZ 864000000 /*! - * LED GPIO pins objects + * \brief RF transmission output power */ -extern Gpio_t Led1; -extern Gpio_t Led2; +#define TX_RF_PWR_IN_DBM 14 + +#else +#error "Please select a region under compiler options." +#endif /*! - * \brief Function executed on Led 1 Timeout event + * \brief Tx timeout + */ +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -void OnLed1TimerEvent( void* context ) -{ - Led1TimerEvent = true; -} /*! - * \brief Function executed on Led 2 Timeout event + * \brief Radio interrupt callbacks */ -void OnLed2TimerEvent( void* context ) -{ - Led2TimerEvent = true; -} +static loramac_radio_irq_t radio_irq_callbacks; /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Tx timeout interrupt callback */ -void OnRadioTxTimeout( void ) +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -144,50 +218,23 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led1Timer, OnLed1TimerEvent ); - TimerSetValue( &Led1Timer, 90 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { + BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } - if( Led1TimerEvent == true ) - { - Led1TimerEvent = false; - - // Switch LED 1 OFF - GpioWrite( &Led1, 1 ); - // Switch LED 2 ON - GpioWrite( &Led2, 0 ); - TimerStart( &Led2Timer ); - } - - if( Led2TimerEvent == true ) - { - Led2TimerEvent = false; - - // Switch LED 2 OFF - GpioWrite( &Led2, 1 ); - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - } + loramac_radio_irq_process( ); } } diff --git a/src/apps/tx-cw/NucleoL476/main.c b/src/apps/tx-cw/NucleoL476/main.c index bccc8c134..906e51bb2 100644 --- a/src/apps/tx-cw/NucleoL476/main.c +++ b/src/apps/tx-cw/NucleoL476/main.c @@ -31,112 +31,186 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_CN470 ) -#define RF_FREQUENCY 470000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 #elif defined( REGION_CN779 ) -#define RF_FREQUENCY 779000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_EU433 ) -#define RF_FREQUENCY 433000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm - -#elif defined( REGION_EU868 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 -#define RF_FREQUENCY 868000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_KR920 ) +#elif defined( REGION_EU868 ) -#define RF_FREQUENCY 920000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 -#elif defined( REGION_IN865 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 865000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +#elif defined( REGION_KR920 ) -#elif defined( REGION_US915 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#elif defined( REGION_RU864 ) +#elif defined( REGION_IN865 ) -#define RF_FREQUENCY 864000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 -#else +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 - #error "Please define a frequency band in the compiler options." +#elif defined( REGION_US915 ) -#endif -#define TX_TIMEOUT 10 // seconds (MAX value) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -static TimerEvent_t Led1Timer; -volatile bool Led1TimerEvent = false; +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -static TimerEvent_t Led2Timer; -volatile bool Led2TimerEvent = false; +#elif defined( REGION_RU864 ) /*! - * Radio events function pointer + * \brief RF frequency */ -static RadioEvents_t RadioEvents; +#define RF_FREQ_IN_HZ 864000000 /*! - * LED GPIO pins objects + * \brief RF transmission output power */ -extern Gpio_t Led1; -extern Gpio_t Led2; +#define TX_RF_PWR_IN_DBM 14 + +#else +#error "Please select a region under compiler options." +#endif /*! - * \brief Function executed on Led 1 Timeout event + * \brief Tx timeout + */ +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -void OnLed1TimerEvent( void* context ) -{ - Led1TimerEvent = true; -} /*! - * \brief Function executed on Led 2 Timeout event + * \brief Radio interrupt callbacks */ -void OnLed2TimerEvent( void* context ) -{ - Led2TimerEvent = true; -} +static loramac_radio_irq_t radio_irq_callbacks; /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Tx timeout interrupt callback */ -void OnRadioTxTimeout( void ) +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -144,50 +218,23 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led1Timer, OnLed1TimerEvent ); - TimerSetValue( &Led1Timer, 90 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { + BoardLowPowerHandler( ); // Process Radio IRQ - if( Radio.IrqProcess != NULL ) - { - Radio.IrqProcess( ); - } - if( Led1TimerEvent == true ) - { - Led1TimerEvent = false; - - // Switch LED 1 OFF - GpioWrite( &Led1, 1 ); - // Switch LED 2 ON - GpioWrite( &Led2, 0 ); - TimerStart( &Led2Timer ); - } - - if( Led2TimerEvent == true ) - { - Led2TimerEvent = false; - - // Switch LED 2 OFF - GpioWrite( &Led2, 1 ); - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - } + loramac_radio_irq_process( ); } } diff --git a/src/apps/tx-cw/SAMR34/main.c b/src/apps/tx-cw/SAMR34/main.c index dd5275395..50239fa77 100644 --- a/src/apps/tx-cw/SAMR34/main.c +++ b/src/apps/tx-cw/SAMR34/main.c @@ -31,101 +31,187 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" #include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_CN470 ) -#define RF_FREQUENCY 470000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 #elif defined( REGION_CN779 ) -#define RF_FREQUENCY 779000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_EU433 ) -#define RF_FREQUENCY 433000000 // Hz -#define TX_OUTPUT_POWER 20 // 20 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 #elif defined( REGION_EU868 ) -#define RF_FREQUENCY 868000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_KR920 ) -#define RF_FREQUENCY 920000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_IN865 ) -#define RF_FREQUENCY 865000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_US915 ) -#define RF_FREQUENCY 915000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -#elif defined( REGION_RU864 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 864000000 // Hz -#define TX_OUTPUT_POWER 14 // 14 dBm +#elif defined( REGION_RU864 ) -#else +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 864000000 - #error "Please define a frequency band in the compiler options." +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 +#else +#error "Please select a region under compiler options." #endif -#define TX_TIMEOUT 65535 // seconds (MAX value) - -static TimerEvent_t Led1Timer; -volatile bool Led1TimerEvent = false; /*! - * Radio events function pointer + * \brief Tx timeout */ -static RadioEvents_t RadioEvents; +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on -/*! - * LED GPIO pins objects +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -extern Gpio_t Led1; /*! - * \brief Function executed on Led 1 Timeout event + * \brief Radio interrupt callbacks */ -void OnLed1TimerEvent( void* context ) -{ - Led1TimerEvent = true; -} - +static loramac_radio_irq_t radio_irq_callbacks; /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Tx timeout interrupt callback */ -void OnRadioTxTimeout( void ) +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -133,33 +219,25 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led1Timer, OnLed1TimerEvent ); - TimerSetValue( &Led1Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led1, 0 ); - TimerStart( &Led1Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { // Tick the RTC to execute callback in context of the main loop (in stead of the IRQ) TimerProcess( ); - - if( Led1TimerEvent == true ) - { - Led1TimerEvent = false; - - // Switch LED 1 OFF - GpioWrite( &Led1, 1 ); - } - - + BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } diff --git a/src/apps/tx-cw/SKiM880B/main.c b/src/apps/tx-cw/SKiM880B/main.c index 6995421df..906e51bb2 100644 --- a/src/apps/tx-cw/SKiM880B/main.c +++ b/src/apps/tx-cw/SKiM880B/main.c @@ -31,108 +31,186 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -#elif defined( REGION_CN779 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 779000000 // Hz +#elif defined( REGION_CN470 ) -#elif defined( REGION_EU868 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_KR920 ) +#elif defined( REGION_CN779 ) -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 -#elif defined( REGION_IN865 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 865000000 // Hz +#elif defined( REGION_EU433 ) -#elif defined( REGION_US915 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_RU864 ) +#elif defined( REGION_EU868 ) -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 -#else +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 - #error "Please define a frequency band in the compiler options." +#elif defined( REGION_KR920 ) -#endif +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 -#define TX_OUTPUT_POWER 20 // 20 dBm -#define TX_TIMEOUT 65535 // seconds (MAX value) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -static TimerEvent_t Led4Timer; -volatile bool Led4TimerEvent = false; +#elif defined( REGION_IN865 ) -static TimerEvent_t Led2Timer; -volatile bool Led2TimerEvent = false; +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 -static TimerEvent_t Led3Timer; -volatile bool Led3TimerEvent = false; +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 + +#elif defined( REGION_US915 ) /*! - * Radio events function pointer + * \brief RF frequency */ -static RadioEvents_t RadioEvents; +#define RF_FREQ_IN_HZ 915000000 /*! - * LED GPIO pins objects + * \brief RF transmission output power */ -extern Gpio_t Led4; -extern Gpio_t Led2; -extern Gpio_t Led3; +#define TX_RF_PWR_IN_DBM 14 + +#elif defined( REGION_RU864 ) /*! - * \brief Function executed on Led 1 Timeout event + * \brief RF frequency */ -void OnLed4TimerEvent( void* context ) -{ - Led4TimerEvent = true; -} +#define RF_FREQ_IN_HZ 864000000 /*! - * \brief Function executed on Led 2 Timeout event + * \brief RF transmission output power */ -void OnLed2TimerEvent( void* context ) -{ - Led2TimerEvent = true; -} +#define TX_RF_PWR_IN_DBM 14 + +#else +#error "Please select a region under compiler options." +#endif /*! - * \brief Function executed on Led 3 Timeout event + * \brief Tx timeout + */ +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -void OnLed3TimerEvent( void* context ) -{ - Led3TimerEvent = true; -} /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Radio interrupt callbacks */ -void OnRadioTxTimeout( void ) +static loramac_radio_irq_t radio_irq_callbacks; + +/*! + * \brief Tx timeout interrupt callback + */ +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -140,59 +218,23 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led4Timer, OnLed4TimerEvent ); - TimerSetValue( &Led4Timer, 90 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 90 ); - - TimerInit( &Led3Timer, OnLed3TimerEvent ); - TimerSetValue( &Led3Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led4, 0 ); - TimerStart( &Led4Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { - if( Led4TimerEvent == true ) - { - Led4TimerEvent = false; - - // Switch LED 4 OFF - GpioWrite( &Led4, 4 ); - // Switch LED 2 ON - GpioWrite( &Led2, 0 ); - TimerStart( &Led2Timer ); - } - - if( Led2TimerEvent == true ) - { - Led2TimerEvent = false; - - // Switch LED 2 OFF - GpioWrite( &Led2, 1 ); - // Switch LED 3 ON - GpioWrite( &Led3, 0 ); - TimerStart( &Led3Timer ); - } - - if( Led3TimerEvent == true ) - { - Led3TimerEvent = false; - - // Switch LED 3 OFF - GpioWrite( &Led3, 1 ); - // Switch LED 1 ON - GpioWrite( &Led4, 0 ); - TimerStart( &Led4Timer ); - } + BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } diff --git a/src/apps/tx-cw/SKiM881AXL/main.c b/src/apps/tx-cw/SKiM881AXL/main.c index 6995421df..906e51bb2 100644 --- a/src/apps/tx-cw/SKiM881AXL/main.c +++ b/src/apps/tx-cw/SKiM881AXL/main.c @@ -31,108 +31,186 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -#elif defined( REGION_CN779 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 779000000 // Hz +#elif defined( REGION_CN470 ) -#elif defined( REGION_EU868 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_KR920 ) +#elif defined( REGION_CN779 ) -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 -#elif defined( REGION_IN865 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 865000000 // Hz +#elif defined( REGION_EU433 ) -#elif defined( REGION_US915 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_RU864 ) +#elif defined( REGION_EU868 ) -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 -#else +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 - #error "Please define a frequency band in the compiler options." +#elif defined( REGION_KR920 ) -#endif +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 -#define TX_OUTPUT_POWER 20 // 20 dBm -#define TX_TIMEOUT 65535 // seconds (MAX value) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -static TimerEvent_t Led4Timer; -volatile bool Led4TimerEvent = false; +#elif defined( REGION_IN865 ) -static TimerEvent_t Led2Timer; -volatile bool Led2TimerEvent = false; +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 -static TimerEvent_t Led3Timer; -volatile bool Led3TimerEvent = false; +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 + +#elif defined( REGION_US915 ) /*! - * Radio events function pointer + * \brief RF frequency */ -static RadioEvents_t RadioEvents; +#define RF_FREQ_IN_HZ 915000000 /*! - * LED GPIO pins objects + * \brief RF transmission output power */ -extern Gpio_t Led4; -extern Gpio_t Led2; -extern Gpio_t Led3; +#define TX_RF_PWR_IN_DBM 14 + +#elif defined( REGION_RU864 ) /*! - * \brief Function executed on Led 1 Timeout event + * \brief RF frequency */ -void OnLed4TimerEvent( void* context ) -{ - Led4TimerEvent = true; -} +#define RF_FREQ_IN_HZ 864000000 /*! - * \brief Function executed on Led 2 Timeout event + * \brief RF transmission output power */ -void OnLed2TimerEvent( void* context ) -{ - Led2TimerEvent = true; -} +#define TX_RF_PWR_IN_DBM 14 + +#else +#error "Please select a region under compiler options." +#endif /*! - * \brief Function executed on Led 3 Timeout event + * \brief Tx timeout + */ +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -void OnLed3TimerEvent( void* context ) -{ - Led3TimerEvent = true; -} /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Radio interrupt callbacks */ -void OnRadioTxTimeout( void ) +static loramac_radio_irq_t radio_irq_callbacks; + +/*! + * \brief Tx timeout interrupt callback + */ +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -140,59 +218,23 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led4Timer, OnLed4TimerEvent ); - TimerSetValue( &Led4Timer, 90 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 90 ); - - TimerInit( &Led3Timer, OnLed3TimerEvent ); - TimerSetValue( &Led3Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led4, 0 ); - TimerStart( &Led4Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { - if( Led4TimerEvent == true ) - { - Led4TimerEvent = false; - - // Switch LED 4 OFF - GpioWrite( &Led4, 4 ); - // Switch LED 2 ON - GpioWrite( &Led2, 0 ); - TimerStart( &Led2Timer ); - } - - if( Led2TimerEvent == true ) - { - Led2TimerEvent = false; - - // Switch LED 2 OFF - GpioWrite( &Led2, 1 ); - // Switch LED 3 ON - GpioWrite( &Led3, 0 ); - TimerStart( &Led3Timer ); - } - - if( Led3TimerEvent == true ) - { - Led3TimerEvent = false; - - // Switch LED 3 OFF - GpioWrite( &Led3, 1 ); - // Switch LED 1 ON - GpioWrite( &Led4, 0 ); - TimerStart( &Led4Timer ); - } + BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } } diff --git a/src/apps/tx-cw/SKiM980A/main.c b/src/apps/tx-cw/SKiM980A/main.c index 6995421df..906e51bb2 100644 --- a/src/apps/tx-cw/SKiM980A/main.c +++ b/src/apps/tx-cw/SKiM980A/main.c @@ -31,108 +31,186 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "board.h" -#include "gpio.h" -#include "timer.h" -#include "radio.h" +#include "../../mac/loramac_radio.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +// clang-format off #if defined( REGION_AS923 ) -#define RF_FREQUENCY 923000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 923000000 + +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 #elif defined( REGION_AU915 ) -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 915000000 -#elif defined( REGION_CN779 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 779000000 // Hz +#elif defined( REGION_CN470 ) -#elif defined( REGION_EU868 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 470000000 -#define RF_FREQUENCY 868000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_KR920 ) +#elif defined( REGION_CN779 ) -#define RF_FREQUENCY 920000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 779000000 -#elif defined( REGION_IN865 ) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -#define RF_FREQUENCY 865000000 // Hz +#elif defined( REGION_EU433 ) -#elif defined( REGION_US915 ) +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 433000000 -#define RF_FREQUENCY 915000000 // Hz +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 20 -#elif defined( REGION_RU864 ) +#elif defined( REGION_EU868 ) -#define RF_FREQUENCY 864000000 // Hz +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 868000000 -#else +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 - #error "Please define a frequency band in the compiler options." +#elif defined( REGION_KR920 ) -#endif +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 920000000 -#define TX_OUTPUT_POWER 20 // 20 dBm -#define TX_TIMEOUT 65535 // seconds (MAX value) +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 -static TimerEvent_t Led4Timer; -volatile bool Led4TimerEvent = false; +#elif defined( REGION_IN865 ) -static TimerEvent_t Led2Timer; -volatile bool Led2TimerEvent = false; +/*! + * \brief RF frequency + */ +#define RF_FREQ_IN_HZ 865000000 -static TimerEvent_t Led3Timer; -volatile bool Led3TimerEvent = false; +/*! + * \brief RF transmission output power + */ +#define TX_RF_PWR_IN_DBM 14 + +#elif defined( REGION_US915 ) /*! - * Radio events function pointer + * \brief RF frequency */ -static RadioEvents_t RadioEvents; +#define RF_FREQ_IN_HZ 915000000 /*! - * LED GPIO pins objects + * \brief RF transmission output power */ -extern Gpio_t Led4; -extern Gpio_t Led2; -extern Gpio_t Led3; +#define TX_RF_PWR_IN_DBM 14 + +#elif defined( REGION_RU864 ) /*! - * \brief Function executed on Led 1 Timeout event + * \brief RF frequency */ -void OnLed4TimerEvent( void* context ) -{ - Led4TimerEvent = true; -} +#define RF_FREQ_IN_HZ 864000000 /*! - * \brief Function executed on Led 2 Timeout event + * \brief RF transmission output power */ -void OnLed2TimerEvent( void* context ) -{ - Led2TimerEvent = true; -} +#define TX_RF_PWR_IN_DBM 14 + +#else +#error "Please select a region under compiler options." +#endif /*! - * \brief Function executed on Led 3 Timeout event + * \brief Tx timeout + */ +#define TX_TIMEOUT_IN_MS 10 // seconds (MAX value) +// clang-format on + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- */ -void OnLed3TimerEvent( void* context ) -{ - Led3TimerEvent = true; -} /*! - * \brief Function executed on Radio Tx Timeout event + * \brief Radio interrupt callbacks */ -void OnRadioTxTimeout( void ) +static loramac_radio_irq_t radio_irq_callbacks; + +/*! + * \brief Tx timeout interrupt callback + */ +static void irq_tx_timeout( void ) { // Restarts continuous wave transmission when timeout expires - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); } -/** - * Main application entry point. +/*! + * \brief Main application entry point. */ int main( void ) { @@ -140,59 +218,23 @@ int main( void ) BoardInitMcu( ); BoardInitPeriph( ); - TimerInit( &Led4Timer, OnLed4TimerEvent ); - TimerSetValue( &Led4Timer, 90 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 90 ); - - TimerInit( &Led3Timer, OnLed3TimerEvent ); - TimerSetValue( &Led3Timer, 90 ); - - // Switch LED 1 ON - GpioWrite( &Led4, 0 ); - TimerStart( &Led4Timer ); - // Radio initialization - RadioEvents.TxTimeout = OnRadioTxTimeout; - Radio.Init( &RadioEvents ); + radio_irq_callbacks.loramac_radio_irq_tx_timeout = irq_tx_timeout; + + loramac_radio_init( &radio_irq_callbacks ); - Radio.SetTxContinuousWave( RF_FREQUENCY, TX_OUTPUT_POWER, TX_TIMEOUT ); + loramac_radio_tx_cw_cfg_params_t cfg_params = { + .rf_freq_in_hz = RF_FREQ_IN_HZ, + .tx_rf_pwr_in_dbm = TX_RF_PWR_IN_DBM, + .timeout_in_s = TX_TIMEOUT_IN_MS, + }; + loramac_radio_set_tx_cw( &cfg_params ); // Blink LEDs just to show some activity while( 1 ) { - if( Led4TimerEvent == true ) - { - Led4TimerEvent = false; - - // Switch LED 4 OFF - GpioWrite( &Led4, 4 ); - // Switch LED 2 ON - GpioWrite( &Led2, 0 ); - TimerStart( &Led2Timer ); - } - - if( Led2TimerEvent == true ) - { - Led2TimerEvent = false; - - // Switch LED 2 OFF - GpioWrite( &Led2, 1 ); - // Switch LED 3 ON - GpioWrite( &Led3, 0 ); - TimerStart( &Led3Timer ); - } - - if( Led3TimerEvent == true ) - { - Led3TimerEvent = false; - - // Switch LED 3 OFF - GpioWrite( &Led3, 1 ); - // Switch LED 1 ON - GpioWrite( &Led4, 0 ); - TimerStart( &Led4Timer ); - } + BoardLowPowerHandler( ); + // Process Radio IRQ + loramac_radio_irq_process( ); } }