Skip to content

UART enhancements #1186

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

Merged
merged 3 commits into from
Sep 12, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ before_script:
- 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
# For coverage testing (upgrade is used to get latest urllib3 version)
- ([[ -z "$TRAVIS_TEST" ]] || sudo pip install --upgrade cpp-coveralls)
- ([[ $TRAVIS_TEST != "docs" ]] || sudo pip install Sphinx sphinx-rtd-theme recommonmark)
- ([[ $TRAVIS_TEST != "docs" ]] || sudo pip install 'Sphinx<1.8.0' sphinx-rtd-theme recommonmark)
- gcc --version
- ([[ -z "$TRAVIS_BOARD" ]] || arm-none-eabi-gcc --version)
- python3 --version
Expand Down
2 changes: 1 addition & 1 deletion ports/atmel-samd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ else
# -finline-limit=80 or so is similar to not having it on.
# There is no simple default value, though.
ifdef INTERNAL_FLASH_FILESYSTEM
CFLAGS += -finline-limit=55
CFLAGS += -finline-limit=50
endif
ifdef CFLAGS_INLINE_LIMIT
CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT)
Expand Down
131 changes: 73 additions & 58 deletions ports/atmel-samd/board_busses.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,81 +33,96 @@
#include "samd/pins.h"
#include "py/runtime.h"

#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)
STATIC mp_obj_t board_i2c(void) {
mp_raise_NotImplementedError("No default I2C bus");
return NULL;
}
#else
STATIC mp_obj_t i2c_singleton = NULL;
#define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL))
#define BOARD_SPI (defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MISO) && defined(DEFAULT_SPI_BUS_MOSI))
#define BOARD_UART (defined(DEFAULT_UART_BUS_RX) && defined(DEFAULT_UART_BUS_TX))

STATIC mp_obj_t board_i2c(void) {
#if BOARD_I2C
STATIC mp_obj_t i2c_singleton = NULL;

if (i2c_singleton == NULL) {
busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t);
self->base.type = &busio_i2c_type;
STATIC mp_obj_t board_i2c(void) {

assert_pin_free(DEFAULT_I2C_BUS_SDA);
assert_pin_free(DEFAULT_I2C_BUS_SCL);
common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0);
i2c_singleton = (mp_obj_t)self;
}
return i2c_singleton;
if (i2c_singleton == NULL) {
busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t);
self->base.type = &busio_i2c_type;

assert_pin_free(DEFAULT_I2C_BUS_SDA);
assert_pin_free(DEFAULT_I2C_BUS_SCL);
common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0);
i2c_singleton = (mp_obj_t)self;
}
return i2c_singleton;
}
#else
STATIC mp_obj_t board_i2c(void) {
mp_raise_NotImplementedError("No default I2C bus");
return NULL;
}
#endif
MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c);

#if !defined(DEFAULT_SPI_BUS_SCK) || !defined(DEFAULT_SPI_BUS_MISO) || !defined(DEFAULT_SPI_BUS_MOSI)
STATIC mp_obj_t board_spi(void) {
mp_raise_NotImplementedError("No default SPI bus");
return NULL;
#if BOARD_SPI
STATIC mp_obj_t spi_singleton = NULL;

STATIC mp_obj_t board_spi(void) {
if (spi_singleton == NULL) {
busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t);
self->base.type = &busio_spi_type;
assert_pin_free(DEFAULT_SPI_BUS_SCK);
assert_pin_free(DEFAULT_SPI_BUS_MOSI);
assert_pin_free(DEFAULT_SPI_BUS_MISO);
const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK);
const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI);
const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO);
common_hal_busio_spi_construct(self, clock, mosi, miso);
spi_singleton = (mp_obj_t)self;
}
return spi_singleton;
}
#else
STATIC mp_obj_t spi_singleton = NULL;

STATIC mp_obj_t board_spi(void) {

if (spi_singleton == NULL) {
busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t);
self->base.type = &busio_spi_type;
assert_pin_free(DEFAULT_SPI_BUS_SCK);
assert_pin_free(DEFAULT_SPI_BUS_MOSI);
assert_pin_free(DEFAULT_SPI_BUS_MISO);
const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK);
const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI);
const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO);
common_hal_busio_spi_construct(self, clock, mosi, miso);
spi_singleton = (mp_obj_t)self;
}
return spi_singleton;
}
STATIC mp_obj_t board_spi(void) {
mp_raise_NotImplementedError("No default SPI bus");
return NULL;
}
#endif
MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);

#if !defined(DEFAULT_UART_BUS_RX) || !defined(DEFAULT_UART_BUS_TX)
STATIC mp_obj_t board_uart(void) {
mp_raise_NotImplementedError("No default UART bus");
return NULL;
}
#else
STATIC mp_obj_t uart_singleton = NULL;
#if BOARD_UART
STATIC mp_obj_t uart_singleton = NULL;

