Removed arduino's shitty serial functionality

This commit is contained in:
2021-12-21 19:25:39 +01:00
parent aa9f5dc65a
commit 6c49028af8
7 changed files with 0 additions and 1004 deletions

View File

@ -12,10 +12,8 @@ set(CORE_SRCS
cores/esp32/esp32-hal-spi.c cores/esp32/esp32-hal-spi.c
cores/esp32/esp32-hal-tinyusb.c cores/esp32/esp32-hal-tinyusb.c
cores/esp32/esp32-hal-touch.c cores/esp32/esp32-hal-touch.c
cores/esp32/esp32-hal-uart.c
cores/esp32/esp32-hal-rmt.c cores/esp32/esp32-hal-rmt.c
cores/esp32/FunctionalInterrupt.cpp cores/esp32/FunctionalInterrupt.cpp
cores/esp32/HardwareSerial.cpp
cores/esp32/IPv6Address.cpp cores/esp32/IPv6Address.cpp
cores/esp32/stdlib_noniso.c cores/esp32/stdlib_noniso.c
cores/esp32/USB.cpp cores/esp32/USB.cpp

View File

@ -134,7 +134,6 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
#include <cmath> #include <cmath>
#include "WCharacter.h" #include "WCharacter.h"
#include "HardwareSerial.h"
using std::abs; using std::abs;
using std::isinf; using std::isinf;

View File

@ -1,195 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "pins_arduino.h"
#include "HardwareSerial.h"
#include "esp32-hal-log.h"
#if CONFIG_IDF_TARGET_ESP32
#ifndef RX1
#define RX1 9
#endif
#ifndef TX1
#define TX1 10
#endif
#ifndef RX2
#define RX2 16
#endif
#ifndef TX2
#define TX2 17
#endif
#else
#ifndef RX1
#define RX1 18
#endif
#ifndef TX1
#define TX1 17
#endif
#endif
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
HardwareSerial Serial0(0);
#else
HardwareSerial Serial(0);
#endif
HardwareSerial Serial1(1);
#if CONFIG_IDF_TARGET_ESP32
HardwareSerial Serial2(2);
#endif
#endif
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {}
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms)
{
if(0 > _uart_nr || _uart_nr > 2) {
log_e("Serial number is invalid, please use 0, 1 or 2");
return;
}
if(_uart) {
end();
}
if(_uart_nr == 0 && rxPin < 0 && txPin < 0) {
#if CONFIG_IDF_TARGET_ESP32
rxPin = 3;
txPin = 1;
#elif CONFIG_IDF_TARGET_ESP32S2
rxPin = 44;
txPin = 43;
#endif
}
if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
rxPin = RX1;
txPin = TX1;
}
#if CONFIG_IDF_TARGET_ESP32
if(_uart_nr == 2 && rxPin < 0 && txPin < 0) {
rxPin = RX2;
txPin = TX2;
}
#endif
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, 256, invert);
_tx_pin = txPin;
_rx_pin = rxPin;
if(!baud) {
uartStartDetectBaudrate(_uart);
time_t startMillis = esp_timer_get_time() / 1000ULL;
unsigned long detectedBaudRate = 0;
while((esp_timer_get_time() / 1000ULL) - startMillis < timeout_ms && !(detectedBaudRate = uartDetectBaudrate(_uart))) {
yield();
}
end();
if(detectedBaudRate) {
vTaskDelay(100 / portTICK_PERIOD_MS); // Give some time...
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, 256, invert);
} else {
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
_uart = NULL;
_tx_pin = 255;
_rx_pin = 255;
}
}
}
void HardwareSerial::updateBaudRate(unsigned long baud)
{
uartSetBaudRate(_uart, baud);
}
void HardwareSerial::end()
{
log_v("pins %d %d",_tx_pin, _rx_pin);
uartEnd(_uart, _tx_pin, _rx_pin);
_uart = 0;
}
size_t HardwareSerial::setRxBufferSize(size_t new_size) {
return uartResizeRxBuffer(_uart, new_size);
}
int HardwareSerial::available(void)
{
return uartAvailable(_uart);
}
int HardwareSerial::availableForWrite(void)
{
return uartAvailableForWrite(_uart);
}
int HardwareSerial::peek(void)
{
if (available()) {
return uartPeek(_uart);
}
return -1;
}
int HardwareSerial::read(void)
{
if(available()) {
return uartRead(_uart);
}
return -1;
}
// read characters into buffer
// terminates if size characters have been read, or no further are pending
// returns the number of characters placed in the buffer
// the buffer is NOT null terminated.
size_t HardwareSerial::read(uint8_t *buffer, size_t size)
{
size_t avail = available();
if (size < avail) {
avail = size;
}
size_t count = 0;
while(count < avail) {
*buffer++ = uartRead(_uart);
count++;
}
return count;
}
void HardwareSerial::flush(void)
{
uartFlush(_uart);
}
void HardwareSerial::flush(bool txOnly)
{
uartFlushTxOnly(_uart, txOnly);
}
size_t HardwareSerial::write(std::basic_string_view<unsigned char> buf)
{
uartWriteBuf(_uart, buf.data(), buf.size());
return buf.size();
}
uint32_t HardwareSerial::baudRate()
{
return uartGetBaudRate(_uart);
}
HardwareSerial::operator bool() const
{
return true;
}
void HardwareSerial::setRxInvert(bool invert)
{
uartSetRxInvert(_uart, invert);
}

