Skip to content

Commit 80db2ce

Browse files
committed
UART changes: timeout in secs, write bytes, etc.
1 parent 57c2c41 commit 80db2ce

8 files changed

Lines changed: 37 additions & 24 deletions

File tree

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static void usart_async_rxc_callback(const struct usart_async_descriptor *const
5353

5454
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
5555
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
56-
uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout,
56+
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
5757
uint8_t receiver_buffer_size) {
5858
Sercom* sercom = NULL;
5959
uint8_t sercom_index = 255; // Unset index
@@ -74,7 +74,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
7474

7575
self->baudrate = baudrate;
7676
self->character_bits = bits;
77-
self->timeout_ms = timeout;
77+
self->timeout_ms = timeout * 1000;
7878

7979
// This assignment is only here because the usart_async routines take a *const argument.
8080
struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
@@ -324,10 +324,8 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
324324
return MP_STREAM_ERROR;
325325
}
326326

327-
struct usart_async_status async_status;
328-
// Could return ERR_BUSY, but if that's true there's already a problem.
329-
usart_async_get_status(usart_desc_p, &async_status);
330-
return async_status.txcnt;
327+
// All the characters got written.
328+
return len;
331329
}
332330

333331
uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ extern UartDevice UartDev;
3939

4040
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
4141
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
42-
uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout,
42+
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
4343
uint8_t receiver_buffer_size) {
4444
if (rx != mp_const_none || tx != &pin_GPIO2) {
4545
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("Only tx supported on UART1 (GPIO2).")));

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
7676

7777
void common_hal_busio_uart_construct (busio_uart_obj_t *self,
7878
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
79-
uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout,
79+
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
8080
uint8_t receiver_buffer_size) {
8181
if ( (tx == mp_const_none) && (rx == mp_const_none) ) {
8282
mp_raise_ValueError(translate("tx and rx cannot both be None"));
@@ -124,7 +124,7 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self,
124124
}
125125

126126
self->baudrate = baudrate;
127-
self->timeout_ms = timeout;
127+
self->timeout_ms = timeout * 1000;
128128

129129
// queue 1-byte transfer for rx_characters_available()
130130
self->rx_count = -1;
@@ -317,7 +317,7 @@ static uint32_t get_nrf_baud (uint32_t baudrate)
317317

318318
void common_hal_busio_uart_construct (busio_uart_obj_t *self,
319319
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
320-
uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout,
320+
uint8_t bits, uart_parity_t parity, uint8_t stop, float timeout,
321321
uint8_t receiver_buffer_size) {
322322
mp_raise_NotImplementedError(translate("busio.UART not available"));
323323
}

py/stream.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ void mp_stream_write_adaptor(void *self, const char *buf, size_t len) {
250250
STATIC mp_obj_t stream_write_method(size_t n_args, const mp_obj_t *args) {
251251
mp_buffer_info_t bufinfo;
252252
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
253+
if (!mp_get_stream(args[0])->is_text && MP_OBJ_IS_STR(args[1])) {
254+
mp_raise_ValueError(translate("string not supported; use bytes or bytearray"));
255+
}
253256
size_t max_len = (size_t)-1;
254257
size_t off = 0;
255258
if (n_args == 3) {
@@ -282,6 +285,9 @@ STATIC mp_obj_t stream_readinto(size_t n_args, const mp_obj_t *args) {
282285
// https://docs.python.org/3/library/socket.html#socket.socket.recv_into
283286
mp_uint_t len = bufinfo.len;
284287
if (n_args > 2) {
288+
if (mp_get_stream(args[0])->pyserial_compatibility) {
289+
mp_raise_ValueError(translate("length argument not allowed for this type"));
290+
}
285291
len = mp_obj_get_int(args[2]);
286292
if (len > bufinfo.len) {
287293
len = bufinfo.len;

py/stream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ typedef struct _mp_stream_p_t {
7070
mp_uint_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode);
7171
mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
7272
mp_uint_t is_text : 1; // default is bytes, set this for text stream
73+
bool pyserial_compatibility: 1; // adjust API to match pyserial more closely
7374
} mp_stream_p_t;
7475

7576
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj);

shared-bindings/busio/I2C.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
//| :param ~microcontroller.Pin scl: The clock pin
5959
//| :param ~microcontroller.Pin sda: The data pin
6060
//| :param int frequency: The clock frequency in Hertz
61-
//| :param int timeout: The maximum clock stretching timeut - only for bitbang
61+
//| :param int timeout: The maximum clock stretching timeut - (used only for bitbangio.I2C; ignored for busio.I2C)
6262
//|
6363
STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
6464
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);

shared-bindings/busio/UART.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,22 @@
4545
//| =================================================
4646
//|
4747
//|
48-
//| .. class:: UART(tx, rx, \*, baudrate=9600, bits=8, parity=None, stop=1, timeout=1000, receiver_buffer_size=64)
48+
//| .. class:: UART(tx, rx, \*, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64)
4949
//|
5050
//| A common bidirectional serial protocol that uses an an agreed upon speed
5151
//| rather than a shared clock line.
5252
//|
5353
//| :param ~microcontroller.Pin tx: the pin to transmit with, or ``None`` if this ``UART`` is receive-only.
5454
//| :param ~microcontroller.Pin rx: the pin to receive on, or ``None`` if this ``UART`` is transmit-only.
5555
//| :param int baudrate: the transmit and receive speed.
56-
/// :param int bits: the number of bits per byte, 7, 8 or 9.
57-
/// :param Parity parity: the parity used for error checking.
58-
/// :param int stop: the number of stop bits, 1 or 2.
59-
/// :param int timeout: the timeout in milliseconds to wait for the first character and between subsequent characters.
60-
/// :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.)
56+
//| :param int bits: the number of bits per byte, 7, 8 or 9.
57+
//| :param Parity parity: the parity used for error checking.
58+
//| :param int stop: the number of stop bits, 1 or 2.
59+
//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters.
60+
//| :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.)
6161
//|
62+
//| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds.
63+
6264
typedef struct {
6365
mp_obj_base_t base;
6466
} busio_uart_parity_obj_t;
@@ -83,7 +85,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, si
8385
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
8486
{ MP_QSTR_parity, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
8587
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
86-
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} },
88+
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} },
8789
{ MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
8890
};
8991
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -115,8 +117,9 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, si
115117
}
116118

117119
common_hal_busio_uart_construct(self, tx, rx,
118-
args[ARG_baudrate].u_int, bits, parity, stop, args[ARG_timeout].u_int,
119-
args[ARG_receiver_buffer_size].u_int);
120+
args[ARG_baudrate].u_int, bits, parity, stop,
121+
mp_obj_get_float(args[ARG_timeout].u_obj),
122+
args[ARG_receiver_buffer_size].u_int);
120123
return (mp_obj_t)self;
121124
}
122125

@@ -161,14 +164,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_
161164
//| :return: Data read
162165
//| :rtype: bytes or None
163166
//|
164-
//| .. method:: readinto(buf, nbytes=None)
167+
//| .. method:: readinto(buf)
165168
//|
166-
//| Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
167-
//| that many bytes. Otherwise, read at most ``len(buf)`` bytes.
169+
//| Read bytes into the ``buf``. Read at most ``len(buf)`` bytes.
168170
//|
169171
//| :return: number of bytes read and stored into ``buf``
170172
//| :rtype: bytes or None
171173
//|
174+
//| *New in CircuitPython 4.0:* No length parameter is permitted.
175+
172176
//| .. method:: readline()
173177
//|
174178
//| Read a line, ending in a newline character.
@@ -180,6 +184,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_
180184
//|
181185
//| Write the buffer of bytes to the bus.
182186
//|
187+
//| *New in CircuitPython 4.0:* ``buf`` must be bytes, not a string.
188+
//|
183189
//| :return: the number of bytes written
184190
//| :rtype: int or None
185191
//|
@@ -353,6 +359,8 @@ STATIC const mp_stream_p_t uart_stream_p = {
353359
.write = busio_uart_write,
354360
.ioctl = busio_uart_ioctl,
355361
.is_text = false,
362+
// Match PySerial when possible, such as disallowing optional length argument for .readinto()
363+
.pyserial_compatibility = true,
356364
};
357365

358366
const mp_obj_type_t busio_uart_type = {

shared-bindings/busio/UART.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ typedef enum {
4141
// Construct an underlying UART object.
4242
extern void common_hal_busio_uart_construct(busio_uart_obj_t *self,
4343
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
44-
uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout,
44+
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
4545
uint8_t receiver_buffer_size);
4646

4747
extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self);

0 commit comments

Comments
 (0)