1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-27 21:16:50 +03:00
Me No Dev 2016-07-08 05:11:14 +03:00 committed by Ivan Grokhotkov
parent edba2d2829
commit f8a8a2a359
4 changed files with 191 additions and 59 deletions

View File

@ -32,21 +32,13 @@
HardwareSerial::HardwareSerial(int uart_nr)
: _uart_nr(uart_nr)
: _uart_nr(uart_nr), _rx_size(256)
{}
void HardwareSerial::begin(unsigned long baud, SerialConfig config, SerialMode mode, uint8_t tx_pin)
{
if(uart_get_debug() == _uart_nr) {
uart_set_debug(UART_NO);
}
if (_uart) {
free(_uart);
}
_uart = uart_init(_uart_nr, baud, (int) config, (int) mode, tx_pin);
_peek_char = -1;
end();
_uart = uart_init(_uart_nr, baud, (int) config, (int) mode, tx_pin, _rx_size);
}
void HardwareSerial::end()
@ -55,8 +47,19 @@ void HardwareSerial::end()
uart_set_debug(UART_NO);
}
uart_uninit(_uart);
_uart = NULL;
if (_uart) {
uart_uninit(_uart);
_uart = NULL;
}
}
size_t HardwareSerial::setRxBufferSize(size_t size){
if(_uart) {
_rx_size = uart_resize_rx_buffer(_uart, size);
} else {
_rx_size = size;
}
return _rx_size;
}
void HardwareSerial::swap(uint8_t tx_pin)
@ -114,14 +117,7 @@ bool HardwareSerial::isRxEnabled(void)
int HardwareSerial::available(void)
{
if(!_uart || !uart_rx_enabled(_uart)) {
return 0;
}
int result = static_cast<int>(uart_rx_available(_uart));
if (_peek_char != -1) {
result += 1;
}
if (!result) {
optimistic_yield(10000);
}
@ -130,25 +126,13 @@ int HardwareSerial::available(void)
int HardwareSerial::peek(void)
{
if (_peek_char != -1) {
return _peek_char;
}
// this may return -1, but that's okay
_peek_char = uart_read_char(_uart);
return _peek_char;
return uart_peek_char(_uart);
}
int HardwareSerial::read(void)
{
if(!_uart || !uart_rx_enabled(_uart)) {
return -1;
}
if (_peek_char != -1) {
auto tmp = _peek_char;
_peek_char = -1;
return tmp;
}
// this may return -1, but that's okay
return uart_read_char(_uart);
}

View File

@ -87,6 +87,8 @@ public:
void end();
size_t setRxBufferSize(size_t size);
void swap()
{
swap(1);
@ -138,7 +140,7 @@ public:
protected:
int _uart_nr;
uart_t* _uart = nullptr;
int _peek_char = -1;
size_t _rx_size;
};
extern HardwareSerial Serial;

View File

@ -47,6 +47,13 @@
static int s_uart_debug_nr = UART0;
struct uart_rx_buffer_ {
size_t size;
size_t rpos;
size_t wpos;
uint8_t * buffer;
};
struct uart_ {
int uart_nr;
int baud_rate;
@ -54,8 +61,132 @@ struct uart_ {
bool tx_enabled;
uint8_t rx_pin;
uint8_t tx_pin;
struct uart_rx_buffer_ * rx_buffer;
};
size_t uart_resize_rx_buffer(uart_t* uart, size_t new_size)
{
if(uart == NULL || !uart->rx_enabled) {
return 0;
}
if(uart->rx_buffer->size == new_size) {
return uart->rx_buffer->size;
}
uint8_t * new_buf = (uint8_t*)malloc(new_size);
if(!new_buf) {
return uart->rx_buffer->size;
}
size_t new_wpos = 0;
ETS_UART_INTR_DISABLE();
while(uart_rx_available(uart) && new_wpos < new_size) {
new_buf[new_wpos++] = uart_read_char(uart);
}
uint8_t * old_buf = uart->rx_buffer->buffer;
uart->rx_buffer->rpos = 0;
uart->rx_buffer->wpos = new_wpos;
uart->rx_buffer->size = new_size;
uart->rx_buffer->buffer = new_buf;
free(old_buf);
ETS_UART_INTR_ENABLE();
return uart->rx_buffer->size;
}
int uart_peek_char(uart_t* uart)
{
if(uart == NULL || !uart->rx_enabled) {
return -1;
}
if (!uart_rx_available(uart)) {
return -1;
}
return uart->rx_buffer->buffer[uart->rx_buffer->rpos];
}
int uart_read_char(uart_t* uart)
{
int data = uart_peek_char(uart);
if(data != -1) {
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size;
}
return data;
}
size_t uart_rx_available(uart_t* uart)
{
if(uart == NULL || !uart->rx_enabled) {
return 0;
}
if(uart->rx_buffer->wpos < uart->rx_buffer->rpos) {
return (uart->rx_buffer->wpos + uart->rx_buffer->size) - uart->rx_buffer->rpos;
}
return uart->rx_buffer->wpos - uart->rx_buffer->rpos;
}
void ICACHE_RAM_ATTR uart_isr(void * arg)
{
uart_t* uart = (uart_t*)arg;
if(uart == NULL || !uart->rx_enabled) {
USIC(uart->uart_nr) = 0xffff;
ETS_UART_INTR_DISABLE();
return;
}
uint32_t int_status = USIS(uart->uart_nr);
if(int_status & (1 << UIFR)) {
USIC(uart->uart_nr) = (1 << UIFR);//clear any frame error
}
if(int_status & (1 << UIFF) || int_status & (1 << UITO)){
ETS_UART_INTR_DISABLE();
while(((USS(uart->uart_nr) >> USRXC) & 0x7F) != 0){
uint8_t data = USF(uart->uart_nr);
size_t nextPos = (uart->rx_buffer->wpos + 1) % uart->rx_buffer->size;
if(nextPos != uart->rx_buffer->rpos) {
uart->rx_buffer->buffer[uart->rx_buffer->wpos] = data;
uart->rx_buffer->wpos = nextPos;
} else {
//rx buffer OverFlow
//maybe stop the loop and try later?
}
}
int_status = USIS(uart->uart_nr);
if(int_status & (1 << UIFF)) {
USIC(uart->uart_nr) = (1 << UIFF);//clear any FIFO FULL error
}
if(int_status & (1 << UITO)) {
USIC(uart->uart_nr) = (1 << UITO);//clear any TimeOut error
}
ETS_UART_INTR_ENABLE();
}
}
void uart_start_isr(uart_t* uart)
{
if(uart == NULL || !uart->rx_enabled) {
return;
}
USC1(uart->uart_nr) = (127 << UCFFT) | (0x02 << UCTOT) | (1 <<UCTOE );
USIC(uart->uart_nr) = 0xffff;
USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIFR) | (1 << UITO);
ETS_UART_INTR_ATTACH(uart_isr, (void *)uart);
ETS_UART_INTR_ENABLE();
}
void uart_stop_isr(uart_t* uart)
{
if(uart == NULL || !uart->rx_enabled) {
return;
}
ETS_UART_INTR_DISABLE();
USC1(uart->uart_nr) = 0;
USIC(uart->uart_nr) = 0xffff;
USIE(uart->uart_nr) = 0;
ETS_UART_INTR_ATTACH(NULL, NULL);
}
void uart_write_char(uart_t* uart, char c)
{
if(uart == NULL || !uart->tx_enabled) {
@ -75,25 +206,6 @@ void uart_write(uart_t* uart, const char* buf, size_t size)
}
}
int uart_read_char(uart_t* uart)
{
if(uart == NULL || !uart->rx_enabled) {
return -1;
}
if (!uart_rx_available(uart)) {
return -1;
}
return USF(uart->uart_nr) & 0xff;
}
size_t uart_rx_available(uart_t* uart)
{
if(uart == NULL || !uart->rx_enabled) {
return -1;
}
return (USS(uart->uart_nr) >> USRXC) & 0xff;
}
size_t uart_tx_free(uart_t* uart)
{
if(uart == NULL || !uart->tx_enabled) {
@ -121,6 +233,10 @@ void uart_flush(uart_t* uart)
uint32_t tmp = 0x00000000;
if(uart->rx_enabled) {
tmp |= (1 << UCRXRST);
ETS_UART_INTR_DISABLE();
uart->rx_buffer->rpos = 0;
uart->rx_buffer->wpos = 0;
ETS_UART_INTR_ENABLE();
}
if(uart->tx_enabled) {
@ -148,7 +264,7 @@ int uart_get_baudrate(uart_t* uart)
return uart->baud_rate;
}
uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin)
uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx_size)
{
uart_t* uart = (uart_t*) malloc(sizeof(uart_t));
if(uart == NULL) {
@ -159,9 +275,29 @@ uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin)
switch(uart->uart_nr) {
case UART0:
ETS_UART_INTR_DISABLE();
ETS_UART_INTR_ATTACH(NULL, NULL);
uart->rx_enabled = (mode != UART_TX_ONLY);
uart->tx_enabled = (mode != UART_RX_ONLY);
uart->rx_pin = (uart->rx_enabled)?3:255;
if(uart->rx_enabled) {
struct uart_rx_buffer_ * rx_buffer = (struct uart_rx_buffer_ *)malloc(sizeof(struct uart_rx_buffer_));
if(rx_buffer == NULL) {
free(uart);
return NULL;
}
rx_buffer->size = rx_size;//var this
rx_buffer->rpos = 0;
rx_buffer->wpos = 0;
rx_buffer->buffer = (uint8_t *)malloc(rx_buffer->size);
if(rx_buffer->buffer == NULL) {
free(rx_buffer);
free(uart);
return NULL;
}
uart->rx_buffer = rx_buffer;
pinMode(uart->rx_pin, SPECIAL);
}
if(uart->tx_enabled) {
if (tx_pin == 2) {
uart->tx_pin = 2;
@ -173,9 +309,6 @@ uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin)
} else {
uart->tx_pin = 255;
}
if(uart->rx_enabled) {
pinMode(uart->rx_pin, SPECIAL);
}
IOSWAP &= ~(1 << IOSWAPU0);
break;
case UART1:
@ -199,6 +332,11 @@ uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin)
USC0(uart->uart_nr) = config;
uart_flush(uart);
USC1(uart->uart_nr) = 0;
USIC(uart->uart_nr) = 0xffff;
USIE(uart->uart_nr) = 0;
if(uart->uart_nr == UART0 && uart->rx_enabled) {
uart_start_isr(uart);
}
return uart;
}
@ -230,6 +368,11 @@ void uart_uninit(uart_t* uart)
break;
}
if(uart->rx_enabled){
free(uart->rx_buffer->buffer);
free(uart->rx_buffer);
//uart_stop_isr(uart);
}
free(uart);
}

View File

@ -113,7 +113,7 @@ extern "C" {
struct uart_;
typedef struct uart_ uart_t;
uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin);
uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx_size);
void uart_uninit(uart_t* uart);
void uart_swap(uart_t* uart, int tx_pin);
@ -125,9 +125,12 @@ bool uart_rx_enabled(uart_t* uart);
void uart_set_baudrate(uart_t* uart, int baud_rate);
int uart_get_baudrate(uart_t* uart);
size_t uart_resize_rx_buffer(uart_t* uart, size_t new_size);
void uart_write_char(uart_t* uart, char c);
void uart_write(uart_t* uart, const char* buf, size_t size);
int uart_read_char(uart_t* uart);
int uart_peek_char(uart_t* uart);
size_t uart_rx_available(uart_t* uart);
size_t uart_tx_free(uart_t* uart);
void uart_wait_tx_empty(uart_t* uart);