This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PPC40x serial_init fix


On Fri, 2 Sep 2005, Gary Thomas wrote:

Fair enough, but we can't just have a hard-wired value for the
base calculation as this differs on how the board is strapped.
That's why my code started with reading the CPC0_CR0 setting.

n.b. for the board/CPU and baud rates I used, no adjustment
of the divisor was necessary.  Feel free to add that code, but
not by including fixed constants which may or may not be correct.

I agree with you. But I thought there must be a reason why it's done that way. While reading the docs a little further, I somewhat found the explanation. (At least I guess so)

18 (baud_clock) * 38400 Baud = 691 200
691 200 * 16 = 11 059 200 (11MHz Clock Rate)
11 059 200 * 18 (clock_divisor) = 199 065 600 ~ 200MHz (CPU Speed)

So that's just an example for a 200MHz CPU and 38400 Baud.
As you can see the 691200 not really fixed, but this value can be
used as base for all PPC405 serial calculations which I will prove:

Now suppose you have 166MHz CPU and want 57600 Baud

clock_divisor = (clk + tmp / 2) / tmp;
tmp = (691200 * 16) = 11 059 200
clock_divisor = (166 000 000 + (11 059 200/2)) / (691200 * 16) = 15.5
which truncates to 15 (actual cpu clock would be at 165 888 000)

tmp = baud * 16 * clock_divisor;
13 824 000 = 57600 Baud * 16 * 15 (clock_divisor)

baud_clock = (clk + tmp / 2) /tmp;
12.5 = ((166 000 000 + (13 824 000/2)) / 13 824 000
so that truncates to 12 for the baud_clock

If you look at the EP manual those values are equal to the proposed ones
(if swapped), but that's barely relevant.

Care for another example?

Now for a 400MHz GP CPU you'd get 36 as clock div which is capped at 32
since we have only 5bits in CR0. And for example 28800 Baud.
Now we get (28800 * 16 * 32) = 14 745 600 and 398 131 200
(400 000 000 + (14 745 600/2)) / 14 745 600 = 27 (27.626)

Nevertheless the equations provide a perfectly sane serial clocking
with the BASE_BAUD value as a starting point for both things. The
addition of (tmp/2) is to ensure that the calculated value is as high
as the desired value.

So if you don't set the ClkDiv you will still have an approriate baud
clock even for 400Mhz and as low as 1200 Baud (assuming unset
clock_divisor == 1) at around 20k. But I think a baud_clock that high
should not be desirable as the highest proposed divisors are just below
1000.

So, what's the conclusion? You are supposed to set the clock_div as it
is always better to initialize something to a know value.
So let's not be to harsh on one hard coded value.

And if you still don't like it. Oh well, I have the simple solution
attached.

Regards,
Markus

Attachment: lite_serial_405ep.patch
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]