Hi everyone,
I turn to you because I have problems making two LoRa devices talk to each other.
I bought two SX1261DVK1BAS Development Kits and I separated one of these to integrate the SX1261 card into a card with a TM4C129.
The goal is to have the master with the TM4C129 and the slave with the second Dev Kit.
I have configured the parameters identically in order to permit them to communicate.
My problem is that when I try to send a signal with the first, the second receives nothing and when I send a signal with the second, the first does not receive anything either.
However I think I did the right thing at the init level, the configuration of the ports and the main ...
I'm a little desperate and really don't know what to do to find the problem.
Thank you very much for your help
Init :
void SX126xIoInit( void )
{
/* CS */
MAP_GPIOPinTypeGPIOOutput(RADIO_NSS); //output
GPIOPinWrite(RADIO_NSS,GPIO_PIN_4); //mise à 1 de la pin
/* BUSY */
GPIOPinWrite(RADIO_BUSY, 0); //mise à 0 de la pin
MAP_GPIOPinTypeGPIOInput(RADIO_BUSY); //input
GPIOPadConfigSet(RADIO_BUSY, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); //Pull Up enabled
/* IRQ */
MAP_GPIOPinTypeGPIOInput(RADIO_DIO_1); // input
GPIOPinWrite(RADIO_DIO_1, 0); //mise à 0 de la pin
MAP_GPIOIntEnable(RADIO_DIO_1);
GPIOPadConfigSet(RADIO_DIO_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); //Pull Up enabled
/*ANT SW*/
GPIOPinWrite(RADIO_ANT_SWITCH_POWER, 0); //mise à 0 de la pin
MAP_GPIOPinTypeGPIOOutput(RADIO_ANT_SWITCH_POWER); //output
/* RESET */
GPIOPinWrite(RADIO_RESET, 0); //mise à 0 de la pin
MAP_GPIOPinTypeGPIOOutput(RADIO_RESET);
/* SPI SSI1 */
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
GPIOPinConfigure(GPIO_PB5_SSI1CLK);
GPIOPinConfigure(GPIO_PE4_SSI1XDAT0); // MOSI (TX)
GPIOPinConfigure(GPIO_PE5_SSI1XDAT1); // MISO (RX)
GPIOPinTypeSSI(SPI_CLOCK);
GPIOPinTypeSSI(SPI_MOSI);
GPIOPinTypeSSI(SPI_MISO);
SSIConfigSetExpClk(SSI1_BASE,
HRD_u32SysClock,
SSI_FRF_MOTO_MODE_0,
SSI_MODE_MASTER,
SX126x_BIT_RATE,
SX126x_DATA_LENGHT);
SSIEnable(SSI1_BASE);
}
void SX126xIoIrqInit(void)
{
MAP_IntEnable(INT_GPIOC);
MAP_GPIOIntTypeSet(RADIO_DIO_1, GPIO_RISING_EDGE);
MAP_IntPrioritySet(INT_GPIOC, (6 << 5));
}
void SX126xReset( void )
{
HRD_vdDelayMs(10);
MAP_GPIOPinWrite(RADIO_RESET, 0);
HRD_vdDelayMs(20);
MAP_GPIOPinWrite(RADIO_RESET, GPIO_PIN_4);
HRD_vdDelayMs(10);
}
void SX126xAntSwOn( void )
{
GPIOPinWrite(RADIO_ANT_SWITCH_POWER, GPIO_PIN_2); //mise à 1 de la pin
}
void SX126xAntSwOff( void )
{
GPIOPinWrite(RADIO_ANT_SWITCH_POWER, 0); //mise à 0 de la pin
}
Main :
const uint8_t PingMsg[] = "PING";
const uint8_t PongMsg[] = "PONG";
uint16_t BufferSize = BUFFER_SIZE;
uint8_t Buffer[BUFFER_SIZE];
States_t State = LOWPOWER;
int8_t RssiValue = 0;
int8_t SnrValue = 0;
/*!
* Radio events function pointer
*/
static RadioEvents_t RadioEvents;
/*!
* \brief Function to be executed on Radio Tx Done event
*/
void OnTxDone( void )
{
Radio.Sleep( );
State = TX;
}
/*!
* \brief Function to be executed on Radio Rx Done event
*/
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
Radio.Sleep( );
BufferSize = size;
memcpy( Buffer, payload, BufferSize );
RssiValue = rssi;
SnrValue = snr;
State = RX;
}
/*!
* \brief Function executed on Radio Tx Timeout event
*/
void OnTxTimeout( void )
{
Radio.Sleep( );
State = TX_TIMEOUT;
}
/*!
* \brief Function executed on Radio Rx Timeout event
*/
void OnRxTimeout( void )
{
Radio.Sleep( );
State = RX_TIMEOUT;
}
/*!
* \brief Function executed on Radio Rx Error event
*/
void OnRxError( void )
{
Radio.Sleep( );
State = RX_ERROR;
}
void LoRa_Task(void * pvParrameters)
{
bool isMaster = true;
uint8_t i;
// Target board initialization
SX126xIoInit();
// SSI1_INIT_DYN();
// Radio initialization
RadioEvents.TxDone = OnTxDone;
RadioEvents.RxDone = OnRxDone;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxTimeout = OnRxTimeout;
RadioEvents.RxError = OnRxError;
Radio.Init( &RadioEvents );
Radio.SetChannel( RF_FREQUENCY );
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.Rx( RX_TIMEOUT_VALUE );
while( 1 )
{
switch( State )
{
case RX:
if( isMaster == true )
{
if( BufferSize > 0 )
{
if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 )
{
// Send the next PING frame
strcpy( ( char* )Buffer, ( char* )PingMsg );
// We fill the buffer with numbers for the payload
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
HRD_vdDelayMs( 1000 );
Radio.Send( Buffer, BufferSize );
}
else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
{ // A master already exists then become a slave
isMaster = false;
// Send the next PONG frame
strcpy( ( char* )Buffer, ( char* )PongMsg );
// We fill the buffer with numbers for the payload
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
HRD_vdDelayMs( 1000 );
Radio.Send( Buffer, BufferSize );
}
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
{
if( BufferSize > 0 )
{
if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
{
// Send the reply to the PING string
strcpy( ( char* )Buffer, ( char* )PongMsg );
// We fill the buffer with numbers for the payload
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
HRD_vdDelayMs( 1000 );
Radio.Send( Buffer, BufferSize );
}
else // valid reception but not a PING as expected
{ // Set device as master and start again
isMaster = true;
Radio.Rx( RX_TIMEOUT_VALUE );
}
}
}
State = LOWPOWER;
break;
case TX:
if( isMaster == true )
{
//debug( "Ping...\r\n" );
}
else
{
//debug( "Pong...\r\n" );
}
Radio.Rx( RX_TIMEOUT_VALUE );
State = LOWPOWER;
break;
case RX_TIMEOUT:
if( isMaster == true )
{
// Send the next PING frame
strcpy( ( char* )Buffer, ( char* )PingMsg );
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
HRD_vdDelayMs( 1000 );
Radio.Send( Buffer, BufferSize );
}
else
{
Radio.Rx( RX_TIMEOUT_VALUE );
}
State = LOWPOWER;
break;
case RX_ERROR:
// We have received a Packet with a CRC error, send reply as if packet was correct
if( isMaster == true )
{
// Send the next PING frame
strcpy( ( char* )Buffer, ( char* )PingMsg );
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
HRD_vdDelayMs( 1000 );
Radio.Send( Buffer, BufferSize );
}
else
{
// Send the next PONG frame
strcpy( ( char* )Buffer, ( char* )PongMsg );
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
HRD_vdDelayMs( 1000 );
Radio.Send( Buffer, BufferSize );
}
State = LOWPOWER;
break;
case TX_TIMEOUT:
Radio.Rx( RX_TIMEOUT_VALUE );
State = LOWPOWER;
break;
case LOWPOWER:
break;
default:
State = LOWPOWER;
break;
}
// Process Radio IRQ
if( Radio.IrqProcess != NULL )
{
Radio.IrqProcess( );
}
HRD_vdDelayMs(10);
}
}