Extending the NINA firmware

Hi. So I was wondering about adding a few custom commands to the WiFi NINA firmware for my Nano RP2040 Connect. To start off, I just wanted to add a simple "ping" command (with no parameters) which would reply with a 4-character long string "pong".
I cloned the arduino/nina-fw repository and set up my building environment according to the README in the repo. I am able to successfully compile the firmware.
Since the is no documentation on adding custom commands. I just guessed the following:

main/CommandHandler.cpp:
I added my command handler to the commandHandlers array:

const CommandHandlerType commandHandlers[] = {
  ...
  stupidPing, //0x80
  ...
};

Above this array, I added the function which handles the command:

int stupidPing(const uint8_t command[], uint8_t response[])
{
  //Dumb ping command - responds with "pong" (char[4])
  const char response_msg[5] = "pong";
  uint8_t msgLen = strlen(response_msg);

  response[2] = 1; // number of parameters
  response[3] = msgLen; // parameter 1 length
  memcpy(&response[4], response_msg, msgLen);
  return (5 + msgLen);
}

I compiled and flashed this modified firmware to the ublox module.
Of course, the WiFiNINA library also had to be modified, which I did like this:

WiFiNINA/src/utility/wifi_spi.h:

enum {
  ...
  STUPID_PING = 0x80,
}

WiFiNINA/src/utility/wifi_drv.cpp:

bool WiFiDrv::stupidPing(uint8_t* rcvd){
    WAIT_FOR_SLAVE_SELECT();

    // Send Command
    SpiDrv::sendCmd(STUPID_PING, PARAM_NUMS_1);

    uint8_t _dummy = DUMMY_DATA;
    SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);

    // pad to multiple of 4
    SpiDrv::readChar();
    SpiDrv::readChar();

    SpiDrv::spiSlaveDeselect();
    //Wait the reply elaboration
    SpiDrv::waitForSlaveReady();
    SpiDrv::spiSlaveSelect();

    char msg[5];
    memset(msg, 0x00, sizeof(msg));

    // Wait for reply
    uint8_t _dataLen = 0;
    SpiDrv::waitResponseCmd(STUPID_PING, PARAM_NUMS_1, (uint8_t*)msg, &_dataLen);
    *rcvd = _dataLen;

    SpiDrv::spiSlaveDeselect();

    return strcmp(msg, "pong") == 0;
}

(I also added this command to the WiFiDrv class in wifi_drv.h)

Now I used the following sketch to test this command:

#include <WiFiNINA.h>

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.println("Testing STUPID_PING command!");
  uint8_t rcvd = 0;
  bool x = WiFiDrv::stupidPing(&rcvd);
  if(x){
    Serial.println("Test successfull!");
  } else {
    Serial.println("Test failed");
  }
  Serial.print("Bytes received: ");
  Serial.println(rcvd);
}

void loop() {
  
}

I keep getting "Test failed" and 0 bytes received on the serial monitor and it also looks like SpiDrv::waitResponseCmd() is failing (returns 0).
Could someone please help me?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.