Skip to content

Commit 2dd9407

Browse files
authored
Merge pull request #1186 from dhalbert/uart-enhancements
UART enhancements
2 parents beb9446 + 6a72084 commit 2dd9407

File tree

11 files changed

+139
-67
lines changed

11 files changed

+139
-67
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ before_script:
6464
- if [[ $TRAVIS_BOARD = "feather_huzzah" ]]; then wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar xavf xtensa-lx106-elf-standalone.tar.gz; PATH=$(readlink -f xtensa-lx106-elf/bin):$PATH; fi
6565
# For coverage testing (upgrade is used to get latest urllib3 version)
6666
- ([[ -z "$TRAVIS_TEST" ]] || sudo pip install --upgrade cpp-coveralls)
67-
- ([[ $TRAVIS_TEST != "docs" ]] || sudo pip install Sphinx sphinx-rtd-theme recommonmark)
67+
- ([[ $TRAVIS_TEST != "docs" ]] || sudo pip install 'Sphinx<1.8.0' sphinx-rtd-theme recommonmark)
6868
- gcc --version
6969
- ([[ -z "$TRAVIS_BOARD" ]] || arm-none-eabi-gcc --version)
7070
- python3 --version

ports/atmel-samd/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ else
115115
# -finline-limit=80 or so is similar to not having it on.
116116
# There is no simple default value, though.
117117
ifdef INTERNAL_FLASH_FILESYSTEM
118-
CFLAGS += -finline-limit=55
118+
CFLAGS += -finline-limit=50
119119
endif
120120
ifdef CFLAGS_INLINE_LIMIT
121121
CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT)

ports/atmel-samd/board_busses.c

Lines changed: 73 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -33,81 +33,96 @@
3333
#include "samd/pins.h"
3434
#include "py/runtime.h"
3535

36-
#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)
37-
STATIC mp_obj_t board_i2c(void) {
38-
mp_raise_NotImplementedError("No default I2C bus");
39-
return NULL;
40-
}
41-
#else
42-
STATIC mp_obj_t i2c_singleton = NULL;
36+
#define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL))
37+
#define BOARD_SPI (defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MISO) && defined(DEFAULT_SPI_BUS_MOSI))
38+
#define BOARD_UART (defined(DEFAULT_UART_BUS_RX) && defined(DEFAULT_UART_BUS_TX))
4339

44-
STATIC mp_obj_t board_i2c(void) {
40+
#if BOARD_I2C
41+
STATIC mp_obj_t i2c_singleton = NULL;
4542

46-
if (i2c_singleton == NULL) {
47-
busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t);
48-
self->base.type = &busio_i2c_type;
43+
STATIC mp_obj_t board_i2c(void) {
4944

50-
assert_pin_free(DEFAULT_I2C_BUS_SDA);
51-
assert_pin_free(DEFAULT_I2C_BUS_SCL);
52-
common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0);
53-
i2c_singleton = (mp_obj_t)self;
54-
}
55-
return i2c_singleton;
45+
if (i2c_singleton == NULL) {
46+
busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t);
47+
self->base.type = &busio_i2c_type;
5648

49+
assert_pin_free(DEFAULT_I2C_BUS_SDA);
50+
assert_pin_free(DEFAULT_I2C_BUS_SCL);
51+
common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0);
52+
i2c_singleton = (mp_obj_t)self;
5753
}
54+
return i2c_singleton;
55+
}
56+
#else
57+
STATIC mp_obj_t board_i2c(void) {
58+
mp_raise_NotImplementedError("No default I2C bus");
59+
return NULL;
60+
}
5861
#endif
5962
MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c);
6063

