Skip to content

Commit eca1341

Browse files
committed
Limit SPI max clock speed to 12Mhz
SAMD21G18A doesn't operate correctly with clock dividers lower than 4
1 parent a2940ed commit eca1341

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

libraries/SPI/SPI.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@ void SPIClass::setDataMode(uint8_t mode)
9797

9898
void SPIClass::setClockDivider(uint8_t div)
9999
{
100-
_p_sercom->setBaudrateSPI(div);
100+
if (div < SPI_MIN_CLOCK_DIVIDER) {
101+
_p_sercom->setBaudrateSPI(SPI_MIN_CLOCK_DIVIDER);
102+
} else {
103+
_p_sercom->setBaudrateSPI(div);
104+
}
101105
}
102106

103107
byte SPIClass::transfer(uint8_t data)

libraries/SPI/SPI.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818
#define SPI_MODE2 0x03
1919
#define SPI_MODE3 0x01
2020

21+
#if defined(__SAMD21G18A__)
22+
// Even if not specified on the datasheet, the SAMD21G18A MCU
23+
// doesn't operate correctly with clock dividers lower than 4.
24+
// This allows a theoretical maximum SPI clock speed of 12Mhz
25+
#define SPI_MIN_CLOCK_DIVIDER 4
26+
// Other SAMD21xxxxx MCU may be affected as well
27+
#else
28+
#define SPI_MIN_CLOCK_DIVIDER 2
29+
#endif
30+
2131
class SPISettings {
2232
public:
2333
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
@@ -36,8 +46,8 @@ class SPISettings {
3646
uint8_t div;
3747
if (clock < (F_CPU / 255)) {
3848
div = 255;
39-
} else if (clock >= (F_CPU / 2)) {
40-
div = 2;
49+
} else if (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER)) {
50+
div = SPI_MIN_CLOCK_DIVIDER;
4151
} else {
4252
div = (F_CPU / (clock + 1)) + 1;
4353
}

0 commit comments

Comments
 (0)