From a780f1f6beb0d66a5bdfff743f7cb1e9b5bee6d6 Mon Sep 17 00:00:00 2001 From: Thibaut VIARD Date: Mon, 10 Aug 2015 13:36:31 +0200 Subject: [PATCH 1/7] [zero] prepare variant for SPI and Wire board parameters --- variants/arduino_zero/variant.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/variants/arduino_zero/variant.h b/variants/arduino_zero/variant.h index a1f1506e4..2e84db490 100644 --- a/variants/arduino_zero/variant.h +++ b/variants/arduino_zero/variant.h @@ -129,6 +129,9 @@ static const uint8_t ATN = PIN_ATN; #define PIN_SPI_MISO (22u) #define PIN_SPI_MOSI (23u) #define PIN_SPI_SCK (24u) +#define PERIPH_SPI sercom4 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_0 static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference. static const uint8_t MOSI = PIN_SPI_MOSI ; @@ -142,6 +145,8 @@ static const uint8_t SCK = PIN_SPI_SCK ; #define PIN_WIRE_SDA (20u) #define PIN_WIRE_SCL (21u) +#define PERIPH_WIRE sercom3 +#define WIRE_IT_HANDLER SERCOM3_Handler /* * USB From 7fbd66521e8ebe24977a0a06e1cd9c44c9c86fcb Mon Sep 17 00:00:00 2001 From: Thibaut VIARD Date: Mon, 10 Aug 2015 13:39:31 +0200 Subject: [PATCH 2/7] [zero] Bring more customization to SPI class --- libraries/SPI/SPI.cpp | 15 ++++++++++++--- libraries/SPI/SPI.h | 7 ++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index e4af0464a..3bcb53c2b 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -28,15 +28,20 @@ const SPISettings DEFAULT_SPI_SETTINGS = SPISettings(); -SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI) +SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad PadTx, SercomRXPad PadRx) { initialized = false; assert(p_sercom != NULL); _p_sercom = p_sercom; + // pins _uc_pinMiso = uc_pinMISO; _uc_pinSCK = uc_pinSCK; _uc_pinMosi = uc_pinMOSI; + + // SERCOM pads + _padTx=PadTx; + _padRx=PadRx; } void SPIClass::begin() @@ -65,7 +70,7 @@ void SPIClass::config(SPISettings settings) { _p_sercom->disableSPI(); - _p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, settings.bitOrder); + _p_sercom->initSPI(_padTx, _padRx, SPI_CHAR_SIZE_8_BITS, settings.bitOrder); _p_sercom->initSPIClock(settings.dataMode, settings.clockFreq); _p_sercom->enableSPI(); @@ -197,4 +202,8 @@ void SPIClass::detachInterrupt() { // Should be disableInterrupt() } -SPIClass SPI( &sercom4, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI ); +#if SPI_INTERFACES_COUNT > 0 + +SPIClass SPI( &PERIPH_SPI, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI, PAD_SPI_TX, PAD_SPI_RX ); + +#endif // SPI_INTERFACES_COUNT > 0 diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index 6259d2d76..63f311710 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -91,7 +91,8 @@ class SPISettings { class SPIClass { public: - SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI); + SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad); + byte transfer(uint8_t data); inline void transfer(void *buf, size_t count); @@ -120,6 +121,10 @@ class SPIClass { uint8_t _uc_pinMiso; uint8_t _uc_pinMosi; uint8_t _uc_pinSCK; + + SercomSpiTXPad _padTx; + SercomRXPad _padRx; + bool initialized; uint8_t interruptMode; char interruptSave; From b81bc464842b57bd0d3259409a394100fc557bfb Mon Sep 17 00:00:00 2001 From: Thibaut VIARD Date: Mon, 10 Aug 2015 13:39:47 +0200 Subject: [PATCH 3/7] [zero] Bring more customization to Wire class --- libraries/Wire/Wire.cpp | 85 ++++------------------------------------- libraries/Wire/Wire.h | 5 ++- 2 files changed, 12 insertions(+), 78 deletions(-) diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index aabc1eff6..7679c9a1c 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -26,9 +26,11 @@ extern "C" { #include "Wire.h" -TwoWire::TwoWire(SERCOM * s) +TwoWire::TwoWire(SERCOM * s, uint8_t pinSDA, uint8_t pinSCL) { this->sercom = s; + this->_uc_pinSDA=pinSDA; + this->_uc_pinSCL=pinSCL; transmissionBegun = false; } @@ -37,8 +39,8 @@ void TwoWire::begin(void) { sercom->initMasterWIRE(TWI_CLOCK); sercom->enableWIRE(); - pinPeripheral(PIN_WIRE_SDA, g_APinDescription[PIN_WIRE_SDA].ulPinType); - pinPeripheral(PIN_WIRE_SCL, g_APinDescription[PIN_WIRE_SCL].ulPinType); + pinPeripheral(_uc_pinSDA, g_APinDescription[_uc_pinSDA].ulPinType); + pinPeripheral(_uc_pinSCL, g_APinDescription[_uc_pinSCL].ulPinType); } void TwoWire::begin(uint8_t address) { @@ -254,77 +256,6 @@ void TwoWire::onService(void) } } -/* -void TwoWire::onService(void) -{ - // Retrieve interrupt status - uint32_t sr = TWI_GetStatus(twi); - - if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) { - TWI_DisableIt(twi, TWI_IDR_SVACC); - TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK - | TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP); - - srvBufferLength = 0; - srvBufferIndex = 0; - - // Detect if we should go into RECV or SEND status - // SVREAD==1 means *master* reading -> SLAVE_SEND - if (!TWI_STATUS_SVREAD(sr)) { - status = SLAVE_RECV; - } else { - status = SLAVE_SEND; - - // Alert calling program to generate a response ASAP - if (onRequestCallback) - onRequestCallback(); - else - // create a default 1-byte response - write((uint8_t) 0); - } - } - - if (status != SLAVE_IDLE) { - if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) { - if (status == SLAVE_RECV && onReceiveCallback) { - // Copy data into rxBuffer - // (allows to receive another packet while the - // user program reads actual data) - for (uint8_t i = 0; i < srvBufferLength; ++i) - rxBuffer[i] = srvBuffer[i]; - rxBufferIndex = 0; - rxBufferLength = srvBufferLength; - - // Alert calling program - onReceiveCallback( rxBufferLength); - } - - // Transfer completed - TWI_EnableIt(twi, TWI_SR_SVACC); - TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK - | TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP); - status = SLAVE_IDLE; - } - } - - if (status == SLAVE_RECV) { - if (TWI_STATUS_RXRDY(sr)) { - if (srvBufferLength < BUFFER_LENGTH) - srvBuffer[srvBufferLength++] = TWI_ReadByte(twi); - } - } - - if (status == SLAVE_SEND) { - if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) { - uint8_t c = 'x'; - if (srvBufferIndex < srvBufferLength) - c = srvBuffer[srvBufferIndex++]; - TWI_WriteByte(twi, c); - } - } -} -*/ - #if WIRE_INTERFACES_COUNT > 0 /*static void Wire_Init(void) { pmc_enable_periph_clk(WIRE_INTERFACE_ID); @@ -346,10 +277,10 @@ void TwoWire::onService(void) }*/ -TwoWire Wire(&sercom3); +TwoWire Wire(&PERIPH_WIRE, PIN_WIRE_SDA, PIN_WIRE_SCL); -void SERCOM3_Handler(void) { +void WIRE_IT_HANDLER(void) { Wire.onService(); } -#endif +#endif // WIRE_INTERFACES_COUNT > 0 diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 844168e35..a0bfa7363 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -31,7 +31,7 @@ class TwoWire : public Stream { public: - TwoWire(SERCOM *s); + TwoWire(SERCOM *s, uint8_t pinSDA, uint8_t pinSCL); void begin(); void begin(uint8_t); void setClock(uint32_t); // dummy function @@ -59,6 +59,9 @@ class TwoWire : public Stream private: SERCOM * sercom; + uint8_t _uc_pinSDA; + uint8_t _uc_pinSCL; + bool transmissionBegun; // RX Buffer From 6ec964dba1f1bffb69f457b124e0e94d93bac030 Mon Sep 17 00:00:00 2001 From: Thibaut VIARD Date: Tue, 11 Aug 2015 09:42:26 +0200 Subject: [PATCH 4/7] [zero/SPI] adding missing library properties --- libraries/SPI/library.properties | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 libraries/SPI/library.properties diff --git a/libraries/SPI/library.properties b/libraries/SPI/library.properties new file mode 100644 index 000000000..3aaa770b8 --- /dev/null +++ b/libraries/SPI/library.properties @@ -0,0 +1,8 @@ +name=SPI +version=1.0 +author=Jonathan BAUDIN, Thibaut VIARD, Arduino +maintainer=Arduino +sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. Specific implementation for Arduino Zero. +paragraph= +url=http://www.arduino.cc/en/Reference/SPI +architectures=samd From 9440d5bf60dc682ae485579fe8a9e372ebc0eafb Mon Sep 17 00:00:00 2001 From: Thibaut VIARD Date: Tue, 11 Aug 2015 09:42:44 +0200 Subject: [PATCH 5/7] [zero/Wire] adding missing library properties --- libraries/Wire/library.properties | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 libraries/Wire/library.properties diff --git a/libraries/Wire/library.properties b/libraries/Wire/library.properties new file mode 100644 index 000000000..eff193aa2 --- /dev/null +++ b/libraries/Wire/library.properties @@ -0,0 +1,9 @@ +name=Wire +version=1.0 +author=Jonathan BAUDIN, Thibaut VIARD, Arduino +maintainer=Arduino +sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. Specific implementation for Arduino Zero. +paragraph= +url=http://www.arduino.cc/en/Reference/Wire +architectures=samd + From 264a5a59e73af5bce7cea352b37487b98d4a84c9 Mon Sep 17 00:00:00 2001 From: Thibaut VIARD Date: Thu, 13 Aug 2015 12:05:14 +0200 Subject: [PATCH 6/7] [zero/SPI] Adding default values for SPI custom definitions --- libraries/SPI/SPI.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 3bcb53c2b..62d28c0d5 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -204,6 +204,21 @@ void SPIClass::detachInterrupt() { #if SPI_INTERFACES_COUNT > 0 +/* In case new variant doesn't define these macros, + * we put here the ones for Arduino Zero. + * + * These values should be different on some variants! + * + * The SPI PAD values can be found in cores/arduino/SERCOM.h: + * - SercomSpiTXPad + * - SercomRXPad + */ +#ifndef PERIPH_SPI +#define PERIPH_SPI sercom4 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_0 +#endif // PERIPH_SPI + SPIClass SPI( &PERIPH_SPI, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI, PAD_SPI_TX, PAD_SPI_RX ); #endif // SPI_INTERFACES_COUNT > 0 From 9888e64d10d3035f4ec7e583954a3ed8acc10cc9 Mon Sep 17 00:00:00 2001 From: Thibaut VIARD Date: Thu, 13 Aug 2015 12:09:25 +0200 Subject: [PATCH 7/7] [zero/Wire] Adding default values for Wire custom definitions --- libraries/Wire/Wire.cpp | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 7679c9a1c..af9ec1111 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -257,25 +257,17 @@ void TwoWire::onService(void) } #if WIRE_INTERFACES_COUNT > 0 -/*static void Wire_Init(void) { - pmc_enable_periph_clk(WIRE_INTERFACE_ID); - PIO_Configure( - g_APinDescription[PIN_WIRE_SDA].pPort, - g_APinDescription[PIN_WIRE_SDA].ulPinType, - g_APinDescription[PIN_WIRE_SDA].ulPin, - g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration); - PIO_Configure( - g_APinDescription[PIN_WIRE_SCL].pPort, - g_APinDescription[PIN_WIRE_SCL].ulPinType, - g_APinDescription[PIN_WIRE_SCL].ulPin, - g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration); - - NVIC_DisableIRQ(WIRE_ISR_ID); - NVIC_ClearPendingIRQ(WIRE_ISR_ID); - NVIC_SetPriority(WIRE_ISR_ID, 0); - NVIC_EnableIRQ(WIRE_ISR_ID); -}*/ +/* In case new variant doesn't define these macros, + * we put here the ones for Arduino Zero. + * + * These values should be different on some variants! + */ + +#ifndef PERIPH_WIRE +# define PERIPH_WIRE sercom3 +# define WIRE_IT_HANDLER SERCOM3_Handler +#endif // PERIPH_WIRE TwoWire Wire(&PERIPH_WIRE, PIN_WIRE_SDA, PIN_WIRE_SCL);