diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 4f520a27b0beaa996a516c36e8e3c934c9c8e83b..29ecbcb65f3b2b8469f058c9328f31c7d2473759 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -97,7 +97,11 @@ void SPIClass::setDataMode(uint8_t mode) void SPIClass::setClockDivider(uint8_t div) { - _p_sercom->setBaudrateSPI(div); + if (div < SPI_MIN_CLOCK_DIVIDER) { + _p_sercom->setBaudrateSPI(SPI_MIN_CLOCK_DIVIDER); + } else { + _p_sercom->setBaudrateSPI(div); + } } byte SPIClass::transfer(uint8_t data) diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index 02ac74f3156b01370cc3be6bf223cde9c41a0e60..6473ab23c6b4c69a020204c8db2563f78ebcd76a 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -18,6 +18,16 @@ #define SPI_MODE2 0x03 #define SPI_MODE3 0x01 +#if defined(__SAMD21G18A__) + // Even if not specified on the datasheet, the SAMD21G18A MCU + // doesn't operate correctly with clock dividers lower than 4. + // This allows a theoretical maximum SPI clock speed of 12Mhz + #define SPI_MIN_CLOCK_DIVIDER 4 + // Other SAMD21xxxxx MCU may be affected as well +#else + #define SPI_MIN_CLOCK_DIVIDER 2 +#endif + class SPISettings { public: SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) { @@ -36,8 +46,8 @@ class SPISettings { uint8_t div; if (clock < (F_CPU / 255)) { div = 255; - } else if (clock >= (F_CPU / 2)) { - div = 2; + } else if (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER)) { + div = SPI_MIN_CLOCK_DIVIDER; } else { div = (F_CPU / (clock + 1)) + 1; }