Hi,
I have been struggling to get the SPI Slave mode to work correctly with the built-in functions. I am using a Raspberry Pi as the master, right now just sending 3 bytes (1, 2, 3), the clock speed is 2.5 MHz. I have tried 3 different ways, DMA transfer, single byte poll transfer, and bit banging. The only one I have gotten to work is the bit banging method.
Here is the logic analyzer output:
Here is the output for the 3 different modes:
Bit Bang Mode
Data Received: 01 02 03
Poll Mode
00 00 00
DMA Mode
Transfer Finished
Received 2 bytes
40 80
Here is the code:
#define NUMBYTES 3
static uint8_t rx_buffer[3];
static uint8_t tx_buffer[3];
static uint32_t select_state = 0x00;
static uint32_t transfer_state = 0x00;
int select_pin = A2;
int clock_pin = A3;
int data_pin = A5;
void onTransferFinished() {
Serial.println("Transfer Finished");
if (SPI.available() > 0) {
Serial.printf("Received %d bytes", SPI.available());
Serial.println();
for (int i = 0; i < SPI.available(); i++) {
Serial.printf("%02x ", rx_buffer[i]);
}
Serial.println();
}
}
void onSelect(uint8_t state) {
if (state) {
SPI.transfer(tx_buffer, rx_buffer, sizeof(rx_buffer), onTransferFinished);
}
//Serial.println("Select Called");
}
void onSelectPoll(uint8_t state) {
if (state) {
for (int i = 0; i < NUMBYTES; i++) {
rx_buffer[i] = SPI.transfer(1);
}
for (int i = 0; i < NUMBYTES; i++) {
Serial.printf("%02x ", rx_buffer[i]);
}
}
//Serial.println("Select Called");
}
void bitBangSPI() {
if (pinReadFast(select_pin) == LOW) {
for (int i = 0; i < NUMBYTES; i++) {
rx_buffer[i] = readSPIByte();
}
Serial.print("Data Received: ");
for (int i = 0; i < 3; i++) {
Serial.printf("%02x ", rx_buffer[i]);
}
Serial.println();
}
}
byte readSPIByte() {
byte spi_byte = 0;
for (int i = 0; i < 8; i++) {
//shift bit
spi_byte = spi_byte << 1;
//wait for clock to go high
while (pinReadFast(clock_pin) == LOW);
if (pinReadFast(data_pin) == HIGH) {
spi_byte |= 1;
}
while (pinReadFast(clock_pin) == HIGH);
}
return spi_byte;
}
void setup() {
Serial.begin(9600);
for (int i = 0; i < sizeof(tx_buffer); i++)
tx_buffer[i] = (uint8_t)i;
//SPI Setup
//dma method
Serial.println("DMA Mode");
SPI.onSelect(onSelect);
//Serial.println("Poll Mode");
//SPI.onSelect(onSelectPoll);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.begin(SPI_MODE_SLAVE, A2);
//for bit bang method
/*Serial.println("Bit Bang Mode");
pinMode(select_pin, INPUT);
pinMode(clock_pin, INPUT);
pinMode(data_pin, INPUT);
attachInterrupt(select_pin, bitBangSPI, FALLING);*/
}
void loop() {
}
Thanks for your help.