FORUM

Sx1276 P2P not working

Hi,
I am new here, so sorry, if it is the wrong subforum.
I am using 2 sx1276 modules for a p2p communication between 2 raspberry pi pico microcontrollers.
I dont use a library currently and I would like to find the mistake instead of just using a library. The programming Language is C.
I am able to talk to the Modules for the microcontroller. I also get a Tx_done flag on the transmitting module, I just cant recieve anything on the other module. Does anybody have an Idea what could be going wrong?
I didnt see any nice way to attatch the code, so I just copied it here, sorry if there is a better way

reciever:
#include <stdio.h>
#include “pico/stdlib.h”
#include “hardware/spi.h”
uint8_t mosi=19;
uint8_t clock=18;
uint8_t cs=17;
uint8_t miso=16;
uint8_t dio0=0;
uint8_t dio5=1;

uint8_t RegFifo = 0x00;
uint8_t RegOpMode = 0x01;
uint8_t RegFrMsb = 0x06;
uint8_t RegFrMid = 0x07;
uint8_t RegFrLsb = 0x08;
uint8_t RegFifoAddrPtr = 0x0D;
uint8_t RegFifoTxBase = 0x0E;
uint8_t RegFifoRxBase = 0x0F;
uint8_t RegFifoRxCurrent = 0x10;
uint8_t RegIrqFlags = 0x12;
uint8_t RegRxNbBytes = 0x13;
uint8_t RegModemStat = 0x18;
uint8_t RegPktSnr = 0x19;
uint8_t RegPktRssi = 0x1A;
uint8_t RegRssi = 0x1B;
uint8_t RegModemConfig1 = 0x1D;
uint8_t RegModemConfig2 = 0x1E;
uint8_t RegDioMapping1 = 0x40;

uint8_t readReg(uint8_t reg);
void writeReg(uint8_t reg, uint8_t msg);

void writeFifo(uint8_t * msg, int count){
writeReg(RegFifoAddrPtr,readReg(RegFifoTxBase));
uint8_t package[count +1];
package[0]=RegFifo | 0x80;
for( int i=0;i<count;i++){
package[i+1]=msg[i+1];
}
gpio_put(cs,0);
spi_write_blocking(spi0,package, count+1);
sleep_ms(10);
gpio_put(cs,1);
}

void readFifo(uint8_t *buf, int count){
gpio_put(cs,0);
writeReg(RegFifoAddrPtr,readReg(RegFifoRxCurrent));
spi_write_blocking(spi0,&RegFifo,1);
spi_read_blocking(spi0,0,buf,count);
sleep_ms(10);
gpio_put(cs,1);
}

uint8_t readReg(uint8_t reg){
uint8_t result;
gpio_put(cs,0);
spi_write_blocking(spi0,&reg,1);
spi_read_blocking(spi0,0,&result, 1);
sleep_ms(10);
gpio_put(cs,1);
return result;
}

void writeReg(uint8_t reg, uint8_t msg){
uint8_t package[2];
package[0]=reg | 0x80;
package[1]=msg;
gpio_put(cs,0);
spi_write_blocking(spi0,package, 2);
sleep_ms(10);
gpio_put(cs,1);

}

void setMode(uint8_t mode){

if(mode<8){
    writeReg(RegOpMode, 0x00);
    writeReg(RegOpMode,0x80 | mode);
}
else{
    printf("invalid mode\n");
}

}

