diff --git a/cores/arduino/RingBuffer.h b/cores/arduino/RingBuffer.h new file mode 100644 index 0000000..2d58dca --- /dev/null +++ b/cores/arduino/RingBuffer.h @@ -0,0 +1,142 @@ +/* + 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 +*/ + +#ifdef __cplusplus + +#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 64 + +template +class RingBufferN +{ + public: + uint8_t _aucBuffer[N] ; + volatile int _iHead ; + volatile int _iTail ; + + public: + RingBufferN( void ) ; + void store_char( uint8_t c ) ; + void clear(); + int read_char(); + int available(); + int availableForStore(); + int peek(); + bool isFull(); + + private: + int nextIndex(int index); +}; + +typedef RingBufferN RingBuffer; + + +template +RingBufferN::RingBufferN( void ) +{ + memset( _aucBuffer, 0, N ) ; + clear(); +} + +template +void RingBufferN::store_char( uint8_t c ) +{ + int i = nextIndex(_iHead); + + // 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 ; + } +} + +template +void RingBufferN::clear() +{ + _iHead = 0; + _iTail = 0; +} + +template +int RingBufferN::read_char() +{ + if(_iTail == _iHead) + return -1; + + uint8_t value = _aucBuffer[_iTail]; + _iTail = nextIndex(_iTail); + + return value; +} + +template +int RingBufferN::available() +{ + int delta = _iHead - _iTail; + + if(delta < 0) + return N + delta; + else + return delta; +} + +template +int RingBufferN::availableForStore() +{ + if (_iHead >= _iTail) + return N - 1 - _iHead + _iTail; + else + return _iTail - _iHead - 1; +} + +template +int RingBufferN::peek() +{ + if(_iTail == _iHead) + return -1; + + return _aucBuffer[_iTail]; +} + +template +int RingBufferN::nextIndex(int index) +{ + return (uint32_t)(index + 1) % N; +} + +template +bool RingBufferN::isFull() +{ + return (nextIndex(_iHead) == _iTail); +} + +#endif /* _RING_BUFFER_ */ + +#endif /* __cplusplus */ \ No newline at end of file diff --git a/cores/arduino/UARTClass.cpp b/cores/arduino/UARTClass.cpp index 229eb92..714a059 100644 --- a/cores/arduino/UARTClass.cpp +++ b/cores/arduino/UARTClass.cpp @@ -24,79 +24,158 @@ #include "pins_arduino.h" #include "uarths.h" #include "fpioa.h" +#include "sysctl.h" -UARTClass Serial; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) +UARTHSClass Serial; +UARTClass Serial1(UART_DEVICE_1); +UARTClass Serial2(UART_DEVICE_2); +UARTClass Serial3(UART_DEVICE_3); +#endif + +static int uart_rec_callback(void *ctx); +static int uarths_rec_callback(void *ctx); // Public Methods ////////////////////////////////////////////////////////////// -UARTClass::UARTClass(void) +UARTClass::UARTClass() { - _rxPin = RX; - _txPin = TX; + } -UARTClass::UARTClass(uint8_t rxPin, uint8_t txPin) +UARTClass::UARTClass(uart_device_number_t device_select) { - _rxPin = rxPin; - _txPin = txPin; + this->_uart = device_select; + switch(this->_uart){ + case UART_DEVICE_1: + this->_rxfunc = FUNC_UART1_RX; + this->_txfunc = FUNC_UART1_TX; + break; + case UART_DEVICE_2: + this->_rxfunc = FUNC_UART2_RX; + this->_txfunc = FUNC_UART2_TX; + break; + case UART_DEVICE_3: + this->_rxfunc = FUNC_UART3_RX; + this->_txfunc = FUNC_UART3_TX; + break; + case UART_DEVICE_MAX: + break; + } } - void -UARTClass::begin(uint32_t bauds) +UARTClass::begin(uint32_t dwBaudRate, uint8_t _rx, uint8_t _tx) { - fpioa_set_function((int)_rxPin, FUNC_UARTHS_RX); - fpioa_set_function((int)_txPin, FUNC_UARTHS_TX); - uarths_config(bauds, UARTHS_STOP_1); + fpioa_set_function((int)_rx, this->_rxfunc); + fpioa_set_function((int)_tx, this->_txfunc); + uart_init(this->_uart); + uart_configure(this->_uart, dwBaudRate, UART_BITWIDTH_8BIT, UART_STOP_1, UART_PARITY_NONE); + this->_buff = new RingBuffer(); + uart_set_receive_trigger(this->_uart, UART_RECEIVE_FIFO_1); + uart_irq_register(this->_uart, UART_RECEIVE, uart_rec_callback, this, 5); + sysctl_enable_irq(); } - - void -UARTClass::end(void) //TODO k210 sdk not have api +UARTClass::end(void) { - + delete this->_buff; + uart_irq_unregister(this->_uart, UART_RECEIVE); } - int -UARTClass::available(void) //TODO Get the number of bytes (characters) available for reading from the serial port. +UARTClass::available(void) { - return(1); + return this->_buff->available(); } - int UARTClass::availableForWrite(void) //TODO Get the number of bytes (characters) available for writing from the serial port. { return (1); } - int -UARTClass::peek(void) //TODO Returns the next byte (character) of incoming serial data without removing it from the internal serial buffer. +UARTClass::peek(void) { - return (-1); + return this->_buff->peek(); } - int UARTClass::read(void) { - - return (uarths_getc()); + while(this->_buff->available()){ + return this->_buff->read_char(); + } } - void -UARTClass::flush(void) //TODO Waits for the transmission of outgoing serial data to complete. +UARTClass::flush(void) { + this->_buff->clear(); } - size_t -UARTClass::write(const uint8_t uc_data) +UARTClass::write(const uint8_t c) +{ + while (uart[this->_uart]->LSR & (1u << 5)) + continue; + uart[this->_uart]->THR = c; + return 0; +} + +static int +uart_rec_callback(void *ctx) +{ + char data; + auto &driver = *reinterpret_cast(ctx); + while(uart_receive_data(driver._uart, &data, 1)){ + driver._buff->store_char(data); + } + return 0; +} + +UARTHSClass::UARTHSClass() { +} + +void +UARTHSClass::begin(uint32_t dwBaudRate, uint8_t _rx, uint8_t _tx) +{ + fpioa_set_function((int)_rx, FUNC_UARTHS_RX); + fpioa_set_function((int)_tx, FUNC_UARTHS_TX); + uarths_init(); + uarths_config(dwBaudRate, UARTHS_STOP_1); + this->_buff = new RingBuffer(); + this->_buff->clear(); + uarths_set_interrupt_cnt(UARTHS_RECEIVE, 0); + uarths_set_irq(UARTHS_RECEIVE, uarths_rec_callback, this,1); + sysctl_enable_irq(); +} + +void +UARTHSClass::end() +{ + delete _buff; + plic_irq_unregister(IRQN_UARTHS_INTERRUPT); +} + +size_t +UARTHSClass::write(const uint8_t uc_data) +{ uarths_putchar(uc_data); return (1); } + +static int +uarths_rec_callback(void *ctx) +{ + int data; + auto &driver = *reinterpret_cast(ctx); + data = uarths_getc(); + if(data != 0){ + driver._buff->store_char((char)data); + } + return 0; +} \ No newline at end of file diff --git a/cores/arduino/UARTClass.h b/cores/arduino/UARTClass.h index e0919ff..0d9ee49 100644 --- a/cores/arduino/UARTClass.h +++ b/cores/arduino/UARTClass.h @@ -23,13 +23,16 @@ #include "HardwareSerial.h" #include "uarths.h" #include "uart.h" +#include "fpioa.h" +#include "pins_arduino.h" +#include "RingBuffer.h" class UARTClass : public HardwareSerial { public: - UARTClass(uint8_t rxPin, uint8_t txPin); - UARTClass(void); - void begin(uint32_t dwBaudRate); + UARTClass(); + UARTClass(uart_device_number_t device_select); + void begin(uint32_t dwBaudRate, uint8_t _rx = 6, uint8_t _tx = 7); void end(void); int available(void); int availableForWrite(void); @@ -40,12 +43,30 @@ class UARTClass : public HardwareSerial using Print::write; // pull in write(str) and write(buf, size) from Print operator bool() {return (true);}; // UART always active - - protected: - uint8_t _rxPin; - uint8_t _txPin; - + //protected: + RingBuffer *_buff; + uint32_t _timeout = 1000; + uart_device_number_t _uart; + private: + fpioa_function_t _rxfunc; + fpioa_function_t _txfunc; + //static int _rec_callback(void *ctx); }; + +class UARTHSClass : public UARTClass +{ + public: + UARTHSClass(); + void begin(uint32_t dwBaudRate, uint8_t _rx = 4, uint8_t _tx = 5); + void end(void); + size_t write(const uint8_t c); + using Print::write; + operator bool() {return (true);}; // UART always active + //private: + //static int _rec_callback(void *ctx); +}; + +extern volatile uart_t* const uart[3]; extern int uarths_putchar(char c); extern int uarths_getc(void); diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp new file mode 100644 index 0000000..e69de29 diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h new file mode 100644 index 0000000..e69de29 diff --git a/variants/standard/sipeedm1.h b/variants/standard/sipeedm1.h index 9d4d2ae..9ef0495 100644 --- a/variants/standard/sipeedm1.h +++ b/variants/standard/sipeedm1.h @@ -11,6 +11,10 @@ #ifdef __cplusplus #include "UARTClass.h" +extern class UARTHSClass Serial; +extern class UARTClass Serial1; +extern class UARTClass Serial2; +extern class UARTClass Serial3; #endif /* BOARD PIN DEFINE */ @@ -25,9 +29,6 @@ #define LED_RED 14 /* KEY */ #define KEY0 16 -/* UART */ -#define RX0 4 -#define TX0 5 /* MIC ARRAY */ #define MIC_BCK 18 #define MIC_WS 19 @@ -55,11 +56,14 @@ #define LCD_DC 38 #define LCD_WR 39 -static const uint8_t RX = RX0; -static const uint8_t TX = TX0; +#define RX0 4 +#define TX0 5 -static const uint8_t SDA = 10; -static const uint8_t SCL = 9; +#define RX1 6 +#define TX1 7 + +#define SDA 10 +#define SCL 9 static const uint8_t SS = SPI0_CS0 ; static const uint8_t MOSI = SPI0_MOSI; @@ -72,9 +76,7 @@ typedef struct _pwm_fpio_set_t{ uint8_t inuse; }pwm_fpio_set_t; -#ifdef __cplusplus -extern UARTClass Serial; -#endif + #define VARIANT_NUM_GPIOHS (32) #define VARIANT_NUM_GPIO ( 8)