From 7faa14d8d4ff25566a8e96de2c5cdc5b3c9a6753 Mon Sep 17 00:00:00 2001 From: midilab Date: Tue, 3 May 2022 06:12:10 -0300 Subject: [PATCH] seedstudio xiao m0 support --- .../AcidStepSequencer/AcidStepSequencer.ino | 6 +- .../LeonardoUsbSlaveMidiClockMonitor.ino | 10 +-- examples/MidiClock/MidiClock.ino | 2 +- .../TeensyUsbMasterMidiClock.ino | 10 +-- .../TeensyUsbSlaveMidiClock.ino | 8 +- .../TeensyUsbSlaveMidiClockMonitor.ino | 8 +- src/uClock.cpp | 83 ++++++++++++------- src/uClock.h | 22 ++--- 8 files changed, 87 insertions(+), 62 deletions(-) diff --git a/examples/AcidStepSequencer/AcidStepSequencer.ino b/examples/AcidStepSequencer/AcidStepSequencer.ino index 19a3c27..bed0953 100644 --- a/examples/AcidStepSequencer/AcidStepSequencer.ino +++ b/examples/AcidStepSequencer/AcidStepSequencer.ino @@ -64,13 +64,13 @@ void sendMidiMessage(uint8_t command, uint8_t byte1, uint8_t byte2) } // The callback function wich will be called by uClock each Pulse of 16PPQN clock resolution. Each call represents exactly one step. -void ClockOut16PPQN(uint32_t * tick) +void ClockOut16PPQN(uint32_t tick) { uint16_t step; uint16_t length = NOTE_LENGTH; // get actual step. - _step = *tick % _step_length; + _step = tick % _step_length; // send note on only if this step are not in rest mode if ( _sequencer[_step].rest == false ) { @@ -102,7 +102,7 @@ void ClockOut16PPQN(uint32_t * tick) } // The callback function wich will be called by uClock each Pulse of 96PPQN clock resolution. -void ClockOut96PPQN(uint32_t * tick) +void ClockOut96PPQN(uint32_t tick) { // Send MIDI_CLOCK to external hardware Serial.write(MIDI_CLOCK); diff --git a/examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino b/examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino index 1c0d0b4..738ddcb 100644 --- a/examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino +++ b/examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino @@ -34,22 +34,22 @@ uint8_t bpm_blink_timer = 1; uint8_t clock_state = 1; uint8_t clock_mode = 0; -void handle_bpm_led(uint32_t * tick) +void handle_bpm_led(uint32_t tick) { // BPM led indicator - if ( !(*tick % (96)) || (*tick == 1) ) { // first compass step will flash longer + if ( !(tick % (96)) || (tick == 1) ) { // first compass step will flash longer bpm_blink_timer = 8; TXLED1; - } else if ( !(*tick % (24)) ) { // each quarter led on + } else if ( !(tick % (24)) ) { // each quarter led on TXLED1; - } else if ( !(*tick % bpm_blink_timer) ) { // get led off + } else if ( !(tick % bpm_blink_timer) ) { // get led off TXLED0; bpm_blink_timer = 1; } } // Internal clock handlers -void ClockOut96PPQN(uint32_t * tick) { +void ClockOut96PPQN(uint32_t tick) { // Send MIDI_CLOCK to external gears MIDI.sendRealTime(MIDI_CLOCK); handle_bpm_led(tick); diff --git a/examples/MidiClock/MidiClock.ino b/examples/MidiClock/MidiClock.ino index eb05552..6ca4bb5 100755 --- a/examples/MidiClock/MidiClock.ino +++ b/examples/MidiClock/MidiClock.ino @@ -7,7 +7,7 @@ #define MIDI_STOP 0xFC // The callback function wich will be called by Clock each Pulse of 96PPQN clock resolution. -void ClockOut96PPQN(uint32_t * tick) +void ClockOut96PPQN(uint32_t tick) { // Send MIDI_CLOCK to external gears Serial.write(MIDI_CLOCK); diff --git a/examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino b/examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino index 3c27364..542b7b5 100644 --- a/examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino +++ b/examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino @@ -21,22 +21,22 @@ #include uint8_t bpm_blink_timer = 1; -void handle_bpm_led(uint32_t * tick) +void handle_bpm_led(uint32_t tick) { // BPM led indicator - if ( !(*tick % (96)) || (*tick == 1) ) { // first compass step will flash longer + if ( !(tick % (96)) || (tick == 1) ) { // first compass step will flash longer bpm_blink_timer = 8; digitalWrite(LED_BUILTIN, HIGH); - } else if ( !(*tick % (24)) ) { // each quarter led on + } else if ( !(tick % (24)) ) { // each quarter led on digitalWrite(LED_BUILTIN, HIGH); - } else if ( !(*tick % bpm_blink_timer) ) { // get led off + } else if ( !(tick % bpm_blink_timer) ) { // get led off digitalWrite(LED_BUILTIN, LOW); bpm_blink_timer = 1; } } // Internal clock handlers -void ClockOut96PPQN(uint32_t * tick) { +void ClockOut96PPQN(uint32_t tick) { // Send MIDI_CLOCK to external gears usbMIDI.sendRealTime(usbMIDI.Clock); handle_bpm_led(tick); diff --git a/examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino b/examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino index a8aa6f0..aae743a 100644 --- a/examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino +++ b/examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino @@ -24,19 +24,19 @@ uint8_t bpm_blink_timer = 1; void handle_bpm_led(uint32_t * tick) { // BPM led indicator - if ( !(*tick % (96)) || (*tick == 1) ) { // first compass step will flash longer + if ( !(tick % (96)) || (tick == 1) ) { // first compass step will flash longer bpm_blink_timer = 8; digitalWrite(LED_BUILTIN, HIGH); - } else if ( !(*tick % (24)) ) { // each quarter led on + } else if ( !(tick % (24)) ) { // each quarter led on digitalWrite(LED_BUILTIN, HIGH); - } else if ( !(*tick % bpm_blink_timer) ) { // get led off + } else if ( !(tick % bpm_blink_timer) ) { // get led off digitalWrite(LED_BUILTIN, LOW); bpm_blink_timer = 1; } } // Internal clock handlers -void ClockOut96PPQN(uint32_t * tick) { +void ClockOut96PPQN(uint32_t tick) { // Send MIDI_CLOCK to external gears on other port? //usbMIDI.sendRealTime(usbMIDI.Clock); handle_bpm_led(tick); diff --git a/examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino b/examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino index 835b028..d912b90 100644 --- a/examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino +++ b/examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino @@ -37,19 +37,19 @@ uint8_t clock_state = 1; void handle_bpm_led(uint32_t * tick) { // BPM led indicator - if ( !(*tick % (96)) || (*tick == 1) ) { // first compass step will flash longer + if ( !(tick % (96)) || (tick == 1) ) { // first compass step will flash longer bpm_blink_timer = 8; digitalWrite(LED_BUILTIN, HIGH); - } else if ( !(*tick % (24)) ) { // each quarter led on + } else if ( !(tick % (24)) ) { // each quarter led on digitalWrite(LED_BUILTIN, HIGH); - } else if ( !(*tick % bpm_blink_timer) ) { // get led off + } else if ( !(tick % bpm_blink_timer) ) { // get led off digitalWrite(LED_BUILTIN, LOW); bpm_blink_timer = 1; } } // Internal clock handlers -void ClockOut96PPQN(uint32_t * tick) { +void ClockOut96PPQN(uint32_t tick) { // Send MIDI_CLOCK to external gears usbMIDI.sendRealTime(MIDI_CLOCK); handle_bpm_led(tick); diff --git a/src/uClock.cpp b/src/uClock.cpp index 43cde97..37f311f 100755 --- a/src/uClock.cpp +++ b/src/uClock.cpp @@ -30,25 +30,18 @@ // // Timer setup for work clock // -#if defined(TEENSYDUINO) && !defined(__AVR_ATmega32U4__) +// all non-avr timmers setup +// Teensyduino port +#if defined(TEENSYDUINO) IntervalTimer _uclockTimer; -void uclockISR(); -void uclockInitTimer() -{ - ATOMIC( +#endif +// Seedstudio XIAO M0 port +#if defined(SEEED_XIAO_M0) +#include +TimerTCC0 _uclockTimer; +#endif - // begin at 120bpm (20833us) - _uclockTimer.begin(uclockISR, 20833); - - // Set the interrupt priority level, controlling which other interrupts - // this timer is allowed to interrupt. Lower numbers are higher priority, - // with 0 the highest and 255 the lowest. Most other interrupts default to 128. - // As a general guideline, interrupt routines that run longer should be given - // lower priority (higher numerical values). - _uclockTimer.priority(0); - ) -} -#else +#if defined(ARDUINO_ARCH_AVR) void uclockInitTimer() { ATOMIC( @@ -67,6 +60,32 @@ void uclockInitTimer() TIMSK1 |= (1 << OCIE1A); ) } +#else +void uclockISR(); +void uclockInitTimer() +{ + // begin at 120bpm (20833us) + const uint16_t init_clock = 20833; + ATOMIC( + #if defined(TEENSYDUINO) + _uclockTimer.begin(uclockISR, init_clock); + + // Set the interrupt priority level, controlling which other interrupts + // this timer is allowed to interrupt. Lower numbers are higher priority, + // with 0 the highest and 255 the lowest. Most other interrupts default to 128. + // As a general guideline, interrupt routines that run longer should be given + // lower priority (higher numerical values). + _uclockTimer.priority(0); + #endif + + #if defined(SEEED_XIAO_M0) + _uclockTimer.initialize(init_clock); + + // attach to generic uclock ISR + _uclockTimer.attachInterrupt(uclockISR); + #endif + ) +} #endif namespace umodular { namespace clock { @@ -153,11 +172,7 @@ void uClockClass::setTimerTempo(float bpm) tick_us_interval = (60000000 / 24 / bpm); tick_hertz_interval = 1/((float)tick_us_interval/1000000); -#if defined(TEENSYDUINO) && !defined(__AVR_ATmega32U4__) - ATOMIC( - _uclockTimer.update(tick_us_interval); - ) -#else +#if defined(ARDUINO_ARCH_AVR) uint32_t ocr; uint8_t tccr = 0; @@ -188,6 +203,16 @@ void uClockClass::setTimerTempo(float bpm) TCCR1B |= (1 << WGM12); TCCR1B |= tccr; ) +#else + ATOMIC( + #if defined(TEENSYDUINO) + _uclockTimer.update(tick_us_interval); + #endif + + #if defined(SEEED_XIAO_M0) + _uclockTimer.setPeriod(tick_us_interval); + #endif + ) #endif } @@ -355,15 +380,15 @@ void uClockClass::handleTimerInt() } if (onClock96PPQNCallback) { - onClock96PPQNCallback(&internal_tick); + onClock96PPQNCallback(internal_tick); } if (mod6_counter == 0) { if (onClock32PPQNCallback) { - onClock32PPQNCallback(&div32th_counter); + onClock32PPQNCallback(div32th_counter); } if (onClock16PPQNCallback) { - onClock16PPQNCallback(&div16th_counter); + onClock16PPQNCallback(div16th_counter); } div16th_counter++; div32th_counter++; @@ -371,7 +396,7 @@ void uClockClass::handleTimerInt() if (mod6_counter == 3) { if (onClock32PPQNCallback) { - onClock32PPQNCallback(&div32th_counter); + onClock32PPQNCallback(div32th_counter); } div32th_counter++; } @@ -439,10 +464,10 @@ volatile uint32_t _timer = 0; // TIMER INTERRUPT HANDLER // // -#if defined(TEENSYDUINO) && !defined(__AVR_ATmega32U4__) -void uclockISR() +#if defined(ARDUINO_ARCH_AVR) +ISR(TIMER1_COMPA_vect) #else -ISR(TIMER1_COMPA_vect) +void uclockISR() #endif { // global timer counter diff --git a/src/uClock.h b/src/uClock.h index 6a3c18f..083f1f8 100755 --- a/src/uClock.h +++ b/src/uClock.h @@ -62,17 +62,17 @@ class uClockClass { void setTimerTempo(float bpm); float inline freqToBpm(uint32_t freq); - void (*onClock96PPQNCallback)(uint32_t * tick); - void (*onClock32PPQNCallback)(uint32_t * tick); - void (*onClock16PPQNCallback)(uint32_t * tick); + void (*onClock96PPQNCallback)(uint32_t tick); + void (*onClock32PPQNCallback)(uint32_t tick); + void (*onClock16PPQNCallback)(uint32_t tick); void (*onClockStartCallback)(); void (*onClockStopCallback)(); // internal clock control - volatile uint32_t internal_tick; - volatile uint32_t div32th_counter; - volatile uint32_t div16th_counter; - volatile uint8_t mod6_counter; + uint32_t internal_tick; + uint32_t div32th_counter; + uint32_t div16th_counter; + uint8_t mod6_counter; // external clock control volatile uint32_t external_clock; @@ -81,7 +81,7 @@ class uClockClass { volatile uint32_t indiv16th_counter; volatile uint8_t inmod6_counter; volatile uint32_t interval; - volatile uint32_t last_interval; + uint32_t last_interval; uint32_t sync_interval; uint32_t tick_us_interval; @@ -111,15 +111,15 @@ class uClockClass { uClockClass(); - void setClock96PPQNOutput(void (*callback)(uint32_t * tick)) { + void setClock96PPQNOutput(void (*callback)(uint32_t tick)) { onClock96PPQNCallback = callback; } - void setClock32PPQNOutput(void (*callback)(uint32_t * tick)) { + void setClock32PPQNOutput(void (*callback)(uint32_t tick)) { onClock32PPQNCallback = callback; } - void setClock16PPQNOutput(void (*callback)(uint32_t * tick)) { + void setClock16PPQNOutput(void (*callback)(uint32_t tick)) { onClock16PPQNCallback = callback; }