diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index 0eb5eeb16ebc54983de7cd0f7b0c901a52071d03..d80961244e3251d97ff099bd8eb6989e25885230 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -82,6 +82,7 @@ typedef void (*voidFuncPtr)( void ) ; #include "HardwareSerial.h" #include "wiring_pulse.h" #include "delay.h" +#include "Uart.h" #endif // __cplusplus diff --git a/cores/arduino/Reset.cpp b/cores/arduino/Reset.cpp index 3e62c28a23f9f4a5fa54a1313822a4d6ad5fa605..00cf0549155bec1bc0e366bddda6a0f52a31a6f2 100644 --- a/cores/arduino/Reset.cpp +++ b/cores/arduino/Reset.cpp @@ -29,7 +29,7 @@ static void banzai() { __disable_irq(); // Reset the device - // todo + NVIC_SystemReset() ; while (true); } diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index 5d96c6b4a6a77d5fb13708f6f2aa874ee5d7a0dd..cfd2577d36fe0dca904f407857443c358f879a3b 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -1,27 +1,39 @@ #include "SERCOM.h" +// Constants for Clock multiplexers +#define GENERIC_CLOCK_SERCOM0 (0x14ul) +#define GENERIC_CLOCK_SERCOM1 (0x15ul) +#define GENERIC_CLOCK_SERCOM2 (0x16ul) +#define GENERIC_CLOCK_SERCOM3 (0x17ul) +#define GENERIC_CLOCK_SERCOM4 (0x18ul) +#define GENERIC_CLOCK_SERCOM5 (0x19ul) -SERCOM::SERCOM(Sercom* sercom) +SERCOM::SERCOM(Sercom* s) { - this->sercom = sercom; + sercom = s; } /* ========================= * ===== Sercom UART * ========================= */ + void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate) -{ +{ resetUART(); + initClock(); + //Setting the CTRLA register sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(mode) | SERCOM_USART_CTRLA_SAMPR(sampleRate); //Setting the Interrupt register - sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_DRE | //Data Register Empty - SERCOM_USART_INTENSET_RXC | //Received complete + sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC | //Received complete SERCOM_USART_INTENSET_ERROR; //All others errors + + NVIC_EnableIRQ(SERCOM0_IRQn); + NVIC_SetPriority (SERCOM0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ if(mode == UART_INT_CLOCK) { @@ -35,7 +47,13 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint sampleRateValue = 3; //Asynchronous arithmetic mode - sercom->USART.BAUD.reg = 65535 * ( 1 - sampleRateValue * division(baudrate,SERCOM_FREQ_REF)); + //sercom->USART.BAUD.reg = 65535 * ( 1 - sampleRateValue * division(baudrate,SERCOM_FREQ_REF)); + uint16_t tmpBaud = (baudrate / SERCOM_FREQ_REF); + tmpBaud = ( 1 - sampleRateValue * tmpBaud); + tmpBaud = (65535ul) * tmpBaud; + + tmpBaud = 63019; + sercom->USART.BAUD.reg = tmpBaud; } } void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits) @@ -132,7 +150,7 @@ int SERCOM::writeDataUART(uint8_t data) flushUART(); //Put data into DATA register - sercom->USART.DATA.bit.DATA = data; + sercom->USART.DATA.reg = (uint16_t)data; return 1; } @@ -155,7 +173,7 @@ void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize ch (0x1ul) << SERCOM_SPI_CTRLB_RXEN_Pos; //Active the SPI receiver. } -void SERCOM::initClock(SercomSpiClockMode clockMode, uint32_t baudrate) +void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) { //Extract data from clockMode int cpha, cpol; @@ -291,36 +309,36 @@ uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate) uint32_t SERCOM::division(uint32_t dividend, uint32_t divisor) { - // division WITHOUT division operator - - uint32_t denom = divisor; - uint32_t current = 1; - uint32_t answer = 0; - - if ( denom > dividend) - return 0; - - if ( denom == dividend) - return 1; - - while (denom <= dividend) { - denom <<= 1; - current <<= 1; - } - - denom >>= 1; - current >>= 1; - - while (current!=0) { - if ( dividend >= denom) { - dividend -= denom; - answer |= current; - } - current >>= 1; - denom >>= 1; - } - - return answer; + //// division WITHOUT division operator + // + //uint32_t denom = divisor; + //uint32_t current = 1; + //uint32_t answer = 0; +// + //if ( denom > dividend) + //return 0; +// + //if ( denom == dividend) + //return 1; +// + //while (denom <= dividend) { + //denom <<= 1; + //current <<= 1; + //} +// + //denom >>= 1; + //current >>= 1; +// + //while (current!=0) { + //if ( dividend >= denom) { + //dividend -= denom; + //answer |= current; + //} + //current >>= 1; + //denom >>= 1; + //} + // + //return answer; } @@ -515,3 +533,56 @@ uint8_t SERCOM::readDataWIRE() else return sercom->I2CS.DATA.reg; } + + +void SERCOM::initClock() +{ + uint8_t clockId; + + if(sercom == SERCOM0) + { + clockId = GENERIC_CLOCK_SERCOM0; + } + else if(sercom == SERCOM1) + { + clockId = GENERIC_CLOCK_SERCOM1; + } + else if(sercom == SERCOM2) + { + clockId = GENERIC_CLOCK_SERCOM2; + } + else if(sercom == SERCOM3) + { + clockId = GENERIC_CLOCK_SERCOM3; + } + else if(sercom == SERCOM4) + { + clockId = GENERIC_CLOCK_SERCOM4; + } + else if(sercom == SERCOM5) + { + clockId = GENERIC_CLOCK_SERCOM5; + } + + //Setting clock + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx) + GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source + GCLK_CLKCTRL_CLKEN ; + + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } +} + +/* ========================= + * ===== 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); diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h index 12dc5c7f709027955eb3c93b58d878a8e178f1a7..c756d81b00413c44c11c0345a5c9efc1bf0226fa 100644 --- a/cores/arduino/SERCOM.h +++ b/cores/arduino/SERCOM.h @@ -61,10 +61,10 @@ typedef enum typedef enum { - UART_TX_PAD_0 = 0, //Only for Intern Clock - UART_TX_PAD_1 = 0, //Only for Extern Clock - UART_TX_PAD_2 = 1, //Only for Intern Clock - UART_TX_PAD_3 = 1 //Only for Extern Clock + UART_TX_PAD_0 = 0x0ul, //Only for UART + UART_TX_PAD_2 = 0x1ul, //Only for UART + //UART_TX_PAD_1 = 0x0ul, //DON'T USE + //UART_TX_PAD_3 = 0x1ul //DON'T USE } SercomUartTXPad; typedef enum @@ -76,10 +76,10 @@ typedef enum typedef enum { - SPI_MODE_0 = 0, // CPOL : 0 | CPHA : 0 - SPI_MODE_1, // CPOL : 0 | CPHA : 1 - SPI_MODE_2, // CPOL : 1 | CPHA : 0 - SPI_MODE_3 // CPOL : 1 | CPHA : 1 + SERCOM_SPI_MODE_0 = 0, // CPOL : 0 | CPHA : 0 + SERCOM_SPI_MODE_1, // CPOL : 0 | CPHA : 1 + SERCOM_SPI_MODE_2, // CPOL : 1 | CPHA : 0 + SERCOM_SPI_MODE_3 // CPOL : 1 | CPHA : 1 } SercomSpiClockMode; typedef enum @@ -127,7 +127,15 @@ typedef enum class SERCOM { public: - SERCOM(Sercom* sercom); + SERCOM(Sercom* s); + + /* ========== 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); @@ -148,7 +156,7 @@ class SERCOM /* ========== SPI ========== */ void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder); - void initClock(SercomSpiClockMode clockMode, uint32_t baudrate); + void initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate); void resetSPI(); void enableSPI(); @@ -190,6 +198,7 @@ class SERCOM Sercom* sercom; uint8_t calculateBaudrateSynchronous(uint32_t baudrate); uint32_t division(uint32_t dividend, uint32_t divisor); + void initClock(); }; #endif diff --git a/cores/arduino/SERCOMUart.cpp b/cores/arduino/Uart.cpp similarity index 61% rename from cores/arduino/SERCOMUart.cpp rename to cores/arduino/Uart.cpp index 4adf8bac75b4a03df012e71686e1da25314815ff..819d07be6047ba8ca1401b9fef2e35ae543dd7d2 100644 --- a/cores/arduino/SERCOMUart.cpp +++ b/cores/arduino/Uart.cpp @@ -1,48 +1,46 @@ -#include "SERCOMUart.h" +#include "Uart.h" -SERCOMUart::SERCOMUart(SERCOM *sercom) +Uart::Uart(SERCOM *sercom) { this->sercom = sercom; + pinPeripheral(0, PIO_SERCOM); + pinPeripheral(1, PIO_SERCOM); } -void SERCOMUart::begin(uint16_t baudrate) +void Uart::begin(unsigned long baudrate) { begin(baudrate, SERIAL_8N1); } -void SERCOMUart::begin(uint16_t baudrate, uint8_t config) +void Uart::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)); - sercom->initPads(UART_TX_PAD_0, SERCOM_RX_PAD_2); + sercom->initPads(UART_TX_PAD_2, SERCOM_RX_PAD_3); + sercom->enableUART(); } -void SERCOMUart::end() +void Uart::end() { sercom->resetUART(); rxBuffer.clear(); } -void SERCOMUart::flush() +void Uart::flush() { sercom->flushUART(); } -void SERCOMUart::IrqHandler() +void Uart::IrqHandler() { if(sercom->availableDataUART()) { rxBuffer.store_char(sercom->readDataUART()); } - if(sercom->isDataRegisterEmptyUART()) - { - sercom->writeDataUART(txBuffer.read_char()); - } - if( sercom->isBufferOverflowErrorUART() || sercom->isFrameErrorUART() || sercom->isParityErrorUART()) @@ -51,31 +49,41 @@ void SERCOMUart::IrqHandler() } } -int SERCOMUart::available() +int Uart::available() { return rxBuffer.available(); } -int SERCOMUart::peek() +int Uart::peek() { return rxBuffer.peek(); } -int SERCOMUart::read() +int Uart::read() { return rxBuffer.read_char(); } -size_t SERCOMUart::write(uint8_t data) +size_t Uart::write(const uint8_t data) { - if(txBuffer.isFull()) - return 0; - - txBuffer.store_char(data); + sercom->writeDataUART(data); return 1; } -SercomNumberStopBit SERCOMUart::extractNbStopBit(uint8_t config) +size_t Uart::write(const char * data) +{ + size_t writed = 0; + + while(*data != '\0') + { + writed += write(*data); + ++data; + } + + return writed; +} + +SercomNumberStopBit Uart::extractNbStopBit(uint8_t config) { switch(config & HARDSER_STOP_BIT_MASK) { @@ -88,7 +96,7 @@ SercomNumberStopBit SERCOMUart::extractNbStopBit(uint8_t config) } } -SercomUartCharSize SERCOMUart::extractCharSize(uint8_t config) +SercomUartCharSize Uart::extractCharSize(uint8_t config) { switch(config & HARDSER_DATA_MASK) { @@ -108,7 +116,7 @@ SercomUartCharSize SERCOMUart::extractCharSize(uint8_t config) } } -SercomParityMode SERCOMUart::extractParity(uint8_t config) +SercomParityMode Uart::extractParity(uint8_t config) { switch(config & HARDSER_PARITY_MASK) { @@ -124,3 +132,13 @@ SercomParityMode SERCOMUart::extractParity(uint8_t config) } } +Uart Serial = Uart(SERCOM::sercom0); + +void SERCOM0_Handler() +{ + Serial.IrqHandler(); +} +void SERCOM5_Handler() +{ + Serial.IrqHandler(); +} diff --git a/cores/arduino/SERCOMUart.h b/cores/arduino/Uart.h similarity index 65% rename from cores/arduino/SERCOMUart.h rename to cores/arduino/Uart.h index d070edb8992969e479bf12300f7c1c7453e5bc24..64f8ec03336446411dde3a481e28ce632ede494a 100644 --- a/cores/arduino/SERCOMUart.h +++ b/cores/arduino/Uart.h @@ -1,6 +1,8 @@ #ifndef _SERCOM_UART_CLASS #define _SERCOM_UART_CLASS +#include "wiring_digital.h" + #include "HardwareSerial.h" #include "SERCOM.h" #include "RingBuffer.h" @@ -8,18 +10,19 @@ #include <cstddef> -class SERCOMUart : public HardwareSerial +class Uart : public HardwareSerial { public: - SERCOMUart(SERCOM *sercom); - void begin(uint16_t baudRate); - void begin(uint16_t baudrate, uint8_t config); + Uart(SERCOM *sercom); + void begin(unsigned long baudRate); + void begin(unsigned long baudrate, uint8_t config); void end(); int available(); int peek(); int read(); void flush(); - size_t write(const uint8_t c); + size_t write(const uint8_t data); + size_t write(const char * data); void IrqHandler(); @@ -28,12 +31,12 @@ class SERCOMUart : public HardwareSerial private: SERCOM *sercom; RingBuffer rxBuffer; - RingBuffer txBuffer; SercomNumberStopBit extractNbStopBit(uint8_t config); SercomUartCharSize extractCharSize(uint8_t config); SercomParityMode extractParity(uint8_t config); }; +extern Uart Serial; #endif diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index a2a55c83814e7b48e8b746dfda26a69017054933..e66dbd3685b4ace0fc31b4b286c67755f51fb2cc 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -10,22 +10,22 @@ #include "SPI.h" -SPIClass::SPIClass(SERCOM *sercom) +SPIClass::SPIClass(SERCOM *s) { - this->sercom = sercom; + 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(PAD_0_SCK_1, PAD_2, 8_BITS, MSB_FIRST); - sercom->initClock(MODE_0, 4000000); + 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); } void SPIClass::end() { sercom->resetSPI(); } -void setBitOrder(BitOrder order) +void SPIClass::setBitOrder(BitOrder order) { if(order == LSBFIRST) sercom->setDataOrderSPI(LSB_FIRST); @@ -33,24 +33,24 @@ void setBitOrder(BitOrder order) sercom->setDataOrderSPI(MSB_FIRST); } -void setDataMode(uint8_t mode) +void SPIClass::setDataMode(uint8_t mode) { switch(mode) { case SPI_MODE0: - sercom->setClockModeSPI(MODE_0); + sercom->setClockModeSPI(SERCOM_SPI_MODE_0); break; case SPI_MODE1: - sercom->setClockModeSPI(MODE_1); + sercom->setClockModeSPI(SERCOM_SPI_MODE_1); break; case SPI_MODE2: - sercom->setClockModeSPI(MODE_2); + sercom->setClockModeSPI(SERCOM_SPI_MODE_2); break; case SPI_MODE3: - sercom->setClockModeSPI(MODE_3); + sercom->setClockModeSPI(SERCOM_SPI_MODE_3); break; default: @@ -58,12 +58,12 @@ void setDataMode(uint8_t mode) } } -void setClockDivider(uint8_t div) +void SPIClass::setClockDivider(uint8_t div) { sercom->setBaudrateSPI(div); } -byte SPIClass::transfer(uint8_t _data) +byte SPIClass::transfer(uint8_t data) { //Can writing new data? while(!sercom->isDataRegisterEmptySPI()); @@ -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::sercom4); #endif diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index 9f3830bf03397d16c40cebc46ea303ef9a0117bd..195723a76656d66f6064d1b9eb59b81b91f2ce43 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -13,14 +13,20 @@ #include "variant.h" #include "SERCOM.h" +#include "wiring_constants.h" #include <stdio.h> +#define SPI_MODE0 0x02 +#define SPI_MODE1 0x00 +#define SPI_MODE2 0x03 +#define SPI_MODE3 0x01 + class SPIClass { public: - SPIClass(SERCOM *sercom); + SPIClass(SERCOM *s); - byte transfer(uint8_t _data); + byte transfer(uint8_t data); // SPI Configuration methods void attachInterrupt(); diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index e64d47f186f3eaac6d7e4545ad0bde510d5d169f..b8fad9cba0ba5952358dcbc3a2682edcd99d78ce 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -24,9 +24,9 @@ extern "C" { #include "Wire.h" -TwoWire::TwoWire(SERCOM * sercom) +TwoWire::TwoWire(SERCOM * s) { - this->sercom = sercom; + this->sercom = s; transmissionBegun = false; } @@ -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); -void WIRE_ISR_HANDLER(void) { - Wire.onService(); -} -#endif +TwoWire Wire(SERCOM::sercom3); -#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); +void SERCOM3_Handler(void) { + Wire.onService(); } -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 c8d3200cf0a28927ef0c65bd564d2e69ebb55ec6..7ae75e39c4273d26653671a2a4c2e80ddec31d01 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -21,7 +21,7 @@ #ifndef TwoWire_h #define TwoWire_h -#include <include/twi.h> +//#include <include/twi.h> #include "Stream.h" #include "variant.h" @@ -32,77 +32,73 @@ #define BUFFER_LENGTH 32 class TwoWire : public Stream { -public: - TwoWire(SERCOM *sercom); - 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 3f423fbbb51d816535e62516153f062917ae5afc..7c8a805a70847a10ec4bd03559af321279188942 100644 --- a/variants/arduino_zero/variant.cpp +++ b/variants/arduino_zero/variant.cpp @@ -73,8 +73,23 @@ * | 33 | | PA24 | USB_NEGATIVE | USB/DM * | 34 | | PA25 | USB_POSITIVE | USB/DP * +------------+------------------+--------+-----------------+------------------------------ - * | 35 | CDC_UART TX | PB22 | | *SERCOM5/PAD[2] - * | 36 | CDC_UART RX | PB23 | | *SERCOM5/PAD[3] + * | | EDBG | | | + * +------------+------------------+--------+-----------------+------------------------------ + * | 35 | | PB22 | EDBG_UART TX | SERCOM5/PAD[2] + * | 36 | | PB23 | EDBG_UART RX | SERCOM5/PAD[3] + * +------------+------------------+--------+-----------------+------------------------------ + * | 37 | | PA22 | EDBG_SDA | SERCOM3/PAD[0] + * | 38 | | PA23 | EDBG_SCL | SERCOM3/PAD[1] + * +------------+------------------+--------+-----------------+------------------------------ + * | 39 | | PA19 | EDBG_MISO | SERCOM1/PAD[3] + * | 40 | | PA16 | EDBG_MOSI | SERCOM1/PAD[0] + * | 41 | | PA18 | EDBG_SS | SERCOM1/PAD[2] + * | 42 | | PA17 | EDBG_SCK | SERCOM1/PAD[1] + * +------------+------------------+--------+-----------------+------------------------------ + * | 43 | | PA13 | EDBG_GPIO0 | EIC/EXTINT[13] *TCC2/WO[1] TCC0/WO[7] + * | 44 | | PA21 | EDBG_GPIO1 | Pin 7 + * | 45 | | PA06 | EDBG_GPIO2 | Pin 8 + * | 46 | | PA07 | EDBG_GPIO3 | Pin 9 * +------------+------------------+--------+-----------------+------------------------------ * | |32.768KHz Crystal | | | * +------------+------------------+--------+-----------------+------------------------------ @@ -82,8 +97,6 @@ * | | | PA01 | XOUT32 | EXTINT[1] SERCOM1/PAD[1] TCC2/WO[1] * +------------+------------------+--------+-----------------+------------------------------ */ -PB22_S5_CDC_TX -PB23_S5_CDC_RX #include "variant.h" @@ -120,7 +133,7 @@ const PinDescription g_APinDescription[]= // 15 (AREF) { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // DAC/VREFP - // 16..17 I2C (SDA/SCL) + // 16..17 I2C (SDA/SCL and also EDBG: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] @@ -153,9 +166,25 @@ const PinDescription g_APinDescription[]= { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // USB/DM { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // USB/DP - // 35 .. 36 - EDBG + // 35 .. 46 - EDBG // ---------------------- - // 35/36 - SERCOM/UART (Serial) + // 35/36 - EDBG/UART { PORTB, 22, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // TX: SERCOM5/PAD[2] { PORTB, 23, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // RX: SERCOM5/PAD[3] + + // 37/38 I2C (SDA/SCL and also EDBG:SDA/SCL) + { PORTA, 22, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCL: SERCOM3/PAD[1] + + // 39 .. 42 - EDBG/SPI + { PORTA, 19, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MISO: SERCOM1/PAD[3] + { PORTA, 16, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI: SERCOM1/PAD[0] + { PORTA, 18, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SS: SERCOM1/PAD[2] + { PORTA, 17, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCK: SERCOM1/PAD[1] + + // 43 .. 46 - EDBG/Digital + { PORTA, 13, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH5, NOT_ON_TIMER }, // EIC/EXTINT[13] *TCC2/WO[1] TCC0/WO[7] + { PORTA, 21, PIO_PWM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH7, NOT_ON_TIMER }, // Pin 7 + { PORTA, 6, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH0, NOT_ON_TIMER }, // Pin 8 + { PORTA, 7, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH1, NOT_ON_TIMER }, // Pin 9 } ; diff --git a/variants/arduino_zero/variant.h b/variants/arduino_zero/variant.h index 692e19f69776c0e5465a7278b5aab374f9d8b16c..def09d700c29cd9bc40db3ac7893a20abccca38e 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)