void loraInit(){
gpio_init(cs);
gpio_set_dir(cs,1);
gpio_put(cs,1);
gpio_init(dio0);
gpio_set_dir(dio0,0);
gpio_init(dio5);
gpio_set_dir(dio5,0);

spi_init(spi0,20000000);
spi_set_format(spi0,8,0,0,SPI_MSB_FIRST);

gpio_set_function(clock,GPIO_FUNC_SPI);
gpio_set_function(mosi,GPIO_FUNC_SPI);
gpio_set_function(miso,GPIO_FUNC_SPI);

writeReg(RegOpMode,0x00);  
writeReg(RegOpMode,0x00);
writeReg(RegOpMode,0x80);
writeReg(RegOpMode,0x85);
writeReg(RegFrMsb,0xD9);
writeReg(RegFrMid,0x40);

writeReg(RegModemConfig1,0x98);
writeReg(RegModemConfig2,0x70);
writeReg(RegDioMapping1,0x01);

}
int main() {
stdio_init_all();
loraInit();

while(1){
   if(gpio_get(dio0)){
       uint8_t msgSize = readReg(RegRxNbBytes);//read size of recieved packag
       printf("%d bytes recieved\n");
       uint8_t buf[msgSize];
       readFifo(buf, msgSize);
       writeReg(RegIrqFlags,0x40);
       printf("recieved message:\n");
       for(int i=0;i<msgSize; i++){
           printf("%d ",buf[i]);
       }
       printf("\n");
       
   } 
printf("%x %x %x %d %x \n", readReg(RegFrMsb), readReg(RegFrMid), readReg(RegOpMode), readReg(RegRssi)-157, readReg(RegModemStat));     
sleep_ms(500);
   
   
   
}

}
transmitter:
#include <stdio.h>
#include “pico/stdlib.h”
#include “hardware/spi.h”
uint8_t mosi=19;
uint8_t clock=18;
uint8_t cs=17;
uint8_t miso=16;
uint8_t dio0=0;
uint8_t dio5=1;

uint8_t RegFifo = 0x00;
uint8_t RegOpMode = 0x01;
uint8_t RegFrMsb = 0x06;
uint8_t RegFrMid = 0x07;
uint8_t RegFrLsb = 0x08;
uint8_t RegFifoAddrPtr = 0x0D;
uint8_t RegFifoTxBase = 0x0E;
uint8_t RegFifoRxBase = 0x0F;
uint8_t RegFifoRxCurrent = 0x10;
uint8_t RegIrqFlags = 0x12;
uint8_t RegRxNbBytes = 0x13;
uint8_t RegPktSnr = 0x19;
uint8_t RegPktRssi = 0x1A;
uint8_t RegRssi = 0x1B;
uint8_t RegModemConfig1 = 0x1D;
uint8_t RegModemConfig2 = 0x1E;
uint8_t RegDioMapping1 = 0x40;
uint8_t RegPayloadLength = 0x22;

uint8_t readReg(uint8_t reg);
void writeReg(uint8_t reg, uint8_t msg);

void writeFifo(uint8_t * msg, int count){
writeReg(RegFifoAddrPtr,readReg(RegFifoTxBase));
uint8_t package[count +1];
package[0]=RegFifo | 0x80;
for( int i=0;i<count;i++){
package[i+1]=msg[i+1];
}
gpio_put(cs,0);
spi_write_blocking(spi0,package, count+1);
writeReg(RegPayloadLength,count);
// sleep_ms(10);
gpio_put(cs,1);
}

void readFifo(uint8_t *buf, int count){
gpio_put(cs,0);
writeReg(RegFifoAddrPtr,readReg(RegFifoRxCurrent));
spi_write_blocking(spi0,&RegFifo,1);
spi_read_blocking(spi0,0,buf,count);
// sleep_ms(10);
gpio_put(cs,1);
}

uint8_t readReg(uint8_t reg){
uint8_t result;
gpio_put(cs,0);
spi_write_blocking(spi0,&reg,1);
spi_read_blocking(spi0,0,&result, 1);
// sleep_ms(10);
gpio_put(cs,1);
return result;
}

void writeReg(uint8_t reg, uint8_t msg){
uint8_t package[2];
package[0]=reg | 0x80;
package[1]=msg;
gpio_put(cs,0);
spi_write_blocking(spi0,package, 2);
// sleep_ms(10);
gpio_put(cs,1);

}

void setMode(uint8_t mode){

if(mode<8){
    writeReg(RegOpMode, 0x00);
    writeReg(RegOpMode,0x80 | mode);
}
else{
    printf("invalid mode\n");
}

}

void loraInit(){
gpio_init(cs);
gpio_set_dir(cs,1);
gpio_put(cs,1);
gpio_init(dio0);
gpio_set_dir(dio0,0);
gpio_init(dio5);
gpio_set_dir(dio5,0);

spi_init(spi0,20000000);
spi_set_format(spi0,8,0,0,SPI_MSB_FIRST);

gpio_set_function(clock,GPIO_FUNC_SPI);
gpio_set_function(mosi,GPIO_FUNC_SPI);
gpio_set_function(miso,GPIO_FUNC_SPI);

writeReg(RegOpMode,0x00);  
writeReg(RegOpMode,0x00);
writeReg(RegOpMode,0x80);
writeReg(RegOpMode,0x81);   //set lora standby mode

writeReg(RegFrMsb,0xD9);
writeReg(RegFrMid,0x40);    //set freq to 869MHz

writeReg(RegDioMapping1,0x40);

// writeReg(RegModemConfig1,0x98);
// writeReg(RegModemConfig2,0x74);
}
int main() {
stdio_init_all();
loraInit();

uint8_t test;

while(1){
   
    writeFifo(&test,1);     
    writeReg(RegOpMode,0x83); //set tx mode
    while(!gpio_get(dio0));//wait for tx done
    sleep_ms(10); 
    writeReg(RegIrqFlags,0x08); //reset tx done flag
    printf("sent message %d\n", test);
    printf("%x %x %x  \n", readReg(RegFrMsb), readReg(RegFrMid), readReg(RegOpMode));     
    sleep_ms(1000);
    ++test;
   

}

}
Thanks for your help

Does noone have an idea, what might be wrong here?

Why dont you debug it by writing a routine that prints all the registers just before the set TX and set RX are called ?

Run that debug print for a known working library and then run it for your setup.

Compare and understand the differences …

I dont have a known working library for the raspberry pi pico.
Thats the only reason, why I am doint this.

Then run the suggested register printout on another microcontroller.

You could for instance use a very cheap 3.3V Arduino Pro Mini, there are several LoRa libraries for Arduino.

I made some progress:
I can now recieve data on the pico from a normal raspberry pi, I just cant manage to transmit data. I managed to get data to the fifo buffer and I get the TxDone Flag on the transmitting Pico, but the other device, no matter if pico or normal raspberry pi, doesnt recieve any data.
The process to transmit data is

  1. set fifo pointer to fifoTxBaseAddr
  2. write payload to Fifo
  3. update payloadLength.

As far as I know, I am doing that and I cant think of anything that is going wrong. Any ideas?
I only add the writeFifo() method and my main loop, for better readability

void writeFifo(uint8_t * msg, int count){
uint8_t base=readReg(RegFifoTxBase);
printf("%x \n", base);
writeReg(RegFifoAddrPtr,base);
uint8_t package[count +1];
package[0]=RegFifo | 0x80;
for( int i=0;i<count;i++){
package[i+1]=msg[i];
}
for(int i=0;i<count+1;i++){
printf("%d “, package[i]);
}
printf(”\n");
gpio_put(cs,0);
spi_write_blocking(spi0,package, count+1);
sleep_ms(10);
gpio_put(cs,1);
writeReg(RegPayloadLength,count);
}

uint8_t test[3];
test[1]=2;
test[2]=4;

while(1){

    writeFifo(test,3);    
    printf("%d\n", readReg(RegPayloadLength));
    writeReg(RegFifoAddrPtr,0x80);
    printf("%x %x %x \n", readReg(RegFifo), readReg(RegFifo), readReg(RegFifo));
    writeReg(RegOpMode,0x83); //set tx mode
    while(!gpio_get(dio0));//wait for tx done
    sleep_ms(10);
    writeReg(RegIrqFlags,0x08); //reset tx done flag
    printf("sent message %d\n", test[0]);
//    printf("%x %x %x \n", readReg(RegFrMsb), readReg(RegFrMid), readReg(RegOpMode));    
    sleep_ms(1000);
    ++test[0];
}

If by ‘fifo’ you mean first in first out, then that does not apply to the internal buffer of a LoRa device.

The internal buffer of a LoRa device can be loaded in any sequence you care to.

In the data sheet, the buffer is called FiFo, so I thought, i would call it like that here.

Got it working, I switched PA_select from RFO to PA_Boost and it worked