From 92d2f670f055511a5cbddc56d489a7a34ff2bec7 Mon Sep 17 00:00:00 2001 From: Jonathan BAUDIN <jonathan.baudin@atmel.com> Date: Wed, 7 May 2014 16:56:34 +0200 Subject: [PATCH] Creating objects SERCOMx, Serial, SPI and Wire. --- cores/arduino/SERCOM.cpp | 11 +++ cores/arduino/SERCOM.h | 8 +++ cores/arduino/SERCOMUart.cpp | 5 +- cores/arduino/SERCOMUart.h | 4 +- libraries/SPI/SPI.cpp | 22 +----- libraries/Wire/Wire.cpp | 52 ++++---------- libraries/Wire/Wire.h | 110 +++++++++++++++--------------- variants/arduino_zero/variant.cpp | 40 +++++------ variants/arduino_zero/variant.h | 8 ++- 9 files changed, 120 insertions(+), 140 deletions(-) diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index 5d96c6b4..99b3ed57 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -515,3 +515,14 @@ uint8_t SERCOM::readDataWIRE() else return sercom->I2CS.DATA.reg; } + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +SERCOM * SERCOM::sercom0 = new SERCOM(SERCOM0); +SERCOM * SERCOM::sercom1 = new SERCOM(SERCOM1); +SERCOM * SERCOM::sercom2 = new SERCOM(SERCOM2); +SERCOM * SERCOM::sercom3 = new SERCOM(SERCOM3); +SERCOM * SERCOM::sercom4 = new SERCOM(SERCOM4); +SERCOM * SERCOM::sercom5 = new SERCOM(SERCOM5); \ No newline at end of file diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h index 98bf6f46..3bbeca22 100644 --- a/cores/arduino/SERCOM.h +++ b/cores/arduino/SERCOM.h @@ -128,6 +128,14 @@ class SERCOM { public: SERCOM(Sercom* sercom); + + /* ========== SERCOM OBJECT ========== */ + static SERCOM * sercom0; + static SERCOM * sercom1; + static SERCOM * sercom2; + static SERCOM * sercom3; + static SERCOM * sercom4; + static SERCOM * sercom5; /* ========== UART ========== */ void initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate=0); diff --git a/cores/arduino/SERCOMUart.cpp b/cores/arduino/SERCOMUart.cpp index 4adf8bac..c90a018e 100644 --- a/cores/arduino/SERCOMUart.cpp +++ b/cores/arduino/SERCOMUart.cpp @@ -6,12 +6,12 @@ SERCOMUart::SERCOMUart(SERCOM *sercom) this->sercom = sercom; } -void SERCOMUart::begin(uint16_t baudrate) +void SERCOMUart::begin(unsigned long baudrate) { begin(baudrate, SERIAL_8N1); } -void SERCOMUart::begin(uint16_t baudrate, uint8_t config) +void SERCOMUart::begin(unsigned long baudrate, uint8_t config) { sercom->initUART(UART_INT_CLOCK, SAMPLE_RATE_x16, baudrate); sercom->initFrame(extractCharSize(config), LSB_FIRST, extractParity(config), extractNbStopBit(config)); @@ -124,3 +124,4 @@ SercomParityMode SERCOMUart::extractParity(uint8_t config) } } +SERCOMUart Serial = SERCOMUart(SERCOM::sercom0); \ No newline at end of file diff --git a/cores/arduino/SERCOMUart.h b/cores/arduino/SERCOMUart.h index d070edb8..78a7bc52 100644 --- a/cores/arduino/SERCOMUart.h +++ b/cores/arduino/SERCOMUart.h @@ -12,8 +12,8 @@ class SERCOMUart : public HardwareSerial { public: SERCOMUart(SERCOM *sercom); - void begin(uint16_t baudRate); - void begin(uint16_t baudrate, uint8_t config); + void begin(unsigned long baudRate); + void begin(unsigned long baudrate, uint8_t config); void end(); int available(); int peek(); diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 76292014..7eedae4a 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -17,7 +17,7 @@ SPIClass::SPIClass(SERCOM *s) void SPIClass::begin() { // Default speed set to 4Mhz, SPI mode set to MODE 0 and Bit order set to MSB first. - sercom->initSPI(SPI_PAD_0_SCK_1, SERCOM_RX_PAD_2, SPI_CHAR_SIZE_8_BITS, MSB_FIRST); + sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, MSB_FIRST); sercom->initClock(SERCOM_SPI_MODE_0, 4000000); } @@ -87,23 +87,5 @@ void SPIClass::detachInterrupt() { } #if SPI_INTERFACES_COUNT > 0 -static void SPI_0_Init(void) { - PIO_Configure( - g_APinDescription[PIN_SPI_MOSI].pPort, - g_APinDescription[PIN_SPI_MOSI].ulPinType, - g_APinDescription[PIN_SPI_MOSI].ulPin, - g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration); - PIO_Configure( - g_APinDescription[PIN_SPI_MISO].pPort, - g_APinDescription[PIN_SPI_MISO].ulPinType, - g_APinDescription[PIN_SPI_MISO].ulPin, - g_APinDescription[PIN_SPI_MISO].ulPinConfiguration); - PIO_Configure( - g_APinDescription[PIN_SPI_SCK].pPort, - g_APinDescription[PIN_SPI_SCK].ulPinType, - g_APinDescription[PIN_SPI_SCK].ulPin, - g_APinDescription[PIN_SPI_SCK].ulPinConfiguration); -} - -SPIClass SPI(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init); +SPIClass SPI(SERCOM::sercom1); #endif diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 8f830527..d99dca55 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -42,16 +42,16 @@ void TwoWire::begin(uint8_t address) { sercom->enableWIRE(); } -size_t SERCOM::resquestFrom(uint8_t address, size_t quantity, bool stopBit) +uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) { //Quantity > 0 AND startTransmission worked ? - if(quantity == 0 || !sercom->startTransmissionWIRE(address, READ_FLAG)) + if(quantity == 0 || !sercom->startTransmissionWIRE(address, WIRE_READ_FLAG)) return 0; - for(size_t readed = 0; read < quantity; ++readed) + for(size_t readed = 0; readed < quantity; ++readed) { //Prepare stop bit ? user want stop bit ? - if(quantity - read == 1 && stopBit) + if(quantity - readed == 1 && stopBit) sercom->prepareStopBitWIRE(); else sercom->prepareAckBitWIRE(); @@ -62,7 +62,7 @@ size_t SERCOM::resquestFrom(uint8_t address, size_t quantity, bool stopBit) return quantity; } -size_t SERCOM::resquestFrom(uint8_t address, size_t quantity) +uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity) { return requestFrom(address, quantity, true); } @@ -129,7 +129,7 @@ uint8_t TwoWire::endTransmission(bool stopBit) return 4; //Start I2C transmission - if(!sercom->startTransmissionWIRE(txAddress, WRITE_FLAG)) + if(!sercom->startTransmissionWIRE(txAddress, WIRE_WRITE_FLAG)) return 2; //Address error //Send all buffer @@ -165,8 +165,11 @@ size_t TwoWire::write(uint8_t data) } else { - sercom->sendDataSlaveWIRE(data); + if(sercom->sendDataSlaveWIRE(data)) + return 1; } + + return 0; } size_t TwoWire::write(const uint8_t *data, size_t quantity) @@ -175,7 +178,7 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity) for(size_t i = 0; i < quantity; ++i) { //Return the number of data stored, when the buffer is full (if write return 0) - if(!write(data[i]) + if(!write(data[i])) return i; } @@ -324,7 +327,7 @@ void TwoWire::onService(void) */ #if WIRE_INTERFACES_COUNT > 0 -static void Wire_Init(void) { +/*static void Wire_Init(void) { pmc_enable_periph_clk(WIRE_INTERFACE_ID); PIO_Configure( g_APinDescription[PIN_WIRE_SDA].pPort, @@ -341,38 +344,13 @@ static void Wire_Init(void) { NVIC_ClearPendingIRQ(WIRE_ISR_ID); NVIC_SetPriority(WIRE_ISR_ID, 0); NVIC_EnableIRQ(WIRE_ISR_ID); -} +}*/ -TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init); + +TwoWire Wire = TwoWire(SERCOM::sercom3); void WIRE_ISR_HANDLER(void) { Wire.onService(); } -#endif -#if WIRE_INTERFACES_COUNT > 1 -static void Wire1_Init(void) { - pmc_enable_periph_clk(WIRE1_INTERFACE_ID); - PIO_Configure( - g_APinDescription[PIN_WIRE1_SDA].pPort, - g_APinDescription[PIN_WIRE1_SDA].ulPinType, - g_APinDescription[PIN_WIRE1_SDA].ulPin, - g_APinDescription[PIN_WIRE1_SDA].ulPinConfiguration); - PIO_Configure( - g_APinDescription[PIN_WIRE1_SCL].pPort, - g_APinDescription[PIN_WIRE1_SCL].ulPinType, - g_APinDescription[PIN_WIRE1_SCL].ulPin, - g_APinDescription[PIN_WIRE1_SCL].ulPinConfiguration); - - NVIC_DisableIRQ(WIRE1_ISR_ID); - NVIC_ClearPendingIRQ(WIRE1_ISR_ID); - NVIC_SetPriority(WIRE1_ISR_ID, 0); - NVIC_EnableIRQ(WIRE1_ISR_ID); -} - -TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init); - -void WIRE1_ISR_HANDLER(void) { - Wire1.onService(); -} #endif diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 3e3a755e..b3d2ab4c 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -32,77 +32,75 @@ #define BUFFER_LENGTH 32 class TwoWire : public Stream { -public: - TwoWire(SERCOM *s); - void begin(); - void begin(uint8_t); + public: + TwoWire(SERCOM *s); + void begin(); + void begin(uint8_t); - uint8_t beginTransmission(uint8_t); - uint8_t endTransmission(void); + void beginTransmission(uint8_t); + uint8_t endTransmission(bool stopBit); + uint8_t endTransmission(void); - uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit); - uint8_t requestFrom(uint8_t address, size_t quantity); + uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit); + uint8_t requestFrom(uint8_t address, size_t quantity); - size_t write(uint8_t data); - size_t write(const uint8_t * data, size_t quantity); + size_t write(uint8_t data); + size_t write(const uint8_t * data, size_t quantity); - virtual int available(void); - virtual int read(void); - virtual int peek(void); - virtual void flush(void); - void onReceive(void(*)(int)); - void onRequest(void(*)(void)); + virtual int available(void); + virtual int read(void); + virtual int peek(void); + virtual void flush(void); + void onReceive(void(*)(int)); + void onRequest(void(*)(void)); - using Print::write; + using Print::write; - //void onService(void); + void onService(void); -private: - SERCOM * sercom; - bool transmissionBegun; + private: + SERCOM * sercom; + bool transmissionBegun; - // RX Buffer - RingBuffer rxBuffer; + // RX Buffer + RingBuffer rxBuffer; - //TX buffer - RingBuffer txBuffer; - uint8_t txAddress; + //TX buffer + RingBuffer txBuffer; + uint8_t txAddress; - // Service buffer - //uint8_t srvBuffer[BUFFER_LENGTH]; - //uint8_t srvBufferIndex; - //uint8_t srvBufferLength; - - // Callback user functions - void (*onRequestCallback)(void); - void (*onReceiveCallback)(int); - - // TWI state - //enum TwoWireStatus { - // UNINITIALIZED, - // MASTER_IDLE, - // MASTER_SEND, - // MASTER_RECV, - // SLAVE_IDLE, - // SLAVE_RECV, - // SLAVE_SEND - //}; - //TwoWireStatus status; - - // TWI clock frequency - static const uint32_t TWI_CLOCK = 100000; - - // Timeouts - //static const uint32_t RECV_TIMEOUT = 100000; - //static const uint32_t XMIT_TIMEOUT = 100000; + // Service buffer + //uint8_t srvBuffer[BUFFER_LENGTH]; + //uint8_t srvBufferIndex; + //uint8_t srvBufferLength; + + // Callback user functions + void (*onRequestCallback)(void); + void (*onReceiveCallback)(int); + + // TWI state + //enum TwoWireStatus { + // UNINITIALIZED, + // MASTER_IDLE, + // MASTER_SEND, + // MASTER_RECV, + // SLAVE_IDLE, + // SLAVE_RECV, + // SLAVE_SEND + //}; + //TwoWireStatus status; + + // TWI clock frequency + static const uint32_t TWI_CLOCK = 100000; + + // Timeouts + //static const uint32_t RECV_TIMEOUT = 100000; + //static const uint32_t XMIT_TIMEOUT = 100000; }; #if WIRE_INTERFACES_COUNT > 0 extern TwoWire Wire; #endif -#if WIRE_INTERFACES_COUNT > 1 -extern TwoWire Wire1; -#endif #endif diff --git a/variants/arduino_zero/variant.cpp b/variants/arduino_zero/variant.cpp index d6ea86e5..d21675a9 100644 --- a/variants/arduino_zero/variant.cpp +++ b/variants/arduino_zero/variant.cpp @@ -87,11 +87,11 @@ */ const PinDescription g_APinDescription[]= { - // 0 .. 19 - Digital pins - // ---------------------- - // 0/1 - SERCOM/UART (Serial) - { PORTA, 10, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // RX: SERCOM0/PAD[2] - { PORTA, 11, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // TX: SERCOM0/PAD[3] + // 0 .. 19 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial) + { PORTA, 10, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // RX: SERCOM0/PAD[2] + { PORTA, 11, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // TX: SERCOM0/PAD[3] // 2..12 { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0 }, // TCC0/WO[0] @@ -116,28 +116,28 @@ const PinDescription g_APinDescription[]= { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // DAC/VREFP // 16..17 I2C (SDA/SCL) - { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SDA: SERCOM3/PAD[0] - { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCL: SERCOM3/PAD[1] + { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCL: SERCOM3/PAD[1] // 18..23 SPI (ICSP:MISO,SCK,MOSI) - { PORTA, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MISO: SERCOM4/PAD[0] - { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // 5V0 - { PORTB, 11, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCK: SERCOM4/PAD[3] - { PORTB, 10, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI: SERCOM4/PAD[2] - { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // RESET - { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // GND - - // 24..29 - Analog pins + { PORTA, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MISO: SERCOM4/PAD[0] + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // 5V0 + { PORTB, 11, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCK: SERCOM4/PAD[3] + { PORTB, 10, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI: SERCOM4/PAD[2] + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // RESET + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // GND + + // 24..29 - Analog pins // -------------------- // 24 - A0 (DAC output) { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC/VOUT // 25..29 - A1-A5 - { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[2] - { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[3] - { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[4] - { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[5] - { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[10] + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[2] + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[3] + { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[5] + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[10] // 30..31 - RX/TX LEDS (PB03/PA27) { PORTB, 3, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // use as pure output diff --git a/variants/arduino_zero/variant.h b/variants/arduino_zero/variant.h index 692e19f6..def09d70 100644 --- a/variants/arduino_zero/variant.h +++ b/variants/arduino_zero/variant.h @@ -93,9 +93,11 @@ extern "C"{ #define PIN_SPI_SS1 (87u) #define PIN_SPI_SS2 (86u) #define PIN_SPI_SS3 (78u) -#define PIN_SPI_MOSI (75u) -#define PIN_SPI_MISO (74u) -#define PIN_SPI_SCK (76u) +*/ +#define PIN_SPI_MOSI (21u) +#define PIN_SPI_MISO (18u) +#define PIN_SPI_SCK (20u) +/* #define BOARD_SPI_SS0 (10u) #define BOARD_SPI_SS1 (4u) #define BOARD_SPI_SS2 (52u) -- GitLab