arduino / arduino/ArduinoCore-sam

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

Open
#72 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
HTML
Stars
91
Forks
112
PR merge metrics
No merged PRs in 30d

Description

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
// 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);
}
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at the SPI.beginTransaction(SPISettings) path and reproduce the provided sketch on an Arduino Due while observing the clock signal. The work is done when SPI_MODE3 consistently produces Mode 3 clock polarity on the first write, including the setup transaction, and the EEPROM receives the correct data.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.