61-
#if !defined(DEFAULT_SPI_BUS_SCK) || !defined(DEFAULT_SPI_BUS_MISO) || !defined(DEFAULT_SPI_BUS_MOSI)
62-
STATIC mp_obj_t board_spi(void) {
63-
mp_raise_NotImplementedError("No default SPI bus");
64-
return NULL;
64+
#if BOARD_SPI
65+
STATIC mp_obj_t spi_singleton = NULL;
66+
67+
STATIC mp_obj_t board_spi(void) {
68+
if (spi_singleton == NULL) {
69+
busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t);
70+
self->base.type = &busio_spi_type;
71+
assert_pin_free(DEFAULT_SPI_BUS_SCK);
72+
assert_pin_free(DEFAULT_SPI_BUS_MOSI);
73+
assert_pin_free(DEFAULT_SPI_BUS_MISO);
74+
const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK);
75+
const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI);
76+
const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO);
77+
common_hal_busio_spi_construct(self, clock, mosi, miso);
78+
spi_singleton = (mp_obj_t)self;
6579
}
80+
return spi_singleton;
81+
}
6682
#else
67-
STATIC mp_obj_t spi_singleton = NULL;
68-
69-
STATIC mp_obj_t board_spi(void) {
70-
71-
if (spi_singleton == NULL) {
72-
busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t);
73-
self->base.type = &busio_spi_type;
74-
assert_pin_free(DEFAULT_SPI_BUS_SCK);
75-
assert_pin_free(DEFAULT_SPI_BUS_MOSI);
76-
assert_pin_free(DEFAULT_SPI_BUS_MISO);
77-
const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK);
78-
const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI);
79-
const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO);
80-
common_hal_busio_spi_construct(self, clock, mosi, miso);
81-
spi_singleton = (mp_obj_t)self;
82-
}
83-
return spi_singleton;
84-
}
83+
STATIC mp_obj_t board_spi(void) {
84+
mp_raise_NotImplementedError("No default SPI bus");
85+
return NULL;
86+
}
8587
#endif
8688
MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);
8789

88-
#if !defined(DEFAULT_UART_BUS_RX) || !defined(DEFAULT_UART_BUS_TX)
89-
STATIC mp_obj_t board_uart(void) {
90-
mp_raise_NotImplementedError("No default UART bus");
91-
return NULL;
92-
}
93-
#else
94-
STATIC mp_obj_t uart_singleton = NULL;
90+
#if BOARD_UART
91+
STATIC mp_obj_t uart_singleton = NULL;
9592

96-
STATIC mp_obj_t board_uart(void) {
97-
if (uart_singleton == NULL) {
98-
busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t);
99-
self->base.type = &busio_uart_type;
93+
STATIC mp_obj_t board_uart(void) {
94+
if (uart_singleton == NULL) {
95+
busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t);
96+
self->base.type = &busio_uart_type;
10097

101-
assert_pin_free(DEFAULT_UART_BUS_RX);
102-
assert_pin_free(DEFAULT_UART_BUS_TX);
98+
assert_pin_free(DEFAULT_UART_BUS_RX);
99+
assert_pin_free(DEFAULT_UART_BUS_TX);
103100

104-
const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX);
105-
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX);
101+
const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX);
102+
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX);
106103

107-
common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64);
108-
uart_singleton = (mp_obj_t)self;
109-
}
110-
return uart_singleton;
104+
common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64);
105+
uart_singleton = (mp_obj_t)self;
111106
}
107+
return uart_singleton;
108+
}
109+
#else
110+
STATIC mp_obj_t board_uart(void) {
111+
mp_raise_NotImplementedError("No default UART bus");
112+
return NULL;
113+
}
112114
#endif
113115
MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart);
116+
117+
118+
void reset_board_busses(void) {
119+
#if BOARD_I2C
120+
i2c_singleton = NULL;
121+
#endif
122+
#if BOARD_SPI
123+
spi_singleton = NULL;
124+
#endif
125+
#if BOARD_UART
126+
uart_singleton = NULL;
127+
#endif
128+
}

ports/atmel-samd/board_busses.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ extern mp_obj_fun_builtin_fixed_t board_spi_obj;
3636
void board_uart(void);
3737
extern mp_obj_fun_builtin_fixed_t board_uart_obj;
3838

39+
void reset_board_busses(void);
40+
3941
#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARD_BUSSES_H

ports/atmel-samd/common-hal/busio/UART.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
254254
uint64_t start_ticks = ticks_ms;
255255

