Rico <b...@cryptoguru.org> wrote:
> Hi List.
> 
> I started developing for the STM32F103C8T6 based on the
> "Beginning STM32" book
> https://www.apress.com/gp/book/9781484236239 Using the regular
> "blue pill", as well as the RobotDyn "black pill" as hadware
> basis and all was well.

I'd personally be wary of a book whos code repo has had ~zero
changes, but I've not looked at this book itself. There was an
earlier book that I didn't think much of, but hopefully this one
is better :)

I'd also like to make clear up front that "regular blue pill" is
a horrible name, as these are made by various companies, with
various parts, and various hardware errors. It's "cheap" but only
if you don't value your time. (nor the time of anyone else
helping you) You can get Nucleo 64 boards with reputable hardware
for very little more, and if you need the form factor, Nucleo32
boards are available as well. You'll get actual documentation,
schematics and reliable assembly.

> 
> Then I got the idea to carefully step up my game by using a
> STM32F303CCT6. Hardware migration promised (and proved) to be
> very seamless, using also a F303 "black pill" with even pin
> compatible layout and the only difference there being basically
> BOOT1/PB2 - see:
> 
> https://www.st.com/resource/en/application_note/dm00073522-migrating-from-stm32f1-series-to-stm32f3-series-microcontrollers-stmicroelectronics.pdf


Please do note page 11 in that document, the number of
peripherals that say "partial compatibility" or even "new
peripheral"

