diff --git a/hardware/arduino/sam/libraries/SPI/SPI.cpp b/hardware/arduino/sam/libraries/SPI/SPI.cpp index d27d13fcc..7741d64ad 100644 --- a/hardware/arduino/sam/libraries/SPI/SPI.cpp +++ b/hardware/arduino/sam/libraries/SPI/SPI.cpp @@ -10,41 +10,87 @@ #include "SPI.h" -SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) : - spi(_spi), id(_id), initCb(_initCb) { - // Empty +SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void), uint32_t *_ss) : + spi(_spi), id(_id), initCb(_initCb) +{ + for (int i=0; iSPI_SR & SPI_SR_TDRE) == 0) + ; + spi->SPI_TDR = d; + + // return SPI_Read(spi); + while ((spi->SPI_SR & SPI_SR_RDRF) == 0) + ; + d = spi->SPI_RDR; + return d & 0xFF; } void SPIClass::attachInterrupt(void) { @@ -71,5 +117,12 @@ static void SPI_0_Init(void) { g_APinDescription[PIN_SPI_SCK].ulPinConfiguration); } -SPIClass SPI_0(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init); +uint32_t SPI_0_SS[] = { + PIN_SPI_SS0, + PIN_SPI_SS1, + PIN_SPI_SS2, + PIN_SPI_SS3 +}; + +SPIClass SPI_0(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init, SPI_0_SS); #endif diff --git a/hardware/arduino/sam/libraries/SPI/SPI.h b/hardware/arduino/sam/libraries/SPI/SPI.h index b183c886c..56d8646f8 100644 --- a/hardware/arduino/sam/libraries/SPI/SPI.h +++ b/hardware/arduino/sam/libraries/SPI/SPI.h @@ -14,45 +14,42 @@ #include "variant.h" #include -#define SPI_CLOCK_DIV4 0x00 -#define SPI_CLOCK_DIV16 0x01 -#define SPI_CLOCK_DIV64 0x02 -#define SPI_CLOCK_DIV128 0x03 -#define SPI_CLOCK_DIV2 0x04 -#define SPI_CLOCK_DIV8 0x05 -#define SPI_CLOCK_DIV32 0x06 -#define SPI_CLOCK_DIV64 0x07 - #define SPI_MODE0 0x00 -#define SPI_MODE1 0x02 -#define SPI_MODE2 0x01 +#define SPI_MODE1 0x01 +#define SPI_MODE2 0x02 #define SPI_MODE3 0x03 -#define SPI_MODE_MASK 0x03 // CPOL = bit 3, CPHA = bit 2 on SPCR -#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR -#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR - class SPIClass { public: - SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)); + SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void), uint32_t *_ss); - byte transfer(byte _data); + byte transfer(byte _data, uint8_t _channel = 0, bool _last = true); // SPI Configuration methods void attachInterrupt(void); - void detachInterrupt(void); // Default + void detachInterrupt(void); - void begin(void); // Default + void begin(void); + void addSlave(uint8_t _channel); void end(void); + // These methods sets the same parameters on all channels void setBitOrder(uint8_t); void setDataMode(uint8_t); void setClockDivider(uint8_t); + // These methods sets a parameter on a single channel + void setBitOrder(uint8_t, uint8_t _channel); + void setDataMode(uint8_t, uint8_t _channel); + void setClockDivider(uint8_t, uint8_t _channel); + private: Spi *spi; - uint32_t id, divider, mode; + uint32_t id; + uint32_t divider[SPI_CHANNELS_NUM]; + uint32_t mode[SPI_CHANNELS_NUM]; + uint32_t ssPins[SPI_CHANNELS_NUM]; void (*initCb)(void); }; diff --git a/hardware/arduino/sam/libraries/SPI/examples/DueX_ATFlashSignatureCheck/DueX_ATFlashSignatureCheck.ino b/hardware/arduino/sam/libraries/SPI/examples/DueX_ATFlashSignatureCheck/DueX_ATFlashSignatureCheck.ino new file mode 100644 index 000000000..4a4e89a63 --- /dev/null +++ b/hardware/arduino/sam/libraries/SPI/examples/DueX_ATFlashSignatureCheck/DueX_ATFlashSignatureCheck.ino @@ -0,0 +1,39 @@ + +#include + +#define FLASH_SPI_CHAN 3 + +void setup() { + Serial1.begin(9600); + SPI_0.begin(); + SPI_0.addSlave(FLASH_SPI_CHAN); + SPI_0.setDataMode(SPI_MODE2, FLASH_SPI_CHAN); + SPI_0.setClockDivider(2); // We are too fast with 1 +} + +void loop() { + Serial1.println("Sending 'Identify' cmd to flash => 9F"); + + // Send cmd and receive response on the same transaction + // Parameter "false" keeps the SS pin active + SPI_0.transfer(0x9f, FLASH_SPI_CHAN, false); + char a1 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false); + char a2 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false); + char a3 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false); + char a4 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false); + char a5 = SPI_0.transfer(0x00, FLASH_SPI_CHAN); + + Serial1.print("Received signature: "); + Serial1.print(a1, HEX); + Serial1.print(" "); + Serial1.print(a2, HEX); + Serial1.print(" "); + Serial1.print(a3, HEX); + Serial1.print(" "); + Serial1.print(a4, HEX); + Serial1.print(" "); + Serial1.print(a5, HEX); + Serial1.println(); + delay(1000); +} + diff --git a/hardware/arduino/sam/libraries/SPI/keywords.txt b/hardware/arduino/sam/libraries/SPI/keywords.txt index fa7616581..326b698da 100644 --- a/hardware/arduino/sam/libraries/SPI/keywords.txt +++ b/hardware/arduino/sam/libraries/SPI/keywords.txt @@ -6,30 +6,23 @@ # Datatypes (KEYWORD1) ####################################### -SPI KEYWORD1 +SPI_0 KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### -begin KEYWORD2 -end KEYWORD2 -transfer KEYWORD2 -setBitOrder KEYWORD2 -setDataMode KEYWORD2 +begin KEYWORD2 +addSlave KEYWORD2 +end KEYWORD2 +transfer KEYWORD2 +setBitOrder KEYWORD2 +setDataMode KEYWORD2 setClockDivider KEYWORD2 ####################################### # Constants (LITERAL1) ####################################### -SPI_CLOCK_DIV4 LITERAL1 -SPI_CLOCK_DIV16 LITERAL1 -SPI_CLOCK_DIV64 LITERAL1 -SPI_CLOCK_DIV128 LITERAL1 -SPI_CLOCK_DIV2 LITERAL1 -SPI_CLOCK_DIV8 LITERAL1 -SPI_CLOCK_DIV32 LITERAL1 -SPI_CLOCK_DIV64 LITERAL1 SPI_MODE0 LITERAL1 SPI_MODE1 LITERAL1 SPI_MODE2 LITERAL1 diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.h b/hardware/arduino/sam/variants/arduino_due_x/variant.h index 5ab9d963c..d59ba5136 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.h +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.h @@ -82,12 +82,19 @@ #define SPI_INTERFACE SPI0 #define SPI_INTERFACE_ID ID_SPI0 -#define PIN_SPI_SS (77u) +#define SPI_CHANNELS_NUM 4 +#define PIN_SPI_SS0 (77u) +#define PIN_SPI_SS1 (4u) +#define PIN_SPI_SS2 (0u) +#define PIN_SPI_SS3 (78u) #define PIN_SPI_MOSI (75u) #define PIN_SPI_MISO (74u) #define PIN_SPI_SCK (76u) -static const uint8_t SS = PIN_SPI_SS ; +static const uint8_t SS = PIN_SPI_SS0 ; +static const uint8_t SS1 = PIN_SPI_SS1 ; +static const uint8_t SS2 = PIN_SPI_SS2 ; +static const uint8_t SS3 = PIN_SPI_SS3 ; static const uint8_t MOSI = PIN_SPI_MOSI ; static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t SCK = PIN_SPI_SCK ;