qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 4/6] hw/char/stm32l4x5_usart: Add options for serial param


From: Peter Maydell
Subject: Re: [PATCH v2 4/6] hw/char/stm32l4x5_usart: Add options for serial parameters setting
Date: Thu, 28 Mar 2024 16:03:22 +0000

On Sun, 24 Mar 2024 at 16:57, Arnaud Minier
<arnaud.minier@telecom-paris.fr> wrote:
>
> Add a function to change the settings of the
> serial connection.
>
> Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
> Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
> ---
>  hw/char/stm32l4x5_usart.c | 98 +++++++++++++++++++++++++++++++++++++++
>  hw/char/trace-events      |  1 +
>  2 files changed, 99 insertions(+)
>
> diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
> index ec8c2f6e63..b4d11dd826 100644
> --- a/hw/char/stm32l4x5_usart.c
> +++ b/hw/char/stm32l4x5_usart.c
> @@ -267,6 +267,92 @@ static void 
> usart_cancel_transmit(Stm32l4x5UsartBaseState *s)
>      }
>  }
>
> +static void stm32l4x5_update_params(Stm32l4x5UsartBaseState *s)
> +{
> +    int speed, parity, data_bits, stop_bits;
> +    uint32_t value, usart_div;
> +    QEMUSerialSetParams ssp;
> +
> +    /* Select the parity type */
> +    if (s->cr1 & R_CR1_PCE_MASK) {
> +        if (s->cr1 & R_CR1_PS_MASK) {
> +            parity = 'O';
> +        } else {
> +            parity = 'E';
> +        }
> +    } else {
> +        parity = 'N';
> +    }
> +
> +    /* Select the number of stop bits */
> +    switch (FIELD_EX32(s->cr2, CR2, STOP)) {
> +    case 0:
> +        stop_bits = 1;
> +        break;
> +    case 2:
> +        stop_bits = 2;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP,
> +            "UNIMPLEMENTED: fractionnal stop bits; CR2[13:12] = %x",

%x without a leading 0x is a bit odd. In this case since
the possible values are 0-3 it doesn't make a difference,
but maybe better to use %u ?

> +            FIELD_EX32(s->cr2, CR2, STOP));
> +        return;
> +    }
> +
> +    /* Select the length of the word */
> +    switch ((FIELD_EX32(s->cr1, CR1, M1) << 1) | FIELD_EX32(s->cr1, CR1, 
> M0)) {
> +    case 0:
> +        data_bits = 8;
> +        break;
> +    case 1:
> +        data_bits = 9;
> +        break;
> +    case 2:
> +        data_bits = 7;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +            "UNDEFINED: invalid word length, CR1.M = 0b11");
> +        return;
> +    }
> +
> +    /* Select the baud rate */
> +    value = FIELD_EX32(s->brr, BRR, BRR);
> +    if (value < 16) {
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +            "UNDEFINED: BRR lesser than 16: %u", value);

"less than"

> +        return;
> +    }
> +
> +    if (FIELD_EX32(s->cr1, CR1, OVER8) == 0) {
> +        /*
> +         * Oversampling by 16
> +         * BRR = USARTDIV
> +         */
> +        usart_div = value;
> +    } else {
> +        /*
> +         * Oversampling by 8
> +         * - BRR[2:0] = USARTDIV[3:0] shifted 1 bit to the right.
> +         * - BRR[3] must be kept cleared.
> +         * - BRR[15:4] = USARTDIV[15:4]
> +         * - The frequency is multiplied by 2
> +         */
> +        usart_div = ((value & 0xFFF0) | ((value & 0x0007) << 1)) / 2;
> +    }
> +
> +    speed = clock_get_hz(s->clk) / usart_div;
> +
> +    ssp.speed     = speed;
> +    ssp.parity    = parity;
> +    ssp.data_bits = data_bits;
> +    ssp.stop_bits = stop_bits;
> +
> +    qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
> +
> +    trace_stm32l4x5_usart_update_params(speed, parity, data_bits, stop_bits);
> +}

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]