diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index cfd2577d36fe0dca904f407857443c358f879a3b..c5dc9bb60e7bc1172cd36a8ddb05dcbad6cdbbf0 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -17,12 +17,11 @@ SERCOM::SERCOM(Sercom* s) * ===== Sercom UART * ========================= */ - void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate) { resetUART(); initClock(); - + initNVIC(); //Setting the CTRLA register sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(mode) | @@ -32,12 +31,10 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint 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) { - uint32_t sampleRateValue; + uint16_t sampleRateValue; if(sampleRate == SAMPLE_RATE_x16) sampleRateValue = 16; @@ -47,13 +44,9 @@ 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)); - uint16_t tmpBaud = (baudrate / SERCOM_FREQ_REF); - tmpBaud = ( 1 - sampleRateValue * tmpBaud); - tmpBaud = (65535ul) * tmpBaud; + //65535 * ( 1 - sampleRateValue * baudrate / SERCOM_FREQ_REF); + sercom->USART.BAUD.reg = 65535.0 * ( 1.0 - (float)(sampleRateValue) * (float)(baudrate) / (float)(SERCOM_FREQ_REF)); - tmpBaud = 63019; - sercom->USART.BAUD.reg = tmpBaud; } } void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits) @@ -303,42 +296,7 @@ bool SERCOM::isReceiveCompleteSPI() uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate) { - return division(SERCOM_FREQ_REF, (2 * baudrate)) - 1; -} - - -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; + return SERCOM_FREQ_REF / (2 * baudrate) - 1; } @@ -537,7 +495,7 @@ uint8_t SERCOM::readDataWIRE() void SERCOM::initClock() { - uint8_t clockId; + uint8_t clockId = 0; if(sercom == SERCOM0) { @@ -576,6 +534,39 @@ void SERCOM::initClock() } } +void SERCOM::initNVIC() +{ + IRQn_Type nvicID; + + if(sercom == SERCOM0) + { + nvicID = SERCOM0_IRQn; + } + else if(sercom == SERCOM1) + { + nvicID = SERCOM1_IRQn; + } + else if(sercom == SERCOM2) + { + nvicID = SERCOM2_IRQn; + } + else if(sercom == SERCOM3) + { + nvicID = SERCOM3_IRQn; + } + else if(sercom == SERCOM4) + { + nvicID = SERCOM4_IRQn; + } + else if(sercom == SERCOM5) + { + nvicID = SERCOM5_IRQn; + } + + NVIC_EnableIRQ(nvicID); + NVIC_SetPriority (nvicID, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ +} + /* ========================= * ===== SERCOM DEFINITION * ========================= diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h index c756d81b00413c44c11c0345a5c9efc1bf0226fa..132e60fa1830a0dc433202af060425e9f2da9d4c 100644 --- a/cores/arduino/SERCOM.h +++ b/cores/arduino/SERCOM.h @@ -199,6 +199,7 @@ class SERCOM uint8_t calculateBaudrateSynchronous(uint32_t baudrate); uint32_t division(uint32_t dividend, uint32_t divisor); void initClock(); + void initNVIC(); }; #endif diff --git a/cores/arduino/Uart.cpp b/cores/arduino/Uart.cpp index 819d07be6047ba8ca1401b9fef2e35ae543dd7d2..683c46377fef043f67f6917418b03eae87ddaa51 100644 --- a/cores/arduino/Uart.cpp +++ b/cores/arduino/Uart.cpp @@ -1,16 +1,24 @@ #include "Uart.h" -Uart::Uart(SERCOM *sercom) +Uart::Uart(SERCOM *s, uint8_t pinRX, uint8_t pinTX) { - this->sercom = sercom; - pinPeripheral(0, PIO_SERCOM); - pinPeripheral(1, PIO_SERCOM); + sercom = s; + if(sercom == SERCOM::sercom0) + { + pinPeripheral(pinRX, g_APinDescription[pinRX].ulPinType); + pinPeripheral(pinTX, g_APinDescription[pinTX].ulPinType); + } + else if(sercom == SERCOM::sercom5) + { + pinPeripheral(pinRX, g_APinDescription[pinRX].ulPinType); + pinPeripheral(pinTX, g_APinDescription[pinTX].ulPinType); + } } void Uart::begin(unsigned long baudrate) { - begin(baudrate, SERIAL_8N1); + begin(baudrate, (uint8_t)SERIAL_8N1); } void Uart::begin(unsigned long baudrate, uint8_t config) @@ -132,7 +140,8 @@ SercomParityMode Uart::extractParity(uint8_t config) } } -Uart Serial = Uart(SERCOM::sercom0); +Uart Serial = Uart(SERCOM::sercom0, 0, 1); +Uart Serial5 = Uart(SERCOM::sercom5, 36, 35); void SERCOM0_Handler() { @@ -140,5 +149,5 @@ void SERCOM0_Handler() } void SERCOM5_Handler() { - Serial.IrqHandler(); + Serial5.IrqHandler(); } diff --git a/cores/arduino/Uart.h b/cores/arduino/Uart.h index 64f8ec03336446411dde3a481e28ce632ede494a..0d40392e3df3832340c1c1734a8ee2bc8d45272e 100644 --- a/cores/arduino/Uart.h +++ b/cores/arduino/Uart.h @@ -13,7 +13,7 @@ class Uart : public HardwareSerial { public: - Uart(SERCOM *sercom); + Uart(SERCOM *s, uint8_t pinRX, uint8_t pinTX); void begin(unsigned long baudRate); void begin(unsigned long baudrate, uint8_t config); void end(); @@ -37,6 +37,7 @@ class Uart : public HardwareSerial SercomParityMode extractParity(uint8_t config); }; extern Uart Serial; +extern Uart Serial5; #endif diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index e66dbd3685b4ace0fc31b4b286c67755f51fb2cc..17d4479711c92aa44792cd6f34222d8cc7944a82 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -18,7 +18,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_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, MSB_FIRST); - sercom->initClock(SERCOM_SPI_MODE_0, 4000000); + sercom->initSPIClock(SERCOM_SPI_MODE_0, 4000000); } void SPIClass::end() { @@ -86,6 +86,4 @@ void SPIClass::detachInterrupt() { // Should be disableInterrupt() } -#if SPI_INTERFACES_COUNT > 0 SPIClass SPI(SERCOM::sercom4); -#endif