Any chance someone more familiar with the low-level firmware GPIO register / timer stuff might be willing to help me port a particular library over to the STM32 / Core?
I was hoping to use one of the 16x32 panels in a Birthday present. I’m pretty sure I could eventually make a hacky port, but I’d love to try and stay as close to the original library as possible for maximum compatibility / holding onto their performance optimizations. My hope is this might be much easier for someone more familiar, but please feel free to say if it’d be too hard / time consuming!
You’re awesome to be working on it at all, thank you! Her birthday is Sunday the 22nd, but without knowing what she’s getting, she’s okayed some production delays…
@peekay123 I was looking at this but really have so much to do already… if you get stuck and just need someone to bounce questions off of feel free to ping me. The BCM is pretty cool, I’ve never used that before. Hopefully you don’t have to understand all of that code to port the library because some of the comments are not fully descriptive in my opinion. Perhaps the matrix datasheet would clarify some of that though.
@Dave, that’s fantastic and will help a lot in testing!
@BDub, the Arduino code is interesting in the way the author uses the Fast PWM mode to regulate the timing of the interrupt. There is a lot of hand tweaking in the ISR code but the idea is to have consistent plane refresh timing between interrupts. The question I am pondering is whether I need a programmable PWM or simply use a programmable timer (IntervalTimer) to fire off the interrupts.
From what I can see, the Fast PWM timing is set for FCPU/100 or 160KHz or about roughly 6us between interrupts. Because of the blocking nature of the ISR, the actual interrupt rate is much lower. Anyway, all the code except the ISR/PWM/TIMER is ready.
@Dave, I am moving along with the code and I’m about to profile the timing on both the Arduino and the Core to make sure I have it right. For the 16x32 LED matrix, this code uses a 1576 byte buffer so things will be interesting in terms of RAM. Besides the library, what other stuff do you expect to use in your program like Spark.function, etc?
My plan is to have some basic information pulled in infrequently (maybe once a minute or less), either through subscriptions or functions. I’m hoping that the 4k of ram we’ll get with the next firmware release will be plenty for occasionally displaying some text.
@Dave, I finally figured out the hardware timer issues I was having and things look good, well at least on my logic analyzer at least. Believe it or not, the atmega328’s more direct port handling makes it faster than the Core! The Core has no way of writing an entire byte to a port without a lot of hassles so the code has to bit-bang each bit which takes more time. Regardless, the refresh rate will still be 90Hz vs 280Hz for the atmega.
Using the latest master repo (lower RAM), the compile shows plenty of RAM left for the other stuff you want to do. Can’t wait to get the display so I can do some testing!
Oh ya, I forgot to mention that I also added my mfGFX library to give you user-definable fonts!
I’d love to try it out here if you felt like pointing me at some code, I appreciate you trying to go the whole byte writing route, but 90Hz is probably great for what I had in mind.
@BDub, as you said, the port pins ARE all over the place so it makes it difficult to write to a single port. The D1-D7 pins span PortA and B and the data in question is 6bits (5bits to PortA, 1 to PortB). The 5bits to PortA would need an IDR read (to preserve the other port bits) then an ODR write. The PortB bit would just use the standard GIPO bit write. Doing everything in assembler would make it way faster but I am not familiar enough with the STM32 to do that yet.
If it helps, a crazy pinout is totally fine if they’re on the same register (I’m just using jumpers for the moment), but I’m also happy starting with the 80Hz version and upgrading later No rush though!
Depends on what you are doing, but I think probably a while loop... just unroll the tasks first time through if you must before the while(). Keep your counters as small as possible to avoid extra unnecessary math.
I'm still looking for a good resource for this as well, I have a lot of reference material but nothing really all that great to learn from properly.
@Dave, I’ll PM you with a link to the repo. It’s not quite ready for prime time and I still need to clean up the code. I will be updating the SparkIntervalTimer library as well but not until I test everything.
@Dave, just so you know, I am working on an optimized version of the RGB-matrix-library that has a higher refresh rate. The catch will be that the RGB pins going to the display will be dedicated so I can do whole-port writing like the Arduino. What this will mean is a higher refresh rate. My intent is to allow a user to select which version is compiled. I am also looking to see if I can get 3 of these 16x32 panels daisy chained.