seedstudio xiao m0 support

pull/9/head
midilab 3 years ago
parent f4009df95f
commit 7faa14d8d4
  1. 6
      examples/AcidStepSequencer/AcidStepSequencer.ino
  2. 10
      examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino
  3. 2
      examples/MidiClock/MidiClock.ino
  4. 10
      examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino
  5. 8
      examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino
  6. 8
      examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino
  7. 83
      src/uClock.cpp
  8. 22
      src/uClock.h

@ -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. // 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 step;
uint16_t length = NOTE_LENGTH; uint16_t length = NOTE_LENGTH;
// get actual step. // get actual step.
_step = *tick % _step_length; _step = tick % _step_length;
// send note on only if this step are not in rest mode // send note on only if this step are not in rest mode
if ( _sequencer[_step].rest == false ) { 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. // 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 // Send MIDI_CLOCK to external hardware
Serial.write(MIDI_CLOCK); Serial.write(MIDI_CLOCK);

@ -34,22 +34,22 @@ uint8_t bpm_blink_timer = 1;
uint8_t clock_state = 1; uint8_t clock_state = 1;
uint8_t clock_mode = 0; uint8_t clock_mode = 0;
void handle_bpm_led(uint32_t * tick) void handle_bpm_led(uint32_t tick)
{ {
// BPM led indicator // 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; bpm_blink_timer = 8;
TXLED1; TXLED1;
} else if ( !(*tick % (24)) ) { // each quarter led on } else if ( !(tick % (24)) ) { // each quarter led on
TXLED1; TXLED1;
} else if ( !(*tick % bpm_blink_timer) ) { // get led off } else if ( !(tick % bpm_blink_timer) ) { // get led off
TXLED0; TXLED0;
bpm_blink_timer = 1; bpm_blink_timer = 1;
} }
} }
// Internal clock handlers // Internal clock handlers
void ClockOut96PPQN(uint32_t * tick) { void ClockOut96PPQN(uint32_t tick) {
// Send MIDI_CLOCK to external gears // Send MIDI_CLOCK to external gears
MIDI.sendRealTime(MIDI_CLOCK); MIDI.sendRealTime(MIDI_CLOCK);
handle_bpm_led(tick); handle_bpm_led(tick);

@ -7,7 +7,7 @@
#define MIDI_STOP 0xFC #define MIDI_STOP 0xFC
// The callback function wich will be called by Clock each Pulse of 96PPQN clock resolution. // 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 // Send MIDI_CLOCK to external gears
Serial.write(MIDI_CLOCK); Serial.write(MIDI_CLOCK);

@ -21,22 +21,22 @@
#include <uClock.h> #include <uClock.h>
uint8_t bpm_blink_timer = 1; uint8_t bpm_blink_timer = 1;
void handle_bpm_led(uint32_t * tick) void handle_bpm_led(uint32_t tick)
{ {
// BPM led indicator // 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; bpm_blink_timer = 8;
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
} else if ( !(*tick % (24)) ) { // each quarter led on } else if ( !(tick % (24)) ) { // each quarter led on
digitalWrite(LED_BUILTIN, HIGH); 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); digitalWrite(LED_BUILTIN, LOW);
bpm_blink_timer = 1; bpm_blink_timer = 1;
} }
} }
// Internal clock handlers // Internal clock handlers
void ClockOut96PPQN(uint32_t * tick) { void ClockOut96PPQN(uint32_t tick) {
// Send MIDI_CLOCK to external gears // Send MIDI_CLOCK to external gears
usbMIDI.sendRealTime(usbMIDI.Clock); usbMIDI.sendRealTime(usbMIDI.Clock);
handle_bpm_led(tick); handle_bpm_led(tick);

@ -24,19 +24,19 @@ uint8_t bpm_blink_timer = 1;
void handle_bpm_led(uint32_t * tick) void handle_bpm_led(uint32_t * tick)
{ {
// BPM led indicator // 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; bpm_blink_timer = 8;
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
} else if ( !(*tick % (24)) ) { // each quarter led on } else if ( !(tick % (24)) ) { // each quarter led on
digitalWrite(LED_BUILTIN, HIGH); 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); digitalWrite(LED_BUILTIN, LOW);
bpm_blink_timer = 1; bpm_blink_timer = 1;
} }
} }
// Internal clock handlers // Internal clock handlers
void ClockOut96PPQN(uint32_t * tick) { void ClockOut96PPQN(uint32_t tick) {
// Send MIDI_CLOCK to external gears on other port? // Send MIDI_CLOCK to external gears on other port?
//usbMIDI.sendRealTime(usbMIDI.Clock); //usbMIDI.sendRealTime(usbMIDI.Clock);
handle_bpm_led(tick); handle_bpm_led(tick);

@ -37,19 +37,19 @@ uint8_t clock_state = 1;
void handle_bpm_led(uint32_t * tick) void handle_bpm_led(uint32_t * tick)
{ {
// BPM led indicator // 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; bpm_blink_timer = 8;
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
} else if ( !(*tick % (24)) ) { // each quarter led on } else if ( !(tick % (24)) ) { // each quarter led on
digitalWrite(LED_BUILTIN, HIGH); 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); digitalWrite(LED_BUILTIN, LOW);
bpm_blink_timer = 1; bpm_blink_timer = 1;
} }
} }
// Internal clock handlers // Internal clock handlers
void ClockOut96PPQN(uint32_t * tick) { void ClockOut96PPQN(uint32_t tick) {
// Send MIDI_CLOCK to external gears // Send MIDI_CLOCK to external gears
usbMIDI.sendRealTime(MIDI_CLOCK); usbMIDI.sendRealTime(MIDI_CLOCK);
handle_bpm_led(tick); handle_bpm_led(tick);

@ -30,25 +30,18 @@
// //
// Timer setup for work clock // Timer setup for work clock
// //
#if defined(TEENSYDUINO) && !defined(__AVR_ATmega32U4__) // all non-avr timmers setup
// Teensyduino port
#if defined(TEENSYDUINO)
IntervalTimer _uclockTimer; IntervalTimer _uclockTimer;
void uclockISR(); #endif
void uclockInitTimer() // Seedstudio XIAO M0 port
{ #if defined(SEEED_XIAO_M0)
ATOMIC( #include <TimerTCC0.h>
TimerTCC0 _uclockTimer;
// begin at 120bpm (20833us) #endif
_uclockTimer.begin(uclockISR, 20833);
// Set the interrupt priority level, controlling which other interrupts #if defined(ARDUINO_ARCH_AVR)
// 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
void uclockInitTimer() void uclockInitTimer()
{ {
ATOMIC( ATOMIC(
@ -67,6 +60,32 @@ void uclockInitTimer()
TIMSK1 |= (1 << OCIE1A); 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 #endif
namespace umodular { namespace clock { namespace umodular { namespace clock {
@ -153,11 +172,7 @@ void uClockClass::setTimerTempo(float bpm)
tick_us_interval = (60000000 / 24 / bpm); tick_us_interval = (60000000 / 24 / bpm);
tick_hertz_interval = 1/((float)tick_us_interval/1000000); tick_hertz_interval = 1/((float)tick_us_interval/1000000);
#if defined(TEENSYDUINO) && !defined(__AVR_ATmega32U4__) #if defined(ARDUINO_ARCH_AVR)
ATOMIC(
_uclockTimer.update(tick_us_interval);
)
#else
uint32_t ocr; uint32_t ocr;
uint8_t tccr = 0; uint8_t tccr = 0;
@ -188,6 +203,16 @@ void uClockClass::setTimerTempo(float bpm)
TCCR1B |= (1 << WGM12); TCCR1B |= (1 << WGM12);
TCCR1B |= tccr; 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 #endif
} }
@ -355,15 +380,15 @@ void uClockClass::handleTimerInt()
} }
if (onClock96PPQNCallback) { if (onClock96PPQNCallback) {
onClock96PPQNCallback(&internal_tick); onClock96PPQNCallback(internal_tick);
} }
if (mod6_counter == 0) { if (mod6_counter == 0) {
if (onClock32PPQNCallback) { if (onClock32PPQNCallback) {
onClock32PPQNCallback(&div32th_counter); onClock32PPQNCallback(div32th_counter);
} }
if (onClock16PPQNCallback) { if (onClock16PPQNCallback) {
onClock16PPQNCallback(&div16th_counter); onClock16PPQNCallback(div16th_counter);
} }
div16th_counter++; div16th_counter++;
div32th_counter++; div32th_counter++;
@ -371,7 +396,7 @@ void uClockClass::handleTimerInt()
if (mod6_counter == 3) { if (mod6_counter == 3) {
if (onClock32PPQNCallback) { if (onClock32PPQNCallback) {
onClock32PPQNCallback(&div32th_counter); onClock32PPQNCallback(div32th_counter);
} }
div32th_counter++; div32th_counter++;
} }
@ -439,10 +464,10 @@ volatile uint32_t _timer = 0;
// TIMER INTERRUPT HANDLER // TIMER INTERRUPT HANDLER
// //
// //
#if defined(TEENSYDUINO) && !defined(__AVR_ATmega32U4__) #if defined(ARDUINO_ARCH_AVR)
void uclockISR()
#else
ISR(TIMER1_COMPA_vect) ISR(TIMER1_COMPA_vect)
#else
void uclockISR()
#endif #endif
{ {
// global timer counter // global timer counter

@ -62,17 +62,17 @@ class uClockClass {
void setTimerTempo(float bpm); void setTimerTempo(float bpm);
float inline freqToBpm(uint32_t freq); float inline freqToBpm(uint32_t freq);
void (*onClock96PPQNCallback)(uint32_t * tick); void (*onClock96PPQNCallback)(uint32_t tick);
void (*onClock32PPQNCallback)(uint32_t * tick); void (*onClock32PPQNCallback)(uint32_t tick);
void (*onClock16PPQNCallback)(uint32_t * tick); void (*onClock16PPQNCallback)(uint32_t tick);
void (*onClockStartCallback)(); void (*onClockStartCallback)();
void (*onClockStopCallback)(); void (*onClockStopCallback)();
// internal clock control // internal clock control
volatile uint32_t internal_tick; uint32_t internal_tick;
volatile uint32_t div32th_counter; uint32_t div32th_counter;
volatile uint32_t div16th_counter; uint32_t div16th_counter;
volatile uint8_t mod6_counter; uint8_t mod6_counter;
// external clock control // external clock control
volatile uint32_t external_clock; volatile uint32_t external_clock;
@ -81,7 +81,7 @@ class uClockClass {
volatile uint32_t indiv16th_counter; volatile uint32_t indiv16th_counter;
volatile uint8_t inmod6_counter; volatile uint8_t inmod6_counter;
volatile uint32_t interval; volatile uint32_t interval;
volatile uint32_t last_interval; uint32_t last_interval;
uint32_t sync_interval; uint32_t sync_interval;
uint32_t tick_us_interval; uint32_t tick_us_interval;
@ -111,15 +111,15 @@ class uClockClass {
uClockClass(); uClockClass();
void setClock96PPQNOutput(void (*callback)(uint32_t * tick)) { void setClock96PPQNOutput(void (*callback)(uint32_t tick)) {
onClock96PPQNCallback = callback; onClock96PPQNCallback = callback;
} }
void setClock32PPQNOutput(void (*callback)(uint32_t * tick)) { void setClock32PPQNOutput(void (*callback)(uint32_t tick)) {
onClock32PPQNCallback = callback; onClock32PPQNCallback = callback;
} }
void setClock16PPQNOutput(void (*callback)(uint32_t * tick)) { void setClock16PPQNOutput(void (*callback)(uint32_t tick)) {
onClock16PPQNCallback = callback; onClock16PPQNCallback = callback;
} }

Loading…
Cancel
Save