Hey all!
I have an STM32 MicroMod I’m working with, and I have been able to successfully interface with the SPI1 peripheral using the default pins (PA5 / PA6 / PA7). However using the exact same code, and changing out the pins to those associated with SPI2 on PB10 / PC2 / PB15, the code hangs at mySPI.transfer.
I’ve gone back and forth to the datasheet to re-verify the valid SPI2 pins, that the ports correspond to the LQFP64 pinout, that those are brought to the MicroMod connector, and how that connector is then brought to the headers of the ATP board:
SPI2 SCK = PB10 = uMod 14 = SCL
SPI2 CIPO (MISO) = PC2 = uMod 71 = G6
SPI2 COPI (MOSI) = PB15 = uMod 35 = HOST D+
SPI2 CS = PB9 = uMod 43 = CAN TX
When viewing this on a scope, none of the SPI signal pins do anything, but the CS pin does toggle low before the code hangs. I wrote some quick code to toggle them as standard GPIOs, verifying that I was connecting at the correct locations, and that there didn’t seem to be any hidden alternate default function, and that worked without issue. Using them as a SPI peripheral seems to cause a conflict that isn’t readily obvious. Just in case there was something I was unaware of that precluded using different SPI peripherals, I verified I could talk to the Flash module over SPI3 (using code not included here, but same setup and configuration essentially).
Here’s the code that hangs at “CODE HANGS HERE”. Commenting out #define USE_SPI2 reverts to the SPI1 default pins and runs normally.
/*
A sketch to control the 10-Bit, 8-channel ADC MCP3008
Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf
*/
#include <SPI.h> // Include the SPI library
#define USE_SPI2
#ifdef USE_SPI2 // SPI2 Peripheral Pins
#define MYSPI_SCLK PB10
#define MYSPI_MISO PC2
#define MYSPI_MOSI PB15
#define MYSPI_NSS PB9
#else // SPI1 Peripheral Pins
#define MYSPI_SCLK PA5
#define MYSPI_MISO PA6
#define MYSPI_MOSI PA7
#define MYSPI_NSS PC4
#endif
SPISettings MCP3008 (2000000, MSBFIRST, SPI_MODE0);
SPIClass mySPI(MYSPI_MOSI, MYSPI_MISO, MYSPI_SCLK);
const byte adc_single_ch0 = (0x08); // ADC Channel 0
const byte adc_single_ch1 = (0x09); // ADC Channel 1
const byte adc_single_ch2 = (0x0A); // ADC Channel 2
const byte adc_single_ch3 = (0x0B); // ADC Channel 3
const byte adc_single_ch4 = (0x0C); // ADC Channel 4
const byte adc_single_ch5 = (0x0D); // ADC Channel 5
const byte adc_single_ch6 = (0x0E); // ADC Channel 6
const byte adc_single_ch7 = (0x0F); // ADC Channel 7
uint8_t counter = 0; // Used for debug
void setup() {
pinMode (LED_BUILTIN, OUTPUT); // Used for debug
Serial.begin (115200);
delay(1000);
mySPI.begin ();
// Datasheet suggests toggling NSS to initialize chip
pinMode (MYSPI_NSS, OUTPUT);
digitalWrite (MYSPI_NSS, LOW);
digitalWrite (MYSPI_NSS, HIGH);
}
void loop() {
counter++;
double vRef = 3.30;
int adc_reading = 0;
adc_reading = adc_single_channel_read (adc_single_ch7);
Serial.print ("ADC Ch ");
Serial.print (adc_single_ch7 & 0x07);
Serial.print ("... Reading: ");
Serial.print (adc_reading);
Serial.print (" and Voltage: ");
Serial.println ((adc_reading * vRef) / 1024, 4);
Serial.println ();
delay(125);
}
int adc_single_channel_read(byte readAddress) {
byte dataMSB = 0;
byte dataLSB = 0;
byte JUNK = 0x00;
// Output to serial monitor that we got this far and toggle the LED
Serial.println ("SPI TEST: " + String(counter));
digitalWrite (LED_BUILTIN, HIGH);
delay (125);
digitalWrite (LED_BUILTIN, LOW);
delay (125);
mySPI.beginTransaction (MCP3008); // Use the SPI configuration
digitalWrite (MYSPI_NSS, LOW); // Drive MYSPI CS Low
mySPI.transfer (0x01); // Transmit Start Bit <---- CODE HANGS HERE
dataMSB = mySPI.transfer(readAddress << 4) & 0x03; // Send readAddress and receive MSB data, masked to two bits
dataLSB = mySPI.transfer(JUNK); // Push junk data and get LSB byte return
digitalWrite (MYSPI_NSS, HIGH);
mySPI.endTransaction ();
return dataMSB << 8 | dataLSB;
}