lkml.org 
[lkml]   [2015]   [Mar]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH v3 10/15] serial: stm32-usart: Add STM32 USART Driver
Hi Maxime,

On 03/24/2015 01:21 PM, Maxime Coquelin wrote:
> Hi Peter,
>
> 2015-03-19 18:35 GMT+01:00 Maxime Coquelin <mcoquelin.stm32@gmail.com>:
>> 2015-03-19 15:58 GMT+01:00 Peter Hurley <peter@hurleysoftware.com>:
>>> On 03/19/2015 09:55 AM, Maxime Coquelin wrote:
>>>>>>>> +static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
>>>>>>>> + struct ktermios *old)
>>> [...]
>>>>>>>> + usardiv = (port->uartclk * 25) / (baud * 4);
>>>>>>>> + mantissa = (usardiv / 100) << USART_BRR_DIV_M_SHIFT;
>>>>>>>> + fraction = DIV_ROUND_CLOSEST((usardiv % 100) * 16, 100);
>>>>>>>> + if (fraction & ~USART_BRR_DIV_F_MASK) {
>>>>>>>> + fraction = 0;
>>>>>>>> + mantissa += (1 << USART_BRR_DIV_M_SHIFT);
>>>>>>>> + }
>>> [...]
>>>> Really, I would prefer keeping this fractional divider as it is
>>>> implemented today.
>>>
>>> You have to admit that's basically an unintelligible mess;
>>> how would anyone ever be able to refactor and replace that with a
>>> common divider implementation?
>>>
>>> At the very least, please comment on the formula and format.
>>
>> Ok, I will refactor the implementation, and comment it.
>
> The implementation was indeed a mess.
> I found some time to refactor the code, and also added support for 8
> times oversampling (16 by default).
> It will allow to achieve higher speeds, with the side effect of being
> less tolerant to clock deviations.
>
> What do you think about the code below?
>
>
> usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud);
>
> /*
> * The USART supports 16 or 8 times oversampling.
> * By default we prefer 16 times oversampling, so that the receiver
> * has a better tolerance to clock deviations.
> * 8 times oversampling is only used to achieve higher speeds.
> */
> if (usartdiv < 16) {
> oversampling = 8;
> stm32_set_bits(port, USART_CR1, USART_CR1_OVER8);
> } else {
> oversampling = 16;
> stm32_clr_bits(port, USART_CR1, USART_CR1_OVER8);
> }
>
> mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT;
> fraction = usartdiv % oversampling;
> writel_relaxed(mantissa | fraction, port->membase + USART_BRR)

Thanks! Way better :)
Much more obvious this is a fixed-point divisor.

Regards,
Peter Hurley





\
 
 \ /
  Last update: 2015-03-24 19:21    [W:0.050 / U:2.244 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site