lgt8fx icon indicating copy to clipboard operation
lgt8fx copied to clipboard

Can't handle Timer3 OC3B interrupt

Open danielwsky opened this issue 4 years ago • 4 comments

I'm trying to use the OC3B in CTC mode, but when I enable the OCIE3B interrupt, my board don't run anything, feeling like it's stuck on something, but the OC3B works, so I think it doesn't handle the interrupt and because of it, it doesn't clear the interrupt flag. Code (short): void setup() { DDRD |= (0 << DDD2); DDRF |= (1 << DDD2); pinMode(A0, OUTPUT); TCCR3A |= (1 << COM3B1) | (0 << COM3B0) | (0 << WGM31) | (0 << WGM30); TCCR3B |= (0 << CS32) | (0 << CS31) | (0 << CS30) | (0 << WGM33) | (1 << WGM32); OCR3BH = highByte(8000); OCR3BL = lowByte(8000); TIMSK3 |= (1 << OCIE3B); TCCR3B |= (1 << CS32) | (0 << CS31) | (1 << CS30); sei(); }

ISR(TIMER3_vect) { digitalWrite(A0, !(digitalRead(A0))); TCCR3B |= (0 << CS32) | (0 << CS31) | (0 << CS30); TIFR3 |= (1 << OCF3B); sei(); }

I can post the full code if necessary, but I think this is enough. Am I missing something?

I'm using ver 1.0.6

danielwsky avatar Jun 07 '21 21:06 danielwsky

I think you are missing the following:

  • You are in CTC mode with OCR3A as top, but you are not setting it
  • DDRD |= (0 << DDD2); DDRF |= (1 << DDD2); you are setting PF2 as output (which is wired internally to PD2), but you are not configuring the output of the OCR3B to it. I see you have OCR3A configured as "clear on compare match", but that output is PF1 (wired to PD1, watch out, you just lost Serial Output :) )

And I see a couple of redundant things:

  • sei(): you are never doing cli(), so what is its function? (btw, interrupts() and noInterrupts() are equivalent and generally recommended for readability
  • TCCR3B |= (0 << CS32) | (0 << CS31) | (0 << CS30);: has no effect, you are logic ORing with zero. If you want to stop the timer, go for TCCR3B &= ~(1 << CS32) | (1 << CS31) | (1 << CS30); instead
  • digitalWrite(A0, !(digitalRead(A0)));: digital A0 is PC0 and you can toggle pins in 1 clock cycle with PINC = PINc | 0b00000001; // toggle PC0/A0
  • OCR3BH = ... you don't need to set the high and low bits yourself. Setting OCR3B will do that in the right order for you :)

But you are close!

dbuezas avatar Jun 09 '21 17:06 dbuezas

Timers are pain to get right, but you are up for a treat, I'm close to releasing this: image

It's interactive so you can just click your way through it, including 80mA outputs, interrupts, etc. I used this to check most of your code, I may have ported something incorrect from the datasheet, so there may be a bug or two still. Eventually I want to also add the configs for the atmega328p and also support to configure dead time in the lgt chip.

dbuezas avatar Jun 09 '21 17:06 dbuezas

follow the progress here: #164

dbuezas avatar Jun 09 '21 17:06 dbuezas

Deployed: https://dbuezas.github.io/arduino-web-timers

dbuezas avatar Jun 28 '21 14:06 dbuezas

@danielwsky does this address your issue sufficiently? If so, please close this.

dwillmore avatar Jan 12 '23 18:01 dwillmore