From b0dc3174225ff1fb7f86dbfbd63f38d27843cab1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 24 Sep 2013 14:20:23 +0200 Subject: [PATCH] Fix in sam SPI library initialization when using multiple CS (extended API). http://forum.arduino.cc/index.php?topic=189682.0 --- build/shared/revisions.txt | 1 + libraries/SPI/arch/sam/SPI.cpp | 20 +++++++++++++------- libraries/SPI/arch/sam/SPI_Class.h | 3 +++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index c690d35e7..53f0e7de7 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -4,6 +4,7 @@ ARDUINO 1.5.5 BETA [libraries] * avr: Fixed buffer overflow in File::doBuffer() (dreggy) * avr: Fixed timeout in Bridge::transfer() +* sam: Fixed SPI initialization (when using extended API and multiple CS) ARDUINO 1.5.4 BETA 2013.09.10 diff --git a/libraries/SPI/arch/sam/SPI.cpp b/libraries/SPI/arch/sam/SPI.cpp index f07b94eb3..565de94fc 100644 --- a/libraries/SPI/arch/sam/SPI.cpp +++ b/libraries/SPI/arch/sam/SPI.cpp @@ -11,15 +11,13 @@ #include "SPI_Class.h" SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) : - spi(_spi), id(_id), initCb(_initCb) + spi(_spi), id(_id), initCb(_initCb), initialized(false) { // Empty } void SPIClass::begin() { - initCb(); - SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS); - SPI_Enable(spi); + init(); // NPCS control is left to the user @@ -30,9 +28,7 @@ void SPIClass::begin() { } void SPIClass::begin(uint8_t _pin) { - initCb(); - SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS); - SPI_Enable(spi); + init(); uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin); PIO_Configure( @@ -47,6 +43,15 @@ void SPIClass::begin(uint8_t _pin) { setBitOrder(_pin, MSBFIRST); } +void SPIClass::init() { + if (initialized) + return; + initCb(); + SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS); + SPI_Enable(spi); + initialized = true; +} + void SPIClass::end(uint8_t _pin) { uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin); // Setting the pin as INPUT will disconnect it from SPI peripheral @@ -55,6 +60,7 @@ void SPIClass::end(uint8_t _pin) { void SPIClass::end() { SPI_Disable(spi); + initialized = false; } void SPIClass::setBitOrder(uint8_t _pin, BitOrder _bitOrder) { diff --git a/libraries/SPI/arch/sam/SPI_Class.h b/libraries/SPI/arch/sam/SPI_Class.h index c11251df0..735bd4bf9 100644 --- a/libraries/SPI/arch/sam/SPI_Class.h +++ b/libraries/SPI/arch/sam/SPI_Class.h @@ -54,12 +54,15 @@ class SPIClass { void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); }; private: + void init(); + Spi *spi; uint32_t id; BitOrder bitOrder[SPI_CHANNELS_NUM]; uint32_t divider[SPI_CHANNELS_NUM]; uint32_t mode[SPI_CHANNELS_NUM]; void (*initCb)(void); + bool initialized; }; #if SPI_INTERFACES_COUNT > 0