-
Notifications
You must be signed in to change notification settings - Fork 80
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
timer1: mode 9 is not working anymore #111
Comments
Thanks for reporting! Do you have any idea if it worked in previous version of the simulator? |
Initial analysis: it seems like the issue happens if OCR1A is still 0 when you configure the timer. A workaround would be to first set OCR1A / OCR1B, and then enable the timer: int main(void){
DDRB |= (1 << PORTB2); //Define OCR1B as Output (pin number arduino: 10)
OCR1A = 4000;
OCR1B = 1000;
TCCR1A |= (1 << COM1A0) | (1 << COM1B1) | (1 << WGM10); // PB2: output, PWM mode 9
TCCR1B |= (1 << CS10) | (1 << CS11) | (1 << WGM13);// prescaler=64, mode 9
while(1) {
}
} Here's a complete functional example: https://wokwi.com/arduino/projects/313183501205635648 To fix it, we need to figure out what to do if the timer starts and TOP (OCR1A) == 0. Should it generate compare match on every single timer cycle? |
Thanks! Is the graph based on version 0.11.4 or on an actual chip? |
version 0.18.2 |
I've tested it. That doesn't seem like the right behavior. int results[500];
int main(void){
Serial.begin(9600);
DDRB |= (1 << PORTB2); //Define OCR1B as Output (pin number arduino: 10)
OCR1A = 2000;
OCR1B = 500;
TCCR1A |= (1 << COM1A0) | (1 << COM1B1) | (1 << WGM10); // PB2: output, PWM mode 9
TCCR1B |= (1 << CS10) | (1 << CS11) | (1 << WGM13);// prescaler=64, mode 9
for (int i = 0; i < 250; i++) {
results[i] = TCNT1;
_delay_us(100);
}
OCR1A = 1000;
OCR1B = 100;
TCNT1 = 0;
for (int i = 0; i < 250; i++) {
results[i+250] = TCNT1;
_delay_us(100);
}
for (int i = 0; i < 500; i++) Serial.println(results[i]);
Serial.flush();
while(1) {
}
} |
Thank you for doing this comparison, it's really useful! I need to search the data sheet to see if I can find where the exact behavior is defined, and adjust the simulation accordingly |
Ok, we have a fix. I verified it it the following test program: int main(void) {
uint8_t v0, v1, v2, v3;
Serial.begin(9600);
asm(R"(
CLR r1 ; r1 is our zero register
LDI r16, 0x0 ; OCR1AH = 0x0;
STS 0x89, r1
LDI r16, 0x8 ; OCR1AL = 0x8;
STS 0x88, r16
; Set waveform generation mode (WGM) to PWM Phase/Frequency Correct mode (9)
LDI r16, 0x01 ; TCCR1A = (1 << WGM10);
STS 0x80, r16
LDI r16, 0x11 ; TCCR1B = (1 << WGM13) | (1 << CS00);
STS 0x81, r16
STS 0x85, r1 ; TCNT1H = 0x0;
STS 0x84, r1 ; TCNT1L = 0x0;
LDI r16, 0x5 ; OCR1AL = 0x5; // TCNT1 should read 0x0
STS 0x88, r16 ; // TCNT1 should read 0x2 (going up)
STS 0x84, r1 ; TCNT1L = 0x0;
LDS %0, 0x84 ; // TCNT1 should read 0x1 (going up)
LDS %1, 0x84 ; // TCNT1 should read 0x3 (going up)
LDS %2, 0x84 ; // TCNT1 should read 0x5 (going down)
LDS %3, 0x84 ; // TCNT1 should read 0x3 (going down)
)" : "=r"(v0) , "=r"(v1), "=r"(v2), "=r"(v3) );
Serial.println(v0);
Serial.println(v1);
Serial.println(v2);
Serial.println(v3);
Serial.flush();
for (;;);
} When running on a physical board, I get the following output:
I added a test case that validates this behavior (it fails with the previous version, passes with the fix). Would love to get your feedback on the new version with the fix (0.18.5) |
The behavior of TCNT1 now seems to be correct. |
Lovely! Thanks again for reporting it and all your help in tracing the issue! |
Thanks for providing detailed reproduction with graphs! I haven't had the time to look into it yet, but it's on my list. |
In real (tested with Arduino Uno), the LED on pin 10 is blinking fast. In simulation nothing happens.
The text was updated successfully, but these errors were encountered: