Arm Mbed OS support forum

Trouble getting the SX1272PingPong demo to function properly

Hello, I’ll start by saying that I don’t know very much at all about radio in general and I also don’t have very much experience with embedded development and with that said, here’s my issue:

I have 2x Nucleo-L073RZ and 2x SX1272MB2DAS Shield and I’ve been trying to get the SX1272PingPong demo to run, which it does, however; it doesn’t really do anything.
What happens is that it enters the LOWPOWER/Idle state and just sits there and I’m not quite sure of why.

I’m ultimately interested in LoRa Radio, e.g. NOT LoRaWAN, all I want to do is send some data between my boards but I’m not entirely sure if mbed is a good fit for this because I haven’t managed to find very much info that isn’t directly related to the LoRaWAN API, except for the PingPong demo.

I’m not using the SX1272Lib that the PingPong demo is using, but rather the driver that is supplied by mbed and the API is slightly different but I think I’ve managed to convert it correctly but none of the events are ever invoked, except the cad_done event which I’ve seen a few times, typically after having left the board running for a few minutes.

This is the mbed_app.json i’m using based on https://github.com/ARMmbed/mbed-os-example-lorawan/blob/master/mbed_app.json although i’ve omitted some(i think anyways) unrelated stuff

{
    "config": {
        "lora-radio": {
            "help": "Which radio to use (options: SX1272,SX1276)",
            "value": "SX1272"
        },
        "main_stack_size":     { "value": 4096 },
 
        "lora-spi-mosi":       { "value": "NC" },
        "lora-spi-miso":       { "value": "NC" },
        "lora-spi-sclk":       { "value": "NC" },
        "lora-cs":             { "value": "NC" },
        "lora-reset":          { "value": "NC" },
        "lora-dio0":           { "value": "NC" },
        "lora-dio1":           { "value": "NC" },
        "lora-dio2":           { "value": "NC" },
        "lora-dio3":           { "value": "NC" },
        "lora-dio4":           { "value": "NC" },
        "lora-dio5":           { "value": "NC" },
        "lora-rf-switch-ctl1": { "value": "NC" },
        "lora-rf-switch-ctl2": { "value": "NC" },
        "lora-txctl":          { "value": "NC" },
        "lora-rxctl":          { "value": "NC" },
        "lora-ant-switch":     { "value": "NC" },
        "lora-pwr-amp-ctl":    { "value": "NC" },
        "lora-tcxo":           { "value": "NC" }
    },
    "target_overrides": {
        "*": {
            "target.components_add": ["SX1272"],
            "platform.stdio-baud-rate": 9600,
            "platform.default-serial-baud-rate": 9600
        },

        "NUCLEO_L073RZ": {
            "lora-radio":          "SX1272",
            "lora-spi-mosi":       "D11",
            "lora-spi-miso":       "D12",
            "lora-spi-sclk":       "D13",
            "lora-cs":             "D10",
            "lora-reset":          "A0",
            "lora-dio0":           "D2",
            "lora-dio1":           "D3",
            "lora-dio2":           "D4",
            "lora-dio3":           "D5",
            "lora-dio4":           "NC",
            "lora-dio5":           "NC",
            "lora-rf-switch-ctl1": "NC",
            "lora-rf-switch-ctl2": "NC",
            "lora-txctl":          "NC",
            "lora-rxctl":          "NC",
            "lora-ant-switch":     "NC",
            "lora-pwr-amp-ctl":    "NC",
            "lora-tcxo":           "NC"
        }
    }
}

I’m not even sure that “target.components_add” thing is required but i noticed it lets me include “SX1272_LoRaRadio.h” instead of writing like “components/lora/blah/blah/SX1272…-” so i kept it

SX1272LoRaRadio constructor

PingPonger::PingPonger() : 
loraRadio(
        MBED_CONF_APP_LORA_SPI_MOSI,
        MBED_CONF_APP_LORA_SPI_MISO, 
        MBED_CONF_APP_LORA_SPI_SCLK, 
        MBED_CONF_APP_LORA_CS, 
        MBED_CONF_APP_LORA_RESET, 
        MBED_CONF_APP_LORA_DIO0,
        MBED_CONF_APP_LORA_DIO1,
        MBED_CONF_APP_LORA_DIO2,
        MBED_CONF_APP_LORA_DIO3,
        NC,
        NC
    )
{}
void PingPonger::Run(void)
{
    radio_events loraEvents;

    loraEvents.tx_done = mbed::callback(this, &PingPonger::OnTransmitDone);
    loraEvents.tx_timeout = mbed::callback(this, &PingPonger::OnTransmitTimeout);

    loraEvents.rx_done = mbed::callback(this, &PingPonger::OnReceiveDone);
    loraEvents.rx_error = mbed::callback(this, &PingPonger::OnReceiveError);
    loraEvents.rx_timeout =  mbed::callback(this, &PingPonger::OnReceiveTimeout);

    loraEvents.fhss_change_channel = mbed::callback(this, &PingPonger::OnFHHSChangeChannel);
    loraEvents.cad_done = mbed::callback(this, &PingPonger::OnCADDone);

    loraRadio.lock(); //unsure what the use of this is tbh, is it required before all calls to the driver?
    loraRadio.init_radio(&loraEvents);
    loraRadio.unlock(); 

    loraRadio.set_tx_config(
        MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
        LORA_SPREADING_FACTOR, LORA_CODINGRATE,
        LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
        LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
        LORA_IQ_INVERSION_ON, 2000
    );

    loraRadio.set_rx_config(
        MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
        LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
        LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
        LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
        LORA_IQ_INVERSION_ON, true 
    );

    Process();
}
void PingPonger::OnTransmitDone(void)
{
    loraRadio.sleep();
    loraState = ApplicationStates::TX;
    debug_if(DEBUG_MESSAGE, "> OnTransmitDone");
}

void PingPonger::OnTransmitTimeout(void) 
{
    loraRadio.sleep();
    loraState = ApplicationStates::TX_TIMEOUT;
    debug_if(DEBUG_MESSAGE, "> OnTransmitTimeout");
}

void PingPonger::OnReceiveDone(const uint8_t* payload, const uint16_t size, const int16_t rssi, const int8_t snr) 
{
    loraRadio.sleep();
    loraState = ApplicationStates::RX;
    debug_if(DEBUG_MESSAGE, "> OnReceiveDone");
}

void PingPonger::OnReceiveTimeout(void) 
{
    loraRadio.sleep();
    loraState = ApplicationStates::RX_TIMEOUT;
    debug_if(DEBUG_MESSAGE, "> OnReceiveTimeout");
}

void PingPonger::OnReceiveError(void) 
{
    loraRadio.sleep();
    loraState = ApplicationStates::RX_ERROR;
    debug_if(DEBUG_MESSAGE, "> OnReceiveError");
}

void PingPonger::OnFHHSChangeChannel(uint8_t channel_index) 
{
    loraRadio.sleep();
    loraState = ApplicationStates::FHHS;
    debug_if(DEBUG_MESSAGE, "> OnFHHSChangeChannel");
}

void PingPonger::OnCADDone(bool channelActivity) 
{
    loraRadio.sleep();
    loraState = ApplicationStates::CAD_DONE;
    debug_if(DEBUG_MESSAGE, "> OnCADDone");
}

The differences between my code and the PingPong demo are only structural.
As far as I gathered from the demo, the rx_timeout event is what should cause the entire thing to tick and send the first ping after the timeout value have been supplied to SX1272_LoRaRadio::receive() but it never times out and the application just keeps cranking in the low power state.

Any input, hints or directions is greatly appreciated, thanks in advance.