midilab / uClock

A tight BPM clock generator for Arduino and PlatformIO using hardware timer interruption. AVR, Teensy, STM32xx, ESP32 and RP2040 support
https://midilab.co/umodular
MIT License
156 stars 20 forks source link

Could uClock be adapted to work on STM32F4? #21

Closed twisted-electrons closed 1 year ago

twisted-electrons commented 1 year ago

Hello, Great library - thanks for making it Do you think it would be easy to adapt to STM32F4? Cheers

midilab commented 1 year ago

Thanks @twisted-electrons .

For now im planning to support only arduino based archs to make it more portable and usable by the community.

I see that arduino supports STM32 series but im not sure if it supports the F4 you have, but in case you have those details and could test it for me i can code a port for STM32XX too.

basicly it needs to init and control a 16bits timer to work, so i found this doc that can be used as start point: https://github.com/stm32duino/Arduino_Core_STM32/wiki/HardwareTimer-library

Please tell me if you are using arduino and if it has support for STM32F4 and then we can try a port.

twisted-electrons commented 1 year ago

Hi @midilab ! Thanks for your reply Yes the STM32F405 is supported by arduino, the MCU I'm using is "Generic F405RGTx" I'm able to compile the HardwareTimer examples you linked.

I've been using this library with success too https://github.com/khoih-prog/STM32_TimerInterrupt Cheers!

analogmonster commented 1 year ago

The nice thing about stm32 chips is a lot of it is portable between M0, M3, M4 etc. there is the occasional outlier but stm32 is designed so that you can easily move between chips. They advertise developing on a powerful chip then moving it to a chip that eg has less RAM once you know what your code requires. I have a few different development boards in stock so I would be happy to beta test a few if you get anywhere with this

midilab commented 1 year ago

great to hear that we can test over the smt32 spectrum @analogmonster , since i dont have any around.

so i've code a port, it compiles but no idea if it will works, its based on the documentation of Hal library(wich has support for almost all stm32 chips around for timer and general hardware interface), wich is included on STM32duino core.

i also finally create a folder for platform specific implemementation to make it easy for new ports to come, so no messy uClock class with dependent architecture anymore, you only have to implement two calls, one for init the timer and other to set the frequency.

so you can checkout the new branch wich was created for this port: stm32xx-support

i've create a basic example for UART midi clock and LED signaling for time, maybe you need to configure for the onboard LED of your testing board.

let me know how the tests will move, so i can code any bug or malfunction back to the repo before release a new version.

twisted-electrons commented 1 year ago

@midilab @analogmonster Hi, this is great, thanks I'll test and report back as soon as possible!

analogmonster commented 1 year ago

I've just gone through my development board collection, I have a Nucleo F401RE, F072RB and F429ZI currently not being used which is 2 different M4 and an M0 I can test. Hope to have time this weekend

analogmonster commented 1 year ago

It is late here, I couldn't sleep so I have quickly tested on 2 boards. Nucleo F429ZI, I know the user LED is on pin PB0, set it in the code and no LED output (verified I have the correct pin for the LED using another arduino program as well as referring to STM32cubeMX). Just to confirm I am not missing anything, your example STM32uartmastermidiclock should have blinking LED at 126BPM with MIDI start, stop and clock messages over UART out pin (I haven't got my scope or a MIDI device out to confirm anything with UART but I will try to do this in the morning). I have not hooked up anything to the UART but I don't see why it would know or care.

There was a error when it comes to the F072, see end of post. It seems things aren't quite as portable as I had previously thought but this application note https://www.st.com/resource/en/application_note/an4013-stm32-crossseries-timer-overview-stmicroelectronics.pdf shows TIM3 isn't available on the F072 but TIM4 should be fine so I don't know why this compile error is happening.

In file included from c:\Users\analo\OneDrive\ARDUINO\libraries\uClock\src\uClock.cpp:58: c:\Users\analo\OneDrive\ARDUINO\libraries\uClock\src\platforms/stm32.h: In function 'void timer_attachInterrupt(TIM_TypeDef*, uint32_t)': c:\Users\analo\OneDrive\ARDUINO\libraries\uClock\src\platforms/stm32.h:15:19: error: 'TIM4' was not declared in this scope; did you mean 'TIM1'? 15 | else if (tim == TIM4) HAL_RCC_TIM4_CLK_ENABLE(); | ^~~~ | TIM1 c:\Users\analo\OneDrive\ARDUINO\libraries\uClock\src\platforms/stm32.h:15:25: error: 'HAL_RCC_TIM4_CLK_ENABLE' was not declared in this scope; did you mean 'HAL_RCC_MODULE_ENABLED'? 15 | else if (tim == TIM4) __HAL_RCC_TIM4_CLK_ENABLE(); | ^~~~~~~~~ | HAL_RCC_MODULE_ENABLED

Using library uClock at version 1.3.0 in folder: C:\Users\analo\OneDrive\ARDUINO\libraries\uClock Using library SrcWrapper at version 1.0.1 in folder: C:\Users\analo\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.5.0\libraries\SrcWrapper exit status 1

Compilation error: exit status 1

midilab commented 1 year ago

It is late here, I couldn't sleep so I have quickly tested on 2 boards. Nucleo F429ZI, I know the user LED is on pin PB0, set it in the code and no LED output (verified I have the correct pin for the LED using another arduino program as well as referring to STM32cubeMX). Just to confirm I am not missing anything, your example STM32uartmastermidiclock should have blinking LED at 126BPM with MIDI start, stop and clock messages over UART out pin (I haven't got my scope or a MIDI device out to confirm anything with UART but I will try to do this in the morning). I have not hooked up anything to the UART but I don't see why it would know or care.

Thanks for the test @analogmonster, i've read over the documentation and found out that i was wrong about the HAL usage inside STM32Duino core, they are using HAL behind the scene so no need to re-implmement it, so i change the platform specific handle to use timer API of STM32Duino instead of HAL directly.

There was a error when it comes to the F072, see end of post. It seems things aren't quite as portable as I had previously thought but this application note https://www.st.com/resource/en/application_note/an4013-stm32-crossseries-timer-overview-stmicroelectronics.pdf shows TIM3 isn't available on the F072 but TIM4 should be fine so I don't know why this compile error is happening.

Since they are using HAL behind the scene the timer code should be portable between all boards, at least this is what HAL project claims... this problem was more related to how i had coded the HAL implmementation. the new commit shouldn't throw this error.

So if you could pull the last changes on stm32 branch it has the new platform specific implemenation ready, i've change the example also to include a comment on each Serial usage. If the led Blinks as it should, then you can go and try to uncomment all Serial usage to see if it works.

analogmonster commented 1 year ago

Progress! Tested all 3 boards in same way. Onboard LED flashes as expected, tried at 60 and 180 bpm also. Serial on STM32 is a little more complicated as there are multiple UARTs and with these NUCLEO boards there is an ST-LINK programmer/debugger which the default serial is attached to. Still playing around with this

analogmonster commented 1 year ago

Success! Using the F401RE board for this but I am sure it will work with the other 2.

First, I removed your LED_BUILTIN definition as with these NUCLEO boards they are defined already.

https://github.com/stm32duino/Arduino_Core_STM32/wiki/API#hardwareserial explains how to set up hardware serial. Using HardwareSerial Serial1(PA10, PA9); and changing Serial to Serial1 in your example code I get MIDI clock out on pin PA9/D8.

I have not been able to use D0 and D1 for serial as they are connected to the ST-LINK. It is possible if I do some solder bridging but I am not going to do that mod as the above is fine for my purposes. Serial over the ST-LINK USB port works with Serial changed to Serial2.

At the moment I only have stm32 branch installed, which supports all platforms anyway. But out of interest, how would the Arduino IDE manage multiple branches of a library in the future? I see the esp32 branch doesn't have the platforms folder with different .h files, I suppose if each branch were structured in the same way the could just combine the libraries into a single library but that would make updating awkward. Or would the plan be to give each branch a unique name to avoid this problem?

midilab commented 1 year ago

Success! Using the F401RE board for this but I am sure it will work with the other 2. First, I removed your LED_BUILTIN definition as with these NUCLEO boards they are defined already. https://github.com/stm32duino/Arduino_Core_STM32/wiki/API#hardwareserial explains how to set up hardware serial. Using HardwareSerial Serial1(PA10, PA9); and changing Serial to Serial1 in your example code I get MIDI clock out on pin PA9/D8

