Skip to content

Commit 8e43b7d

Browse files
committed
Add UART for ESP32.
1 parent bf80b4c commit 8e43b7d

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed

build_config/riscv-esp.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
conf.gem core: "picoruby-adc"
2626
conf.gem core: "picoruby-rng"
2727
conf.gem core: "picoruby-spi"
28+
conf.gem core: "picoruby-uart"
2829
conf.gem core: "picoruby-pwm"
2930
conf.gem core: "picoruby-watchdog"
3031
conf.gem core: "picoruby-rmt"

build_config/xtensa-esp.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
conf.gem core: "picoruby-adc"
2727
conf.gem core: "picoruby-rng"
2828
conf.gem core: "picoruby-spi"
29+
conf.gem core: "picoruby-uart"
2930
conf.gem core: "picoruby-pwm"
3031
conf.gem core: "picoruby-watchdog"
3132
conf.gem core: "picoruby-rmt"
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
#include <stdio.h>
2+
#include <stdint.h>
3+
#include <string.h>
4+
#include <stdbool.h>
5+
6+
#include "freertos/FreeRTOS.h"
7+
#include "driver/uart.h"
8+
9+
#include "../../include/uart.h"
10+
11+
#define PICORUBY_UART_ESP32_UART0 (UART_NUM_0)
12+
#define PICORUBY_UART_ESP32_UART1 (UART_NUM_1)
13+
#ifdef UART_NUM_2
14+
#define PICORUBY_UART_ESP32_UART2 (UART_NUM_2)
15+
#endif
16+
#define RECEIVE_BUFF_SIZE (128)
17+
#define QUEUE_LENGTH (20)
18+
#define STACK_SIZE (4096)
19+
#define PRIORITY (12)
20+
21+
typedef struct uart_context {
22+
int unit_num;
23+
QueueHandle_t queue;
24+
RingBuffer* buff;
25+
} uart_context_t;
26+
static uart_context_t contexts[UART_NUM_MAX];
27+
28+
static void uart_event_task(void* pvParameters)
29+
{
30+
uart_context_t* context = (uart_context_t*)pvParameters;
31+
uart_event_t event;
32+
uint8_t buff[RECEIVE_BUFF_SIZE];
33+
34+
for(;;) {
35+
if(xQueueReceive(context->queue, (void*)&event, (TickType_t)portMAX_DELAY)) {
36+
switch (event.type) {
37+
case UART_DATA:
38+
uart_read_bytes(context->unit_num, buff, event.size > RECEIVE_BUFF_SIZE ? RECEIVE_BUFF_SIZE : event.size, portMAX_DELAY);
39+
for(size_t i = 0; i < event.size; i++) {
40+
UART_pushBuffer(context->buff, buff[i]);
41+
}
42+
break;
43+
default:
44+
break;
45+
}
46+
}
47+
}
48+
49+
vTaskDelete(NULL);
50+
}
51+
52+
int
53+
UART_unit_name_to_unit_num(const char *name)
54+
{
55+
if(strcmp(name, "ESP32_UART0") == 0) {
56+
return PICORUBY_UART_ESP32_UART0;
57+
}
58+
if(strcmp(name, "ESP32_UART1") == 0) {
59+
return PICORUBY_UART_ESP32_UART1;
60+
}
61+
#ifdef PICORUBY_UART_ESP32_UART2
62+
if(strcmp(name, "ESP32_UART2") == 0) {
63+
return PICORUBY_UART_ESP32_UART2;
64+
}
65+
#endif
66+
return ERROR_INVALID_UNIT;
67+
}
68+
69+
70+
void
71+
UART_init(int unit_num, uint32_t txd_pin, uint32_t rxd_pin, RingBuffer *ring_buffer)
72+
{
73+
uart_config_t uart_config = {
74+
.baud_rate = 9600,
75+
.data_bits = UART_DATA_8_BITS,
76+
.parity = UART_PARITY_DISABLE,
77+
.stop_bits = UART_STOP_BITS_1,
78+
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
79+
.source_clk = UART_SCLK_DEFAULT,
80+
};
81+
82+
ESP_ERROR_CHECK(uart_driver_install(unit_num, ring_buffer->size, 0, QUEUE_LENGTH, &contexts[unit_num].queue, 0));
83+
ESP_ERROR_CHECK(uart_param_config(unit_num, &uart_config));
84+
ESP_ERROR_CHECK(uart_set_pin(unit_num, txd_pin, rxd_pin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
85+
86+
contexts[unit_num].unit_num = unit_num;
87+
contexts[unit_num].buff = ring_buffer;
88+
89+
char task_name[32];
90+
sprintf(task_name, "uart_event_task_%d", unit_num);
91+
xTaskCreate(uart_event_task, task_name, STACK_SIZE, (void*)&contexts[unit_num], PRIORITY, NULL);
92+
}
93+
94+
uint32_t
95+
UART_set_baudrate(int unit_num, uint32_t baudrate)
96+
{
97+
ESP_ERROR_CHECK(uart_set_baudrate(unit_num, baudrate));
98+
return 0;
99+
}
100+
101+
void
102+
UART_set_flow_control(int unit_num, bool cts, bool rts)
103+
{
104+
ESP_ERROR_CHECK(
105+
uart_set_hw_flow_ctrl(
106+
unit_num,
107+
cts ? UART_HW_FLOWCTRL_CTS : UART_HW_FLOWCTRL_DISABLE,
108+
rts ? UART_HW_FLOWCTRL_RTS : UART_HW_FLOWCTRL_DISABLE
109+
)
110+
);
111+
}
112+
113+
void
114+
UART_set_format(int unit_num, uint32_t data_bits, uint32_t stop_bits, uint8_t parity)
115+
{
116+
uart_word_length_t uart_word_length[4] = {
117+
UART_DATA_5_BITS, // 5 bits
118+
UART_DATA_6_BITS, // 6 bits
119+
UART_DATA_7_BITS, // 7 bits
120+
UART_DATA_8_BITS // 8 bits
121+
};
122+
uart_stop_bits_t uart_stop_bits[3] = {
123+
UART_STOP_BITS_1, // 1 stop bit
124+
UART_STOP_BITS_2 // 2 stop bits
125+
};
126+
uart_parity_t uart_parity[3] = {
127+
UART_PARITY_DISABLE, // PARITY_NONE
128+
UART_PARITY_EVEN, // PARITY_EVEN
129+
UART_PARITY_ODD // PARITY_ODD
130+
};
131+
if(data_bits >= 5 && data_bits <= 8) {
132+
ESP_ERROR_CHECK(
133+
uart_set_word_length(unit_num, uart_word_length[data_bits - 5])
134+
);
135+
}
136+
if(stop_bits >= 1 && stop_bits <= 2) {
137+
ESP_ERROR_CHECK(
138+
uart_set_stop_bits(unit_num, uart_stop_bits[stop_bits - 1])
139+
);
140+
}
141+
if(parity <= 2) {
142+
ESP_ERROR_CHECK(
143+
uart_set_parity(unit_num, uart_parity[parity])
144+
);
145+
}
146+
}
147+
148+
void
149+
UART_set_function(uint32_t pin)
150+
{
151+
//no-op
152+
}
153+
154+
bool
155+
UART_is_writable(int unit_num)
156+
{
157+
//no-op
158+
return true;
159+
}
160+
161+
void
162+
UART_write_blocking(int unit_num, const uint8_t *src, size_t len)
163+
{
164+
ESP_ERROR_CHECK(
165+
uart_write_bytes(unit_num, (const char *)src, len)
166+
);
167+
}
168+
169+
bool
170+
UART_is_readable(int unit_num)
171+
{
172+
size_t buffered_len;
173+
uart_get_buffered_data_len(unit_num, &buffered_len);
174+
return (buffered_len > 0);
175+
}
176+
177+
size_t
178+
UART_read_nonblocking(int unit_num, uint8_t *dst, size_t maxlen)
179+
{
180+
size_t len = 0;
181+
ESP_ERROR_CHECK(
182+
len = uart_read_bytes(unit_num, dst, maxlen, 0)
183+
);
184+
return len;
185+
}
186+
187+
void
188+
UART_break(int unit_num, uint32_t interval)
189+
{
190+
ESP_ERROR_CHECK(
191+
uart_write_bytes_with_break(unit_num, NULL, 0, interval)
192+
);
193+
}
194+
195+
void
196+
UART_flush(int unit_num)
197+
{
198+
ESP_ERROR_CHECK(
199+
uart_wait_tx_done(unit_num, 100)
200+
);
201+
}
202+
203+
void
204+
UART_clear_rx_buffer(int unit_num)
205+
{
206+
ESP_ERROR_CHECK(
207+
uart_flush_input(unit_num)
208+
);
209+
}
210+
211+
void
212+
UART_clear_tx_buffer(int unit_num)
213+
{
214+
// no-op
215+
}

0 commit comments

Comments
 (0)