Skip to content

stm32: flow= parameter in pyb.UART().init() #1981

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
rolandvs opened this issue Apr 13, 2016 · 6 comments
Closed

stm32: flow= parameter in pyb.UART().init() #1981

rolandvs opened this issue Apr 13, 2016 · 6 comments
Labels
enhancement Feature requests, new feature implementations port-stm32

Comments

@rolandvs
Copy link
Contributor

When initializing an UART with u3 = pyb.UART(3, 57600) the default settings are set to no flow control (flow=0). It would be 'better' when None would be used instead of 0. Furthermore when using u3 at REPL the current initialization is shown, but flow is omitted if 0.

I would like to see flow=None or flow=RTS in all cases. Furthermore any value can be entered setting "stray" bits so it would be 'better' to mask off all bits except for RTS and CTS.

I have changed these in stmhal\uart.c and added to my fork, but it seems to me these could be integrated in the mpy code base.

If I only knew how to git that....

@rolandvs
Copy link
Contributor Author

For consistency the use of flow=None instead of flow=0 is preferred.

This needs a few minor changes in uart.c as documented below. As @dhylands indicated at the forum it is not a habit to include extra error checking on bits so None=0, RTS=256, CTS=512, other values where bit 8 and 9 are not set will indicate flow= whereas some extra masking would force 0.

@ pyb_uart_print

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 = self_in;
    if (!self->is_enabled) {
        mp_printf(print, "UART(%u)", self->uart_id);
    } else {
        mp_int_t bits = (self->uart.Init.WordLength == UART_WORDLENGTH_8B ? 8 : 9);
        if (self->uart.Init.Parity != UART_PARITY_NONE) {
            bits -= 1;
        }
        mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=",
            self->uart_id, self->uart.Init.BaudRate, bits);
        if (self->uart.Init.Parity == UART_PARITY_NONE) {
            mp_print_str(print, "None");
        } else {
            mp_printf(print, "%u", self->uart.Init.Parity == UART_PARITY_EVEN ? 0 : 1);
        }
        mp_printf(print, ", flow=");
        if (self->uart.Init.HwFlowCtl == UART_HWCONTROL_NONE) {
            mp_printf(print, "None"); 
        } else {
            if (self->uart.Init.HwFlowCtl & UART_HWCONTROL_RTS) {
                mp_printf(print, "RTS%s", self->uart.Init.HwFlowCtl & UART_HWCONTROL_CTS ? "|" : "");
            }
            if (self->uart.Init.HwFlowCtl & UART_HWCONTROL_CTS) {
                mp_printf(print, "CTS");
            }
        }
        mp_printf(print, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u)",
            self->uart.Init.StopBits == UART_STOPBITS_1 ? 1 : 2,
            self->timeout, self->timeout_char,
            self->read_buf_len == 0 ? 0 : self->read_buf_len - 1); // -1 to adjust for usable length of buffer
    }
}

@ mp_obj_t pyb_uart_init_helper()

/// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0, flow=None, read_buf_len=64)
///
/// Initialise the UART bus with the given parameters:
///
///   - `baudrate` is the clock rate.
///   - `bits` is the number of bits per byte, 7, 8 or 9.
///   - `parity` is the parity, `None`, 0 (even) or 1 (odd).
///   - `stop` is the number of stop bits, 1 or 2.
///   - `timeout` is the timeout in milliseconds to wait for the first character.
///   - `timeout_char` is the timeout in milliseconds to wait between characters.
///   - `flow` is `None` or `RTS | CTS` where `RTS` == 256, `CTS` == 512**
///   - `read_buf_len` is the character length of the read buffer (0 to disable).
STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
    static const mp_arg_t allowed_args[] = {
        { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 9600} },
        { MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
        { MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = mp_const_none} },
        { MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} },
        { MP_QSTR_flow, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
        { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} },
        { MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
        { MP_QSTR_read_buf_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
    };

    // parse args
    // set the UART configuration values
    // baudrate
    // parity
    // number of bits
    // stop bits

    // flow control
    if (args.flow.u_obj == mp_const_none) {
        init->HwFlowCtl = UART_HWCONTROL_NONE;
    } else {
        init->HwFlowCtl = mp_obj_get_int(args.flow.u_obj);
        init->HwFlowCtl &= (UART_HWCONTROL_RTS | UART_HWCONTROL_CTS);
    }

@rolandvs
Copy link
Contributor Author

@dpgeorge Would you consider including this too so that None can be used instead of 0 and the flow= parameter is also reported?

@peterhinch
Copy link
Contributor

Have you seen #2602? It may be a while before this gets addressed.

@dpgeorge dpgeorge changed the title flow= parameter in pyb.UART().init() stm32: flow= parameter in pyb.UART().init() Oct 24, 2017
@dpgeorge dpgeorge added enhancement Feature requests, new feature implementations port-stm32 labels Oct 24, 2017
@dpgeorge
Copy link
Member

dpgeorge commented Dec 4, 2018

@rolandvs comming back to this issue: I'm happy for it to print the flow parameter when flow control is disabled (this is useful, to know explicitly it's disabled). But what is you reasoning about flow=None being more consistent than flow=0 for no flow control? This parameter is a bitwise integer, so 0 means off.

@rolandvs
Copy link
Contributor Author

rolandvs commented Dec 4, 2018

About None: Learned a few thing since then, I perfectly fine the way it is :-).

dpgeorge added a commit that referenced this issue Dec 4, 2018
Also change the order of printing of flow so it is after stop (so bits,
parity, stop are one after the other), and reduce code size by using
mp_print_str instead of mp_printf where possible.

See issue #1981.
@dpgeorge
Copy link
Member

dpgeorge commented Dec 4, 2018

Ok! So in 9262f54 I made it so that the flow setting is always printed.

@dpgeorge dpgeorge closed this as completed Dec 4, 2018
tannewt added a commit to tannewt/circuitpython that referenced this issue Jul 18, 2019
This fixes the bug that bitmap changes do not cause screen updates
and optimizes the refresh when the bitmap is simply shown on the
screen. If the bitmap is used in tiles, then changing it will
cause all TileGrids using it to do a full refresh.

Fixes micropython#1981
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature requests, new feature implementations port-stm32
Projects
None yet
Development

No branches or pull requests

3 participants