Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tone() issue on SAMD51 cores #371

Open
ZombieFodder opened this issue Jan 21, 2025 · 0 comments
Open

tone() issue on SAMD51 cores #371

ZombieFodder opened this issue Jan 21, 2025 · 0 comments

Comments

@ZombieFodder
Copy link

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant