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

Adding additional ARM support for uClock (Adafruit QT Py M0)? #17

Closed m-r-m-s closed 1 year ago

m-r-m-s commented 1 year ago

Hi @midilab,

I have been working with another ARM board, the Adafruit QT Py M0 which is pin compatible to the Seeed Xiao board with a few hardware differences. Honestly it is a little bit easier to work with on development side and it also uses the current version of the Adafruit Tiny USB library unlike the Seeed Xiao.

Since the Adafruit M0 board is so similar, I thought it would be an easy switch over to using it since you updated the uClock library to support the Xiao.

However, the Arduino core for the QT Py board does not include the same TCC0 and TC3 helper libraries as the Xiao SAMD implementation unfortunately. Those libraries are actually based of the work of this timer interrupt library that I believe should work with the QT Py M0: https://github.com/khoih-prog/TimerInterrupt_Generic

Here is an example of using hardware timers directly: https://github.com/khoih-prog/TimerInterrupt_Generic#1-using-only-hardware-timer-directly-1

The MACRO for the QT Py M0 can be __SAMD21E18A__ or ADAFRUIT_QTPY_M0

Using the above example, I started to try and figure out how to implement in uClock.cpp but got stuck. Specifically:

1) What value should #define TIMER_INTERVAL_MS be?

2) What the if def should be for uclockInitTimer() ? Maybe:

#if defined(ADAFRUIT_QTPY_M0)
     ITimer.attachInterruptInterval_MS(init_clock, uclockISR)
#endif

3) What the if def should be for void uClockClass::setTimerTempo(float bpm) ?

Sorry I can't be more helpful to do a pull request but I hope this gets the process going. Thanks!

m-r-m-s commented 1 year ago

Hey @midilab, a small update: I have successfully gotten the Adafruit QT py M0 board to work with uClock!

It is a workaround where I included the TCC0 and TC3 libraries from the Seeed Xiao Arduino core (https://github.com/Seeed-Studio/ArduinoCore-samd/tree/master/libraries) to the Adadfruit Arduino core libraries with a slight modification to the #ifdef for both of those libraries.

Here is the modified version of TimerTCC0.cpp which supports multiple SAMD boards: https://gist.github.com/m-r-m-s/8727b900a8814028781509814de3db1f#file-timertcc0_modified-cpp-L10

This modification works with the uClock.cpp #if defined(SEEED_XIAO_M0) because __SAMD21G18A__ is also a MACRO for the Seeed Xiao. Hope that makes sense.

It would be great to add QT Py M0 to the list of supported hardware but I think this method is a bit opaque =)

midilab commented 1 year ago

hey @m-r-m-s , thanks for the implementation details! i will try to incorporate it to the uClock as soon as possible.

midilab commented 1 year ago

Well looking to all the docs you've found so far i think the best approach is the first one, to have the support out-of-the-box. i will open a branch with some changes here and let you know!

midilab commented 1 year ago
  1. What value should #define TIMER_INTERVAL_MS be?

This is used only for AVRs, i think i will start to divide files per port.

midilab commented 1 year ago

its the same mcu used by arduino zero by the way: https://github.com/adafruit/Adafruit_ZeroTimer/ and also for GEMMA M0 and Trinket M0 boards so it looks like a lots of new devices supported by this port

m-r-m-s commented 1 year ago

Well looking to all the docs you've found so far i think the best approach is the first one, to have the support out-of-the-box. i will open a branch with some changes here and let you know!

Sounds good and thank you!

midilab commented 1 year ago

Well after some hang about this issue i discovery that Tc3 library is bugged, also its marked as legacy already. So far looks like TCC0 library work as expected but i didnt conduct some deep tests to make sure, any way i think the best solution will be to port the usage of TCx or TCCx for directly register access, that will probrably be usable on a wide range of SAMDxx.

I was looking at https://github.com/khoih-prog/TimerInterrupt_Generic wich looks good to use as port but it requires the user to make patches before use the library, wich i want to avoid.

The reason i decide to make the whole port based on register handling is because the uCtrl makes use of Tc3 while uClock makes use of TCC0 on uMODULAR environments.

I will send news as soon as i get something done!

Once again thanks for the research over samd timers.

mightycoco commented 1 year ago

Tbh. I see this library usefull in an application but not in a library like uClock. The timerinterrupt_generic doesn't seem to play well, if you are already using timer stuff in your application. Having now a dependancy to uClock which depends on tc_generic would force you, to change your app to also use tc_generic (from what I understood) Also there are a lot of prerequisites using tc_generic like patching the sdk and some files for different boards - from what I have seen in a quick read.

Maybe I'm wrong and would have to see this in a dedicated fork.

midilab commented 1 year ago

well the ideia was just to get the part of the code that handles the Timer(form SAMDx) at register level to implement a call at uClock to initialize the timer and to change the frequency but not to incorporate the whole library, but i just give up when i've check that this library still needs a patch per microcontroler arch.

But honestly deals with specific registers to get it running make it no portable at all and could give a lot of headache on maintain side.

m-r-m-s commented 1 year ago

@midilab Thanks for looking into additional porting for uClock. Sounds like it is too much hassle unfortunately. I really appreciate the time trying to make it work! I think I can just work with just adding the TCC0 and TC3 helper libraries to Adafruit Arduino Core like I did when testing.

midilab commented 1 year ago

@midilab Thanks for looking into additional porting for uClock. Sounds like it is too much hassle unfortunately. I really appreciate the time trying to make it work! I think I can just work with just adding the TCC0 and TC3 helper libraries to Adafruit Arduino Core like I did when testing.

Well i think it worth to take a note at README about this hacky way to use it with QT Py M0 for those who wish to. I will update a note with your description of how to do it.

My guess is that soon or later a timer library will be officially integrated into their SDK for Arduino.

Thanks for the research too! it is always good for a project to grow and extend as much as possible.

The whole goal behind uClock and uCtrl is exacly that, make it portable on Arduino platform to as many board as we can.

m-r-m-s commented 1 year ago

Sounds good. Thank you for including the workaround in the readme description. And yes let's hope there is better timer integration in the SDK in the near future 🙌

m-r-m-s commented 1 year ago

Hi @midilab - I wanted to provide another update. I have done some additional testing and I am not confident that this workaround for the QT Py M0 board is working correctly with uClock. While it would be nice to have an additional board option, I think we will have to wait until a timer library is officially integrated into their SDK for Arduino as you mention above.

midilab commented 1 year ago

Thanks for testing out @m-r-m-s ! in case of any updates on a official library please open another issue for integration.