Re: STM32F103x port

Nashif, Anas

On 2 Mar 2016, at 10:54, Benjamin Walsh <benjamin.walsh(a)> wrote:

On Tue, Mar 01, 2016 at 10:17:17AM -0800, Dirk Brandewie wrote:

On 02/29/2016 02:26 PM, Kalowsky, Daniel wrote:
-----Original Message-----
First suggestion, create an arch/arm/soc/stm32, and use the Kconfig to
allow selecting of the various flavors of the STM32 chip. This would
be similar to what you've already got with the Kconfig.soc.stm32f103ve
file, merged with the values from your Kconfig.soc. Then keeping the
Kconfig to the pieces generic to all the STM32 portions (i.e. flash
size, base address, etc).

Makes sense. I think we should also add another 'MCU family' level of
hierarchy. We would have then:

<soc specific>
<soc specific>
<soc specific>
I'm not opposed to this.

Ben/Dirk any commentary?
Having thought about it for 10 seconds it seems reasonable :-) To the
greatest extent reasonable please avoid link time binding of SOC specifc
code into the generic stm32 code. We don't want to the next guy to
wonder which init() function is called.
The main issue with this is the fact that stm32 extends all the way from M0 to M7, in total set of 11 series

• STM32F0 Series
• STM32F1 Series
• STM32F2 Series
• STM32F3 Series
• STM32F4 Series
• STM32F7 Series
• STM32L0 Series
• STM32L1 Series
• STM32L4 Series
• STM32T Series
• STM32W Series

where each series can have up to 10 different SoCs in some cases.


If it turns out to painful we can "move the deck chairs around later" (tm)
IMO having a soc specific defconfig would be great too. Right now there are
only arch and board defconfigs. A soc defconfig would save a lot of typing
and if'ing in Kconfigs, what happens to be really error prone by the way.
Depending upon what you see going into such a file, this is a relatively reasonable idea.

Second thing to add, in your use of addresses, please add a comment
where these values were originally sourced from (aka the DataSheet
document to be used for cross-referencing). Specifically looking at
your soc.h.

Third, I like your rcc.h, using the union for structs. In my opinion
this makes things a lot cleaner. This is also has been a bit of a
contention for the project between several of us. :-) Two things on
this. 1) rename val to raw, it keeps it consistent with other
locations where this has been in use. 2) you may also need to add
#define register definitions for these. I've got a bunch already
typed up that I can share with you off-list to save some typing (if
you want it).
Sure, I'd be glad to take a look.

The demo code has been archived in bboozzoo/stm32f103-demo branch.

Once I deem the work somewhat feature complete, I'll clean that up
and push for review. I'd be glad if someone took a look at the code
and shared their opinion on whether the path I took seems reasonable.

I think there might be some room for extending clock control driver
API. The problem comes form the fact that some chips may a more
elaborate clock distribution within the SoC itself. For instance,
inside the STM32F103x chip, there are at least 2 clock domains
driving the peripherals (low speed clock
PCLK1 and high speed PCLK2). When setting up UARTx baud rate one
needs to know the clock rate in order to calculate the timings for the
Also, on this particular chip
USART1 is driven by PCLK2, while the remaining for UARTx are driven
by PLCK1. Finding out the rate of the clock driving particular
peripheral is useful if we want to keep things generic to some extent.

I've added the following call to driver specific part of the API:

void stm32f10x_clock_control_get_subsys_rate(struct device *clock,
clock_control_subsys_t subsys,
uint32_t *rate);

where `subsys` is the regular clock subsystem and the clock rate is
returned in `*rate` field.

Since this might be a more general problem, I think the
functionality can be added to the clock_control API:

typedef void (*clock_control_get_clock)(struct device *dev,
clock_control_subsys_t sys,
uint32_t *rate);

struct clock_control_driver_api {
clock_control_get_clock get_clock;

As for the drivers. The RCC (Reset & Clock Control) driver mostly
delivers the CC part of the name. I have intentionally specified a
low priority (1) in
DEVICE_INIT() call. The RCC has to be initialized early in the
startup process, otherwise no peripherals will work.

RCC subsytem mapping enums have been put in driver specific header.
I did not feel like these belonged to the SoC specific part as the
mappings are shared by the whole family of SoCs.
I need to look more at this, as in my own port for STM32F2xx I've left
the RCC in the SOC section. Not saying that is right, just have left
it there for now.

The pinmux driver contains only the parts essential for getting the
UART to work. Again, this is not part of the board specific code,
neither the SoC specific one, as the driver is shared by a family of
MCUs. I have looked at the pinmux driver for Galileo and I
understand the the API has been shaped having this board in mind.
While the API methods are sufficient, I have only implemented the
*_get() and *_set() calls. The pin config on STM32F10x is a bit
elaborate so I reused the `func` parameter in *_get()/*_set() calls
to pass driver specific function mappings. The function mapping
names are currently shaped after pinconf-generic Linux driver.
Perhaps I'm being too pragmatic here, but I'd like to avoid replication of
STM32Cube's functionality and typing in all possible pin mappings.

I'm 90% sure that the pinmux can probably be renamed to something like
pinmux_stm32, as I believe the functions are the same for the F1xx and
F2xx series of chips. I would strongly encourage you to read some
just recently posted messages on the mailing list for changes that are
coming to the pinmux. It would be best to utilize those early on.

The pinmux you're providing is very SOC specific, which is good.
Are you referring to this discussion?
That would be the very specific discussion. :-)

The UART driver is still using polling, however drive init has been
reworked to use the pinmux and clock_control APIs. The baud rate is
not hardcoded anymore and is calculated based on configuration. The
fixed point arithmetic should be correct for low speeds and close enough
for higher speeds.

The UART is looking like it is coming along nicely. Again I think
this is code that can be re-used on many of the STM32 chips.
Agreed. I've just briefly looked at STM32F4xxxx Reference Manual. The
register map looks the same. Specific registers (CR1, CR3) use a couple of bits
more, but nothing that cannot be handled by #ifdefs. I expect that the lower
families (2xxx, 3xxx) are also very much identical.

Join { to automatically receive all group messages.