I am having a real hard time understanding how to do external clock multiplication on an MCU 
For my project I have a 32 step sequencer type thing going on. Now, it would be fairly easy for me to write some interrupt code to advance the sequence every-time a trigger/pulse is detected on a digital input pin - but what I would actually like to do is generate a higher resolution internal clock from the external clock. A simple use case would be to convert an analog clock signal to a MIDI clock signal which operates at 24 pulses per quarter note.
The sudo code for my current approach looks something like this:
#define PPQN 24
uint32_t lastClockTimeStamp;
uint32_t newClockTimeStamp;
uint32_t clockPeriod; // ie. PW
void extClock() {
lastClockTimeStamp = newClockTimeStamp;
newClockTimeStamp = timer.read_us();
clockPeriod = newClockTimeStamp - lastClockTimeStamp;
timer.attachInterrupt(clockPeriod, tickClock());
}
int currTick = 0;
int currPosition = 0;
int currStep = 0;
void tickClock() {
currTick += 1;
currPosition += 1;
// when currTick exceeds PPQN, reset to 0
if (currTick >= PPQN) {
currTick = 0;
currStep += 1;
}
if (currPosition >= totalPPQN) {
currPosition = 0;
currStep = 0;
}
}
I use an Interrupt Input pin to detect the external clock signal. For each rising edge on this pin, the extClock() function executes and calculates the “period” of the external clock (from last recorded clock to the current time of execution).
After the period is determined, I divide the period by my desired PPQN value and then set an internal interrupt routine to execute the tickClock() function.
For example, if the the external clock has a frequency of say… 0.96s, then my internal clock would be triggered every 0.96s/24 = 0.04s.
Now, this all makes sense to me however after hooking things up to a scope it turns out I have no idea what I am doing!
External Clock Signal = yellow (I am colour blind
)
Internal Clock Output (post clock multiplication) = Blue (I am colour blind
)
You can see in this picture that my clock multiplication is too fast
.
What am I doing wrong? Is there a different approach to clock multiplication? After looking at some other open source projects like OC, MI, the RCD, etc. I noticed there is a lot of bit masking going on, but its a bit hard to decipher how those clocks work.