diff --git a/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp b/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp
index 59f40a3655c1ef87e25c57a3f83c20cd4d0d7cd4..ef0dc8b1a2b121f5ff7ff3372bcdf936e5c3ebf4 100644
--- a/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp
+++ b/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp
@@ -1,4 +1,4 @@
-/**
+/*
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
@@ -94,7 +94,9 @@ void spiBegin (void) {
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
}
- //------------------------------------------------------------------------------
+
+
+ //------------------------------------------------------------------------------
/** SPI receive a byte */
uint8_t spiRec(void) {
SPDR = 0xFF;
@@ -132,6 +134,72 @@ void spiBegin (void) {
}
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
+
+
+ /** begin spi transaction */
+ void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
+ // Based on Arduino SPI library
+ // Clock settings are defined as follows. Note that this shows SPI2X
+ // inverted, so the bits form increasing numbers. Also note that
+ // fosc/64 appears twice
+ // SPR1 SPR0 ~SPI2X Freq
+ // 0 0 0 fosc/2
+ // 0 0 1 fosc/4
+ // 0 1 0 fosc/8
+ // 0 1 1 fosc/16
+ // 1 0 0 fosc/32
+ // 1 0 1 fosc/64
+ // 1 1 0 fosc/64
+ // 1 1 1 fosc/128
+
+ // We find the fastest clock that is less than or equal to the
+ // given clock rate. The clock divider that results in clock_setting
+ // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
+ // slowest (128 == 2 ^^ 7, so clock_div = 6).
+ uint8_t clockDiv;
+
+ // When the clock is known at compiletime, use this if-then-else
+ // cascade, which the compiler knows how to completely optimize
+ // away. When clock is not known, use a loop instead, which generates
+ // shorter code.
+ if (__builtin_constant_p(spiClock)) {
+ if (spiClock >= F_CPU / 2) {
+ clockDiv = 0;
+ } else if (spiClock >= F_CPU / 4) {
+ clockDiv = 1;
+ } else if (spiClock >= F_CPU / 8) {
+ clockDiv = 2;
+ } else if (spiClock >= F_CPU / 16) {
+ clockDiv = 3;
+ } else if (spiClock >= F_CPU / 32) {
+ clockDiv = 4;
+ } else if (spiClock >= F_CPU / 64) {
+ clockDiv = 5;
+ } else {
+ clockDiv = 6;
+ }
+ } else {
+ uint32_t clockSetting = F_CPU / 2;
+ clockDiv = 0;
+ while (clockDiv < 6 && spiClock < clockSetting) {
+ clockSetting /= 2;
+ clockDiv++;
+ }
+ }
+
+ // Compensate for the duplicate fosc/64
+ if (clockDiv == 6)
+ clockDiv = 7;
+
+ // Invert the SPI2X bit
+ clockDiv ^= 0x1;
+
+ SPCR = _BV(SPE) | _BV(MSTR) | ((bitOrder == SPI_LSBFIRST) ? _BV(DORD) : 0) |
+ (dataMode << CPHA) | ((clockDiv >> 1) << SPR0);
+ SPSR = clockDiv | 0x01;
+ }
+
+
//------------------------------------------------------------------------------
#else // SOFTWARE_SPI
//------------------------------------------------------------------------------
@@ -144,6 +212,12 @@ void spiBegin (void) {
UNUSED(spiRate);
}
+ /** Begin SPI transaction, set clock, bit order, data mode */
+ void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
+ // nothing to do
+ UNUSED(spiBeginTransaction);
+ }
+
//------------------------------------------------------------------------------
/** Soft SPI receive byte */
uint8_t spiRec() {
@@ -206,7 +280,7 @@ void spiBegin (void) {
spiSend(token);
for (uint16_t i = 0; i < 512; i++)
spiSend(buf[i]);
- }
+ }
#endif // SOFTWARE_SPI
diff --git a/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp b/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp
index 95123615c07641bdb0529fc428ddf446a5a61d59..2b9ec803877aa055fcf06b67463d0720e8a5579e 100644
--- a/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp
+++ b/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp
@@ -571,6 +571,12 @@
WRITE(SCK_PIN, LOW);
}
+ /** Begin SPI transaction, set clock, bit order, data mode */
+ void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
+ // TODO: to be implemented
+
+ }
+
#pragma GCC reset_options
#else
@@ -767,6 +773,13 @@
}
spiSend(buf[511]);
}
+
+ /** Begin SPI transaction, set clock, bit order, data mode */
+ void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
+ // TODO: to be implemented
+
+ }
+
#endif // ENABLED(SOFTWARE_SPI)
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp
index 507ac61cff74e3185247958361a544c6df3258ff..eb8d5ba98303218d8ae70d1900ea8d5455b25894 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp
@@ -299,6 +299,13 @@ PinCfg.Portnum = LPC1768_PIN_PORT(MISO_PIN);
// Write from buffer to SPI
void spiSendBlock(uint8_t token, const uint8_t* buf) {
}
+
+ /** Begin SPI transaction, set clock, bit order, data mode */
+ void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
+ // TODO: to be implemented
+
+ }
+
#endif // ENABLED(LPC_SOFTWARE_SPI)
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp
index 87169c5a512dde20984a09f770e25dd952bc60a2..650938c136c5b4e9d37d4068aaca5145643f7b58 100644
--- a/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp
@@ -164,6 +164,13 @@ void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPI.endTransaction();
}
+/** Begin SPI transaction, set clock, bit order, data mode */
+void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
+ spiConfig = SPISettings(spiClock, bitOrder, dataMode);
+
+ SPI.beginTransaction(spiConfig);
+}
+
#endif // SOFTWARE_SPI
#endif // __STM32F1__
diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp
index df6e0265f4d96e7c8f789e2f76ff79290d681246..25b3dc935574d8a05148a05ae8e05d8461b54461 100644
--- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp
+++ b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp
@@ -101,4 +101,12 @@ void spiSendBlock(uint8_t token, const uint8_t* buf) {
}
+/** Begin SPI transaction, set clock, bit order, data mode */
+void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
+ spiConfig = SPISettings(spiClock, bitOrder, dataMode);
+
+ SPI.beginTransaction(spiConfig);
+}
+
+
#endif
diff --git a/Marlin/src/HAL/SPI.h b/Marlin/src/HAL/SPI.h
index 632c50b9ad44c9ba6f4697efdb76f08c99db1dbe..d8c67076c2cfbc02c24630b34cdee362adf09858 100644
--- a/Marlin/src/HAL/SPI.h
+++ b/Marlin/src/HAL/SPI.h
@@ -55,6 +55,14 @@
#define SPI_SPEED_5 5 // Set SCK rate to 1/32 of max rate
#define SPI_SPEED_6 6 // Set SCK rate to 1/64 of max rate
+#define SPI_LSBFIRST 0
+#define SPI_MSBFIRST 1
+
+#define SPI_DATAMODE_0 0x00
+#define SPI_DATAMODE_1 0x04
+#define SPI_DATAMODE_2 0x08
+#define SPI_DATAMODE_3 0x0C
+
// Standard SPI functions
/** Initialise SPI bus */
void spiBegin(void);
@@ -68,5 +76,7 @@ uint8_t spiRec(void);
void spiRead(uint8_t* buf, uint16_t nbyte);
/** Write token and then write from 512 byte buffer to SPI (for SD card) */
void spiSendBlock(uint8_t token, const uint8_t* buf);
+/** Begin SPI transaction, set clock, bit order, data mode */
+void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode);
#endif // _SPI_H_