256256
// Busy-wait until timeout or until we've read enough chars.
257-
while (ticks_ms - start_ticks < self->timeout_ms) {
257+
while (ticks_ms - start_ticks <= self->timeout_ms) {
258258
// Read as many chars as we can right now, up to len.
259259
size_t num_read = io_read(io, data, len);
260260

@@ -273,6 +273,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
273273
#ifdef MICROPY_VM_HOOK_LOOP
274274
MICROPY_VM_HOOK_LOOP
275275
#endif
276+
// If we are zero timeout, make sure we don't loop again (in the event
277+
// we read in under 1ms)
278+
if (self->timeout_ms == 0)
279+
break;
276280
}
277281

278282
if (total_read == 0) {
@@ -345,7 +349,18 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat
345349
}
346350

347351
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
348-
return self->buffer_size;
352+
// This assignment is only here because the usart_async routines take a *const argument.
353+
struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
354+
struct usart_async_status async_status;
355+
usart_async_get_status(usart_desc_p, &async_status);
356+
return async_status.rxcnt;
357+
}
358+
359+
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
360+
// This assignment is only here because the usart_async routines take a *const argument.
361+
struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
362+
usart_async_flush_rx_buffer(usart_desc_p);
363+
349364
}
350365

351366
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {

ports/atmel-samd/common-hal/busio/UART.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ typedef struct {
4242
bool rx_error;
4343
uint32_t baudrate;
4444
uint32_t timeout_ms;
45-
// Index of the oldest received character.
46-
uint32_t buffer_start;
47-
// Index of the next available spot to store a character.
48-
uint32_t buffer_size;
4945
uint32_t buffer_length;
5046
uint8_t* buffer;
5147
} busio_uart_obj_t;

ports/atmel-samd/supervisor/port.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "samd/external_interrupts.h"
6262
#include "samd/dma.h"
6363
#include "shared-bindings/rtc/__init__.h"
64+
#include "board_busses.h"
6465
#include "tick.h"
6566
#include "usb.h"
6667

@@ -270,6 +271,8 @@ void reset_port(void) {
270271

271272
reset_all_pins();
272273

274+
reset_board_busses();
275+
273276
// Output clocks for debugging.
274277
// not supported by SAMD51G; uncomment for SAMD51J or update for 51G
275278
// #ifdef SAMD51

ports/esp8266/common-hal/busio/UART.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
137137
return 0;
138138
}
139139

140+
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
141+
}
142+
140143
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
141144
return true;
142145
}

ports/nrf/common-hal/busio/UART.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
8383
return 0;
8484
}
8585

86+
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
87+
mp_raise_NotImplementedError("busio.UART not yet implemented");
88+
}
89+
8690
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
8791
mp_raise_NotImplementedError("busio.UART not yet implemented");
8892
return false;

shared-bindings/busio/UART.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,36 @@ const mp_obj_property_t busio_uart_baudrate_obj = {
252252
(mp_obj_t)&mp_const_none_obj},
253253
};
254254

255+
//| .. attribute:: in_waiting
256+
//|
257+
//| The number of bytes in the input buffer, available to be read
258+
//|
259+
STATIC mp_obj_t busio_uart_obj_get_in_waiting(mp_obj_t self_in) {
260+
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
261+
raise_error_if_deinited(common_hal_busio_uart_deinited(self));
262+
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_rx_characters_available(self));
263+
}
264+
MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_in_waiting_obj, busio_uart_obj_get_in_waiting);
265+
266+
const mp_obj_property_t busio_uart_in_waiting_obj = {
267+
.base.type = &mp_type_property,
268+
.proxy = {(mp_obj_t)&busio_uart_get_in_waiting_obj,
269+
(mp_obj_t)&mp_const_none_obj,
270+
(mp_obj_t)&mp_const_none_obj},
271+
};
272+
273+
//| .. method:: reset_input_buffer()
274+
//|
275+
//| Discard any unread characters in the input buffer.
276+
//|
277+
STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) {
278+
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
279+
raise_error_if_deinited(common_hal_busio_uart_deinited(self));
280+
common_hal_busio_uart_clear_rx_buffer(self);
281+
return mp_const_none;
282+
}
283+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer);
284+
255285
//| .. class:: busio.UART.Parity
256286
//|
257287
//| Enum-like class to define the parity used to verify correct data transfer.
@@ -306,9 +336,12 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = {
306336
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
307337
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
308338

339+
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&busio_uart_reset_input_buffer_obj) },
340+
309341
// Properties
310342
{ MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) },
311-
343+
{ MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) },
344+
312345
// Nested Enum-like Classes.
313346
{ MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) },
314347
};

shared-bindings/busio/UART.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t
6060

6161

6262
extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self);
63+
extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self);
6364
extern bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self);
6465

6566
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H

0 commit comments

Comments
 (0)