STATIC mp_obj_t board_uart(void) {
if (uart_singleton == NULL) {
busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t);
self->base.type = &busio_uart_type;
STATIC mp_obj_t board_uart(void) {
if (uart_singleton == NULL) {
busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t);
self->base.type = &busio_uart_type;

assert_pin_free(DEFAULT_UART_BUS_RX);
assert_pin_free(DEFAULT_UART_BUS_TX);
assert_pin_free(DEFAULT_UART_BUS_RX);
assert_pin_free(DEFAULT_UART_BUS_TX);

const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX);
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX);
const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX);
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX);

common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64);
uart_singleton = (mp_obj_t)self;
}
return uart_singleton;
common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64);
uart_singleton = (mp_obj_t)self;
}
return uart_singleton;
}
#else
STATIC mp_obj_t board_uart(void) {
mp_raise_NotImplementedError("No default UART bus");
return NULL;
}
#endif
MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart);


void reset_board_busses(void) {
#if BOARD_I2C
i2c_singleton = NULL;
#endif
#if BOARD_SPI
spi_singleton = NULL;
#endif
#if BOARD_UART
uart_singleton = NULL;
#endif
}
2 changes: 2 additions & 0 deletions ports/atmel-samd/board_busses.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ extern mp_obj_fun_builtin_fixed_t board_spi_obj;
void board_uart(void);
extern mp_obj_fun_builtin_fixed_t board_uart_obj;

void reset_board_busses(void);

#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARD_BUSSES_H
19 changes: 17 additions & 2 deletions ports/atmel-samd/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
uint64_t start_ticks = ticks_ms;

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

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

if (total_read == 0) {
Expand Down Expand Up @@ -345,7 +349,18 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat
}

uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return self->buffer_size;
// This assignment is only here because the usart_async routines take a *const argument.
struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
struct usart_async_status async_status;
usart_async_get_status(usart_desc_p, &async_status);
return async_status.rxcnt;
}

void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// This assignment is only here because the usart_async routines take a *const argument.
struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
usart_async_flush_rx_buffer(usart_desc_p);

}

bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
Expand Down
4 changes: 0 additions & 4 deletions ports/atmel-samd/common-hal/busio/UART.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ typedef struct {
bool rx_error;
uint32_t baudrate;
uint32_t timeout_ms;
// Index of the oldest received character.
uint32_t buffer_start;
// Index of the next available spot to store a character.
uint32_t buffer_size;
uint32_t buffer_length;
uint8_t* buffer;
} busio_uart_obj_t;
Expand Down
3 changes: 3 additions & 0 deletions ports/atmel-samd/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include "samd/external_interrupts.h"
#include "samd/dma.h"
#include "shared-bindings/rtc/__init__.h"
#include "board_busses.h"
#include "tick.h"
#include "usb.h"

Expand Down Expand Up @@ -270,6 +271,8 @@ void reset_port(void) {

reset_all_pins();

reset_board_busses();

// Output clocks for debugging.
// not supported by SAMD51G; uncomment for SAMD51J or update for 51G
// #ifdef SAMD51
Expand Down
3 changes: 3 additions & 0 deletions ports/esp8266/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return 0;
}

void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
}

bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
return true;
}
4 changes: 4 additions & 0 deletions ports/nrf/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return 0;
}

void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
mp_raise_NotImplementedError("busio.UART not yet implemented");
}

bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
mp_raise_NotImplementedError("busio.UART not yet implemented");
return false;
Expand Down
35 changes: 34 additions & 1 deletion shared-bindings/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,36 @@ const mp_obj_property_t busio_uart_baudrate_obj = {
(mp_obj_t)&mp_const_none_obj},
};

//| .. attribute:: in_waiting
//|
//| The number of bytes in the input buffer, available to be read
//|
STATIC mp_obj_t busio_uart_obj_get_in_waiting(mp_obj_t self_in) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
raise_error_if_deinited(common_hal_busio_uart_deinited(self));
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_rx_characters_available(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_in_waiting_obj, busio_uart_obj_get_in_waiting);

const mp_obj_property_t busio_uart_in_waiting_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&busio_uart_get_in_waiting_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};

//| .. method:: reset_input_buffer()
//|
//| Discard any unread characters in the input buffer.
//|
STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
raise_error_if_deinited(common_hal_busio_uart_deinited(self));
common_hal_busio_uart_clear_rx_buffer(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer);

//| .. class:: busio.UART.Parity
//|
//| Enum-like class to define the parity used to verify correct data transfer.
Expand Down Expand Up @@ -306,9 +336,12 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },

{ MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&busio_uart_reset_input_buffer_obj) },

// Properties
{ MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) },

{ MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) },

// Nested Enum-like Classes.
{ MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) },
};
Expand Down
1 change: 1 addition & 0 deletions shared-bindings/busio/UART.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t


extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self);
extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self);
extern bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self);

#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H