arduino / arduino/ArduinoCore-samd

SPI / SERCOM library doesn't seem to configure SPI clock correctly

Open
#603 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
502
Forks
740
PR merge metrics
No merged PRs in 30d

Description

I'm having difficulties interfacing with an SPI device on my Arduino MKR 1010. I checked the signal with a scope and it looks like the frequency is much higher than what I configured: the pulse width is 2us, even though I configured a clock of only 10kHz.

I checked the Arduino Core implementation [1] that contains the following logic:

```
sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate);

(...)

uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate)
{
return SERCOM_FREQ_REF / (2 * baudrate) - 1;
}
```

In my case, this would overflow the unit8_t.

This differs from other example SPI master initialization [2]:

```
// Calculate BAUD value
uint16_t BAUD_REG = ((float)SPI_CLK_FREQ / (float)(2 * SPI_BAUD)) - 1;

// Set the SPI baud rate
SPI_SERCOM->SPI.BAUD.reg = SERCOM_SPI_BAUD_BAUD(BAUD_REG);
```

And the macro seems to be defined as follows:

```
#define SERCOM_SPI_BAUD_BAUD_Pos 0 /**< \brief (SERCOM_SPI_BAUD) Baud Rate Value */
#define SERCOM_SPI_BAUD_BAUD_Msk (0xFFu << SERCOM_SPI_BAUD_BAUD_Pos)
#define SERCOM_SPI_BAUD_BAUD(value) ((SERCOM_SPI_BAUD_BAUD_Msk & ((value) << SERCOM_SPI_BAUD_BAUD_Pos)))
#define SERCOM_SPI_BAUD_MASK 0xFFu /**< \brief (SERCOM_SPI_BAUD) MASK Register */
```

Also, in the datasheet of SAMD21 [3], the initialization looks different:

```
SERCOM1->SPI.BAUD.reg = (system_gclk_chan_get_hz(SERCOM1_GCLK_ID_CORE)/(2*SPI_SPEED)) -
1;
```

I didn't dig deeper, so I could just be wrong. But: Is setting the SPI frequency to a lower values (like 10kHz) known to be working?

[1]: https://github.com/arduino/ArduinoCore-samd/blob/master/libraries/SPI/SPI.cpp
[2]: https://microchipdeveloper.com/32arm:samd21-sercom-spi-master-configuration
[3]: https://ww1.microchip.com/downloads/en/DeviceDoc/00002465A.pdf

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in libraries/SPI/SPI.cpp at calculateBaudrateSynchronous and compare its BAUD assignment with the SAMD21 datasheet and the linked SERCOM example. Verify whether a 10kHz SPI setting is represented correctly in the register and determine what change or clarification is needed for the observed clock frequency.

Written by the indexing model from the issue text.

Assessment

Tech stack
arduino, 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.