diff --git a/hardware/arduino/sam/libraries/SPI/SPI.cpp b/hardware/arduino/sam/libraries/SPI/SPI.cpp index 9517e22263a..4307d2ca2a7 100644 --- a/hardware/arduino/sam/libraries/SPI/SPI.cpp +++ b/hardware/arduino/sam/libraries/SPI/SPI.cpp @@ -25,6 +25,7 @@ void SPIClass::begin() { setClockDivider(BOARD_SPI_DEFAULT_SS, 21); setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0); setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST); + setTransferWidth(BOARD_SPI_DEFAULT_SS, SPI_WIDTH_8); } void SPIClass::begin(uint8_t _pin) { @@ -41,6 +42,7 @@ void SPIClass::begin(uint8_t _pin) { setClockDivider(_pin, 21); setDataMode(_pin, SPI_MODE0); setBitOrder(_pin, MSBFIRST); + setTransferWidth(_pin, SPI_WIDTH_8); } void SPIClass::init() { @@ -73,18 +75,28 @@ void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) { mode[ch] = _mode | SPI_CSR_CSAAT; // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed // transfer. Some device needs that for working properly. - SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1)); + SPI_ConfigureNPCS(spi, ch, mode[ch] | width[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1)); } +void SPIClass::setTransferWidth(uint8_t _pin, uint8_t _width) { + uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin); + width[ch] = _width<<8; + // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed + // transfer. Some device needs that for working properly. + SPI_ConfigureNPCS(spi, ch, mode[ch] | width[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1)); +} + + void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) { uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin); divider[ch] = _divider; // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed // transfer. Some device needs that for working properly. - SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1)); + SPI_ConfigureNPCS(spi, ch, mode[ch] | width[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1)); } -byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) { + +byte SPIClass::transfer(byte _pin, uint16_t _data, SPITransferMode _mode) { uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin); // Reverse bit order if (bitOrder[ch] == LSBFIRST) @@ -105,7 +117,7 @@ byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) { // Reverse bit order if (bitOrder[ch] == LSBFIRST) d = __REV(__RBIT(d)); - return d & 0xFF; + return d & (1<<(8+width[ch])-1); } void SPIClass::attachInterrupt(void) { diff --git a/hardware/arduino/sam/libraries/SPI/SPI.h b/hardware/arduino/sam/libraries/SPI/SPI.h index 735bd4bf9a5..e4d81b9d789 100644 --- a/hardware/arduino/sam/libraries/SPI/SPI.h +++ b/hardware/arduino/sam/libraries/SPI/SPI.h @@ -23,13 +23,25 @@ enum SPITransferMode { SPI_CONTINUE, SPI_LAST }; +enum SPITransferWidth { + SPI_WIDTH_8, + SPI_WIDTH_9, + SPI_WIDTH_10, + SPI_WIDTH_11, + SPI_WIDTH_12, + SPI_WIDTH_13, + SPI_WIDTH_14, + SPI_WIDTH_15, + SPI_WIDTH_16 +}; class SPIClass { public: SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)); - byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST) { return transfer(BOARD_SPI_DEFAULT_SS, _data, _mode); } - byte transfer(byte _channel, uint8_t _data, SPITransferMode _mode = SPI_LAST); + byte transfer(uint16_t _data, SPITransferMode _mode = SPI_LAST) { return transfer(BOARD_SPI_DEFAULT_SS, _data, _mode); } + byte transfer(byte _channel, uint16_t _data, SPITransferMode _mode = SPI_LAST); + // SPI Configuration methods @@ -46,12 +58,14 @@ class SPIClass { // These methods sets a parameter on a single pin void setBitOrder(uint8_t _pin, BitOrder); void setDataMode(uint8_t _pin, uint8_t); + void setTransferWidth(uint8_t _pin, uint8_t _width); void setClockDivider(uint8_t _pin, uint8_t); // These methods sets the same parameters but on default pin BOARD_SPI_DEFAULT_SS void setBitOrder(BitOrder _order) { setBitOrder(BOARD_SPI_DEFAULT_SS, _order); }; void setDataMode(uint8_t _mode) { setDataMode(BOARD_SPI_DEFAULT_SS, _mode); }; void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); }; + void setTransferWidth(uint8_t _width) { setTransferWidth(BOARD_SPI_DEFAULT_SS, _width); }; private: void init(); @@ -61,6 +75,7 @@ class SPIClass { BitOrder bitOrder[SPI_CHANNELS_NUM]; uint32_t divider[SPI_CHANNELS_NUM]; uint32_t mode[SPI_CHANNELS_NUM]; + uint32_t width[SPI_CHANNELS_NUM]; void (*initCb)(void); bool initialized; };