Skip to content

Commit a87b258

Browse files
committed
feat: Add UART support
This commit adds support for UART with interrupt possibility and helper functions especially for RX path
1 parent db20fc4 commit a87b258

File tree

46 files changed

+18696
-80
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+18696
-80
lines changed

src/target/base/include/target/uart.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,101 @@
77
#pragma once
88

99
#include <stdint.h>
10+
#include <stdbool.h>
11+
#include "soc_caps.h"
1012

13+
/**
14+
* @brief UART port numbers
15+
*
16+
* Available UART ports depend on the chip's SOC_UART_HP_NUM capability.
17+
*/
18+
typedef enum {
19+
UART_NUM_0, /*!< UART port 0 */
20+
UART_NUM_1, /*!< UART port 1 */
21+
#if SOC_UART_HP_NUM > 2
22+
UART_NUM_2, /*!< UART port 2 */
23+
#endif
24+
#if SOC_UART_HP_NUM > 3
25+
UART_NUM_3, /*!< UART port 3 */
26+
#endif
27+
#if SOC_UART_HP_NUM > 4
28+
UART_NUM_4, /*!< UART port 4 */
29+
#endif
30+
UART_NUM_MAX, /*!< UART port max */
31+
} uart_port_t;
32+
33+
#define UART_INTR_RXFIFO_FULL (0x1<<0)
34+
#define UART_INTR_RXFIFO_TOUT (0x1<<8)
35+
36+
/**
37+
* @brief Wait until UART is idle
38+
*
39+
* @param uart_num UART port number
40+
*/
41+
void stub_target_uart_wait_idle(uint8_t uart_num);
42+
43+
/**
44+
* @brief Initialize UART
45+
*
46+
* @param uart_num UART port number
47+
* @param baudrate Baud rate
48+
*/
1149
void stub_target_uart_init(uint8_t uart_num, uint32_t baudrate);
50+
51+
/**
52+
* @brief Set UART baud rate
53+
*
54+
* @param uart_num UART port number
55+
* @param baudrate Baud rate
56+
*/
57+
void stub_target_uart_set_baudrate(uint8_t uart_num, uint32_t baudrate);
58+
59+
/**
60+
* @brief Attach interrupt handler to UART and configure interrupts
61+
*
62+
* @param uart_num UART port number
63+
* @param intr_num CPU interrupt source
64+
* @param handler Interrupt handler function pointer
65+
* @param flags Interrupt enable flags (bitwise OR of UART_INTR_* values)
66+
*/
67+
void stub_target_uart_intr_attach(uint8_t uart_num, int intr_num, void *handler, uint32_t flags);
68+
69+
/**
70+
* @brief Get and clear UART interrupt status
71+
*
72+
* This function returns the interrupt status and automatically clears it.
73+
* Call this at the beginning of your interrupt handler.
74+
*
75+
* @param uart_num UART port number
76+
* @return Bitmask of active interrupts that were cleared
77+
*/
78+
uint32_t stub_target_uart_get_intr_flags(uint8_t uart_num);
79+
80+
/**
81+
* @brief Get number of bytes available in RX FIFO
82+
*
83+
* @param uart_num UART port number
84+
* @return Number of bytes currently in the RX FIFO
85+
*/
86+
uint32_t stub_target_uart_get_rxfifo_count(uint8_t uart_num);
87+
88+
/**
89+
* @brief Read a single byte from UART RX FIFO
90+
*
91+
* This function reads one byte from the RX FIFO without checking
92+
* if data is available. Call stub_target_uart_get_rxfifo_count()
93+
* first to ensure data is available.
94+
*
95+
* @param uart_num UART port number
96+
* @return The byte read from the FIFO
97+
*/
98+
uint8_t stub_target_uart_read_rxfifo_byte(uint8_t uart_num);
99+
100+
/**
101+
* @brief Configure RX timeout threshold
102+
*
103+
* @param uart_num UART port number
104+
* @param timeout Timeout value in bit times (1-126, 0 to disable)
105+
* timeout mean the multiple of UART packets (~11 bytes) that can be received before timeout
106+
*/
107+
void stub_target_uart_set_rx_timeout(uint8_t uart_num, uint8_t timeout);

src/target/common/src/uart.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,80 @@
44
* SPDX-License-Identifier: Apache-2.0 OR MIT
55
*/
66

7+
#include <stdbool.h>
78
#include <stdint.h>
89
#include <stddef.h>
910
#include <target/uart.h>
11+
#include <target/soc_utils.h>
12+
#include <soc/uart_reg.h>
13+
14+
extern void ets_update_cpu_frequency(uint32_t ticks_per_us);
15+
extern void uartAttach(void *rxBuffer);
16+
extern void Uart_Init(uint8_t uart_no);
17+
extern uint32_t ets_clk_get_cpu_freq(void);
18+
extern void uart_tx_switch(uint8_t uart_no);
19+
extern void uart_tx_wait_idle(uint8_t uart_num);
20+
extern void uart_div_modify(uint8_t uart_no, uint32_t divisor);
21+
22+
void __attribute__((weak)) stub_target_uart_wait_idle(uint8_t uart_num)
23+
{
24+
uart_tx_wait_idle(uart_num);
25+
}
1026

1127
void __attribute__((weak)) stub_target_uart_init(uint8_t uart_num, uint32_t baudrate)
1228
{
13-
(void)baudrate;
29+
ets_update_cpu_frequency(ets_clk_get_cpu_freq() / 1000000);
30+
uartAttach(NULL);
31+
Uart_Init(uart_num);
32+
uart_tx_switch(uart_num);
33+
stub_target_uart_set_baudrate(uart_num, baudrate);
34+
}
35+
36+
void __attribute__((weak)) stub_target_uart_set_baudrate(uint8_t uart_num, uint32_t baudrate)
37+
{
38+
uint32_t clock = ets_clk_get_cpu_freq() << 4;
39+
uint32_t divisor = clock / baudrate;
40+
stub_target_uart_wait_idle(uart_num);
41+
uart_div_modify(uart_num, divisor);
42+
// TODO: Consider decimal part
43+
}
44+
45+
void __attribute__((weak)) stub_target_uart_intr_attach(uint8_t uart_num, int intr_num, void *handler, uint32_t flags)
46+
{
1447
(void)uart_num;
48+
(void)intr_num;
49+
(void)handler;
50+
(void)flags;
51+
// TODO: implement
52+
}
53+
54+
uint32_t __attribute__((weak)) stub_target_uart_get_intr_flags(uint8_t uart_num)
55+
{
56+
uint32_t status = READ_PERI_REG(UART_INT_ST_REG(uart_num));
57+
// Clear the interrupts
58+
WRITE_PERI_REG(UART_INT_CLR_REG(uart_num), status);
59+
return status;
60+
}
61+
62+
uint32_t __attribute__((weak)) stub_target_uart_get_rxfifo_count(uint8_t uart_num)
63+
{
64+
uint32_t status = READ_PERI_REG(UART_STATUS_REG(uart_num));
65+
return (status >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT_V;
66+
}
67+
68+
uint8_t __attribute__((weak)) stub_target_uart_read_rxfifo_byte(uint8_t uart_num)
69+
{
70+
return (uint8_t)(READ_PERI_REG(UART_FIFO_REG(uart_num)) & UART_RXFIFO_RD_BYTE_V);
71+
}
72+
73+
void __attribute__((weak)) stub_target_uart_set_rx_timeout(uint8_t uart_num, uint8_t timeout)
74+
{
75+
uint32_t conf1 = READ_PERI_REG(UART_CONF1_REG(uart_num));
76+
conf1 &= ~(UART_RX_TOUT_THRHD_M | UART_RX_TOUT_EN_M);
77+
78+
if (timeout > 0U) {
79+
conf1 |= (((uint32_t)timeout & UART_RX_TOUT_THRHD_V) << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN;
80+
}
81+
82+
WRITE_PERI_REG(UART_CONF1_REG(uart_num), conf1);
1583
}

src/target/esp32/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_library(${ESP_TARGET_LIB} STATIC ${srcs})
77

88
target_link_options(${ESP_TARGET_LIB}
99
PUBLIC -T${CMAKE_CURRENT_LIST_DIR}/ld/esp32.rom.ld
10+
PUBLIC -T${CMAKE_CURRENT_LIST_DIR}/ld/esp32.rom.redefined.ld
1011
PUBLIC -T${CMAKE_CURRENT_LIST_DIR}/ld/esp32.rom.libc-funcs.ld
1112
PUBLIC -T${CMAKE_CURRENT_LIST_DIR}/ld/esp32.rom.libgcc.ld
1213
)

0 commit comments

Comments
 (0)