mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
a8c82b506f
Move hw-esp32-uart and hw-rp2040-uart into hw-uart/ports/esp32/ and hw-uart/ports/rp2040/ using the new ports build system. Co-authored-by: Claude <noreply@anthropic.com>
148 lines
3.5 KiB
C
148 lines
3.5 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "driver/uart.h"
|
|
#include <mruby/uart.h>
|
|
|
|
#define RX_TASK_BUF_SIZE 128
|
|
#define QUEUE_LENGTH 20
|
|
#define TASK_STACK_SIZE 4096
|
|
#define TASK_PRIORITY 12
|
|
|
|
typedef struct {
|
|
int unit;
|
|
QueueHandle_t queue;
|
|
mrb_uart_ringbuf *rxbuf;
|
|
} uart_ctx;
|
|
|
|
static uart_ctx ctx[UART_NUM_MAX];
|
|
|
|
static void
|
|
rx_task(void *arg)
|
|
{
|
|
uart_ctx *c = (uart_ctx*)arg;
|
|
uart_event_t event;
|
|
uint8_t buf[RX_TASK_BUF_SIZE];
|
|
|
|
for (;;) {
|
|
if (xQueueReceive(c->queue, &event, portMAX_DELAY)) {
|
|
if (event.type == UART_DATA) {
|
|
size_t n = event.size > RX_TASK_BUF_SIZE ? RX_TASK_BUF_SIZE : event.size;
|
|
uart_read_bytes(c->unit, buf, n, portMAX_DELAY);
|
|
for (size_t i = 0; i < n; i++) {
|
|
mrb_uart_ringbuf_push(c->rxbuf, buf[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
mrb_uart_unit_name_to_num(const char *name)
|
|
{
|
|
if (strcmp(name, "ESP32_UART0") == 0) return UART_NUM_0;
|
|
if (strcmp(name, "ESP32_UART1") == 0) return UART_NUM_1;
|
|
#ifdef UART_NUM_2
|
|
if (strcmp(name, "ESP32_UART2") == 0) return UART_NUM_2;
|
|
#endif
|
|
return MRB_UART_ERROR_UNIT;
|
|
}
|
|
|
|
mrb_uart_status
|
|
mrb_uart_init(int unit, uint32_t tx_pin, uint32_t rx_pin,
|
|
mrb_uart_ringbuf *rxbuf)
|
|
{
|
|
if (unit < 0 || unit >= UART_NUM_MAX) return MRB_UART_ERROR_UNIT;
|
|
|
|
uart_config_t cfg = {
|
|
.baud_rate = 9600,
|
|
.data_bits = UART_DATA_8_BITS,
|
|
.parity = UART_PARITY_DISABLE,
|
|
.stop_bits = UART_STOP_BITS_1,
|
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
|
.source_clk = UART_SCLK_DEFAULT,
|
|
};
|
|
|
|
int bufsize = (rxbuf->mask + 1);
|
|
uart_driver_install(unit, bufsize, 0, QUEUE_LENGTH, &ctx[unit].queue, 0);
|
|
uart_param_config(unit, &cfg);
|
|
uart_set_pin(unit, tx_pin, rx_pin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
|
|
|
ctx[unit].unit = unit;
|
|
ctx[unit].rxbuf = rxbuf;
|
|
|
|
char name[32];
|
|
snprintf(name, sizeof(name), "uart_rx_%d", unit);
|
|
xTaskCreate(rx_task, name, TASK_STACK_SIZE, &ctx[unit], TASK_PRIORITY, NULL);
|
|
|
|
return MRB_UART_OK;
|
|
}
|
|
|
|
uint32_t
|
|
mrb_uart_set_baudrate(int unit, uint32_t baudrate)
|
|
{
|
|
uart_set_baudrate(unit, baudrate);
|
|
return baudrate;
|
|
}
|
|
|
|
void
|
|
mrb_uart_set_format(int unit, uint32_t data_bits, uint32_t stop_bits,
|
|
uint8_t parity)
|
|
{
|
|
static const uart_word_length_t wl[] = {
|
|
UART_DATA_5_BITS, UART_DATA_6_BITS, UART_DATA_7_BITS, UART_DATA_8_BITS
|
|
};
|
|
static const uart_stop_bits_t sb[] = {
|
|
UART_STOP_BITS_1, UART_STOP_BITS_2
|
|
};
|
|
static const uart_parity_t pr[] = {
|
|
UART_PARITY_DISABLE, UART_PARITY_EVEN, UART_PARITY_ODD
|
|
};
|
|
if (data_bits >= 5 && data_bits <= 8)
|
|
uart_set_word_length(unit, wl[data_bits - 5]);
|
|
if (stop_bits >= 1 && stop_bits <= 2)
|
|
uart_set_stop_bits(unit, sb[stop_bits - 1]);
|
|
if (parity <= 2)
|
|
uart_set_parity(unit, pr[parity]);
|
|
}
|
|
|
|
void
|
|
mrb_uart_set_flow_control(int unit, bool cts, bool rts)
|
|
{
|
|
uart_hw_flowcontrol_t mode = UART_HW_FLOWCTRL_DISABLE;
|
|
if (cts && rts) mode = UART_HW_FLOWCTRL_CTS_RTS;
|
|
else if (cts) mode = UART_HW_FLOWCTRL_CTS;
|
|
else if (rts) mode = UART_HW_FLOWCTRL_RTS;
|
|
uart_set_hw_flow_ctrl(unit, mode, 122);
|
|
}
|
|
|
|
void
|
|
mrb_uart_write(int unit, const uint8_t *src, size_t len)
|
|
{
|
|
uart_write_bytes(unit, (const char*)src, len);
|
|
}
|
|
|
|
void
|
|
mrb_uart_flush(int unit)
|
|
{
|
|
uart_wait_tx_done(unit, 100);
|
|
}
|
|
|
|
void
|
|
mrb_uart_send_break(int unit, uint32_t duration_ms)
|
|
{
|
|
uart_write_bytes_with_break(unit, NULL, 0, duration_ms);
|
|
}
|
|
|
|
void
|
|
mrb_uart_clear_rx(int unit)
|
|
{
|
|
uart_flush_input(unit);
|
|
}
|
|
|
|
void
|
|
mrb_uart_clear_tx(int unit)
|
|
{
|
|
/* not supported on ESP-IDF */
|
|
}
|