> 
> I thought I could start writing somewhat device independent
> code. Well
> ... code that should run on both the STM32F103 and STM32F303.
> However, I'm hitting quite a few walls with libopencm3 there.
> It seems there are particular inconsistencies for libopencm3
> for these two families where I had actually hoped they would be
> "almost the same".
> 
> I still haven't the amount of insight I'd like to have in the
> libopencm3 code base, but to my defense I have to say it
> doesn't make it easy.
> 
> https://github.com/libopencm3/libopencm3/commit/ebb058825f356474aa5cefa3b3e71b5f18cc670c
> ("[STM32F3] Removed all specific F3 stuff out of common
> files.")
> 
> And there you see the code being moved to e.g.
> ...common_f0124.h 

I'm impressed? that you picked out an 8 year old commit, but
you've missed all it's context. That was part of work designed to
_increase_ the portability of code, to handle the two different
SPI peripherals. The "f3" code is actually "SPI peripheral
version 2" code and eventually landed into
https://github.com/libopencm3/libopencm3/blob/master/lib/stm32/common/spi_common_v2.c
but anyway...

> So why exactly is "3" omitted from the common
> stuff, when it is supposed to be THE migration path for F1
> devices? 
> Maybe they are so similar I could simply continue use
> the F1 files? Nope
> - that messes up way more one is willing to fix.
> 
> Why are there such inconsistencies even in the register naming?
> 
> e.g.
> 
> F1/NVIC
> 
> #define NVIC_USART1_IRQ 37
> #define NVIC_USART2_IRQ 38
> #define NVIC_USART3_IRQ 39


We chose to use the naming as provided in the reference manuals.
Unfortunately these are not always consistent. ST's CMSIS packs
simply _ignore_ this, and do provide "compatible" headers...

f1:
USART1_IRQn = 37, /*!< USART1 global Interrupt */ f3: USART1_IRQn
= 37, /*!< USART1 global Interrupt & EXTI Line25 Interrupt
(USART1 wakeup) */ (From
https://github.com/STMicroelectronics/STM32CubeF1/blob/master/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
and
https://github.com/STMicroelectronics/STM32CubeF3/blob/master/Drivers/CMSIS/Device/ST/STM32F3xx/Include/stm32f303xc.h)


> 
> then you try to compile your code for F3 and after this gets
> thrown at you
> 
> 
> src/uartlib.c:42:24: error: 'NVIC_USART1_IRQ' undeclared here
> (not in a function); did you mean 'NVIC_USB_HP_IRQ'?
>     42 |  { USART1, RCC_USART1, NVIC_USART1_IRQ, uart1_getc, uart1_putc 
> },
>        |                        ^~~~~~~~~~~~~~~
>        |                        NVIC_USB_HP_IRQ
> src/uartlib.c:43:24: error: 'NVIC_USART2_IRQ' undeclared here
> (not in a function); did you mean 'NVIC_SPI2_IRQ'?
>     43 |  { USART2, RCC_USART2, NVIC_USART2_IRQ, uart2_getc, uart2_putc 
> },
>        |                        ^~~~~~~~~~~~~~~
>        |                        NVIC_SPI2_IRQ
> src/uartlib.c:44:24: error: 'NVIC_USART3_IRQ' undeclared here
> (not in a function); did you mean 'NVIC_USB_HP_IRQ'?
>     44 |  { USART3, RCC_USART3, NVIC_USART3_IRQ, uart3_getc, uart3_putc }
>        |                        ^~~~~~~~~~~~~~~
> 
> 
> you find out that for F3 it is (observe the "did you mean")
> 
> #define NVIC_USART1_EXTI25_IRQ 37
> #define NVIC_USART2_EXTI26_IRQ 38
> #define NVIC_USART3_EXTI28_IRQ 39
> 
> :-P Uh.
> 
> So - what am I doing wrong in using libopencm3 or does it
> really need some streamlining between F1 and F3 family?

Yes and no. libopencm3 isn't, wasn't, and doesn't really plan on
offering a single HAL. It certainly does try to use the same APIs
where reasonable and possible, and work does get done unifying
things where obvious pain points exist. Other places are simply
not reasonable or feasible. It's extremely tedious work,
reviewing cross family datasheets and reference manuals to clean
up unified code without omitting features added. Especially
within the STM32 targets, we try and use the same APIs as much as
possible. (Do note that there are other targets than STM32 in the
project)

In the specific case of F3, the code style of the original
submission proved rather awkward, with a lot more copying and
editing and less adherence to existing styles than would have
been desirable. It was brought in before most of the ideas of
"peripheral vN" existed, as there were only a couple of ST parts
available, and they were all different. This peripheral
versioning became much more obvious and intuitive later, as more
parts came out, but not all code has been cleaned or de-duped.

In general, within the STM32 environment, these are the places
where you _will_ need to make target specific code:

## clock setup
Most targets use a clock structure, but even the clock structure
will be different, as there are many different clock trees. F1
uses a slew of copy/pasted static routines, and should eventually
be replaced with similar structure routines for consistency, but
it's the "original" so it stays for now.

## GPIO setup
really, this is just "F1" style, vs "every one else" style. The
peripherals are completely different, and it's definitely the
biggest pain point, as it's something you hit so _easily_. On the
bright side, it's also a very simple peripheral, so it's normally
straightforward to fix. Making a layer above this might be
viable, but it's only for the pin setup, not the pin operations,
so it's normally just been put in people's target specific code
anyway, and if anything, has driven people to "do the right
thing" a little earlier in their process than they might have
done otherwise.... I don't dispute that this isn't a sharp edge
of course :)

## IRQs
ST does a _pretty_ good job of these, but they do change names.
We chose to stick quite hard to the names of the vectors in the
reference manual. [1] For instance, in your specific case:

F1 RM extract: https://bin.jvnv.net/file/UMxdb.png
F3 RM extract: https://bin.jvnv.net/file/ciFWw.png

To ease porting from CMSIS sw, it may have been easier to use the CMSIS names, 
but also note that when this project was started, the CMSIS headers weren't 
licensed in a way that allowed free re-use.  

Beyond these portions, you mostly only need to consider the
peripheral version you are targetting. Basic stuff should be the
same. ST's "Migrating from X to Y" docs are pretty good at
explaining the differences.

Hope this helps give you some context at least, though it does
nothing to make your code compile I'm afraid :)

Sincerely,
Karl Palsson

[1] I'm cheating a little bit, but, it's relevant. The F1 extract
is from RM0008 rev 15, but the F3 extract is from RM0316 rev 1.
(Which is when the f3 vector names were written) In RM0316 rev 5,
(or somewhere in between) the vector names have been changed
again. Providing aliases would be a "good thing" here, but the
current code generation doesn't support that. I've filed a ticket
to track this if anyone's bored and wants to work on it:
https://github.com/libopencm3/libopencm3/issues/1342

Attachment: OpenPGP-digital-signature.html
Description: OpenPGP Digital Signature

_______________________________________________
libopencm3-devel mailing list
libopencm3-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libopencm3-devel

Reply via email to