-
-
Save DatanoiseTV/10683910d877e187037515ff2e98cab6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <teemi_clock.h> // Clock Generator Functions | |
#include <core.h> // Helper Functions | |
void setup() | |
{ | |
pinMode(13, OUTPUT); | |
clock.setPPQN(24); | |
clock.setBPM(120); | |
clock.start(); | |
} | |
void loop() | |
{ | |
if((clock.getTick() % 96) == 0) | |
{ | |
usbMIDI.sendNoteOn(60, 99, 0); // 60 = C4 | |
} | |
while (usbMIDI.read()) { | |
// ignore incoming messages | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "teemi_clock.h" | |
#include <Arduino.h> | |
static void isr_outer(); | |
TeemiClock::TeemiClock(void) | |
{ | |
this->state = CLOCK_IDLE; | |
this->tick_count = 0; | |
this->ppqn = 48; | |
this->bpm = 120; | |
} | |
int8_t TeemiClock::setBPM(uint16_t bpm) | |
{ | |
__disable_irq(); | |
if(bpm >= 1 && bpm <= 999) | |
{ | |
this->bpm = bpm; | |
return 0; | |
} | |
__enable_irq(); | |
return -1; | |
}; | |
int8_t TeemiClock::setPPQN(uint16_t ppqn) | |
{ | |
__disable_irq(); | |
if(ppqn >= 12 && ppqn <= 384) | |
{ | |
this->ppqn = ppqn; | |
} | |
__enable_irq(); | |
return -1; | |
}; | |
uint32_t TeemiClock::getTick(void) | |
{ | |
return this->tick_count; | |
}; | |
int16_t TeemiClock::getPPQN(void) | |
{ | |
__disable_irq(); | |
return this->ppqn; | |
__enable_irq(); | |
}; | |
bool TeemiClock::isRunning(void) | |
{ | |
return(this->state == CLOCK_RUNNING ? 1 : 0); | |
}; | |
static void isr_outer() | |
{ | |
clock.tick(); | |
}; | |
void TeemiClock::tick(void) | |
{ | |
__disable_irq(); | |
tick_count++; | |
__enable_irq(); | |
}; | |
int8_t TeemiClock::start(void) | |
{ | |
__disable_irq(); | |
this->tick_count = 0; | |
this->state = CLOCK_RUNNING; | |
__enable_irq(); | |
internalClock.begin(isr_outer, (60000 / (bpm/ppqn)) ); | |
//internalClock.priority(0); // We want most precise timing, so highest prio | |
return -1; | |
}; | |
int8_t TeemiClock::pause(void) | |
{ | |
switch(this->state) | |
{ | |
case CLOCK_PAUSED: | |
this->state = CLOCK_RUNNING; | |
break; | |
case CLOCK_RUNNING: | |
this->state = CLOCK_PAUSED; | |
break; | |
} | |
return -1; | |
}; | |
int8_t TeemiClock::stop(void) | |
{ | |
internalClock.end(); | |
this->tick_count = 0; | |
return -1; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _TEEMI_CLOCK_H_ | |
#define _TEEMI_CLOCK_H_ | |
#include <stdint.h> | |
#include <Arduino.h> | |
typedef enum { | |
CLOCK_IDLE = 0, | |
CLOCK_PAUSED, | |
CLOCK_RUNNING | |
} clock_state_t; | |
class TeemiClock | |
{ | |
public: | |
TeemiClock(); | |
int8_t setBPM(uint16_t bpm); | |
int8_t setPPQN(uint16_t ppqn); | |
int16_t getPPQN(void); | |
uint32_t getTick(void); | |
int8_t setTick(uint32_t); | |
bool isRunning(void); | |
int8_t start(void); | |
int8_t pause(void); | |
int8_t stop(void); | |
void tick(); | |
volatile uint32_t tick_count; | |
private: | |
int8_t state; | |
volatile uint16_t ppqn; | |
volatile uint16_t bpm; | |
IntervalTimer internalClock; | |
}; | |
extern TeemiClock clock; | |
#endif // _TEEMI_CLOCK_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment