arduino/ArduinoCore-sam

SPI Mode 3 on Due doesn't work properly with new APIs i.e. using SPI.beginTransaction(SPISettings)

arpita-agrawal opened this issue · 2 comments

When I try to set SPI in Mode 3 on Due the first write doesn't work all the time. Upon investigating more I observed that when Due is set in Mode 3 the clock polarity on the oscilloscope is wrong for the cases it doesn't work on the first write, it generates Mode 0 clock.

The issue can be reproduced by using the following sketch to write to an EEPROM, the write in the setup function doesn't write correct data when the Clock of Mode 0 is generated when the SPI_Mode is set to Mode 3. However, the data written in the loop is read correctly and printed on Serial monitor when the:

#include <SPI.h>
// Using simple SPI APIs for Due
#define CSPin 4
#define CLKRate 16000000
void setup() {
  pinMode(CSPin ,OUTPUT);
  SPI.begin();
  digitalWrite(CSPin,HIGH);
  Serial.begin(9600);
  Serial.println("SETUP");
  SPI.beginTransaction(SPISettings(CLKRate, MSBFIRST, SPI_MODE3));
  digitalWrite(CSPin,LOW);

  SPI.transfer(6);
  digitalWrite(CSPin,HIGH);
  SPI.endTransaction();
  delay(10000);

  Serial.println("SETUP:WriteData"); 
  SPI.beginTransaction(SPISettings(CLKRate, MSBFIRST, SPI_MODE3));
  byte dataWrite[8] = {2, 0, 0, 1, 3, 8, 4, 6};
  digitalWrite(CSPin,LOW);

  for(int i = 0 ; i < 7;i++)
  {
    SPI.transfer(dataWrite[i]);
  }
  SPI.transfer(dataWrite[7]);
  digitalWrite(CSPin,HIGH);
  SPI.endTransaction();
  delay(10000);

  Serial.println("SETUP:ReadData");
  SPI.beginTransaction(SPISettings(CLKRate, MSBFIRST, SPI_MODE3));
  byte dataWrite1[8] = {3, 0, 0, 0, 0, 0, 0, 0};
  byte readData[8];
  digitalWrite(CSPin,LOW);

  for(int j = 0 ; j < 7;j++)
  {
    readData[j] = SPI.transfer(dataWrite1[j]);
    Serial.println(readData[j]);
  }
  readData[7] = SPI.transfer(dataWrite1[7]);
  Serial.println(readData[7]);
  digitalWrite(CSPin,HIGH);
  SPI.endTransaction();
  Serial.println("ExitingSetup");
}

void loop() {
  // put your main code here, to run repeatedly:
  // Set BitRate to 4 MHz
  Serial.println("LOOP");
  SPI.beginTransaction(SPISettings(CLKRate, MSBFIRST, SPI_MODE3));
  digitalWrite(CSPin,LOW);

  SPI.transfer(6);
  digitalWrite(CSPin,HIGH); 
  SPI.endTransaction(); 
  delay(1000); 
  SPI.beginTransaction(SPISettings(CLKRate, MSBFIRST, SPI_MODE3));
  byte dataWrite[8] = {2, 0, 0, 1, 3, 6, 4, 5};
  digitalWrite(CSPin,LOW);

  for(int i = 0 ; i < 7;i++)
  {
    SPI.transfer(dataWrite[i]);
  }
  SPI.transfer(dataWrite[7]);
  digitalWrite(CSPin,HIGH);
  SPI.endTransaction();
  delay(1000);
  SPI.beginTransaction(SPISettings(CLKRate, MSBFIRST, SPI_MODE3));
  byte dataWrite1[8] = {3, 0, 0, 0, 0, 0, 0, 0};
  byte readData[8];
  digitalWrite(CSPin,LOW);

  for(int j = 0 ; j < 7;j++)
  {
    readData[j] = SPI.transfer(dataWrite1[j]);
    Serial.println(readData[j]);
  }
  readData[7] = SPI.transfer(dataWrite1[7]);
  Serial.println(readData[7]);
  digitalWrite(CSPin,HIGH);
  SPI.endTransaction();
  delay(10000);
}

Does the CSPin have a pull-up resistor?

During the bootstrap, just after the reset, all the pins are configured as INPUT, so it may be that the CSPin may be low for some milliseconds (confusing the eeprom).

Hi,

I tried connecting a 10K pull-up to CSPin. But still the issue isn't resolved.

Thanks
Arpita