8000 esp8266/uart: rework uart io structure so it can work with dupterm() and be used to disable stdio by mhoffma · Pull Request #2891 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

esp8266/uart: rework uart io structure so it can work with dupterm() and be used to disable stdio #2891

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions esp8266/esp_mphal.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,20 @@ void mp_hal_signal_input(void) {
#endif
}

void mp_hal_uart_rx_intr(int uart_no) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this belongs in machine_uart.c, since it's specific to UART behaviour. Also, since UART1 can't receive it doesn't need to take an argument.

int ch;
for (;;) {
if ((ch = uart_rx_one_char(uart_no))==-1)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this the correct spacing?

if ((ch = uart_rx_one_char(uart_no)) == -1)

break;
if (ch == mp_interrupt_char)
mp_keyboard_interrupt();
else
ringbuf_put(&input_buf, ch);
}
mp_hal_signal_input();
}


static int call_dupterm_read(void) {
if (MP_STATE_PORT(term_obj) == NULL) {
return -1;
Expand Down
4 changes: 4 additions & 0 deletions esp8266/esp_mphal.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ extern const struct _mp_print_t mp_debug_print;
extern ringbuf_t input_buf;
// Call this after putting data to input_buf
void mp_hal_signal_input(void);
// Call this to put characters into connected uart buffer if repl connected
void mp_hal_uart_rx_intr(int uart_no);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way this function is currently implemented, it handles chars even if REPL is not connected.



// Call this when data is available in dupterm object
void mp_hal_signal_dupterm_input(void);

Expand Down
16 changes: 12 additions & 4 deletions esp8266/machine_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,19 @@ typedef struct _pyb_uart_obj_t {
uint16_t timeout_char; // timeout waiting between chars (in ms)
} pyb_uart_obj_t;

pyb_uart_obj_t pyb_uart_objs[2];

8000 STATIC const char *_parity_name[] = {"None", "1", "0"};

/******************************************************************************/
// MicroPython bindings for UART

void uart_init0 (void) {
// save references of the UART objects, to prevent the read buffers from being trashed by the gc
MP_STATE_PORT(pyb_uart_objs)[0] = &pyb_uart_objs[0];
MP_STATE_PORT(pyb_uart_objs)[1] = &pyb_uart_objs[1];
}

STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, timeout=%u, timeout_char=%u)",
Expand Down Expand Up @@ -169,7 +177,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
}

// create instance
pyb_uart_obj_t *self = m_new_obj(pyb_uart_obj_t);
pyb_uart_obj_t *self = &pyb_uart_objs[uart_id];
self->base.type = &pyb_uart_type;
self->uart_id = uart_id;
self->baudrate = 115200;
Expand Down Expand Up @@ -217,16 +225,16 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i
}

// wait for first char to become available
if (!uart_rx_wait(self->timeout * 1000)) {
if (!uart_rx_wait(self->uart_id, self->timeout * 1000)) {
*errcode = MP_EAGAIN;
return MP_STREAM_ERROR;
}

// read the data
uint8_t *buf = buf_in;
for (;;) {
*buf++ = uart_rx_char();
if (--size == 0 || !uart_rx_wait(self->timeout_char * 1000)) {
*buf++ = uart_rx_one_char(self->uart_id);
if (--size == 0 || !uart_rx_wait(self->uart_id, self->timeout_char * 1000)) {
// return number of bytes read
return buf - (uint8_t*)buf_in;
}
Expand Down
3 changes: 3 additions & 0 deletions esp8266/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include "gccollect.h"
#include "user_interface.h"

void uart_init0 (void);

STATIC char heap[36 * 1024];

STATIC void mp_reset(void) {
Expand All @@ -59,6 +61,7 @@ STATIC void mp_reset(void) {
esp_native_code_init();
#endif
pin_init0();
uart_init0();
readline_init0();
dupterm_task_init();
#if MICROPY_MODULE_FROZEN
Expand Down
3 changes: 3 additions & 0 deletions esp8266/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ extern const struct _mp_obj_module_t onewire_module;
const char *readline_hist[8]; \
vstr_t *repl_line; \
mp_obj_t pin_irq_handler[16]; \
struct _pyb_uart_obj_t *pyb_uart_objs[2]; \



// We need to provide a declaration/definition of alloca()
#include <alloca.h>
Expand Down
29 changes: 7 additions & 22 deletions esp8266/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,18 +167,7 @@ static void uart0_rx_intr_handler(void *para) {
} else if (UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) {
read_chars:
ETS_UART_INTR_DISABLE();

while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
uint8 RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
if (RcvChar == mp_interrupt_char) {
mp_keyboard_interrupt();
} else {
ringbuf_put(&input_buf, RcvChar);
}
}

mp_hal_signal_input();

mp_hal_uart_rx_intr(uart_no);
// Clear pending FIFO interrupts
WRITE_PERI_REG(UART_INT_CLR(UART_REPL), UART_RXFIFO_TOUT_INT_CLR | UART_RXFIFO_FULL_INT_ST);
ETS_UART_INTR_ENABLE();
Expand All @@ -187,10 +176,10 @@ static void uart0_rx_intr_handler(void *para) {

// Waits at most timeout microseconds for at least 1 char to become ready for reading.
// Returns true if something available, false if not.
bool uart_rx_wait(uint32_t timeout_us) {
bool uart_rx_wait(uint8 uart_no, uint32_t timeout_us) {
uint32_t start = system_get_time();
for (;;) {
if (input_buf.iget != input_buf.iput) {
if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
return true; // have at least 1 char ready for reading
}
if (system_get_time() - start >= timeout_us) {
Expand All @@ -200,25 +189,21 @@ bool uart_rx_wait(uint32_t timeout_us) {
}
}

int uart_rx_any(uint8 uart) {
if (input_buf.iget != input_buf.iput) {
int uart_rx_any(uint8 uart_no) {
if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
return true; // have at least 1 char ready for reading
}
return false;
}

int uart_tx_any_room(uint8 uart) {
uint32_t fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
int uart_tx_any_room(uint8 uart_no) {
uint32_t fifo_cnt = READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) >= 126) {
return false;
}
return true;
}

// Returns char from the input buffer, else -1 if buffer is empty.
int uart_rx_char(void) {
return ringbuf_get(&input_buf);
}

int uart_rx_one_char(uint8 uart_no) {
if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
Expand Down
4 changes: 2 additions & 2 deletions esp8266/uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ typedef struct {

void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
int uart0_rx(void);
bool uart_rx_wait(uint32_t timeout_us);
int uart_rx_char(void);
bool uart_rx_wait(uint8 uart, uint32_t timeout_us);
int uart_rx_one_char(uint8 uart);
void uart_tx_one_char(uint8 uart, uint8 TxChar);
void uart_flush(uint8 uart);
void uart_os_config(int uart);
Expand Down
0