Nice to hear! thanks again for the tests so far @analogmonster !

Could you send back to repo via pull request using the branch stm32xx the example and changes you had made to get it working? that way we can have a tested example ready to go. For now i guess Serial1 is ok as startpoint for example to be used. STM32 guys probably will know how to get other Serial ports to work if they need it.

To send the pull request you need to fork uClock, checkout stm32-support branch, copy your tested and modified version of STM32UartMasterMidiClock.ino into the newly forked and cloned uClock repo at same example folder location and file name, commit your changes into your forked uClock repo, after that you'll find a send pull request button where you select the original uClock repo here to send the changes back. By doing that you become a contributor of this repository and can keep track of original repo on your forked one.

At the moment I only have stm32 branch installed, which supports all platforms anyway. But out of interest, how would the Arduino IDE manage multiple branches of a library in the future? I see the esp32 branch doesn't have the platforms folder with different .h files, I suppose if each branch were structured in the same way the could just combine the libraries into a single library but that would make updating awkward. Or would the plan be to give each branch a unique name to avoid this problem?

The branches are used only at git repo side to work on new features without disrrupt the stable version at main branch, so each time there is new features or port, i create a new branch that will be later(when all the work is done) merged into main branch and deleted after. Its not part of Arduino way of handling library, just my preference to work on new features over git, its called gitflow, but without the development branch(since there is no constantly development i didn't create one and features out of main branch is ok for this project).

The ESP32 branch was created and used the same way we're doing now, i just forget to delete it! but all the changes and new features created at ESP32 branch are now merged into main branch and so, the stm32xx branch will be after we close this issue as done.

analogmonster commented 1 year ago

Yeah I was planning to do a pull request with a few examples for you, will do these this evening

Jackson-Devices commented 1 year ago

I have more than one github account, pull request made. I plan to send more when I have tested MIDI receive over UART also but ran out of time

midilab commented 1 year ago

Yeah I was planning to do a pull request with a few examples for you, will do these this evening

Great! thanks for the contributions so far @analogmonster, i think we have what we need for 1.3.0 release with this support, i will merge everything and roll the version

I have more than one github account, pull request made. I plan to send more when I have tested MIDI receive over UART also but ran out of time

Thanks, no rush at all, i will merge what we have done so far into master branch and then we can continue from there for examples improvements and extension.

midilab commented 1 year ago

Implemented at v1.3.0 release

twisted-electrons commented 1 year ago

Hello Happy to report it works great on the STM32F405RGT6 compiled in Platorm.io Thanks!

midilab commented 1 year ago

great! kinda off topic but, there is an very old uClock on platform.io registry, do you have any idea how to force or ask to update? i never intent to support platform.io but since i receive some reports back os other users using i was starting thinking about support platform.io too.

twisted-electrons commented 1 year ago

I'm new to this too, apparently the crawler updates every 24hrs based on the version number. This pages says the library needs a manifest (library.json) -could that be the issue? https://docs.platformio.org/en/latest/librarymanager/creating.html

midilab commented 1 year ago

Yeah, you're rigth, i've just made a commit with a library.json, lets hope the crawl updates it! i will try to compile some projects with platform.io either to check if everything is ok. thanks for the help!

twisted-electrons commented 1 year ago

Sounds great! tick-tac-tick-tac...

analogmonster commented 1 year ago

On the subject of updating @midilab, could we get this submitted to the Arduino library manager index? See here https://github.com/arduino/library-registry#adding-a-library-to-library-manager

midilab commented 1 year ago

On the subject of updating @midilab, could we get this submitted to the Arduino library manager index? See here https://github.com/arduino/library-registry#adding-a-library-to-library-manager

it has being long since i want to do it, i thinks thats a good time to move forward and publish it.

the platformio registry needs the user credentials to login and publish new versions, someone had publish using midilab as user but it keeps my email as account default, so i was able to reset the password to login and then publish the new version: https://registry.platformio.org/libraries/midilab/uClock

midilab commented 1 year ago

Also the Arduino library-registry was updated for uClock... https://github.com/arduino/library-registry/pull/2872