I have a code for Arduino Nano RP2040 written with the usage of Raspberry Pi SDK (it was written to use with Raspberry Pi Pico, but then I switched to Arduino Nano Connect RP2040). Now I want to add WiFi functionality to it, so I want to control the WiFi NINA which is on the board.
I'm trying to port Arduino's WIFININA library to Raspberry Pi: change the pins numbers, replace the SPI functions with the ones from Raspberry SDK etc. Unfortunately already when sending first SPI command to WiFi module it fails. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
#define SET_PASSPHRASE_CMD 0x11
#define START_CMD 0xE0
#define END_CMD 0xEE
#define REPLY_FLAG 1<<7
#define NINA_GPIO0 (2u)
#define SPI1_CIPO (8u)
#define SPI1_COPI (11u)
#define SPI1_SCK (14u)
#define SPIWIFI_SS (9u)
#define SPIWIFI spi1
static uint8_t SLAVEREADY = 10; // handshake pin
static uint8_t SLAVERESET = 3; // reset pin
int transfer(uint8_t buf_to_write, uint8_t buf_to_read = 11)
{
printf("transfer - buf_to_write = %u, buf_to_read = %u \n", buf_to_write, buf_to_read);
int response{0};
response = spi_write_read_blocking(SPIWIFI, &buf_to_write, &buf_to_read, 1);
printf("transfer - response = %u, buf_to_read = %u \n", response, buf_to_read);
return response;
}
void sendCmd(uint8_t cmd, uint8_t numParam)
{
printf("sendCmd - cmd = %u, numParam = %u \n", cmd, numParam);
uint8_t buf_to_write{START_CMD};
transfer(buf_to_write);
buf_to_write = cmd & ~(REPLY_FLAG);
transfer(buf_to_write);
buf_to_write = numParam;
transfer(buf_to_write);
if(numParam == 0)
{
printf("sendCmd - END_CMD \n");
buf_to_write = END_CMD;
transfer(buf_to_write);
}
}
int main()
{
stdio_init_all();
sleep_ms(2000);
gpio_init(SPIWIFI_SS);
gpio_set_dir(SPIWIFI_SS, GPIO_OUT);
gpio_init(SLAVEREADY);
gpio_set_dir(SLAVEREADY, GPIO_IN);
gpio_init(SLAVERESET);
gpio_set_dir(SLAVERESET, GPIO_OUT);
gpio_init(NINA_GPIO0);
gpio_set_dir(NINA_GPIO0, GPIO_OUT);
gpio_put(NINA_GPIO0, 1);
gpio_put(SPIWIFI_SS, 1);
gpio_put(SLAVERESET, 0);
sleep_ms(10);
gpio_put(SLAVERESET, 1);
sleep_ms(750);
gpio_put(NINA_GPIO0, 0);
gpio_set_dir(NINA_GPIO0, GPIO_IN);
// initialize SPI
spi_init(SPIWIFI, 8000000);
spi_set_format(SPIWIFI, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
gpio_set_function(SPI1_COPI, GPIO_FUNC_SPI);
gpio_set_function(SPI1_SCK, GPIO_FUNC_SPI);
sleep_ms(10);
gpio_put(SPIWIFI_SS, 0);
sendCmd(SET_PASSPHRASE_CMD, 2);
gpio_put(SPIWIFI_SS, 1);
while(true)
{
sleep_ms(10);
}
}
Here is the result of the print:
sendCmd - cmd = 17, numParam = 2
transfer - buf_to_write = 224, buf_to_read = 11
transfer - response = 1, buf_to_read = 0
transfer - buf_to_write = 17, buf_to_read = 11
transfer - response = 1, buf_to_read = 0
transfer - buf_to_write = 2, buf_to_read = 11
transfer - response = 1, buf_to_read = 0
buf_to_read is always "0", but it should contain some response. When I run the same using Arduino's WIFININA, there is always some response. And for the response to command "17" is always "54". Any suggestions what am I doing wrong?
Below working version, which is using Arduino's SDK (communication with WiFi is based on WiFiNINA library, which can be found here https://github.com/arduino-libraries/WiFiNINA/tree/master/src/utility):
#include <SPI.h>
#include "pins_arduino.h"
#include "SPI.h"
#define SET_PASSPHRASE_CMD 0x11
#define START_CMD 0xE0
#define END_CMD 0xEE
#define REPLY_FLAG 1<<7
#define SLAVESELECT (26u)
#define SLAVEREADY (27u)
#define SLAVERESET (24u)
#define NINA_GPIO0 (20u)
char spiTransfer(volatile char data)
{
Serial.print("spiTransfer - data = ");
Serial.println((uint8_t)data);
char result = SPI1.transfer(data);
Serial.print("spiTransfer - result = ");
Serial.println((uint8_t)result);
return result; // return the received byte
}
void sendCmd(uint8_t cmd, uint8_t numParam)
{
Serial.print("sendCmd - cmd = ");
Serial.print(cmd);
Serial.print(" numParam = ");
Serial.println(numParam);
// Send SPI START CMD
spiTransfer(START_CMD);
// Send SPI C + cmd
spiTransfer(cmd & ~(REPLY_FLAG));
// Send SPI totLen
//spiTransfer(totLen);
// Send SPI numParam
spiTransfer(numParam);
// If numParam == 0 send END CMD
if (numParam == 0)
spiTransfer(END_CMD);
}
void setup()
{
Serial.begin(9600);
delay(2000);
pinMode(SLAVESELECT, OUTPUT);
pinMode(SLAVEREADY, INPUT);
pinMode(SLAVERESET, OUTPUT);
pinMode(NINA_GPIO0, OUTPUT);
digitalWrite(NINA_GPIO0, HIGH);
digitalWrite(SLAVESELECT, HIGH);
digitalWrite(SLAVERESET, LOW);
delay(10);
digitalWrite(SLAVERESET, HIGH);
delay(750);
digitalWrite(NINA_GPIO0, LOW);
pinMode(NINA_GPIO0, INPUT);
SPI1.begin();
SPI1.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
digitalWrite(SLAVESELECT,LOW);
sendCmd(SET_PASSPHRASE_CMD, 2);
digitalWrite(SLAVESELECT,HIGH);
SPI1.endTransaction();
}
void loop() {
// Nothing in the loop for this example
}
In this case the result is:
sendCmd - cmd = 17 numParam = 2
spiTransfer - data = 224
spiTransfer - result = 176
spiTransfer - data = 17
spiTransfer - result = 54
spiTransfer - data = 2
spiTransfer - result = 222
Both above codes send only part of full command. I wrote the full code which is sending the full command with parameters to connect to WiFi. In case of code which is using Raspberry's SDK it was failing, but the Arduino's was successful. Here I post only the first part to make it easier to read. Already in this part, there is a difference in the results.
I couldn't find any documentation for that WiFi module, which would allow to write driver for it. Hence I'm trying to port Arduino's WiFiNINA library.