Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPI not working Raspberry Pico #417

Closed
steeley opened this issue Jan 14, 2022 · 5 comments
Closed

SPI not working Raspberry Pico #417

steeley opened this issue Jan 14, 2022 · 5 comments

Comments

@steeley
Copy link

steeley commented Jan 14, 2022

Have used SPI.h with Arduino and similar boards (Mostly Teensy 3.2/4) with various digital pots, swipes EEProms and all my code works fine.

Nothing appears to work using SPI on RPI Pico. :(

The code below controls a digital pot - works perfectly on every board I have tried. On Pico SPI signals appear to do nothing
Software defined CS line seems to be a square wave at 50Hz!!!.

I've tried setting the pins before initing the library( SPI.setTX(SPI_MOSI_PIN). etc but that seems to produce some signals
but they are just wrong, or not there.

#include <SPI.h>

const int slaveSelectPin = 10;
//other pins as default:  GP18=CLK GP19=TX for Pico. 13=CLK 11=TX for Teensy 4
void setup() {

  pinMode (slaveSelectPin, OUTPUT);
  SPI.begin();
  delay(500);
//SPI_CLOCK_DIV4 = 0
  //setup pot registers
  SPI.beginTransaction(SPISettings(0, MSBFIRST, SPI_MODE1));
  digitalWrite(slaveSelectPin,LOW);
  SPI.transfer(0x18);
  SPI.transfer(0x02);
  digitalWrite(slaveSelectPin,HIGH);
  SPI.endTransaction();
}

void loop() {
  unsigned int val;
  for (val = 10; val <= 500; val++) {
    digitalPotWrite(1024-val);
    delay(10);
  }
  for (val = 500; val > 10; val--) {
    digitalPotWrite(1024-val);
    delay(10);
  } 
}

void digitalPotWrite(unsigned int val) {
  SPI.beginTransaction(SPISettings(0, MSBFIRST, SPI_MODE1));
  digitalWrite(slaveSelectPin, LOW);
  byte highbyte = (val >> 8) + 0x04; //high wiper byte + command
  byte lowbyte = val & 0xFF;
  SPI.transfer(highbyte); //send wiper data high byte
  SPI.transfer(lowbyte); //send wiper data low byte
  digitalWrite(slaveSelectPin, HIGH);
  SPI.endTransaction();
}
@earlephilhower
Copy link
Owner

SPI most assuredly does work, at least well enough for myself and lots of other folks to interface displays and related stuff.

There is a debug SPI mode setting, enable it and set the debug port itself to Serial and re-run your tests to collect some information on what's being done in the core.

Off the bat, I think the 0 Hz max clock is causing your grief. Set it to 100000 or something (whatever the max SPI rate is for your devices) and retry.

@earlephilhower
Copy link
Owner

In fact, we take the max speed you pass in and send it directly to the SDK which is probably only able to give a 50hz SPI clock as its lowest speed.

spi_init(_spi, _spis.getClockFreq());

So, I do think changing 0 to the proper max speed of your devices will get things rolling.

@steeley
Copy link
Author

steeley commented Jan 14, 2022

Ok the issue with this library seems to be the CS line. In the code below I'm using software CS and it works.if I use hardware the line does nothing.
As you say there are many people using this successfully., perhaps you could point me to. a code example that shows this working.( on a Pico) I've not found any unfortunately.

`#include <SPI.h>
//#include <Arduino.h>

const uint8_t SPI_MISO = 16;
const uint8_t SPI_CS = 22; //17 Pico hardware default
const uint8_t SPI_SCK = 18;
const uint8_t SPI_MOSI = 19;
//

SPISettings parSPI(10000, MSBFIRST, SPI_MODE1);

void setup() {
Serial.begin(115200);
pinMode(22,OUTPUT);
//---- Define the SPI pins -------
SPI.setRX(SPI_MISO);
SPI.setTX(SPI_MOSI);
SPI.setSCK(SPI_SCK);
//SPI.setCS(SPI_CS);
SPI.begin();

//setup pot registers
SPI.beginTransaction(parSPI);
digitalWrite(SPI_CS,LOW);
SPI.transfer(0x18);
SPI.transfer(0x02);
digitalWrite(SPI_CS,HIGH);
SPI.endTransaction();
}

void loop() {
unsigned int val;
for (val = 10; val <= 500; val++) {
digitalPotWrite(1024-val);
delay(10);
}
for (val = 500; val > 10; val--) {
digitalPotWrite(1024-val);
delay(10);
}
}

void digitalPotWrite(unsigned int val) {
SPI.beginTransaction(parSPI);
digitalWrite(SPI_CS, LOW);
byte highbyte = (val >> 8) + 0x04; //high wiper byte + command
byte lowbyte = val & 0xFF;
SPI.transfer(highbyte); //send wiper data high byte
SPI.transfer(lowbyte); //send wiper data low byte
digitalWrite(SPI_CS, HIGH);
SPI.endTransaction();
}`

@earlephilhower
Copy link
Owner

The Adafruit graphics libraries and even the included SD card libraries use SPI, so you can look there. The WizNet W5100S-Pico also uses SPI to connect to the onboard TCP chip.

@steeley
Copy link
Author

steeley commented Jan 15, 2022

Got a colleague to try running SPI on a Pico and they got the same result.
Switched to a different SPI library and the Pico works perfectly again. Not going to waste anymore of your/my time on this.
Going with Mbed or back to our usual stm32 stuff.

@steeley steeley closed this as completed Jan 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants