diff --git a/.gitignore b/.gitignore index 96a65c9e..c523b483 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.elf *.swp *.bin +.* diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp new file mode 100644 index 00000000..78c5e360 --- /dev/null +++ b/cores/arduino/Print.cpp @@ -0,0 +1,261 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + */ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + n += write(*buffer++); + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + return print(reinterpret_cast(ifsh)); +} + +size_t Print::print(const String &s) +{ + size_t n = 0; + for (uint16_t i = 0; i < s.length(); i++) { + n += write(s[i]); + } + return n; +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + size_t n = print('\r'); + n += print('\n'); + return n; +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) { + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + unsigned long m = n; + n /= base; + char c = m - base * n; + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number <-4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int toPrint = int(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/cores/arduino/RingBuffer.cpp b/cores/arduino/RingBuffer.cpp new file mode 100644 index 00000000..c6b86498 --- /dev/null +++ b/cores/arduino/RingBuffer.cpp @@ -0,0 +1,49 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified by Dan O'Donovan Apr 29 2014: add buffer overflow control +*/ + +#include "RingBuffer.h" +#include + +RingBuffer::RingBuffer( void ) +{ + memset( _aucBuffer, 0, SERIAL_BUFFER_SIZE ) ; + _iHead=0 ; + _iTail=0 ; +} + +void RingBuffer::store_char( uint8_t c ) +{ + int i = (uint32_t)(_iHead + 1) % SERIAL_BUFFER_SIZE ; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if ( i != _iTail ) + { + _aucBuffer[_iHead] = c ; + _iHead = i ; + } + else + { + _buffer_overflow = true; + } +} + diff --git a/cores/arduino/RingBuffer.h b/cores/arduino/RingBuffer.h new file mode 100644 index 00000000..e391ace4 --- /dev/null +++ b/cores/arduino/RingBuffer.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Modified by Dan O'Donovan Apr 29 2014: add buffer overflow control +*/ + +#ifndef _RING_BUFFER_ +#define _RING_BUFFER_ + +#include + +// Define constants and variables for buffering incoming serial data. We're +// using a ring buffer (I think), in which head is the index of the location +// to which to write the next incoming character and tail is the index of the +// location from which to read. +#define SERIAL_BUFFER_SIZE 256 + +class RingBuffer +{ +public: + uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ; + int _iHead ; + int _iTail ; + bool _buffer_overflow ; + + RingBuffer( void ) ; + void store_char( uint8_t c ) ; + bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; } +} ; + +#endif diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp new file mode 100644 index 00000000..b31942f2 --- /dev/null +++ b/cores/arduino/Stream.cpp @@ -0,0 +1,317 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + + findMulti/findUntil routines written by Jim Leonard/Xuth + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait +#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field + +// private method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit() +{ + int c; + while (1) { + c = timedPeek(); + if (c < 0) return c; // timeout + if (c == '-') return c; + if (c >= '0' && c <= '9') return c; + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + if (terminator == NULL) { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0 ? true : false; + } else { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0 ? true : false; + } +} + + +// returns the first valid (long) integer value from the current position. +// initial characters that are not digits (or the minus sign) are skipped +// function is terminated by the first character that is not a digit. +long Stream::parseInt() +{ + return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) +} + +// as above but a given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +long Stream::parseInt(char skipChar) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore this charactor + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == skipChar ); + + if(isNegative) + value = -value; + return value; +} + + +// as parseInt but returns a floating point value +float Stream::parseFloat() +{ + return parseFloat(NO_SKIP_CHAR); +} + +// as above but the given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +float Stream::parseFloat(char skipChar){ + bool isNegative = false; + bool isFraction = false; + long value = 0; + char c; + float fraction = 1.0; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + if (t->len <= 0) + return t - targets; + } + + while (1) { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) { + t->index++; + break; + } + + // otherwise we just try the next index + } while (t->index); + } + } + // unreachable + return -1; +} diff --git a/cores/arduino/UARTClass.cpp b/cores/arduino/UARTClass.cpp new file mode 100644 index 00000000..2f89cb93 --- /dev/null +++ b/cores/arduino/UARTClass.cpp @@ -0,0 +1,199 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include "Arduino.h" +#include "portable.h" +#include "UARTClass.h" +#include "wiring_constants.h" +#include "wiring_digital.h" + +// Constructors //////////////////////////////////////////////////////////////// + +//UARTClass::UARTClass( Uart *pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer *pRx_buffer, RingBuffer *pTx_buffer ) +UARTClass::UARTClass( uart_init_info *info, RingBuffer *pRx_buffer, RingBuffer *pTx_buffer ) +{ + this->info = info; + this->_rx_buffer = pRx_buffer; + this->_tx_buffer = pTx_buffer; +} + +// Public Methods ////////////////////////////////////////////////////////////// + +void UARTClass::begin(const uint32_t dwBaudRate) +{ + begin(dwBaudRate, 0); +} + +void UARTClass::begin(const uint32_t dwBaudRate, const int config) +{ + init(dwBaudRate, config ); +} + + +void UARTClass::init(const uint32_t dwBaudRate, const uint32_t modeReg) +{ + // Make sure both ring buffers are initialized back to empty. + _rx_buffer->_iHead = _rx_buffer->_iTail = 0; + _tx_buffer->_iHead = _tx_buffer->_iTail = 0; + + + SET_PIN_MODE(17, UART_MUX_MODE); // Rdx SOC PIN + SET_PIN_MODE(16, UART_MUX_MODE); // Txd SOC PIN + + info->options = 0; + info->sys_clk_freq = 32000000; + info->baud_rate = dwBaudRate; + info->regs = PERIPH_ADDR_BASE_UART1; + info->irq = IRQ_UART1_INTR; + info->int_pri = 0; + + uart_init(0, info); + +} + +void UARTClass::end( void ) +{ + // Clear any received data + _rx_buffer->_iHead = _rx_buffer->_iTail; + + // Wait for any outstanding data to be sent + flush(); +} + +void UARTClass::setInterruptPriority(uint32_t priority) +{ + //NVIC_SetPriority(_dwIrq, priority & 0x0F); +} + +uint32_t UARTClass::getInterruptPriority() +{ + //return NVIC_GetPriority(_dwIrq); + return 0; +} + +int UARTClass::available( void ) +{ + //return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE; + return 0; +} + +int UARTClass::availableForWrite(void) +{ + int head = _tx_buffer->_iHead; + int tail = _tx_buffer->_iTail; + if (head >= tail) return SERIAL_BUFFER_SIZE - 1 - head + tail; + return tail - head - 1; +} + +int UARTClass::peek( void ) +{ + if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) + return -1; + + return _rx_buffer->_aucBuffer[_rx_buffer->_iTail]; +} + +int UARTClass::read( void ) +{ + uint8_t uc_data; + int ret; + ret = uart_poll_in(0, &uc_data); + if ( ret==-1 ) + return -1; + else + return uc_data; +#if 0 + // if the head isn't ahead of the tail, we don't have any characters + if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) + return -1; + + uint8_t uc = _rx_buffer->_aucBuffer[_rx_buffer->_iTail]; + _rx_buffer->_iTail = (unsigned int)(_rx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; + return uc; +#endif +} + +void UARTClass::flush( void ) +{ + while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent + // Wait for transmission to complete + //while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY); +} + +size_t UARTClass::write( const uint8_t uc_data ) +{ + + uart_poll_out(0, uc_data); +#if 0 + // Is the hardware currently busy? + if (_tx_buffer->_iTail != _tx_buffer->_iHead) + { + // If busy we buffer + unsigned int l = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE; + while (_tx_buffer->_iTail == l) + ; // Spin locks if we're about to overwrite the buffer. This continues once the data is sent + + _tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data; + _tx_buffer->_iHead = l; + // Make sure TX interrupt is enabled + //_pUart->UART_IER = UART_IER_TXRDY; + } + else + { + // Bypass buffering and send character directly + //_pUart->UART_THR = uc_data; + } +#endif + return 1; +} + +void UARTClass::IrqHandler( void ) +{ +#if 0 + uint32_t status = _pUart->UART_SR; + + // Did we receive data? + if ((status & UART_SR_RXRDY) == UART_SR_RXRDY) + _rx_buffer->store_char(_pUart->UART_RHR); + + // Do we need to keep sending data? + if ((status & UART_SR_TXRDY) == UART_SR_TXRDY) + { + if (_tx_buffer->_iTail != _tx_buffer->_iHead) { + _pUart->UART_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail]; + _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; + } + else + { + // Mask off transmit interrupt so we don't get it anymore + _pUart->UART_IDR = UART_IDR_TXRDY; + } + } + + // Acknowledge errors + if ((status & UART_SR_OVRE) == UART_SR_OVRE || (status & UART_SR_FRAME) == UART_SR_FRAME) + { + // TODO: error reporting outside ISR + _pUart->UART_CR |= UART_CR_RSTSTA; + } +#endif +} + diff --git a/cores/arduino/UARTClass.h b/cores/arduino/UARTClass.h new file mode 100644 index 00000000..93fd6cc7 --- /dev/null +++ b/cores/arduino/UARTClass.h @@ -0,0 +1,66 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _UART_CLASS_ +#define _UART_CLASS_ + +#include "HardwareSerial.h" +#include "RingBuffer.h" + +#include +#include + +class UARTClass : public HardwareSerial +{ + public: + //UARTClass(Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer); + UARTClass(uart_init_info *info, RingBuffer *pRx_buffer, RingBuffer *pTx_buffer ); + + void begin(const uint32_t dwBaudRate); + void begin(const uint32_t dwBaudRate, const int config); + void end(void); + int available(void); + int availableForWrite(void); + int peek(void); + int read(void); + void flush(void); + size_t write(const uint8_t c); + //TODO implemtn Print + //using Print::write; // pull in write(str) and write(buf, size) from Print + + void setInterruptPriority(uint32_t priority); + uint32_t getInterruptPriority(); + + void IrqHandler(void); + + operator bool() { return true; }; // UART always active + + protected: + void init(const uint32_t dwBaudRate, const uint32_t config); + + RingBuffer *_rx_buffer; + RingBuffer *_tx_buffer; + + uart_init_info *info; + //Uart* _pUart; + //IRQn_Type _dwIrq; + uint32_t _dwId; + +}; + +#endif // _UART_CLASS_ diff --git a/cores/arduino/WMath.cpp b/cores/arduino/WMath.cpp new file mode 100644 index 00000000..ec2e29b2 --- /dev/null +++ b/cores/arduino/WMath.cpp @@ -0,0 +1,68 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +extern "C" { + #include "stdlib.h" + #include "stdint.h" +} +#include "WMath.h" + +extern void randomSeed( uint32_t dwSeed ) +{ + if ( dwSeed != 0 ) + { + srand( dwSeed ) ; + } +} + +extern long random( long howbig ) +{ + if ( howbig == 0 ) + { + return 0 ; + } + + return rand() % howbig; +} + +extern long random( long howsmall, long howbig ) +{ + if (howsmall >= howbig) + { + return howsmall; + } + + long diff = howbig - howsmall; + + return random(diff) + howsmall; +} + +extern long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +extern uint16_t makeWord( uint16_t w ) +{ + return w ; +} + +extern uint16_t makeWord( uint8_t h, uint8_t l ) +{ + return (h << 8) | l ; +} diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp new file mode 100644 index 00000000..73222678 --- /dev/null +++ b/cores/arduino/WString.cpp @@ -0,0 +1,712 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified by Daniel Hugo on 6 Mar 2014: + - Implement operator+ in .h per Arduino spec, fix long snprintf + fmt in .cpp. + + Modified by Manoel Ramon 6 Jun 6 2014: + - String + does not handle implicit type of string "" + +*/ + +#include "WString.h" +#include + + +// following the C++ standard operators with attributes in right +// side must be defined globally +String operator + ( const char *cstr, const String &str_arg) +{ + String &str_arg_o = const_cast(str_arg); + String aux = String(cstr); + aux.concat(str_arg_o); + return aux; +} +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +static char * c_spec_signed[] = { + (char *) "%d", + (char *) "%ld", + (char *) "%o", + (char *) "%x", + (char *) "unsupported base", + }; + +static char * c_spec_unsigned[] = { + (char *) "%u", + (char *) "%lu", + (char *) "%o", + (char *) "%x", + (char *) "unsupported base", + }; + + +char * String::getCSpec(int base, bool issigned, bool islong){ + int int_idx = 0; + + if(islong == true) + int_idx = 1; + + switch(base){ + case 8: + if(issigned == true) + return c_spec_signed[2]; + else + return c_spec_unsigned[2]; + case 10: + if(issigned == true) + return c_spec_signed[int_idx]; + else + return c_spec_unsigned[int_idx]; + case 16: + if(issigned == true) + return c_spec_signed[3]; + else + return c_spec_unsigned[3]; + default: + return c_spec_unsigned[4]; + } +}; + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[9]; + //utoa(value, buf, base); + snprintf(buf, sizeof(buf), getCSpec(base, false, false), value); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[18]; + //itoa(value, buf, base); + snprintf(buf, sizeof(buf), getCSpec(base, true, false), value); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[17]; + //utoa(value, buf, base); + snprintf(buf, sizeof(buf), getCSpec(base, false, false), value); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[34]; + //ltoa(value, buf, base); + snprintf(buf, sizeof(buf), getCSpec(base, true, true), value); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[33]; + //ultoa(value, buf, base); + snprintf(buf, sizeof(buf), getCSpec(base, false, true), value); + *this = buf; +} + +String::~String() +{ + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; + flags = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int _length) +{ + if (!reserve(_length)) { + invalidate(); + return *this; + } + len = _length; + strcpy(buffer, cstr); + return *this; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +void String::move(String &rhs) +{ + if (buffer) { + if (capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int _length) +{ + unsigned int newlen = len + _length; + if (!cstr) return 0; + if (_length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[4]; + //itoa(num, buf, 10); + snprintf(buf, sizeof(buf), getCSpec(10, true, false), num); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[7]; + //itoa(num, buf, 10); + snprintf(buf, sizeof(buf), getCSpec(10, true, false), num); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[6]; + //utoa(num, buf, 10); + snprintf(buf, sizeof(buf), getCSpec(10, false, false), num); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[12]; + //ltoa(num, buf, 10); + snprintf(buf, sizeof(buf), getCSpec(10, true, true), num); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[11]; + //ultoa(num, buf, 10); + snprintf(buf, sizeof(buf), getCSpec(10, false, true), num); + return concat(buf, strlen(buf)); +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left > len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char _replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = _replace; + } +} + +void String::replace(const String& find, const String& _replace) +{ + if (len == 0 || find.len == 0) return; + int diff = _replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, _replace.buffer, _replace.len); + readFrom = foundAt + _replace.len; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, _replace.buffer, _replace.len); + writeTo += _replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, _replace.buffer, _replace.len); + index--; + } + } +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + + diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h index 5cbdc882..dfe561a9 100644 --- a/cores/arduino/WString.h +++ b/cores/arduino/WString.h @@ -17,6 +17,10 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified by Daniel Hugo Thu Mar 6 17:14:38 2014: + Implement operator+ in .h per Arduino spec, fix long snprintf + fmt in .cpp. */ #ifndef String_class_h @@ -26,6 +30,7 @@ #include #include #include +//#include // When compiling programs with this class, the following gcc parameters // dramatically increase performance and memory (RAM) efficiency, typically @@ -57,7 +62,6 @@ class String // be false). String(const char *cstr = ""); String(const String &str); - String(const __FlashStringHelper *str); #ifdef __GXX_EXPERIMENTAL_CXX0X__ String(String &&rval); String(StringSumHelper &&rval); @@ -68,8 +72,6 @@ class String explicit String(unsigned int, unsigned char base=10); explicit String(long, unsigned char base=10); explicit String(unsigned long, unsigned char base=10); - explicit String(float, unsigned char decimalPlaces=2); - explicit String(double, unsigned char decimalPlaces=2); ~String(void); // memory management @@ -80,21 +82,20 @@ class String inline unsigned int length(void) const {return len;} // creates a copy of the assigned value. if the value is null or - // invalid, or if the memory allocation fails, the string will be + // invalid, or if the memory allocation fails, the string will be // marked as invalid ("if (s)" will be false). String & operator = (const String &rhs); String & operator = (const char *cstr); - String & operator = (const __FlashStringHelper *str); #ifdef __GXX_EXPERIMENTAL_CXX0X__ String & operator = (String &&rval); String & operator = (StringSumHelper &&rval); #endif // concatenate (works w/ built-in types) - + // returns true on success, false on failure (in which case, the string - // is left unchanged). if the argument is null or invalid, the - // concatenation is considered unsucessful. + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. unsigned char concat(const String &str); unsigned char concat(const char *cstr); unsigned char concat(char c); @@ -103,24 +104,30 @@ class String unsigned char concat(unsigned int num); unsigned char concat(long num); unsigned char concat(unsigned long num); - unsigned char concat(float num); - unsigned char concat(double num); - unsigned char concat(const __FlashStringHelper * str); - + // if there's not enough memory for the concatenated value, the string // will be left unchanged (but this isn't signalled in any way) String & operator += (const String &rhs) {concat(rhs); return (*this);} String & operator += (const char *cstr) {concat(cstr); return (*this);} String & operator += (char c) {concat(c); return (*this);} - String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} String & operator += (int num) {concat(num); return (*this);} String & operator += (unsigned int num) {concat(num); return (*this);} String & operator += (long num) {concat(num); return (*this);} String & operator += (unsigned long num) {concat(num); return (*this);} - String & operator += (float num) {concat(num); return (*this);} - String & operator += (double num) {concat(num); return (*this);} - String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + // Implement StringAdditionOperator per Arduino docs... String + __ + String operator + (const String &rhs) {return String(*this) += rhs;} + String operator + (const char *cstr) {return String(*this) += cstr;} + String operator + (char c) {return String(*this) += c;} + String operator + (unsigned char num) {return String(*this) += num;} + String operator + (int num) {return String(*this) += num;} + String operator + (unsigned int num) {return String(*this) += num;} + String operator + (long num) {return String(*this) += num;} + String operator + (unsigned long num) {return String(*this) += num;} + +#if 0 friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); @@ -129,9 +136,7 @@ class String friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); +#endif // comparison (only works w/ Strings and "strings") operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } @@ -159,7 +164,6 @@ class String void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const {getBytes((unsigned char *)buf, bufsize, index);} - const char * c_str() const { return buffer; } // search int indexOf( char ch ) const; @@ -176,21 +180,19 @@ class String // modification void replace(char find, char replace); void replace(const String& find, const String& replace); - void remove(unsigned int index); - void remove(unsigned int index, unsigned int count); void toLowerCase(void); void toUpperCase(void); void trim(void); // parsing/conversion long toInt(void) const; - float toFloat(void) const; + char * getCSpec(int base, bool issigned, bool islong); -protected: char *buffer; // the actual char array unsigned int capacity; // the array length minus one (for the '\0') unsigned int len; // the String length (not counting the '\0') -protected: + unsigned char flags; // unused, for future features + void init(void); void invalidate(void); unsigned char changeBuffer(unsigned int maxStrLen); @@ -198,7 +200,6 @@ class String // copy and move String & copy(const char *cstr, unsigned int length); - String & copy(const __FlashStringHelper *pstr, unsigned int length); #ifdef __GXX_EXPERIMENTAL_CXX0X__ void move(String &rhs); #endif @@ -215,8 +216,6 @@ class StringSumHelper : public String StringSumHelper(unsigned int num) : String(num) {} StringSumHelper(long num) : String(num) {} StringSumHelper(unsigned long num) : String(num) {} - StringSumHelper(float num) : String(num) {} - StringSumHelper(double num) : String(num) {} }; #endif // __cplusplus diff --git a/cores/arduino/abi.cpp b/cores/arduino/abi.cpp new file mode 100644 index 00000000..b9472bec --- /dev/null +++ b/cores/arduino/abi.cpp @@ -0,0 +1,38 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); +extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); + + +void __cxa_pure_virtual(void) { + // We might want to write some diagnostics to uart in this case + //std::terminate(); + while (1) + ; +} + +void __cxa_deleted_virtual(void) { + // We might want to write some diagnostics to uart in this case + //std::terminate(); + while (1) + ; +} + diff --git a/cores/arduino/hooks.c b/cores/arduino/hooks.c new file mode 100644 index 00000000..aa16d119 --- /dev/null +++ b/cores/arduino/hooks.c @@ -0,0 +1,58 @@ +/* + Copyright (c) 2012 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/** + * Empty yield() hook. + * + * This function is intended to be used by library writers to build + * libraries or sketches that supports cooperative threads. + * + * Its defined as a weak symbol and it can be redefined to implement a + * real cooperative scheduler. + */ +static void __empty() { + // Empty +} +void yield(void) __attribute__ ((weak, alias("__empty"))); + +/** + * SysTick hook + * + * This function is called from SysTick handler, before the default + * handler provided by Arduino. + */ +static int __false() { + // Return false + return 0; +} +int sysTickHook(void) __attribute__ ((weak, alias("__false"))); + +/** + * SVC hook + * PendSV hook + * + * These functions are called from SVC handler, and PensSV handler. + * Default action is halting. + */ +static void __halt() { + // Halts + while (1) + ; +} +void svcHook(void) __attribute__ ((weak, alias("__halt"))); +void pendSVHook(void) __attribute__ ((weak, alias("__halt"))); diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c new file mode 100644 index 00000000..f52597eb --- /dev/null +++ b/cores/arduino/wiring.c @@ -0,0 +1,89 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "Arduino.h" + +#include "wiring.h" +#include "arcv2_timer0.h" +#include "data_type.h" +#include "conf.h" +#include "interrupt.h" +#include "aux_regs.h" + +#define FREQ_MHZ ((ARCV2_TIMER0_CLOCK_FREQ)/1000000) + +void delay(uint32_t msec) +{ + if(0 == msec) + return; + uint32_t no_of_irqs = timer0_overflows + msec; + uint32_t microseconds = arcv2_timer0_count_get(); + + while(timer0_overflows < no_of_irqs){ + yield(); + /* Enter sleep and enable interrupts and sets interrupts threshold to 3 */ + __asm__ volatile ("sleep 0x13"); + } + /* For the last fraction of millisecond don't go to sleep - you'll wake up + * too late - just spin */ + while ((arcv2_timer0_count_get() < microseconds) && + (timer0_overflows == no_of_irqs)); +} + + +uint32_t millis(void) +{ + return timer0_overflows; +} + + +uint32_t micros(void) +{ + uint32_t tmr0_ctrl_reg; + uint32_t microsecs; + + uint32_t flags = interrupt_lock(); + + tmr0_ctrl_reg = arcv2_timer0_control_get(); + if(tmr0_ctrl_reg && ARC_V2_TMR0_CONTROL_IP_MASK){ + /* The IP bit is set, means the timer overflowed but the IRQ handler + * hasn't updated the timer0_overflows value because the IRQs are + * disabled; it is manually incremented here */ + microsecs = arcv2_timer0_count_get(); + microsecs = (timer0_overflows + 1) * 1000 + microsecs; + }else{ + /* The timer hasn't reached LIMIT from the point where we disabled the + * interrupts until here => read COUNT0 and check again the overflow + * condition */ + microsecs = arcv2_timer0_count_get(); + tmr0_ctrl_reg = arcv2_timer0_control_get(); + if(tmr0_ctrl_reg && ARC_V2_TMR0_CONTROL_IP_MASK){ + /* The COUNT0 reached LIMIT0 while reading COUNT0 value and + * possibly overflowed */ + microsecs = arcv2_timer0_count_get(); + microsecs = (timer0_overflows + 1) * 1000 + microsecs; + }else{ + microsecs = timer0_overflows * 1000 + microsecs; + } + } + + interrupt_unlock(flags); + + return microsecs; +} diff --git a/cores/arduino/wiring.h b/cores/arduino/wiring.h index 2535be0d..ffeb4965 100644 --- a/cores/arduino/wiring.h +++ b/cores/arduino/wiring.h @@ -24,6 +24,9 @@ extern "C" { #endif +#include +#include "wiring_constants.h" + /** * */ @@ -57,28 +60,8 @@ extern uint32_t micros( void ) ; * * \param dwMs the number of milliseconds to pause (uint32_t) */ -#if 0 extern void delay( uint32_t dwMs ) ; -#else - -#include "arcv2_timer1.h" - -static volatile boolean_t expired = true; - -static void timer1_user_isr(void) -{ - expired = true; -} - -static inline void delay(uint32_t) __attribute__((always_inline)); -static inline void delay(uint32_t msec){ - /* TODO */ - expired = false; - timer1_driver_init(timer1_user_isr, msec); - while(!expired); -} -#endif /** * \brief Pauses the program for the amount of time (in microseconds) specified as parameter. diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index a176f2f7..73fcc2a1 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -26,12 +26,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /* Standard Arduino PWM resolution */ static int _writeResolution = 8; +static int _readResolution = 10; -void analogResolution(int res) + +void analogWriteResolution(int res) { _writeResolution = res; } +void analogReadResolution(int res) +{ + _readResolution = res; +} + static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) { if (from == to) diff --git a/platform.txt b/platform.txt index a28f58d7..e91fb0c3 100644 --- a/platform.txt +++ b/platform.txt @@ -20,7 +20,7 @@ compiler.c.elf.flags=-nostartfiles -nodefaultlibs -nostdlib -static -Wl,-X -Wl,- compiler.S.flags=-c -g -x assembler-with-cpp #compiler.cpp.cmd=arc-elf32-g++ compiler.cpp.cmd=arc-elf32-gcc -compiler.cpp.flags=-c -mARCv2EM -mav2em -mlittle-endian -g -Os -Wall -fno-reorder-functions -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -fno-defer-pop -Wno-unused-but-set-variable -Wno-main -ffreestanding -fno-stack-protector -mno-sdata -ffunction-sections -fdata-sections -MMD +compiler.cpp.flags=-c -mARCv2EM -mav2em -mlittle-endian -g -Os -Wall -fno-reorder-functions -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -fno-defer-pop -Wno-unused-but-set-variable -Wno-main -ffreestanding -fno-stack-protector -mno-sdata -ffunction-sections -fdata-sections -MMD -fno-rtti compiler.ar.cmd=arc-elf32-ar compiler.ar.flags=rcs compiler.objcopy.cmd=arc-elf32-objcopy diff --git a/system/libarc32_edu/.gitignore b/system/libarc32_edu/.gitignore new file mode 100644 index 00000000..96a65c9e --- /dev/null +++ b/system/libarc32_edu/.gitignore @@ -0,0 +1,6 @@ +*.o +*.a +*.map +*.elf +*.swp +*.bin diff --git a/system/libarc32_edu/bootcode/c_init.c b/system/libarc32_edu/bootcode/c_init.c index 23f529b3..393147c4 100644 --- a/system/libarc32_edu/bootcode/c_init.c +++ b/system/libarc32_edu/bootcode/c_init.c @@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include "interrupt.h" +#include "arcv2_timer0.h" /* Application main() function prototype */ extern int main (void); @@ -57,6 +58,8 @@ static void _exec_ctors (void) /* Init the the interrupt unit device - disable all the interrupts; The * default value of IRQ_ENABLE is 0x01 for all configured interrupts */ interrupt_unit_device_init(); + /* Start the system 1 millisecond tick */ + timer0_driver_init(); /* Jump to application main() */ main (); /* Never reached */ diff --git a/system/libarc32_edu/bootcode/conf.h b/system/libarc32_edu/bootcode/conf.h index 300753eb..a12ba5e2 100644 --- a/system/libarc32_edu/bootcode/conf.h +++ b/system/libarc32_edu/bootcode/conf.h @@ -31,5 +31,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #define ARCV2_IRQ_TIMER0 16 #define ARCV2_IRQ_TIMER1 17 +#define ARCV2_TIMER0_CLOCK_FREQ 32000000 /* 32MHz reference clock */ +#define ARCV2_TIMER1_CLOCK_FREQ 32000000 /* 32MHz reference clock */ + +#define ARC_V2_TMR_CTRL_IE 0x1 /* interrupt enable */ +#define ARC_V2_TMR_CTRL_NH 0x2 /* count only while not halted */ +#define ARC_V2_TMR_CTRL_W 0x4 /* watchdog mode enable */ +#define ARC_V2_TMR_CTRL_IP 0x8 /* interrupt pending flag */ + + #endif /* _ARCV2_CONF__H_ */ diff --git a/system/libarc32_edu/bootcode/init.S b/system/libarc32_edu/bootcode/init.S index f28bc69b..0823547e 100644 --- a/system/libarc32_edu/bootcode/init.S +++ b/system/libarc32_edu/bootcode/init.S @@ -43,11 +43,9 @@ _do_reset: /* Set up stack pointer */ // mov sp, @_DefaultStack + STACK_SIZE mov sp, @__stack_start - /* Setup automatic (hardware) context saving feature */ - sr AUX_IRQ_CTRL_SAVE_ALL, [ARC_V2_AUX_IRQ_CTRL] /* Enable instruction cache */ - mov r0, 0 - sr r0, [ARC_V2_IC_CTRL] + //mov r0, 0 + //sr r0, [ARC_V2_IC_CTRL] /* Jump to C init function */ j @_main diff --git a/system/libarc32_edu/bootcode/interrupt.c b/system/libarc32_edu/bootcode/interrupt.c index 4f36b127..4537484a 100644 --- a/system/libarc32_edu/bootcode/interrupt.c +++ b/system/libarc32_edu/bootcode/interrupt.c @@ -105,6 +105,9 @@ void interrupt_unit_device_init(void) aux_reg_write(ARC_V2_IRQ_TRIGGER, ARC_V2_INT_LEVEL); } + /* Setup automatic (hardware) context saving feature */ + aux_reg_write(ARC_V2_AUX_IRQ_CTRL,AUX_IRQ_CTRL_SAVE_ALL); + /* Configure the interrupt priority threshold and enable interrupts */ __builtin_arc_seti(INTERRUPT_ENABLE | INTERRUPT_THRESHOLD); } diff --git a/system/libarc32_edu/drivers/arcv2_timer0.h b/system/libarc32_edu/common/arcv2_timer0.h similarity index 85% rename from system/libarc32_edu/drivers/arcv2_timer0.h rename to system/libarc32_edu/common/arcv2_timer0.h index 187f3a77..9e9990a2 100644 --- a/system/libarc32_edu/drivers/arcv2_timer0.h +++ b/system/libarc32_edu/common/arcv2_timer0.h @@ -12,6 +12,7 @@ #define _ARCV2_TIMER0__H_ #include +#include "aux_regs.h" #ifdef __cplusplus extern "C" { @@ -49,7 +50,11 @@ void timer0_driver_init(void); * * \NOMANUAL */ -uint32_t arcv2_timer0_count_get(void); +static inline __attribute__((always_inline)) +uint32_t arcv2_timer0_count_get(void) +{ + return (aux_reg_read(ARC_V2_TMR0_COUNT)); +} /******************************************************************************* @@ -62,7 +67,11 @@ uint32_t arcv2_timer0_count_get(void); * * \NOMANUAL */ -uint32_t arcv2_timer0_control_get(void); +static inline __attribute__((always_inline)) +uint32_t arcv2_timer0_control_get(void) +{ + return (aux_reg_read(ARC_V2_TMR0_CONTROL)); +} #ifdef __cplusplus diff --git a/system/libarc32_edu/common/arcv2_timer1.h b/system/libarc32_edu/common/arcv2_timer1.h new file mode 100644 index 00000000..a7c891dc --- /dev/null +++ b/system/libarc32_edu/common/arcv2_timer1.h @@ -0,0 +1,60 @@ +/* arcv2_timer1.h - ARC timer 1 device driver */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * The right to copy, distribute, modify or otherwise make use + * of this software may be licensed only pursuant to the terms + * of an applicable Wind River license agreement. + */ + +#ifndef _ARCV2_TIMER1__H_ +#define _ARCV2_TIMER1__H_ + +#include + + + +#ifdef __cplusplus + extern "C" { +#endif + +/******************************************************************************* +* +* timer1_driver_init - initialize timer1 and enable interrupt +* +* RETURNS: N/A +*/ +void timer1_driver_init(void(*int_handler)(void), uint32_t ticktime_ms); + +/******************************************************************************* +* +* arcv2_timer1_count_get - get the current counter value +* +* This routine gets the value from the timer's count register. This +* value is the 'time' elapsed from the starting count (assumed to be 0). +* +* RETURNS: the current counter value +* +* \NOMANUAL +*/ +uint32_t arcv2_timer1_count_get(void); + + +/******************************************************************************* +* +* timer1_disable - Disables Timer1 interrupt generation. +* +* This routine disables timer interrupt generation and delivery. +* Note that the timer's counting cannot be stopped by software. +* +* RETURNS: N/A +*/ +void timer1_disable(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* _ARCV2_TIMER1__H_ */ diff --git a/system/libarc32_edu/drivers/arcv2_timer0.c b/system/libarc32_edu/drivers/arcv2_timer0.c index 49f261fd..e259ae9f 100644 --- a/system/libarc32_edu/drivers/arcv2_timer0.c +++ b/system/libarc32_edu/drivers/arcv2_timer0.c @@ -28,20 +28,9 @@ conjunction with a microkernel. */ #include "arcv2_timer0.h" -#include "aux_regs.h" #include "conf.h" #include "interrupt.h" -#define ARCV2_TIMER0_CLOCK_FREQ 32000000 /* 32MHz reference clock */ - -/* defines */ - -#define ARC_V2_TMR_CTRL_IE 0x1 /* interrupt enable */ -#define ARC_V2_TMR_CTRL_NH 0x2 /* count only while not halted */ -#define ARC_V2_TMR_CTRL_W 0x4 /* watchdog mode enable */ -#define ARC_V2_TMR_CTRL_IP 0x8 /* interrupt pending flag */ - - #define ONE_MILLISECOND ARCV2_TIMER0_CLOCK_FREQ/1000 /* Maxim number of Timer0 overflows used to compute micros() @@ -69,49 +58,18 @@ uint32_t volatile timer0_overflows_us = 0x00; * \NOMANUAL */ -static inline __attribute__((always_inline)) void arcv2_timer0_enable - ( - uint32_t count /* count to which timer is to increment to */ - ) +static inline __attribute__((always_inline)) +void arcv2_timer0_enable(uint32_t count) { - aux_reg_write(ARC_V2_TMR0_LIMIT, count); /* write the limit value */ + /* ensure that the timer will not generate interrupts */ + aux_reg_write(ARC_V2_TMR0_CONTROL, 0); + /* write the limit value */ + aux_reg_write(ARC_V2_TMR0_LIMIT, count); /* count only when not halted for debug and enable interrupts */ aux_reg_write(ARC_V2_TMR0_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE); - //aux_reg_write(ARC_V2_TMR0_COUNT, 0); /* write the start value */ -} - -/******************************************************************************* -* -* arcv2_timer0_count_get - get the current counter value -* -* This routine gets the value from the timer's count register. This -* value is the 'time' elapsed from the starting count (assumed to be 0). -* -* RETURNS: the current counter value -* -* \NOMANUAL -*/ -inline __attribute__((always_inline)) -uint32_t arcv2_timer0_count_get(void) -{ - return (aux_reg_read(ARC_V2_TMR0_COUNT)); -} - -/******************************************************************************* -* -* arcv2_timer0_control_get - get the value of CONTROL0 aux register -* -* This routine gets the value from the timer's control register. -* -* RETURNS: the value of CONTROL0 auxiliary register. -* -* \NOMANUAL -*/ -inline __attribute__((always_inline)) -uint32_t arcv2_timer0_control_get(void) -{ - return (aux_reg_read(ARC_V2_TMR0_CONTROL)); + /* clear the count value */ + aux_reg_write(ARC_V2_TMR0_COUNT, 0); } /******************************************************************************* @@ -150,16 +108,10 @@ void _arcv2_timer0_int_handler(void) */ void timer0_driver_init(void) { - /* ensure that the timer will not generate interrupts */ - aux_reg_write(ARC_V2_TMR0_CONTROL, 0); - aux_reg_write(ARC_V2_TMR0_COUNT, 0); /* clear the count value */ - /* connect specified routine/parameter to the timer 0 interrupt vector */ interrupt_connect(ARCV2_IRQ_TIMER0, _arcv2_timer0_int_handler, 0); - /* configure timer to overflow and fire an IRQ every 1 ms */ arcv2_timer0_enable(ONE_MILLISECOND); - /* Everything has been configured. It is now safe to enable the interrupt */ interrupt_enable(ARCV2_IRQ_TIMER0); } diff --git a/system/libarc32_edu/drivers/arcv2_timer1.c b/system/libarc32_edu/drivers/arcv2_timer1.c index 07cb8b4c..0ca968e1 100644 --- a/system/libarc32_edu/drivers/arcv2_timer1.c +++ b/system/libarc32_edu/drivers/arcv2_timer1.c @@ -32,28 +32,15 @@ conjunction with a microkernel. #include "conf.h" #include "../bootcode/interrupt.h" -#define ARCV2_TIMER1_CLOCK_FREQ 32000000 /* 32MHz reference clock */ - -/* defines */ - -#define ARC_V2_TMR_CTRL_IE 0x1 /* interrupt enable */ -#define ARC_V2_TMR_CTRL_NH 0x2 /* count only while not halted */ -#define ARC_V2_TMR_CTRL_W 0x4 /* watchdog mode enable */ -#define ARC_V2_TMR_CTRL_IP 0x8 /* interrupt pending flag */ /* globals */ void (* timer1_user_int_handler)(void) = 0x00; -/* locals */ - -/* forward declarations */ - -uint32_t timer1_read(void); /******************************************************************************* * -* arcv2_timer_enable - enable the timer with the given limit/countup value +* arcv2_timer1_enable - enable the timer with the given limit/countup value * * This routine sets up the timer for operation by: * - setting value to which the timer will count up to; @@ -66,7 +53,7 @@ uint32_t timer1_read(void); */ static inline __attribute__((always_inline)) -void arcv2_timer_enable +void arcv2_timer1_enable ( uint32_t count /* count to which timer is to increment to */ ) @@ -79,7 +66,7 @@ void arcv2_timer_enable /******************************************************************************* * -* arcv2_timer_count_get - get the current counter value +* arcv2_timer1_count_get - get the current counter value * * This routine gets the value from the timer's count register. This * value is the 'time' elapsed from the starting count (assumed to be 0). @@ -88,35 +75,18 @@ void arcv2_timer_enable * * \NOMANUAL */ -static inline __attribute__((always_inline)) +inline __attribute__((always_inline)) uint32_t arcv2_timer1_count_get(void) { return (aux_reg_read(ARC_V2_TMR1_COUNT)); } -/******************************************************************************* - * - * arcv2_timer_limit_get - get the limit/countup value - * - * This routine gets the value from the timer's limit register, which is the - * value to which the timer will count up to. - * - * RETURNS: the current counter value - * - * \NOMANUAL - */ -static inline __attribute__((always_inline)) -uint32_t arcv2_timer1_limit_get(void) -{ - return (aux_reg_read(ARC_V2_TMR1_LIMIT)); -} - /******************************************************************************* * -* _arcv2_timer_int_handler - system clock periodic tick handler +* _arcv2_timer1_int_handler - Timer1 configured tick handler * -* This routine handles the system clock periodic tick interrupt. A TICK_EVENT -* event is pushed onto the microkernel stack. +* This routine handles the Timer1 overflow interrupt. +* It clears Timer1 IRQ and executes the user's interrupt handler. * * RETURNS: N/A * @@ -134,7 +104,7 @@ void _arcv2_timer1_int_handler(void) /******************************************************************************* * -* timer_driver - initialize timer1 and enable interrupt +* timer1_driver_init - initialize timer1 and enable interrupt * * RETURNS: N/A */ @@ -150,11 +120,6 @@ void timer1_driver_init(void(*int_handler)(void), uint32_t ticktime_ms) /* connect specified routine/parameter to the timer 0 interrupt vector */ interrupt_connect(ARCV2_IRQ_TIMER1, _arcv2_timer1_int_handler, 0); timer1_user_int_handler = int_handler; -#if 0 - (void) nanoCpuIntConnect(_WRS_CONFIG_ARCV2_TIMER1_INT_LVL, - _WRS_CONFIG_ARCV2_TIMER1_INT_PRI, - _arcv2_timer1_int_handler, 0); -#endif tickunit = (ARCV2_TIMER1_CLOCK_FREQ / 1000) * ticktime_ms; @@ -165,7 +130,7 @@ void timer1_driver_init(void(*int_handler)(void), uint32_t ticktime_ms) * The global variable 'tickunit' represents the #cycles/tick. */ - arcv2_timer_enable(tickunit); + arcv2_timer1_enable(tickunit); /* Everything has been configured. It is now safe to enable the interrupt */ interrupt_enable(ARCV2_IRQ_TIMER1); @@ -173,29 +138,13 @@ void timer1_driver_init(void(*int_handler)(void), uint32_t ticktime_ms) /******************************************************************************* * -* timer_read - read the BSP timer hardware -* -* This routine returns the current time in terms of timer hardware clock cycles. -* -* RETURNS: up counter of elapsed clock cycles -*/ - -uint32_t timer1_read(void) -{ - return arcv2_timer1_count_get(); -} - - -/******************************************************************************* -* -* timer_disable - stop announcing ticks into the kernel +* timer1_disable - Disables Timer1 interrupt generation. * * This routine disables timer interrupt generation and delivery. * Note that the timer's counting cannot be stopped by software. * * RETURNS: N/A */ - void timer1_disable(void) { uint32_t saved; @@ -211,7 +160,4 @@ void timer1_disable(void) /* disable interrupt in the interrupt controller */ interrupt_disable(ARCV2_IRQ_TIMER1); -#if 0 - nanoCpuIntDisable (ARCV2_IRQ_TIMER1); -#endif } diff --git a/system/libarc32_edu/drivers/arcv2_timer1.h b/system/libarc32_edu/drivers/arcv2_timer1.h deleted file mode 100644 index 75f38154..00000000 --- a/system/libarc32_edu/drivers/arcv2_timer1.h +++ /dev/null @@ -1,35 +0,0 @@ -/* arcv2_timer1.c - ARC timer 1 device driver */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * The right to copy, distribute, modify or otherwise make use - * of this software may be licensed only pursuant to the terms - * of an applicable Wind River license agreement. - */ - -#ifndef _ARCV2_TIMER1__H_ -#define _ARCV2_TIMER1__H_ - -#include - - -/******************************************************************************* -* -* timer_driver - initialize timer1 and enable interrupt -* -* RETURNS: N/A -*/ - -#ifdef __cplusplus - extern "C" { -#endif - -void timer1_driver_init(void(*int_handler)(void), uint32_t ticktime_ms); -uint32_t timer1_read(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _ARCV2_TIMER1__H_ */ diff --git a/system/libarc32_edu/framework/include/os/os.h b/system/libarc32_edu/framework/include/os/os.h index 34a6f950..4bb9920d 100644 --- a/system/libarc32_edu/framework/include/os/os.h +++ b/system/libarc32_edu/framework/include/os/os.h @@ -134,28 +134,6 @@ extern void queue_get_message (T_QUEUE queue, T_QUEUE_MESSAGE* message, int time */ extern void queue_send_message(T_QUEUE queue, T_QUEUE_MESSAGE message, OS_ERR_TYPE* err ); -/** - * \brief Get the current tick in ms - * - * Return the current tick converted in milliseconds - * - * Authorized execution levels: task, fiber, ISR - * - * \return current tick converted in milliseconds - */ -extern uint32_t get_time_ms (void); - -/** - * \brief Get the current tick in us - * - * Return the current tick converted in microseconds - * - * Authorized execution levels: task, fiber, ISR - * - * \return current tick converted in microseconds - */ -extern uint64_t get_time_us (void); - /** * \brief Reserves a block of memory * @@ -209,12 +187,6 @@ extern void* balloc (uint32_t size, OS_ERR_TYPE* err); */ extern OS_ERR_TYPE bfree(void* buffer); -/** - * \brief Initialize the OS abstraction layer - * - */ -extern void os_init (void); - #endif /**@} @} @}*/ diff --git a/system/libarc32_edu/framework/include/os/os_types.h b/system/libarc32_edu/framework/include/os/os_types.h index 79b241dc..58dc4e9e 100644 --- a/system/libarc32_edu/framework/include/os/os_types.h +++ b/system/libarc32_edu/framework/include/os/os_types.h @@ -56,22 +56,8 @@ typedef enum { /** Types for kernel objects */ -typedef void* T_SEMAPHORE ; -typedef void* T_MUTEX; typedef void* T_QUEUE; typedef void* T_QUEUE_MESSAGE; -typedef void* T_TIMER; -typedef void* T_TASK ; -typedef uint8_t T_TASK_PRIO ; -#define HIGHEST_TASK_PRIO OS_SPECIFIC_HIGHEST_PRIO -#define LOWEST_TASK_PRIO OS_SPECIFIC_LOWEST_PRIO - -typedef enum { - E_TASK_UNCREATED = 0, - E_TASK_RUNNING, - E_TASK_SUSPENDED, -} T_TASK_STATE; - /** Special values for "timeout" parameter */ #define OS_NO_WAIT 0 diff --git a/system/libarc32_edu/framework/include/pf_init.h b/system/libarc32_edu/framework/include/pf_init.h deleted file mode 100644 index 50542ca9..00000000 --- a/system/libarc32_edu/framework/include/pf_init.h +++ /dev/null @@ -1,32 +0,0 @@ -/** INTEL CONFIDENTIAL Copyright 2014 Intel Corporation All Rights Reserved. - * - * The source code contained or described herein and all documents related to - * the source code ("Material") are owned by Intel Corporation or its suppliers - * or licensors. - * Title to the Material remains with Intel Corporation or its suppliers and - * licensors. - * The Material contains trade secrets and proprietary and confidential information - * of Intel or its suppliers and licensors. The Material is protected by worldwide - * copyright and trade secret laws and treaty provisions. - * No part of the Material may be used, copied, reproduced, modified, published, - * uploaded, posted, transmitted, distributed, or disclosed in any way without - * Intel’s prior express written permission. - * - * No license under any patent, copyright, trade secret or other intellectual - * property right is granted to or conferred upon you by disclosure or delivery - * of the Materials, either expressly, by implication, inducement, estoppel or - * otherwise. - * - * Any license under such intellectual property rights must be express and - * approved by Intel in writing - * - ******************************************************************************/ - -#ifndef __PF_INIT_H_ -#define __PF_INIT_H_ - -void platform_init(); - -void platform_main_loop(); - -#endif diff --git a/system/libarc32_edu/main.c b/system/libarc32_edu/main.c index 49128c42..f4d18de5 100644 --- a/system/libarc32_edu/main.c +++ b/system/libarc32_edu/main.c @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include "drivers/soc_gpio.h" -#include "drivers/arcv2_timer1.h" +#include "arcv2_timer1.h" #include "scss_registers.h" #include "infra/ipc.h" diff --git a/variants/intel_edu_x/libarc32drv_edu.a b/variants/intel_edu_x/libarc32drv_edu.a new file mode 100644 index 00000000..460ac710 Binary files /dev/null and b/variants/intel_edu_x/libarc32drv_edu.a differ diff --git a/variants/intel_edu_x/variant.cpp b/variants/intel_edu_x/variant.cpp index 46777ece..105df069 100644 --- a/variants/intel_edu_x/variant.cpp +++ b/variants/intel_edu_x/variant.cpp @@ -86,15 +86,19 @@ PinDescription g_APinDescription[]= uint32_t sizeof_g_APinDescription; -#ifdef OUT /* * UART objects */ RingBuffer rx_buffer1; RingBuffer tx_buffer1; +uart_init_info info1; + +UARTClass Serial(&info1, &rx_buffer1, &tx_buffer1); + + +#ifdef OUT -UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1, &tx_buffer1); void serialEvent() __attribute__((weak)); void serialEvent() { } diff --git a/variants/intel_edu_x/variant.h b/variants/intel_edu_x/variant.h index 1adf74dd..50a61628 100644 --- a/variants/intel_edu_x/variant.h +++ b/variants/intel_edu_x/variant.h @@ -35,10 +35,10 @@ #include "Arduino.h" #include "wiring_digital.h" #include "pins_arduino.h" -//#ifdef __cplusplus -//#include "UARTClass.h" +#ifdef __cplusplus +#include "UARTClass.h" //#include "USARTClass.h" -//#endif +#endif #ifdef __cplusplus extern "C"{ @@ -65,6 +65,9 @@ extern "C"{ */ #define GPIO_MUX_MODE QRK_PMUX_SEL_MODEA +#define SS_GPIO 1 +#define SOC_GPIO 2 + /* * PWM */ @@ -77,6 +80,12 @@ extern "C"{ #define PWM_SCALE_490HZ 0 /* "Standard" Arduino PWM frequency is 490Hz */ #define PWM_SCALE_980HZ 1 /* Some pins on Arduino boards emit 980Hz PWM */ +/* + * UART + */ + +#define UART_MUX_MODE QRK_PMUX_SEL_MODEC + #ifdef __cplusplus } #endif @@ -87,7 +96,7 @@ extern "C"{ #ifdef __cplusplus -//extern UARTClass Serial; +extern UARTClass Serial; //extern USARTClass Serial1; #endif @@ -113,9 +122,6 @@ extern "C"{ #define SERIAL_PORT_HARDWARE Serial1 #define SERIAL_PORT_HARDWARE1 Serial1 -#define SS_GPIO 1 -#define SOC_GPIO 2 - extern uint32_t sizeof_g_APinDescription; #endif /* _VARIANT_INTEL_EDU_X_ */