Description
Hello, I am using an Adafruit ItsyBitsy M4 to generate a tone using
tone(7,25)
Note: I didn't post the entire code base because this micro is doing a lot of things and the sketch is too busy.
I expect this code should generate a 25Hz tone on pin 7, but instead I see a frequency around 64 times higher. I traced this down to some unhandled cases in the tone code.
while(ccValue > TONE_TC_TOP)
{
ccValue = toneMaxFrequency / frequency / (2<<i) - 1;
i++;
if(i == 4 || i == 6 || i == 8) //DIV32 DIV128 and DIV512 are not available
i++;
}
switch(i-1)
{
case 0: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV2; break;
case 1: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV4; break;
case 2: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV8; break;
case 3: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV16; break;
case 5: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV64; break;
case 7: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV256; break;
case 9: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV1024; break;
default: break;
}
Adding case 8 to 7, 6 to 5 and 4 to 3 seems to resolve the issue. This seems to be a result of the if statement in the while loop adding an extra ++ when the proper prescaler is adjacent to one of the missing ones. The -1 in the switch then puts you in the default case (while generates a "9" then switch looks for a "8"). It should be possible to re-create this issue to confirm my code works as a fix and is accurate across a large range of frequencies...
switch(i-1)
{
case 0: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV2; break;
case 1: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV4; break;
case 2: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV8; break;
case 3: case 4: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV16; break;
case 5: case 6: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV64; break;
case 7: case 8: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV256; break;
case 9: prescalerConfigBits = TC_CTRLA_PRESCALER_DIV1024; break;
default: break;
}
I request you consider this or another fix for the next release of the Arduino cores for the SAMD51 (or 21) devices. Thanks!