seedstudio xiao m0 support

pull/9/head
midilab 2 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.
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);

@ -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);

@ -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);

@ -21,22 +21,22 @@
#include <uClock.h>
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);

@ -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);

@ -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);

@ -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.h>
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

@ -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;
}

Loading…
Cancel
Save