Cheers to my fellow engineers !
So yeah, since it’s been a while since my last post, you’re in for quite a bit if stuff that I have to share. But anyway, as soon as you saw my name at the top of this post, you knew it was going to be like that. So gird your loins, because about the only thing I haven’t done in the past week and a half or so is posting on rose.eu.org . Don’t worry however, I’ll sort out the irrelevant stuff.
For starters, I’ll have you notice that spring may be – *may* be – finally there. Oh wait, the fact that the sun is shining in the outside world is irrelevant. Let’ skip that.
Last week was the BDE campaign. By luck, it was also an FH week, so I didn’t have class (since I’m in the theater club, and by the way, we rehearsed all week-end, which explains why I wasn’t around much). So last week I could work during the day and party during the night, for my birthday or any other reason (or pretext, rather) – quite a rhythm I held up. We finished our first development sprint a week ago. We did not achieve all the tasks we had set out to achieve at the beginning, but we knew that would be hard given their number. Among other things (thinking about booting and loading, thinking about project architecture), I managed to get the buzzer working, and performed tests on our lab board. Our buzzer module has a state machine that continuously reads notes from either somewhere in memory we tell it to play from, or from a buffer in which we can store music (thus allowing music to come from a Bluetooth stream). The volume can also be adjusted.
I discovered along the way the concept and usage of thread mailboxes. For those who care by the way, mailboxes can be really useful. It’s basically a queue of msg_t (which are uint32_t) on which any entity can post (if it has a pointer on the mailbox) and which the thread can checkout and fetch in. The advantage here is that each msg_t can mean a lot of work to be achieved by the thread before it goes to fetch the next message. In that sense you’ve achieved a kind of mutual exclusion : you ensure all the work one message implies has been done before moving on to the next one. Example : a memory in which you move entire chunks, or which you reorganize through complex algorithms. The dedicated thread reads one message after another, and performs such complex movements in “message-atomic” blocks at the end of which the memory is in a coherent state, so that the next message (and associated algorithm) can be applied safely. Later, I happened to check out the “Mutual exclusion” page of the ChibiOS
Last, I worked on the LEDs. For the on/off blue ones (that don’t require a PWM§driven intensity setting) it wasn’t too hard, and I discovered the concept of virtual timers to implement different blinks with different periods on different LEDs.
Beyond that, I worked on the concept of PWM driver and how they are implemented in ChibiOS. I’m really starting to like this OS. But the thing is, it doesn’t have support for PWM on timers beyond 8 on STM32F405, and we need that for our RGB LEDs (so as to display any color we want by setting blue, red, and green intensity). So with Clémentine and on Giovanni’s advice, we took a look inside the ChibiOS machine, and figured out how timers are defined and referenced, and how PWM drivers are initialized and started. Then we took a long look at the reference manual and at all the timer config registers (there are MANY of them). And we discovered how beautiful it was.
The thing is that on STM32F405 there are 14 timers. Yes, 14 of them. Some (2->5) are of general purpose, some are advanced (1 and 8, can do lots of things), some are just good timers. But ChibiOS only has PWMDrivers for timers from 1 to 8 – because the other ones (beyond 9) share the same interrupt handlers, and that’s specific to STM32F405, and Giovanni’s philosophy about ChibiOS is to keep things general and portable. So he told me to create my own PWM drivers, and said he just might add support for general interrupt-less PWM driving. Nonetheless, we set out to implement our own drivers for timers 12, 13 and 14 (the ones we nee).
And remember, it’s beautiful ! So even though all the timers are different, in the sense that some have feature A but not B, and some have B but not A, they all have the same registers, mapped in the same order starting at the timer’s base address in memory, and within the registers, the bits are mapped out the same way ! Say now that timer N doesn’t have feature A, then the corresponding registers or bits (feature A config register for instance, or the feature A enable bit in the main config register) are just “reserved”. So it’s really easy to use existing code for another timer – you don’t call the functions you don’t want to use and don’t write in the corresponding bits and registers, and the remaining ones (feature B) work just the same, with corresponding registers and bits at exactly the same places ! All you have to do is change the timer base address, and only use offsets from there on. Whatever timer it is you’re using, at offset 0 is the config register 1, and its bit 0 is “timer enable”. And if in your initialization method there are writes or reads to registers or bits that timer N doesn’t have (because it doesn’t have feature A), you’re fine, you’re just talking to “reserved” bits and registers, and that doesn’t matter. That’s how beautiful it is.
Now we still need to test all this, and there are still some weird OpenOCD behaviors that we don’t understand … We’ve fixed a few things already but that doesn’t appear to be enough. The thing is, and that’s a very general remark here, is that we’re learning and applying at the same time. It’s great, but sometimes it gets you stuck when there’s something you don’t know yet. We’re basically putting down the rails AND moving the locomotive forward, like they used to in the Far West in America – and sometimes those two processes don’t work well together, and one hinders the other. Especially when you’re trying to go too fast with the locomotive (the work application) and the rails (the learning and understanding part) are not properly setup yet. You just risk a wreck. It’s an intense experience, and I’ve learned this much stuff in so little time. I’m like a sponge – I try to absorb it all (risking to be full and letting some slip by). Any way
The last thing I wanted to share that was implicit in all the previous stuff is that our PCBs have arrived and have been valiantly and efficiently soldered by Loïk, Quentin, and of course Mr. Polti ! Many thanks to them ! It’s great to see the fruit of our design work come to reality – and function. I would’ve liked to be a part of that soldering step of the process, but we have to try to keep the work parallelized. Speaking of which, moving on to LEDs and timers tests !