SPI not working

Hello,

I think I have a big problem with the SPI communication :

I am currently trying to make a SPI communication between an "arduino" (Teensy 3.6), and a demo board (LPC5411X, based on NXP MCU LPC54114). The Teensy is the master, and the board is the slave.

Data that I receive and that I sent are wrong or shifted (84 instead of 44, 148 instead of 171 ...).
I think the problem is coming from Arduino :

  • LPC Slave + Teensy Master : Not OK
  • LPC Slave (same code) + LPC Master (another same board, same data) : OK
  • Teensy Master MISO to MOSI (same code) : OK
  • LPC Slave (same code) + Teensy Master Bit banging : OK
  • LPC Slave (same code) + Arduino Uno Master (same code) : Not OK
  • LPC Slave (same code) + Arduino Uno Master Bit banging : OK

Thus, I think the problem is coming from the code/Arduino but I dont know where and why.

I check with a scope, looks like everything is good (I dont have a signal analyzer), pin connection are ok, otherwise I receive only 0 or 255.

  • SCK 13
  • SS 10
  • MOSI 11
  • MISO 12

In the example, I sent 2 numbers with 5s delay, and if the slave receives the good number (171 and 8 ), it turn on and off a LED with the 5s delay (and sent back 44 and 171 ), but it is not happening (rarely it happens for some reasons ... ).

I tried to slow down the communication (9600Hz) : Not OK (NXP data sheet says up to 13MHz in slave mode, LPC Slave (same code) + LPC Master is working at 500kHZ, Teensy running at 180MHz)

SPI Mode 0 = CPOL 0 /CPHA 0, same settings on the slave.

Master test code :

#include <SPI.h>


void setup() {
  // put your setup code here, to run once:
  Serial.begin (115200);
  SPI.begin();
  pinMode(SS, OUTPUT);

  digitalWrite(SS, HIGH);
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  unsigned char x;

  delay(5000);

  digitalWrite(SS, LOW);
  x = SPI.transfer(171); //171=0xAB
  digitalWrite(SS, HIGH);

  Serial.print(x);
  delay(5000);

  digitalWrite(SS, LOW);
  x = SPI.transfer(8); //
  digitalWrite(SS, HIGH);

  Serial.print(x);
  while (1) {}
}

void loop() {
  // put your main code here, to run repeatedly:

}

Bit banging test code :

#include <SPI.h>

#define SSL_PIN 10
#define MISO_PIN 12
#define MOSI_PIN 11
#define SCK_PIN 13

void setup() {
  Serial.begin(115200);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, INPUT);
  pinMode(SCK_PIN, OUTPUT);
  pinMode(SSL_PIN, OUTPUT);
  digitalWrite(MOSI_PIN, LOW);
  digitalWrite(SCK_PIN, LOW);
  digitalWrite(SSL_PIN, HIGH);
  
  unsigned char rx = 0;
  unsigned char tx = 171;

  delay(5000);

  delay(100);
  digitalWrite(SSL_PIN, LOW);
  for( int i =0; i<8; i++){
      digitalWrite(MOSI_PIN, (tx)&(1<<(7-i)));
      digitalWrite(SCK_PIN, HIGH);
      delay(1);
      rx = rx + (digitalRead(MISO_PIN)<<(7-i));
      digitalWrite(SCK_PIN, LOW);
  }
  delay(100);
  digitalWrite(SSL_PIN, HIGH);

  Serial.print(rx);
  
  rx = 0;
  tx = 8;
  delay(5000);
  digitalWrite(SSL_PIN, LOW);
  for( int i =0; i<8; i++){
      digitalWrite(MOSI_PIN, (tx)&(1<<(7-i)));
      digitalWrite(SCK_PIN, HIGH);
      delay(1);
      rx = rx + (digitalRead(MISO_PIN)<<(7-i));
      digitalWrite(SCK_PIN, LOW);
  }
  delay(100);
  digitalWrite(SSL_PIN, HIGH);

  Serial.print(rx);



  while(1){}
}

void loop() {
  // put your main code here, to run repeatedly:
}

Slave test code :

#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "LPC54114_cm4.h"
/* TODO: insert other include files here. */
#include "fsl_spi.h"
#include "fsl_gpio.h"
/* TODO: insert other definitions and declarations here. */

spi_slave_handle_t handle;
static volatile bool slaveFinished = false;
static void slaveCallback(SPI_Type *base, spi_slave_handle_t *slaveHandle, status_t status, void *userData)
{
    slaveFinished = true;
}

int main(void) {
    unsigned int pin_bleu = 9;
    unsigned int port = 1;

    GPIO_PinWrite(GPIO, port, pin_bleu, 0);

	unsigned char tx = 0x2C; //44
	unsigned char rx;

  	/* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();

    spi_transfer_t xfer = {0};

    xfer.txData = &tx;
    xfer.rxData = &rx;
    xfer.dataSize = 1;

    SPI_SlaveTransferCreateHandle(SPI_1_PERIPHERAL, &handle, slaveCallback, NULL);

    SPI_SlaveTransferNonBlocking(SPI_1_PERIPHERAL, &handle, &xfer);
    while (slaveFinished != true){}
    slaveFinished = false;
    if( rx == 0xAB){
    	GPIO_PinWrite(GPIO, port, pin_bleu, 1);
    }

    xfer.txData = &rx;
    xfer.rxData = &rx;
    xfer.dataSize = 1;

    SPI_SlaveTransferNonBlocking(SPI_1_PERIPHERAL, &handle, &xfer);
    while (slaveFinished != true){}
    slaveFinished = false;
    if( rx == 0x8){
    	GPIO_PinWrite(GPIO, port, pin_bleu, 0);
    }




    while(1){}


    return 0 ;
}

I thing I am missing something, but I am currently completely lost :frowning:

Thank you very much in advance for your help
Regards,
Hugo

Sounds like a wiring problem. I agree that you don't get anything it you break one connection but the result you get sounds more like to long wires or electrical noise to the wires. I don't know well enough the hardware of the Teensie but the UNO should work, although you're at the limit with the voltage if you connect an UNO directly.

Yeah it is a very strange problem, and with bit banging I can only get a 1kHz SPI, so if anyone has an idea to solve this problem :frowning: