On Sun, 24 Mar 2024 at 16:57, Arnaud Minier <arnaud.min...@telecom-paris.fr> wrote: > > Add a function to change the settings of the > serial connection. > > Signed-off-by: Arnaud Minier <arnaud.min...@telecom-paris.fr> > Signed-off-by: Inès Varhol <ines.var...@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.mayd...@linaro.org> thanks -- PMM