void change_tempo(uint16_t set_tempo) {
uint16_t t3_prescale;
uint32_t num_instr;
uint16_t top_num_instr;
if (set_tempo > MAX_TEMPO) {
set_tempo = MAX_TEMPO;
}
if (set_tempo < MIN_TEMPO) {
set_tempo = MIN_TEMPO;
}
// figure out what the interrupt should be!
// (use counter 3 for finest resolution!)
num_instr = F_CPU * 60;
num_instr /= set_tempo*48;
top_num_instr = num_instr >> 16;
if (!top_num_instr) {
t3_prescale = 1;
timer3_init = num_instr;
TCCR3B = 1;
} else if ((top_num_instr & ~0x7) == 0) {
t3_prescale = 8;
timer3_init = num_instr >> 3;
TCCR3B = 2;
}
/*
else if ((top_num_instr & ~0xF) == 0) {
t3_prescale = 16;
timer3_init = num_instr >> 4;
TCCR3B = 6;
} else if ((top_num_instr & ~0x1F) == 0) {
t3_prescale = 32;
timer3_init = num_instr >> 5;
TCCR3B = 7;
}
*/
else if ((top_num_instr & ~0x3F) == 0) {
t3_prescale = 64;
timer3_init = num_instr >> 6;
TCCR3B = 3;
} else if ((top_num_instr & ~0xFF) == 0) {
t3_prescale = 256;
timer3_init = num_instr >> 8;
TCCR3B = 4;
} else if ((top_num_instr & ~0x3FF) == 0) {
t3_prescale = 1024;
timer3_init = num_instr >> 10;
TCCR3B = 5;
} else {
t3_prescale = 0;
TCCR3B = 0;
}
timer3_init *= -1;
//printf("T3 Prescale: %d. Init: 0x%x\n\r", t3_prescale, timer3_init);
TCNT3 = timer3_init;
}