mirror of https://github.com/ArduPilot/ardupilot
217 lines
4.7 KiB
C++
217 lines
4.7 KiB
C++
|
/*
|
||
|
* This file is free software: you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published by the
|
||
|
* Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This file 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 General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License along
|
||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include <AP_HAL_ESP32/UARTDriver.h>
|
||
|
#include <AP_Math/AP_Math.h>
|
||
|
|
||
|
#include "esp_log.h"
|
||
|
|
||
|
extern const AP_HAL::HAL& hal;
|
||
|
|
||
|
namespace ESP32
|
||
|
{
|
||
|
|
||
|
UARTDesc uart_desc[] = {HAL_ESP32_UART_DEVICES};
|
||
|
|
||
|
void UARTDriver::vprintf(const char *fmt, va_list ap)
|
||
|
{
|
||
|
|
||
|
uart_port_t p = uart_desc[uart_num].port;
|
||
|
if (p == 0) {
|
||
|
esp_log_writev(ESP_LOG_INFO, "", fmt, ap);
|
||
|
} else {
|
||
|
AP_HAL::UARTDriver::vprintf(fmt, ap);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UARTDriver::begin(uint32_t b)
|
||
|
{
|
||
|
begin(b, 0, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
void UARTDriver::begin(uint32_t b, uint16_t rxS, uint16_t txS)
|
||
|
{
|
||
|
if (uart_num < ARRAY_SIZE(uart_desc)) {
|
||
|
uart_port_t p = uart_desc[uart_num].port;
|
||
|
if (!_initialized) {
|
||
|
|
||
|
uart_config_t config = {
|
||
|
.baud_rate = (int)b,
|
||
|
.data_bits = UART_DATA_8_BITS,
|
||
|
.parity = UART_PARITY_DISABLE,
|
||
|
.stop_bits = UART_STOP_BITS_1,
|
||
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||
|
};
|
||
|
uart_param_config(p, &config);
|
||
|
uart_set_pin(p,
|
||
|
uart_desc[uart_num].tx,
|
||
|
uart_desc[uart_num].rx,
|
||
|
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||
|
//uart_driver_install(p, 2*UART_FIFO_LEN, 0, 0, nullptr, 0);
|
||
|
uart_driver_install(p, 2*UART_FIFO_LEN, 0, 0, nullptr, 0);
|
||
|
_readbuf.set_size(RX_BUF_SIZE);
|
||
|
_writebuf.set_size(TX_BUF_SIZE);
|
||
|
|
||
|
_initialized = true;
|
||
|
} else {
|
||
|
flush();
|
||
|
uart_set_baudrate(p, b);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UARTDriver::end()
|
||
|
{
|
||
|
if (_initialized) {
|
||
|
uart_driver_delete(uart_desc[uart_num].port);
|
||
|
_readbuf.set_size(0);
|
||
|
_writebuf.set_size(0);
|
||
|
}
|
||
|
_initialized = false;
|
||
|
}
|
||
|
|
||
|
void UARTDriver::flush()
|
||
|
{
|
||
|
uart_port_t p = uart_desc[uart_num].port;
|
||
|
uart_flush(p);
|
||
|
}
|
||
|
|
||
|
bool UARTDriver::is_initialized()
|
||
|
{
|
||
|
return _initialized;
|
||
|
}
|
||
|
|
||
|
void UARTDriver::set_blocking_writes(bool blocking)
|
||
|
{
|
||
|
//blocking writes do not used anywhere
|
||
|
}
|
||
|
|
||
|
bool UARTDriver::tx_pending()
|
||
|
{
|
||
|
return (_writebuf.available() > 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
uint32_t UARTDriver::available()
|
||
|
{
|
||
|
if (!_initialized) {
|
||
|
return 0;
|
||
|
}
|
||
|
return _readbuf.available();
|
||
|
}
|
||
|
|
||
|
uint32_t UARTDriver::txspace()
|
||
|
{
|
||
|
if (!_initialized) {
|
||
|
return 0;
|
||
|
}
|
||
|
int result = _writebuf.space();
|
||
|
result -= TX_BUF_SIZE / 4;
|
||
|
return MAX(result, 0);
|
||
|
|
||
|
}
|
||
|
|
||
|
ssize_t IRAM_ATTR UARTDriver::read(uint8_t *buffer, uint16_t count)
|
||
|
{
|
||
|
if (!_initialized) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
const uint32_t ret = _readbuf.read(buffer, count);
|
||
|
if (ret == 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int16_t IRAM_ATTR UARTDriver::read()
|
||
|
{
|
||
|
if (!_initialized) {
|
||
|
return -1;
|
||
|
}
|
||
|
uint8_t byte;
|
||
|
if (!_readbuf.read_byte(&byte)) {
|
||
|
return -1;
|
||
|
}
|
||
|
return byte;
|
||
|
}
|
||
|
|
||
|
void IRAM_ATTR UARTDriver::_timer_tick(void)
|
||
|
{
|
||
|
if (!_initialized) {
|
||
|
return;
|
||
|
}
|
||
|
read_data();
|
||
|
write_data();
|
||
|
}
|
||
|
|
||
|
void IRAM_ATTR UARTDriver::read_data()
|
||
|
{
|
||
|
uart_port_t p = uart_desc[uart_num].port;
|
||
|
int count = 0;
|
||
|
do {
|
||
|
count = uart_read_bytes(p, _buffer, sizeof(_buffer), 0);
|
||
|
if (count > 0) {
|
||
|
_readbuf.write(_buffer, count);
|
||
|
}
|
||
|
} while (count > 0);
|
||
|
}
|
||
|
|
||
|
void IRAM_ATTR UARTDriver::write_data()
|
||
|
{
|
||
|
uart_port_t p = uart_desc[uart_num].port;
|
||
|
int count = 0;
|
||
|
_write_mutex.take_blocking();
|
||
|
do {
|
||
|
count = _writebuf.peekbytes(_buffer, sizeof(_buffer));
|
||
|
if (count > 0) {
|
||
|
count = uart_tx_chars(p, (const char*) _buffer, count);
|
||
|
_writebuf.advance(count);
|
||
|
}
|
||
|
} while (count > 0);
|
||
|
_write_mutex.give();
|
||
|
}
|
||
|
|
||
|
size_t IRAM_ATTR UARTDriver::write(uint8_t c)
|
||
|
{
|
||
|
return write(&c,1);
|
||
|
}
|
||
|
|
||
|
size_t IRAM_ATTR UARTDriver::write(const uint8_t *buffer, size_t size)
|
||
|
{
|
||
|
if (!_initialized) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
_write_mutex.take_blocking();
|
||
|
|
||
|
|
||
|
size_t ret = _writebuf.write(buffer, size);
|
||
|
_write_mutex.give();
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
bool UARTDriver::discard_input()
|
||
|
{
|
||
|
//uart_port_t p = uart_desc[uart_num].port;
|
||
|
//return uart_flush_input(p) == ESP_OK;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|