diff --git a/hardware/sam/libraries/SPI/SPI.cpp b/hardware/sam/libraries/SPI/SPI.cpp index 10170ef8d..8b3ab0fd3 100644 --- a/hardware/sam/libraries/SPI/SPI.cpp +++ b/hardware/sam/libraries/SPI/SPI.cpp @@ -10,73 +10,48 @@ #include "SPI.h" -SPIClass SPI ; - -void SPIClass::begin() -{ - // Set direction register for SCK and MOSI pin. - // MISO pin automatically overrides to INPUT. - // When the SS pin is set as OUTPUT, it can be used as - // a general purpose output port (it doesn't influence - // SPI operations). - - pinMode(SCK, OUTPUT); - pinMode(MOSI, OUTPUT); - pinMode(SS, OUTPUT); - - digitalWrite(SCK, LOW); - digitalWrite(MOSI, LOW); - digitalWrite(SS, HIGH); - - // Warning: if the SS pin ever becomes a LOW INPUT then SPI - // automatically switches to Slave, so the data direction of - // the SS pin MUST be kept as OUTPUT. - SPCR |= _BV(MSTR); - SPCR |= _BV(SPE); +SPIClass::SPIClass(Spi *_spi, uint32_t _id) : spi(_spi), id(_id) { + // Empty } -void SPIClass::end() -{ - SPCR &= ~_BV(SPE); +void SPIClass::begin() { + // Set CS on NPCS3 + SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_PCS(0x07)); + SPI_Enable( spi); + setClockDivider(1); } -void SPIClass::setBitOrder( uint8_t bitOrder ) -{ - if(bitOrder == LSBFIRST) - { - SPCR |= _BV(DORD); - } - else - { - SPCR &= ~(_BV(DORD)); - } +void SPIClass::end() { + SPI_Disable( spi); } -void SPIClass::setDataMode( uint8_t mode ) -{ - SPCR = (SPCR & ~SPI_MODE_MASK) | mode; +void SPIClass::setBitOrder(uint8_t bitOrder) { + // Not supported } -void SPIClass::setClockDivider( uint8_t rate ) -{ - SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK); - SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK); +void SPIClass::setDataMode(uint8_t _mode) { + mode = _mode; + SPI_ConfigureNPCS(spi, 3, mode | SPI_CSR_SCBR(divider)); } -byte SPIClass::transfer( byte _data ) -{ - SPDR = _data; - while (!(SPSR & _BV(SPIF))) - ; - return SPDR; +void SPIClass::setClockDivider(uint8_t _divider) { + divider = _divider; + SPI_ConfigureNPCS(spi, 3, mode | SPI_CSR_SCBR(divider)); } -void SPIClass::attachInterrupt( void ) -{ - SPCR |= _BV(SPIE) ; +byte SPIClass::transfer(byte _data) { + SPI_Write(spi, 0, _data); + return SPI_Read(spi); } -void SPIClass::detachInterrupt( void ) -{ - SPCR &= ~_BV(SPIE) ; +void SPIClass::attachInterrupt(void) { + // Should be enableInterrupt() } + +void SPIClass::detachInterrupt(void) { + // Should be disableInterrupt() +} + +#if SPI_INTERFACES_COUNT > 0 +SPIClass SPI0(SPI_INTERFACE, SPI_INTERFACE_ID); +#endif diff --git a/hardware/sam/libraries/SPI/SPI.h b/hardware/sam/libraries/SPI/SPI.h index b643c1f1d..1bc39a0e2 100644 --- a/hardware/sam/libraries/SPI/SPI.h +++ b/hardware/sam/libraries/SPI/SPI.h @@ -32,25 +32,31 @@ #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 -{ +class SPIClass { public: - static byte transfer( byte _data ) ; + SPIClass(Spi *_spi, uint32_t _id); - // SPI Configuration methods + byte transfer(byte _data); - static void attachInterrupt( void ) ; - static void detachInterrupt( void ) ; // Default + // SPI Configuration methods - static void begin( void ) ; // Default - static void end( void ) ; + void attachInterrupt(void); + void detachInterrupt(void); // Default - static void setBitOrder( uint8_t ) ; - static void setDataMode( uint8_t ) ; - static void setClockDivider( uint8_t ) ; -} ; + void begin(void); // Default + void end(void); -extern SPIClass SPI; + void setBitOrder(uint8_t); + void setDataMode(uint8_t); + void setClockDivider(uint8_t); + private: + Spi *spi; + uint32_t id, divider, mode; +}; + +#if SPI_INTERFACES_COUNT > 0 +extern SPIClass SPI0; +#endif #endif diff --git a/hardware/sam/variants/arduino_due/variant.h b/hardware/sam/variants/arduino_due/variant.h index 8a74c7021..f6f962707 100644 --- a/hardware/sam/variants/arduino_due/variant.h +++ b/hardware/sam/variants/arduino_due/variant.h @@ -71,6 +71,15 @@ #define PIN_LED2 PIN_LED_RXL #define PIN_LED3 PIN_LED_TXL +#define SPI_INTERFACES_COUNT 1 + +#define SPI_INTERFACE SPI +#define SPI_INTERFACE_ID ID_SPI +#define PIN_SPI_SS (4u) +#define PIN_SPI_MOSI (76u) +#define PIN_SPI_MISO (75u) +#define PIN_SPI_SCK (77u) + #define WIRE_INTERFACES_COUNT 2 #define PIN_WIRE_SDA (20u)