View File

@ -1,105 +0,0 @@
/*
HardwareSerial.h - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. 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 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
Modified 3 December 2013 by Matthijs Kooijman
Modified 18 December 2014 by Ivan Grokhotkov (esp8266 platform support)
Modified 31 March 2015 by Markus Sattler (rewrite the code for UART0 + UART1 support in ESP8266)
Modified 25 April 2015 by Thomas Flayols (add configuration different from 8N1 in ESP8266)
Modified 13 October 2018 by Jeroen Döll (add baudrate detection)
Baudrate detection example usage (detection on Serial1):
void setup() {
Serial.begin(115200);
vTaskDelay(100 / portTICK_PERIOD_MS);
Serial.println();
Serial1.begin(0, SERIAL_8N1, -1, -1, true, 11000UL); // Passing 0 for baudrate to detect it, the last parameter is a timeout in ms
unsigned long detectedBaudRate = Serial1.baudRate();
if(detectedBaudRate) {
Serial.printf("Detected baudrate is %lu\n", detectedBaudRate);
} else {
Serial.println("No baudrate detected, Serial1 will not work!");
}
}
Pay attention: the baudrate returned by baudRate() may be rounded, eg 115200 returns 115201
*/
#ifndef HardwareSerial_h
#define HardwareSerial_h
#include <inttypes.h>
#include <string_view>
#include "esp32-hal.h"
class HardwareSerial
{
public:
HardwareSerial(int uart_nr);
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL);
void end();
void updateBaudRate(unsigned long baud);
int available(void);
int availableForWrite(void);
int peek(void);
int read(void);
size_t read(uint8_t *buffer, size_t size);
inline size_t read(char * buffer, size_t size)
{
return read((uint8_t*) buffer, size);
}
void flush(void);
void flush( bool txOnly);
size_t write(std::string_view buf) { return write(std::basic_string_view<unsigned char>{reinterpret_cast<const unsigned char *>(buf.data()), buf.size()}); }
size_t write(std::basic_string_view<unsigned char> buf);
uint32_t baudRate();
operator bool() const;
size_t setRxBufferSize(size_t);
void setRxInvert(bool);
protected:
int _uart_nr;
uart_t* _uart;
uint8_t _tx_pin;
uint8_t _rx_pin;
};
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
#ifndef ARDUINO_SERIAL_PORT
#define ARDUINO_SERIAL_PORT 0
#endif
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
#include "USB.h"
#include "USBCDC.h"
extern HardwareSerial Serial0;
#else
extern HardwareSerial Serial;
#endif
extern HardwareSerial Serial1;
#if CONFIG_IDF_TARGET_ESP32
extern HardwareSerial Serial2;
#endif
#endif
#endif // HardwareSerial_h

View File

@ -1,616 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp32-hal-uart.h"
#include "esp32-hal.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_attr.h"
#include "soc/uart_reg.h"
#include "soc/uart_struct.h"
#include "soc/io_mux_reg.h"
#include "soc/gpio_sig_map.h"
#include "soc/dport_reg.h"
#include "soc/rtc.h"
#include "esp_intr_alloc.h"
#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/ets_sys.h"
#include "esp32/rom/uart.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#include "esp32s2/rom/uart.h"
#include "soc/periph_defs.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#include "rom/uart.h"
#include "esp_intr.h"
#endif
#if CONFIG_IDF_TARGET_ESP32S2
#define UART_PORTS_NUM 2
#define UART_REG_BASE(u) ((u==0)?DR_REG_UART_BASE:( (u==1)?DR_REG_UART1_BASE:0))
#define UART_RXD_IDX(u) ((u==0)?U0RXD_IN_IDX:( (u==1)?U1RXD_IN_IDX:0))
#define UART_TXD_IDX(u) ((u==0)?U0TXD_OUT_IDX:( (u==1)?U1TXD_OUT_IDX:0))
#define UART_INTR_SOURCE(u) ((u==0)?ETS_UART0_INTR_SOURCE:( (u==1)?ETS_UART1_INTR_SOURCE:0))
#else
#define UART_PORTS_NUM 3
#define UART_REG_BASE(u) ((u==0)?DR_REG_UART_BASE:( (u==1)?DR_REG_UART1_BASE:( (u==2)?DR_REG_UART2_BASE:0)))
#define UART_RXD_IDX(u) ((u==0)?U0RXD_IN_IDX:( (u==1)?U1RXD_IN_IDX:( (u==2)?U2RXD_IN_IDX:0)))
#define UART_TXD_IDX(u) ((u==0)?U0TXD_OUT_IDX:( (u==1)?U1TXD_OUT_IDX:( (u==2)?U2TXD_OUT_IDX:0)))
#define UART_INTR_SOURCE(u) ((u==0)?ETS_UART0_INTR_SOURCE:( (u==1)?ETS_UART1_INTR_SOURCE:((u==2)?ETS_UART2_INTR_SOURCE:0)))
#endif
struct uart_struct_t {
uart_dev_t * dev;
#if !CONFIG_DISABLE_HAL_LOCKS
xSemaphoreHandle lock;
#endif
uint8_t num;
xQueueHandle queue;
intr_handle_t intr_handle;
};
#if CONFIG_DISABLE_HAL_LOCKS
#define UART_MUTEX_LOCK()
#define UART_MUTEX_UNLOCK()
static uart_t _uart_bus_array[] = {
{&UART0, 0, NULL, NULL},
{&UART1, 1, NULL, NULL},
#if CONFIG_IDF_TARGET_ESP32
{&UART2, 2, NULL, NULL}
#endif
};
#else
#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS)
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
static uart_t _uart_bus_array[] = {
{&UART0, NULL, 0, NULL, NULL},
{&UART1, NULL, 1, NULL, NULL},
#if CONFIG_IDF_TARGET_ESP32
{&UART2, NULL, 2, NULL, NULL}
#endif
};
#endif
static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb);
static void ARDUINO_ISR_ATTR _uart_isr(void *arg)
{
uint8_t i, c;
BaseType_t xHigherPriorityTaskWoken;
uart_t* uart;
for(i=0;i<UART_PORTS_NUM;i++){
uart = &_uart_bus_array[i];
if(uart->intr_handle == NULL){
continue;
}
uart->dev->int_clr.rxfifo_full = 1;
uart->dev->int_clr.frm_err = 1;
uart->dev->int_clr.rxfifo_tout = 1;
#if CONFIG_IDF_TARGET_ESP32
while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
c = uart->dev->fifo.rw_byte;
#else
uint32_t fifo_reg = UART_FIFO_AHB_REG(i);
while(uart->dev->status.rxfifo_cnt) {
c = ESP_REG(fifo_reg);
#endif
if(uart->queue != NULL) {
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
}
}
}
if (xHigherPriorityTaskWoken) {
portYIELD_FROM_ISR();
}
}
void uartEnableInterrupt(uart_t* uart)
{
UART_MUTEX_LOCK();
uart->dev->conf1.rxfifo_full_thrhd = 112;
#if CONFIG_IDF_TARGET_ESP32
uart->dev->conf1.rx_tout_thrhd = 2;
#else
uart->dev->mem_conf.rx_tout_thrhd = 2;
#endif
uart->dev->conf1.rx_tout_en = 1;
uart->dev->int_ena.rxfifo_full = 1;
uart->dev->int_ena.frm_err = 1;
uart->dev->int_ena.rxfifo_tout = 1;
uart->dev->int_clr.val = 0xffffffff;
esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ARDUINO_ISR_FLAG, _uart_isr, NULL, &uart->intr_handle);
UART_MUTEX_UNLOCK();
}
void uartDisableInterrupt(uart_t* uart)
{
UART_MUTEX_LOCK();
uart->dev->conf1.val = 0;
uart->dev->int_ena.val = 0;
uart->dev->int_clr.val = 0xffffffff;
esp_intr_free(uart->intr_handle);
uart->intr_handle = NULL;
UART_MUTEX_UNLOCK();
}
void uartDetachRx(uart_t* uart, uint8_t rxPin)
{
if(uart == NULL) {
return;
}
pinMatrixInDetach(rxPin, false, false);
uartDisableInterrupt(uart);
}
void uartDetachTx(uart_t* uart, uint8_t txPin)
{
if(uart == NULL) {
return;
}
pinMatrixOutDetach(txPin, false, false);
}
void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted)
{
if(uart == NULL || rxPin >= GPIO_PIN_COUNT) {
return;
}
pinMode(rxPin, INPUT);
uartEnableInterrupt(uart);
pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted);
}
void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted)
{
if(uart == NULL || txPin >= GPIO_PIN_COUNT) {
return;
}
pinMode(txPin, OUTPUT);
pinMatrixOutAttach(txPin, UART_TXD_IDX(uart->num), inverted, false);
}
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted)
{
if(uart_nr >= UART_PORTS_NUM) {
return NULL;
}
if(rxPin == -1 && txPin == -1) {
return NULL;
}
uart_t* uart = &_uart_bus_array[uart_nr];
#if !CONFIG_DISABLE_HAL_LOCKS
if(uart->lock == NULL) {
uart->lock = xSemaphoreCreateMutex();
if(uart->lock == NULL) {
return NULL;
}
}
#endif
if(queueLen && uart->queue == NULL) {
uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue
if(uart->queue == NULL) {
return NULL;
}
}
if(uart_nr == 1){
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART1_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST);
#if CONFIG_IDF_TARGET_ESP32
} else if(uart_nr == 2){
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART2_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST);
#endif
} else {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
}
uartFlush(uart);
uartSetBaudRate(uart, baudrate);
UART_MUTEX_LOCK();
uart->dev->conf0.val = config;
#define TWO_STOP_BITS_CONF 0x3
#define ONE_STOP_BITS_CONF 0x1
if ( uart->dev->conf0.stop_bit_num == TWO_STOP_BITS_CONF) {
uart->dev->conf0.stop_bit_num = ONE_STOP_BITS_CONF;
uart->dev->rs485_conf.dl1_en = 1;
}
// tx_idle_num : idle interval after tx FIFO is empty(unit: the time it takes to send one bit under current baudrate)
// Setting it to 0 prevents line idle time/delays when sending messages with small intervals
uart->dev->idle_conf.tx_idle_num = 0; //
UART_MUTEX_UNLOCK();
if(rxPin != -1) {
uartAttachRx(uart, rxPin, inverted);
}
if(txPin != -1) {
uartAttachTx(uart, txPin, inverted);
}
addApbChangeCallback(uart, uart_on_apb_change);
return uart;
}
void uartEnd(uart_t* uart, uint8_t txPin, uint8_t rxPin)
{
if(uart == NULL) {
return;
}
removeApbChangeCallback(uart, uart_on_apb_change);
UART_MUTEX_LOCK();
if(uart->queue != NULL) {
vQueueDelete(uart->queue);
uart->queue = NULL;
}
uart->dev->conf0.val = 0;
UART_MUTEX_UNLOCK();
uartDetachRx(uart, rxPin);
uartDetachTx(uart, txPin);
}
size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) {
if(uart == NULL) {
return 0;
}
UART_MUTEX_LOCK();
if(uart->queue != NULL) {
vQueueDelete(uart->queue);
uart->queue = xQueueCreate(new_size, sizeof(uint8_t));
if(uart->queue == NULL) {
UART_MUTEX_UNLOCK();
return 0;
}
}
UART_MUTEX_UNLOCK();
return new_size;
}
void uartSetRxInvert(uart_t* uart, bool invert)
{
if (uart == NULL)
return;
if (invert)
uart->dev->conf0.rxd_inv = 1;
else
uart->dev->conf0.rxd_inv = 0;
}
uint32_t uartAvailable(uart_t* uart)
{
if(uart == NULL || uart->queue == NULL) {
return 0;
}
return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt) ;
}
uint32_t uartAvailableForWrite(uart_t* uart)
{
if(uart == NULL) {
return 0;
}
return 0x7f - uart->dev->status.txfifo_cnt;
}
void uartRxFifoToQueue(uart_t* uart)
{
uint8_t c;
UART_MUTEX_LOCK();
//disable interrupts
uart->dev->int_ena.val = 0;
uart->dev->int_clr.val = 0xffffffff;
#if CONFIG_IDF_TARGET_ESP32
while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
c = uart->dev->fifo.rw_byte;
#else
uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num);
while (uart->dev->status.rxfifo_cnt) {
c = ESP_REG(fifo_reg);
#endif
xQueueSend(uart->queue, &c, 0);
}
//enable interrupts
uart->dev->int_ena.rxfifo_full = 1;
uart->dev->int_ena.frm_err = 1;
uart->dev->int_ena.rxfifo_tout = 1;
uart->dev->int_clr.val = 0xffffffff;
UART_MUTEX_UNLOCK();
}
uint8_t uartRead(uart_t* uart)
{
if(uart == NULL || uart->queue == NULL) {
return 0;
}
uint8_t c;
if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0))
{
uartRxFifoToQueue(uart);
}
if(xQueueReceive(uart->queue, &c, 0)) {
return c;
}
return 0;
}
uint8_t uartPeek(uart_t* uart)
{
if(uart == NULL || uart->queue == NULL) {
return 0;
}
uint8_t c;
if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0))
{
uartRxFifoToQueue(uart);
}
if(xQueuePeek(uart->queue, &c, 0)) {
return c;
}
return 0;
}
void uartWrite(uart_t* uart, uint8_t c)
{
if(uart == NULL) {
return;
}
UART_MUTEX_LOCK();
while(uart->dev->status.txfifo_cnt == 0x7F);
#if CONFIG_IDF_TARGET_ESP32
uart->dev->fifo.rw_byte = c;
#else
ESP_REG(UART_FIFO_AHB_REG(uart->num)) = c;
#endif
UART_MUTEX_UNLOCK();
}
void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len)
{
if(uart == NULL) {
return;
}
UART_MUTEX_LOCK();
#ifndef CONFIG_IDF_TARGET_ESP32
uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num);
#endif
while(len) {
while(uart->dev->status.txfifo_cnt == 0x7F);
#if CONFIG_IDF_TARGET_ESP32
uart->dev->fifo.rw_byte = *data++;
#else
ESP_REG(fifo_reg) = *data++;
#endif
len--;
}
UART_MUTEX_UNLOCK();
}
void uartFlush(uart_t* uart)
{
uartFlushTxOnly(uart,true);
}
void uartFlushTxOnly(uart_t* uart, bool txOnly)
{
if(uart == NULL) {
return;
}
UART_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32
while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out);
if( !txOnly ){
//Due to hardware issue, we can not use fifo_rst to reset uart fifo.
//See description about UART_TXFIFO_RST and UART_RXFIFO_RST in <<esp32_technical_reference_manual>> v2.6 or later.
// we read the data out and make `fifo_len == 0 && rd_addr == wr_addr`.
while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
READ_PERI_REG(UART_FIFO_REG(uart->num));
}
xQueueReset(uart->queue);
}
#else
while(uart->dev->status.txfifo_cnt);
uart->dev->conf0.txfifo_rst = 1;
uart->dev->conf0.txfifo_rst = 0;
#endif
UART_MUTEX_UNLOCK();
}
void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
{
if(uart == NULL) {
return;
}
UART_MUTEX_LOCK();
uint32_t clk_div = ((getApbFrequency()<<4)/baud_rate);
uart->dev->clk_div.div_int = clk_div>>4 ;
uart->dev->clk_div.div_frag = clk_div & 0xf;
UART_MUTEX_UNLOCK();
}
static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb)
{
uart_t* uart = (uart_t*)arg;
if(ev_type == APB_BEFORE_CHANGE){
UART_MUTEX_LOCK();
//disabple interrupt
uart->dev->int_ena.val = 0;
uart->dev->int_clr.val = 0xffffffff;
// read RX fifo
uint8_t c;
// BaseType_t xHigherPriorityTaskWoken;
#if CONFIG_IDF_TARGET_ESP32
while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
c = uart->dev->fifo.rw_byte;
#else
uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num);
while(uart->dev->status.rxfifo_cnt != 0) {
c = ESP_REG(fifo_reg);
#endif
if(uart->queue != NULL ) {
xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken);
}
}
UART_MUTEX_UNLOCK();
// wait TX empty
#if CONFIG_IDF_TARGET_ESP32
while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out);
#else
while(uart->dev->status.txfifo_cnt);
#endif
} else {
//todo:
// set baudrate
UART_MUTEX_LOCK();
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
uint32_t baud_rate = ((old_apb<<4)/clk_div);
clk_div = ((new_apb<<4)/baud_rate);
uart->dev->clk_div.div_int = clk_div>>4 ;
uart->dev->clk_div.div_frag = clk_div & 0xf;
//enable interrupts
uart->dev->int_ena.rxfifo_full = 1;
uart->dev->int_ena.frm_err = 1;
uart->dev->int_ena.rxfifo_tout = 1;
uart->dev->int_clr.val = 0xffffffff;
UART_MUTEX_UNLOCK();
}
}
uint32_t uartGetBaudRate(uart_t* uart)
{
if(uart == NULL) {
return 0;
}
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
if(!clk_div) {
return 0;
}
return ((getApbFrequency()<<4)/clk_div);
}
/*
* if enough pulses are detected return the minimum high pulse duration + minimum low pulse duration divided by two.
* This equals one bit period. If flag is true the function return inmediately, otherwise it waits for enough pulses.
*/
unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
{
while(uart->dev->rxd_cnt.edge_cnt < 30) { // UART_PULSE_NUM(uart_num)
if(flg) return 0;
ets_delay_us(1000);
}
UART_MUTEX_LOCK();
unsigned long ret = ((uart->dev->lowpulse.min_cnt + uart->dev->highpulse.min_cnt) >> 1) + 12;
UART_MUTEX_UNLOCK();
return ret;
}
/*
* To start detection of baud rate with the uart the auto_baud.en bit needs to be cleared and set. The bit period is
* detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is
* rounded to the closed real baudrate.
*/
void uartStartDetectBaudrate(uart_t *uart) {
if(!uart) return;
uart->dev->auto_baud.glitch_filt = 0x08;
uart->dev->auto_baud.en = 0;
uart->dev->auto_baud.en = 1;
}
unsigned long
uartDetectBaudrate(uart_t *uart)
{
static bool uartStateDetectingBaudrate = false;
if(!uartStateDetectingBaudrate) {
uart->dev->auto_baud.glitch_filt = 0x08;
uart->dev->auto_baud.en = 0;
uart->dev->auto_baud.en = 1;
uartStateDetectingBaudrate = true;
}
unsigned long divisor = uartBaudrateDetect(uart, true);
if (!divisor) {
return 0;
}
uart->dev->auto_baud.en = 0;
uartStateDetectingBaudrate = false; // Initialize for the next round
unsigned long baudrate = getApbFrequency() / divisor;
static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400};
size_t i;
for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) // find the nearest real baudrate
{
if (baudrate <= default_rates[i])
{
if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) {
i--;
}
break;
}
}
return default_rates[i];
}
/*
* Returns the status of the RX state machine, if the value is non-zero the state machine is active.
*/
bool uartRxActive(uart_t* uart) {
#if CONFIG_IDF_TARGET_ESP32
return uart->dev->status.st_urx_out != 0;
#else
return 0;
#endif
}

View File

@ -1,84 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MAIN_ESP32_HAL_UART_H_
#define MAIN_ESP32_HAL_UART_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#define SERIAL_5N1 0x8000010
#define SERIAL_6N1 0x8000014
#define SERIAL_7N1 0x8000018
#define SERIAL_8N1 0x800001c
#define SERIAL_5N2 0x8000030
#define SERIAL_6N2 0x8000034
#define SERIAL_7N2 0x8000038
#define SERIAL_8N2 0x800003c
#define SERIAL_5E1 0x8000012
#define SERIAL_6E1 0x8000016
#define SERIAL_7E1 0x800001a
#define SERIAL_8E1 0x800001e
#define SERIAL_5E2 0x8000032
#define SERIAL_6E2 0x8000036
#define SERIAL_7E2 0x800003a
#define SERIAL_8E2 0x800003e
#define SERIAL_5O1 0x8000013
#define SERIAL_6O1 0x8000017
#define SERIAL_7O1 0x800001b
#define SERIAL_8O1 0x800001f
#define SERIAL_5O2 0x8000033
#define SERIAL_6O2 0x8000037
#define SERIAL_7O2 0x800003b
#define SERIAL_8O2 0x800003f
struct uart_struct_t;
typedef struct uart_struct_t uart_t;
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted);
void uartEnd(uart_t* uart, uint8_t rxPin, uint8_t txPin);
uint32_t uartAvailable(uart_t* uart);
uint32_t uartAvailableForWrite(uart_t* uart);
uint8_t uartRead(uart_t* uart);
uint8_t uartPeek(uart_t* uart);
void uartWrite(uart_t* uart, uint8_t c);
void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len);
void uartFlush(uart_t* uart);
void uartFlushTxOnly(uart_t* uart, bool txOnly );
void uartSetBaudRate(uart_t* uart, uint32_t baud_rate);
uint32_t uartGetBaudRate(uart_t* uart);
size_t uartResizeRxBuffer(uart_t* uart, size_t new_size);
void uartSetRxInvert(uart_t* uart, bool invert);
void uartStartDetectBaudrate(uart_t *uart);
unsigned long uartDetectBaudrate(uart_t *uart);
bool uartRxActive(uart_t* uart);
#ifdef __cplusplus
}
#endif
#endif /* MAIN_ESP32_HAL_UART_H_ */

View File

@ -62,7 +62,6 @@ void yield(void);
//#include "esp32-hal-log.h" //#include "esp32-hal-log.h"
#include "esp32-hal-matrix.h" #include "esp32-hal-matrix.h"
#include "esp32-hal-uart.h"
#include "esp32-hal-gpio.h" #include "esp32-hal-gpio.h"
#include "esp32-hal-touch.h" #include "esp32-hal-touch.h"
#include "esp32-hal-dac.h" #include "esp32-hal-dac.h"