8 ms·
How to flash an LED: writing ARM assembly for an STM32 microcontroller
- amelius 6y agoAnybody got USB communication (CDC class) working on this platform without the proprietary libs?
- dmitrygr 6y agono, i spent months on this, and the answer is no They use IP from synopsis, but <rumor>synopsis refuses to allow their docs to be published so every manufacturer has to read them and regurgitate them into their own docs in their own words</rumor>. In any case official STM docs are incomplete. See their driver source - it accesses undocumented registers and sets undocumented bits in documented regs. Without them the usb core will not start or run. Your options are to carefully rewrite STM's libs (which are based on real synopsis docs and DO work) or use them as is. Both solutions IMHO leave you subject to STM's EULA and such this is the #1 issue in stm32 a close #2 is the their so-smart-it-is-useless i2c controller. I know of no project that uses it. Everyone bitbangs i2c master on stm32. The hardware unit is very easy to wedge to a point where only a power cycle unwedges it.
- kevin_thibedeau 6y agoIt's not a rumor. You have to be a Synopsys licensee to see the docs on their IP cores.
- duskwuff 6y agoCan you point to where the undocumented registers are used in the source? I don't see anything obvious that fits that definition in: https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Middlewares/ST/STM32_USB_Device_Library https://github.com/STMicroelectronics/STM32CubeF4/tree/maste... (I've chosen the version for STM32F4 arbitrarily; if there's something similar in one of their other USB support libraries, feel free to point to that instead.)
- dmitrygr 6y agoa few bits used here are not in the docs: https://github.com/STMicroelectronics/STM32CubeF4/blob/master/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c https://github.com/STMicroelectronics/STM32CubeF4/blob/maste...
- duskwuff 6y agoThat's a 2000-line file. What part of it are you referring to?
- HeyLaughingBoy 6y agoMaybe I don't understand the question. Aren't the STM32 CDC libraries redistributable?
- duskwuff 6y agoThe STM32 USB libraries are provided under the oddly named "Ultimate Liberty License" [1], which is actually incredibly restrictive -- it requires the code to only be used on ST hardware, and prohibits it from being used "in any manner that would subject this software to any Open Source Terms". [1]: http://www.st.com/SLA0044 http://www.st.com/SLA0044
- rabryan 6y agoAvoid ST at all costs in my experience. Their documentation is terrible. They never acknowledge hardware errata even after clear evidence of it. They’re not a company with a solid engineering culture imo
- detaro 6y agoWhich MCU makers do you prefer?
- rabryan 6y agoAtmel (now under Microchip). They have great documentation and software libraries. And they actually acknowledge hardware errata in the documentation.
- reportingsjr 6y agoI used a SAMD21 for my latest project and I was definitely impressed with it versus STM32s. I will say that STM has definitely released better tools that make it much easier to get designs up and running (STM32Cube specifically).
- userbinator 6y agoAnd they actually acknowledge hardware errata in the documentation. More so for Microchip than Atmel --- it's pretty common to find on some of their newer and more complex parts a ton of errata, among which there are some extremely "WTF!?" ones like "feature X does not work at all".
- rabryan 6y agoYeah I love those. They highlight features xyz on first page of datasheet. Then on the last few pages its like btw features xyz dont work on rev A-F. And your supplier doesnt know what revs they have...
- __init 6y agoI'm really surprised to hear that. ST has always been one of my favorite manufacturers. I find their datasheets to be clear and well laid out, though I will note that I'm usually more interested in the hardware side than the software side. Their chips and boards are also high quality and convenient, e.g. GPIOs are often five-volt tolerant, Nucleo boards come with well-made breakout headers and several peripherals (at seemingly impossibly low cost), chips have wide supply voltages, etc. I can't say I know anything about their errata (I've never run into any), but even if the situation is as bad as you say, that's quite a harsh condemnation, especially considering how widely-used and successful they are in industry. Do you have other complaints?
- _noise_ 6y agoI don't know what issues you are having with STM32 I2C, but I have done dozens of STM32 designs and have never had an issue and needed to bitbang it.
- dmitrygr 6y agoSend an address only packet (smbus uses these) Just try. Now do it to an address that doesn't ack. Enjoy your wedged i2c state machine.
- thebruce87m 6y agoI’ve recently used the “HAL_I2C_IsDeviceReady” function to scan the whole address range to find devices on the bus with no issues. I’m not near my PC to double check but I’m pretty sure that does what you’re talking about and seems to work ok for me - unless you’re suggesting it’s intermittent?
- lochsh 6y agoI think it's worth noting that there are multiple I2C peripherals by ST -- one for STM32F1, F4, and L1; and a different one used for STM32F0, F3, F7, L0, and L4.
- lochsh 6y agoI don't have experience with this, but from talking to people who do, there are indeed open source implementations. They say the documentation is a bit confusing, but it does describe everything. This Rust library is an abstract USB library that can implement CDC serial https://docs.rs/usb-device/0.2.5/usb_device/ https://docs.rs/usb-device/0.2.5/usb_device/, and this library connects it to the STM32 USB peripheral https://github.com/stm32-rs/stm32-usbd https://github.com/stm32-rs/stm32-usbd Examples here: https://github.com/stm32-rs/stm32-usbd-examples https://github.com/stm32-rs/stm32-usbd-examples
- dmitrygr 6y agothose open source libs use undocumented regs documented and thus are based on STM lib. License in question thus
- userbinator 6y agoThat's what "clean room reverse engineering" is for. If you document what the code does, then code written based only on those docs wouldn't need to be under the same license.
- nine_k 6y agoIs clean-room reverse engineering even viable? That is, would anyone agree that an independent discovery of what bit does what is even possible, and this is not lifted from known drivers?
- duskwuff 6y agoClean-room reverse engineering doesn't require that. If someone were to read the existing drivers and write documentation explaining how the hardware appears to work, that documentation would be unencumbered, and a freely licensed driver could be written based on that documentation. The only methodology that would be questionable would be a developer writing a new driver while referring directly to the vendor driver. To put it another way -- the IP protections on the current library are a matter of copyright law, and the protections are on the code itself. The facts of which bits do what -- which are embodied in that code -- are not protected (or protectable!), and can be reused freely.
- twarge 6y agoChibiOS' CDC works great. Don't know about licensing, but it's fine for non-commercial use.
- markrages 6y agoBlack magic probe has it (two of them!) working with just libopencm3.
- dmitrygr 6y ago@author: 1 @ Set BR8 field in GPIOA_BSRR, to clear GPIOA8 2 movw r1, #0x0000 3 movt r1, #0x0100 you can just use a mov to get that value. Any 8-bit value shifted left any number of bits is synthesizable using one MOV
- lochsh 6y agoThis is true! If I was writing something to be optimal speed- and size-wise, I'd do that. I think I just liked the consistency with the other parts of the code where using both was necessary :)
- lochsh 6y agoOh actually I was being sleepy and hadn't understood what you'd said! I hadn't realised you could do that actually, neat, thanks! So you could do `mov r1, #0x01000000` right? nice.
- MuffinFlavored 6y agoIs there a better way to sleep/delay other than what basically seems like 100% CPU usage in a subtraction loop?
- dmitrygr 6y agoif you have an OS, yes
- lochsh 6y agoYou don't need an OS to do more advanced or efficient sleeping. You could have one of the timer peripherals generate an interrupt on a regular basis, and then put the chip in a lower power sleep mode in between interrupts.
- saagarjha 6y agoIsn't that what an OS would do, essentially?
- lochsh 6y agoYes, probably! But you can do it yourself without one. Here is an example in C using libopencm3, that uses timers to trigger an interrupt used to flash LEDs https://github.com/libopencm3/libopencm3-examples/tree/master/examples/stm32/f4/stm32f4-discovery/timer https://github.com/libopencm3/libopencm3-examples/tree/maste...
- bloopernova 6y agoThis was a really interesting article, and I learned a lot. I'm very much lacking in chip/assembly level knowledge, and this helped me to understand a little bit more. Thank you, Lochsh, for writing it!
- lochsh 6y agoThis is lovely to hear, I'm so glad it was helpful!
- Optimal_Persona 6y agoNot too familiar with the content of your post, but...I love your site design - great use of space, color & serif fonts!
- lochsh 6y agoI love getting compliments on my site design, thanks very much.
- geokon 6y agoI did something similar with CMake and a lot of the details are incredibly challenging to piece together. Everyone just blindly copies existing linker/startup scripts. Very low level articles like this are rare and invaluable I spent a month and got things working with a modern toolchain C/CMake/GCC/OpenOCD but gave up on further work bc I couldn't nail down a lot of details. micro programming outside arduino is painful and backward. it's stuck in the 90s https://geokon-gh.github.io/bluepill/ https://geokon-gh.github.io/bluepill/
- deleted 6y ago[deleted]
- digitaltom 6y agoFantastic article, thanks for taking the time to write it up! I'm trying to learn about embedded systems at the moment and it feela like a super steep learning curve, really appreciate your post breaking everything down. A little typo I think I spotted: ' So, to turn on our LED we want to set the BR8 field, and to turn it off, we want to set the BS8 field.' Should this be: ' So, to turn on our LED we want to clear the BR8 field, and to turn it off, we want to set the BS8 field. '
- lochsh 6y agoThank you for the compliment ^_^ I'm glad you found the post helpful. This isn't a typo, actually. If you look at the documentation of the BSRR register (which is screenshotted in the blog post), it says of BRy: > These bits are write-only [...] [Setting to 1] Resets the corresponding ODRx bit So setting BR8 in the BSRR clears the ORD8 bit in the output data register. Because our LED is active low, this turns the LED on. The indirection can make this a little confusing, I hope this cleans it up!
- digitaltom 6y agoAhh I see now, thank you for teaching me. My mistake! Do you happen to know of any great learning resources, basically more posts like you've written that go into lots of details and explain why things are done? Thanks again!
- lochsh 6y agoI'm not sure I do have suggestions for such resources sadly :( If anyone has any please drop them here!
- unbalancedevh 6y agoI have years of experience in asm programming with PIC processors, and my job is embedded software development. I got an STM32 development board a couple years ago to get my feet wet in ARM embedded development. I got completely bogged-down in setting up the development environment. It took me forever to get a blinking LED, and I spent an ungodly amount of time unsuccessfully trying to figure out how to change the rate based on a potentiometer input. It was a very frustrating experience, but articles like this make me want to dive in and try again!
- thebruce87m 6y agoDo you mean in assembly? If you just mean C, then if you’re already in embedded then I’d say a few years ago it was easy. These days it’s super easy - tools like STM32CubeMX will allow you to get even custom hardware up and running in no time. It will even spit out multiple project types - everything from ARM Keil/MDK/uVision to just a simple makefile.
- jbott 6y agoI disagree that GUI tools like STM32CubeMX are useful. They end up being a crutch that end up adding increasingly complex wizard driven autogeneration, rather than just exposing the configuration in easy to consume ways. Sure, you can get something running fast, but it’s incredibly difficult to move from “blink a led via this template project” to “build a useful project integrating multiple peripherals”. I think there’s some actually interesting work being done with standardization like SVD files, but too many vendors treat them like second class citizens compared to their bulky code gen solutions.
- thebruce87m 6y agoI think it’s decent - configuring a clock tree and initialising the peripherals by hand might be a good way to learn the chip but in terms of rapid prototyping I’ll take the GUI driven leg up any day.