diff options
| author | Scott Shawcroft <scott@adafruit.com> | 2020-07-02 13:56:09 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-02 13:56:09 -0700 |
| commit | c33542f978cc61f0466ff60ea769e3067baca95f (patch) | |
| tree | 071e8f8a86971f7e947053c3b4fb2ff7da95d223 /shared-bindings/busio/UART.c | |
| parent | f572b723060382bbc9ca7a3edc88cb7c30fdcc30 (diff) | |
| parent | eec42d4cb53536a75e88f7f9321515bc6dcfeaa7 (diff) | |
Merge branch 'main' into patch-1
Diffstat (limited to 'shared-bindings/busio/UART.c')
| -rw-r--r-- | shared-bindings/busio/UART.c | 196 |
1 files changed, 94 insertions, 102 deletions
diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index e4a6b93d9..25cf5f480 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -39,33 +39,31 @@ #include "py/stream.h" #include "supervisor/shared/translate.h" - -//| .. currentmodule:: busio -//| -//| :class:`UART` -- a bidirectional serial protocol -//| ================================================= -//| -//| -//| .. class:: UART(tx, rx, *, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64) -//| -//| A common bidirectional serial protocol that uses an an agreed upon speed -//| rather than a shared clock line. -//| -//| :param ~microcontroller.Pin tx: the pin to transmit with, or ``None`` if this ``UART`` is receive-only. -//| :param ~microcontroller.Pin rx: the pin to receive on, or ``None`` if this ``UART`` is transmit-only. -//| :param ~microcontroller.Pin rts: the pin for rts, or ``None`` if rts not in use. -//| :param ~microcontroller.Pin cts: the pin for cts, or ``None`` if cts not in use. -//| :param ~microcontroller.Pin rs485_dir: the pin for rs485 direction setting, or ``None`` if rs485 not in use. -//| :param bool rs485_invert: set to invert the sense of the rs485_dir pin. -//| :param int baudrate: the transmit and receive speed. -//| :param int bits: the number of bits per byte, 7, 8 or 9. -//| :param Parity parity: the parity used for error checking. -//| :param int stop: the number of stop bits, 1 or 2. -//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters when reading. Raises ``ValueError`` if timeout >100 seconds. -//| :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.) -//| -//| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds. -//| The new upper limit on ``timeout`` is meant to catch mistaken use of milliseconds. +#define STREAM_DEBUG(...) (void)0 +// #define STREAM_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) + +//| class UART: +//| """A bidirectional serial protocol""" +//| def __init__(self, tx: microcontroller.Pin, rx: microcontroller.Pin, *, baudrate: int = 9600, bits: int = 8, parity: Parity = None, stop: int = 1, timeout: float = 1, receiver_buffer_size: int = 64): +//| """A common bidirectional serial protocol that uses an an agreed upon speed +//| rather than a shared clock line. +//| +//| :param ~microcontroller.Pin tx: the pin to transmit with, or ``None`` if this ``UART`` is receive-only. +//| :param ~microcontroller.Pin rx: the pin to receive on, or ``None`` if this ``UART`` is transmit-only. +//| :param ~microcontroller.Pin rts: the pin for rts, or ``None`` if rts not in use. +//| :param ~microcontroller.Pin cts: the pin for cts, or ``None`` if cts not in use. +//| :param ~microcontroller.Pin rs485_dir: the output pin for rs485 direction setting, or ``None`` if rs485 not in use. +//| :param bool rs485_invert: rs485_dir pin active high when set. Active low otherwise. +//| :param int baudrate: the transmit and receive speed. +//| :param int bits: the number of bits per byte, 7, 8 or 9. +//| :param Parity parity: the parity used for error checking. +//| :param int stop: the number of stop bits, 1 or 2. +//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters when reading. Raises ``ValueError`` if timeout >100 seconds. +//| :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.) +//| +//| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds. +//| The new upper limit on ``timeout`` is meant to catch mistaken use of milliseconds.""" +//| ... //| typedef struct { mp_obj_base_t base; @@ -89,8 +87,8 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size, ARG_rts, ARG_cts, ARG_rs485_dir,ARG_rs485_invert}; static const mp_arg_t allowed_args[] = { - { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_tx, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_rx, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 9600} }, { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, { MP_QSTR_parity, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, @@ -105,24 +103,23 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - assert_pin(args[ARG_rx].u_obj, true); - const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(args[ARG_rx].u_obj); - assert_pin_free(rx); + const mcu_pin_obj_t* rx = validate_obj_is_free_pin_or_none(args[ARG_rx].u_obj); + const mcu_pin_obj_t* tx = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj); - assert_pin(args[ARG_tx].u_obj, true); - const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(args[ARG_tx].u_obj); - assert_pin_free(tx); + if ( (tx == NULL) && (rx == NULL) ) { + mp_raise_ValueError(translate("tx and rx cannot both be None")); + } uint8_t bits = args[ARG_bits].u_int; if (bits < 7 || bits > 9) { mp_raise_ValueError(translate("bits must be 7, 8 or 9")); } - uart_parity_t parity = PARITY_NONE; + busio_uart_parity_t parity = BUSIO_UART_PARITY_NONE; if (args[ARG_parity].u_obj == &busio_uart_parity_even_obj) { - parity = PARITY_EVEN; + parity = BUSIO_UART_PARITY_EVEN; } else if (args[ARG_parity].u_obj == &busio_uart_parity_odd_obj) { - parity = PARITY_ODD; + parity = BUSIO_UART_PARITY_ODD; } uint8_t stop = args[ARG_stop].u_int; @@ -133,22 +130,21 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); validate_timeout(timeout); - const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(args[ARG_rts].u_obj); - - const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj); + const mcu_pin_obj_t* rts = validate_obj_is_free_pin_or_none(args[ARG_rts].u_obj); + const mcu_pin_obj_t* cts = validate_obj_is_free_pin_or_none(args[ARG_cts].u_obj); + const mcu_pin_obj_t* rs485_dir = validate_obj_is_free_pin_or_none(args[ARG_rs485_dir].u_obj); - const mcu_pin_obj_t* rs485_dir = args[ARG_rs485_dir].u_obj; - bool rs485_invert = args[ARG_rs485_invert].u_bool; + const bool rs485_invert = args[ARG_rs485_invert].u_bool; common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert, args[ARG_baudrate].u_int, bits, parity, stop, timeout, - args[ARG_receiver_buffer_size].u_int); + args[ARG_receiver_buffer_size].u_int, NULL, false); return (mp_obj_t)self; } -//| .. method:: deinit() -//| -//| Deinitialises the UART and releases any hardware resources for reuse. +//| def deinit(self, ) -> Any: +//| """Deinitialises the UART and releases any hardware resources for reuse.""" +//| ... //| STATIC mp_obj_t busio_uart_obj_deinit(mp_obj_t self_in) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -163,16 +159,16 @@ STATIC void check_for_deinit(busio_uart_obj_t *self) { } } -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. +//| def __enter__(self, ) -> Any: +//| """No-op used by Context Managers.""" +//| ... //| // Provided by context manager helper. -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. See -//| :ref:`lifetime-and-contextmanagers` for more info. +//| def __exit__(self, ) -> Any: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... //| STATIC mp_obj_t busio_uart_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; @@ -183,46 +179,49 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ // These are standard stream methods. Code is in py/stream.c. // -//| .. method:: read(nbytes=None) -//| -//| Read characters. If ``nbytes`` is specified then read at most that many -//| bytes. Otherwise, read everything that arrives until the connection -//| times out. Providing the number of bytes expected is highly recommended -//| because it will be faster. +//| def read(self, nbytes: Any = None) -> Any: +//| """Read characters. If ``nbytes`` is specified then read at most that many +//| bytes. Otherwise, read everything that arrives until the connection +//| times out. Providing the number of bytes expected is highly recommended +//| because it will be faster. //| -//| :return: Data read -//| :rtype: bytes or None +//| :return: Data read +//| :rtype: bytes or None""" +//| ... //| -//| .. method:: readinto(buf) -//| -//| Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. -//| -//| :return: number of bytes read and stored into ``buf`` -//| :rtype: int or None (on a non-blocking error) -//| -//| *New in CircuitPython 4.0:* No length parameter is permitted. + +//| def readinto(self, buf: Any) -> Any: +//| """Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. //| -//| .. method:: readline() +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: int or None (on a non-blocking error) //| -//| Read a line, ending in a newline character, or -//| return None if a timeout occurs sooner, or -//| return everything readable if no newline is found and timeout=0 +//| *New in CircuitPython 4.0:* No length parameter is permitted.""" +//| ... //| -//| :return: the line read -//| :rtype: str or None +//| def readline(self, ) -> Any: +//| """Read a line, ending in a newline character, or +//| return None if a timeout occurs sooner, or +//| return everything readable if no newline is found and timeout=0 //| -//| .. method:: write(buf) +//| :return: the line read +//| :rtype: bytes or None""" +//| ... //| -//| Write the buffer of bytes to the bus. + +//| def write(self, buf: Any) -> Any: +//| """Write the buffer of bytes to the bus. //| -//| *New in CircuitPython 4.0:* ``buf`` must be bytes, not a string. +//| *New in CircuitPython 4.0:* ``buf`` must be bytes, not a string. //| -//| :return: the number of bytes written -//| :rtype: int or None +//| :return: the number of bytes written +//| :rtype: int or None""" +//| ... //| // These three methods are used by the shared stream methods. STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + STREAM_DEBUG("busio_uart_read stream %d\n", size); busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); byte *buf = buf_in; @@ -263,9 +262,8 @@ STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t return ret; } -//| .. attribute:: baudrate -//| -//| The current baudrate. +//| baudrate: Any = ... +//| """The current baudrate.""" //| STATIC mp_obj_t busio_uart_obj_get_baudrate(mp_obj_t self_in) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -290,9 +288,8 @@ 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 +//| in_waiting: Any = ... +//| """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); @@ -308,9 +305,8 @@ const mp_obj_property_t busio_uart_in_waiting_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| .. attribute:: timeout -//| -//| The current timeout, in seconds (float). +//| timeout: Any = ... +//| """The current timeout, in seconds (float).""" //| STATIC mp_obj_t busio_uart_obj_get_timeout(mp_obj_t self_in) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -337,9 +333,8 @@ const mp_obj_property_t busio_uart_timeout_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| .. method:: reset_input_buffer() -//| -//| Discard any unread characters in the input buffer. +//| def reset_input_buffer(self, ) -> Any: ... +//| """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); @@ -349,17 +344,14 @@ STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { } 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. -//| -//| .. data:: ODD -//| -//| Total number of ones should be odd. +//| class Parity: +//| """Enum-like class to define the parity used to verify correct data transfer.""" //| -//| .. data:: EVEN +//| ODD: Any = ... +//| """Total number of ones should be odd.""" //| -//| Total number of ones should be even. +//| EVEN: Any = ... +//| """Total number of ones should be even.""" //| const mp_obj_type_t busio_uart_parity_type; |
