Skip to content

Instantly share code, notes, and snippets.

@DatanoiseTV
Last active September 5, 2016 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DatanoiseTV/10683910d877e187037515ff2e98cab6 to your computer and use it in GitHub Desktop.
Save DatanoiseTV/10683910d877e187037515ff2e98cab6 to your computer and use it in GitHub Desktop.
#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
}
}
#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;
};
#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