/* 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 "UARTClass.h" #include "Arduino.h" #include "uarths.h" #include "fpioa.h" #include "sysctl.h" #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() { } UARTClass::UARTClass(uart_device_number_t device_select) { 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 dwBaudRate) { begin(dwBaudRate, RX1, TX1); } void UARTClass::begin(uint32_t dwBaudRate, uint8_t _rx, uint8_t _tx) { fpioa_set_function((int)MD_PIN_MAP(_rx), this->_rxfunc); fpioa_set_function((int)MD_PIN_MAP(_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) { delete this->_buff; uart_irq_unregister(this->_uart, UART_RECEIVE); } int UARTClass::available(void) { 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) { return this->_buff->peek(); } int UARTClass::read(void) { while(this->_buff->available()){ return this->_buff->read_char(); } return -1; } void UARTClass::flush(void) { this->_buff->clear(); } size_t 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) { begin(dwBaudRate, RX0, TX0); } void UARTHSClass::begin(uint32_t dwBaudRate, uint8_t _rx, uint8_t _tx) { fpioa_set_function((int)MD_PIN_MAP(_rx), FUNC_UARTHS_RX); fpioa_set_function((int)MD_PIN_MAP(_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 != EOF){ driver._buff->store_char((char)data); } return 0; }