Using Spreading factor 12 on NUCLEO-WL55JC1 LoRa boards
I have 2 NUCLEO-WL55JC1 boards I am using to communicate using LoRa. The Tx board sends a message every 10 seconds, the Rx board receives the message and lights up an LED..I have this working at SF7, the same spreading factor as the ping-pong example I copied the code from, but if I try to change this to SF12 (on both Tx and Rx projects) the Rx board never receives messages.
Any ideas on how I can fix this? Her is the code
#include <stdio.h>
#include <radio_driver.h>
#include "types.h"
#include "radio.h"
#define RF_FREQUENCY 924000000 /* Hz */
#define TX_OUTPUT_POWER 14 /* dBm */
#define LORA_BANDWIDTH LORA_BW_500 /* KHz */
#define LORA_SPREADING_FACTOR LORA_SF9
#define LORA_CODINGRATE LORA_CR_4_5
#define LORA_PREAMBLE_LENGTH 8 /* Same for Tx and Rx */
#define LORA_SYMBOL_TIMEOUT 5 /* Symbols */
#define LORA_RX_TIMEOUT 10000 /* milliseconds */
#define RADIO_RX_BUFFER_SIZE 10
#define ZERO_OFFSET 0
typedef enum {
RADIO_STATE_IDLE,
RADIO_STATE_RX_COMPLETE,
RADIO_STATE_RX_ERROR
} RADIO_STATES;
PacketParams_t Radio_PacketParams;
const RadioLoRaBandwidths_t Radio_Bandwidths[] = { LORA_BW_125, LORA_BW_250, LORA_BW_500 };
RADIO_STATES Radio_State;
const char Radio_TimeoutText[] = "Rx Timeout\r\n";
const char Radio_ReceivedText[] = "Rx Received\r\n";
const char Radio_InitializedText[] = "Radio Initialized\r\n";
const char Radio_CrlfText[] = "\r\n";
extern UART_HandleTypeDef huart2;
void Radio_ReceiveMsg( void );
void Radio_IrqHandler(RadioIrqMasks_t radioIrq);
/*****************************************************************************************
* FUNCTION: Radio_Init
*
* DESCRIPTION: Initializes LoRa Radio
*
* PARAMETERS: None
*
* RETURN: None
*****************************************************************************************/
void Radio_Init(void)
{
ModulationParams_t modulationParams;
// Initialize the hardware (SPI bus, TCXO control, RF switch)
SUBGRF_Init(Radio_IrqHandler);
// Use DCDC converter if `DCDC_ENABLE` is defined in radio_conf.h
// "By default, the SMPS clock detection is disabled and must be enabled before enabling the SMPS." (6.1 in RM0453)
SUBGRF_WriteRegister(SUBGHZ_SMPSC0R, (SUBGRF_ReadRegister(SUBGHZ_SMPSC0R) | SMPS_CLK_DET_ENABLE));
SUBGRF_SetRegulatorMode();
// Use the whole 256-byte buffer for both TX and RX
SUBGRF_SetBufferBaseAddress(0x00, 0x00);
SUBGRF_SetRfFrequency(RF_FREQUENCY);
SUBGRF_SetRfTxPower(TX_OUTPUT_POWER);
SUBGRF_SetStopRxTimerOnPreambleDetect(FALSE);
SUBGRF_SetPacketType(PACKET_TYPE_LORA);
SUBGRF_WriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF );
SUBGRF_WriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF );
modulationParams.PacketType = PACKET_TYPE_LORA;
modulationParams.Params.LoRa.Bandwidth = LORA_BANDWIDTH;
modulationParams.Params.LoRa.CodingRate = LORA_CODINGRATE;
modulationParams.Params.LoRa.LowDatarateOptimize = 0x00;
modulationParams.Params.LoRa.SpreadingFactor = LORA_SPREADING_FACTOR;
SUBGRF_SetModulationParams(&modulationParams);
Radio_PacketParams.PacketType = PACKET_TYPE_LORA;
Radio_PacketParams.Params.LoRa.CrcMode = LORA_CRC_ON;
Radio_PacketParams.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH;
Radio_PacketParams.Params.LoRa.InvertIQ = LORA_IQ_NORMAL;
Radio_PacketParams.Params.LoRa.PayloadLength = 0xFF;
Radio_PacketParams.Params.LoRa.PreambleLength = LORA_PREAMBLE_LENGTH;
SUBGRF_SetPacketParams(&Radio_PacketParams);
//SUBGRF_SetLoRaSymbNumTimeout(LORA_SYMBOL_TIMEOUT);
// WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4
// RegIqPolaritySetup @address 0x0736
SUBGRF_WriteRegister( 0x0736, SUBGRF_ReadRegister( 0x0736 ) | ( 1 << 2 ) );
HAL_UART_Transmit(&huart2, (uint8_t *)Radio_InitializedText, sizeof(Radio_InitializedText) - 1, HAL_MAX_DELAY);
BSP_LED_On(LED_GREEN);
Radio_State = RADIO_STATE_IDLE;
Radio_ReceiveMsg();
}
/*****************************************************************************************
* FUNCTION: Radio_IrqHandler
*
* DESCRIPTION: Process a radio interrupt
*
* PARAMETERS: radioIrq - Event causing the interrupt
*
* RETURN: None
*****************************************************************************************/
void Radio_IrqHandler(RadioIrqMasks_t radioIrq)
{
switch (radioIrq)
{
case IRQ_TX_DONE:
break;
case IRQ_RX_DONE:
Radio_State = RADIO_STATE_RX_COMPLETE;
break;
case IRQ_RX_TX_TIMEOUT:
Radio_State = RADIO_STATE_RX_ERROR;
break;
case IRQ_CRC_ERROR:
Radio_State = RADIO_STATE_RX_ERROR;
break;
default:
Radio_State = RADIO_STATE_IDLE;
break;
}
}
/*****************************************************************************************
* FUNCTION: Radio_HandleTick
*
* DESCRIPTION: Process a Lora radio interrupt
*
* PARAMETERS: radioIrq - Event causing the interrupt
*
* RETURN: None
*****************************************************************************************/
void Radio_HandleTick(void)
{
char RxBuffer[RADIO_RX_BUFFER_SIZE];
if(Radio_State != RADIO_STATE_IDLE)
{
if(Radio_State == RADIO_STATE_RX_COMPLETE)
{
memset(RxBuffer, 0 , sizeof(RxBuffer));
SUBGRF_ReadBuffer( ZERO_OFFSET, (uint8_t *)RxBuffer, RADIO_RX_BUFFER_SIZE );
strcat(RxBuffer, Radio_CrlfText);
HAL_UART_Transmit(&huart2, (uint8_t *)RxBuffer, RADIO_RX_BUFFER_SIZE, HAL_MAX_DELAY);
BSP_LED_On(LED_RED);
HAL_Delay(500);
BSP_LED_Off(LED_RED);
}
else if(Radio_State == RADIO_STATE_RX_ERROR)
{
HAL_UART_Transmit(&huart2, (uint8_t *)Radio_TimeoutText, sizeof(Radio_TimeoutText) - 1, HAL_MAX_DELAY);
}
Radio_ReceiveMsg();
Radio_State = RADIO_STATE_IDLE;
}
}
/*****************************************************************************************
* FUNCTION: Radio_ReceiveMsg
*
* DESCRIPTION: Receive a message from the Roam Remote
*
* PARAMETERS: None
*
* RETURN: None
*****************************************************************************************/
void Radio_ReceiveMsg( void )
{
SUBGRF_SetDioIrqParams( IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR | IRQ_HEADER_ERROR,
IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR | IRQ_HEADER_ERROR,
IRQ_RADIO_NONE,
IRQ_RADIO_NONE );
SUBGRF_SetSwitch(RFO_LP, RFSWITCH_RX);
Radio_PacketParams.Params.LoRa.PayloadLength = 0xFF;
SUBGRF_SetPacketParams(&Radio_PacketParams);
SUBGRF_SetRx(LORA_RX_TIMEOUT << 6);
}
