// Timer1Excerciser -- Experiment with Timer1
// Code: https://wokwi.com/projects/328669448533705299
//
// Using TimeHelpers from http://www.gammon.com.au/timers
// Uno 328 DSatasheet http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
// Uno source https://store-usa.arduino.cc/products/arduino-uno-rev3
//
// This is intended to excercise the different options of Timer1 CTC(OCR1A)
// for https://github.com/wokwi/avr8js/issues/122
//
#include "TimerHelpers.h"
/* ---------------------------------------------------------------
Test sketch
--------------------------------------------------------------- */
// pins
const byte OC1B_pin = 10; // this is OC1B (timer 1 output compare B)
const byte OC1A_pin = 9; // this is OC1A (timer 1 output compare A)
const byte OVF_LED = 8; //
const byte MATCH_LED = 7; //
// state vars
bool T1IntsOn = false;
int16_t tiempo = 65536-3;//max freq preescaler to 1024 3.125Hz
//int16_t tiempo = 65536-484;//max freq preescaler to 1024 32HZ
volatile bool overflowed = false, matched = false;
volatile uint32_t overflow_time, match_time;
/*
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
timer1_counter = 34286; // preload timer 65536-16MHz/256/2Hz
TCNT1 = timer1_counter; // preload timer
TCCR1B |= (1 << CS12); // 256 prescaler
//TCCR1B |= (1<<CS11); //64 prescaler
//TCCR1B |=(1<<CS10);
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
interrupts(); // enable all interrupts
*/
void setup() {
Serial.begin(115200);
pinMode (OC1A_pin, OUTPUT);
pinMode (OC1B_pin, OUTPUT);
digitalWrite (OC1B_pin, HIGH);
pinMode(OVF_LED, OUTPUT);
pinMode(MATCH_LED, OUTPUT);
TCCR1A = 0; // reset timer 1
TCCR1B = 0;
// set up Timer 1
//OCR1A = 65535; // compare A register value
//OCR1B = 32767; // compare A register value
//ICR1 = 65535;
TCCR1B |= bit (CS12) | bit (CS10);
TCNT1 = tiempo; // reset counter
/*
// Mode 4: CTC, top = OCR1A
Timer1::setMode (4,
Timer1::PRESCALE_256,
Timer1::TOGGLE_A_ON_COMPARE | Timer1::TOGGLE_B_ON_COMPARE);
*/
/*
//
Timer1::setMode (1,
Timer1::PRESCALE_256,
Timer1::SET_A_ON_COMPARE | Timer1::CLEAR_B_ON_COMPARE);
*/
TIFR1 |= bit (OCF1A); // clear interrupt flag
TIMSK1 |= bit(TOIE1); // interrupt on Compare A Match & overflow
T1IntsOn = true;
} // end of setup
ISR(TIMER1_OVF_vect)
{
overflowed = true;
overflow_time = micros();
// digitalWrite(OVF_LED, !digitalRead(OVF_LED));
// TCCR1B = 0; // kill the timer
} // end of TIMER1_COMPA_vect
/*
ISR(TIMER1_COMPA_vect)
{
matched = true;
match_time = micros();
//digitalWrite(MATCH_LED, !digitalRead(MATCH_LED));
} // end of TIMER1_COMPA_vect
*/
/*
void toggleTimerInterrupt(void) {
const unsigned long interval = 5000000UL;
static unsigned long last = -interval;
unsigned long now = micros();
if (now - last >= interval) {
last += interval;
T1IntsOn = !T1IntsOn;
if (T1IntsOn) {
TIFR1 |= bit (OCF1A); // clear interrupt flag
TIMSK1 = bit (OCIE1A) | bit(TOIE1); // interrupt on Compare A Match & overflow
} else { // off
TIFR1 |= bit (OCF1A); // clear interrupt flag
TIMSK1 &= ~(bit (OCIE1A) | bit(TOIE1)); // clear interrupt on Compare A Match & overflow
}
Serial.print(now);
Serial.print("us Timer1 Interrupts ");
Serial.print(T1IntsOn ? "on" : "off");
Serial.print(", TCCR1A = 0b");
Serial.print(TCCR1A,BIN);
Serial.print(", TCCR1B = 0b");
Serial.println(TCCR1B,BIN);
}
}
*/
/*
void doOcr1aChanges(void) {
static uint16_t OCR1Astate = 0;
const unsigned long interval = 10000000UL;
static unsigned long last = 0;
unsigned long now = micros();
if (now - last >= interval) {
last += interval;
if (OCR1A == 0 ) {
OCR1A = 0xFFFF;
} else {
OCR1A = OCR1A >> 1;
}
Serial.print(now);
Serial.print("us OCR1A = 0x");
Serial.println(OCR1A,HEX);
}
}
*/
void loop() {
if (overflowed) {
noInterrupts();
overflowed = false;
interrupts();
digitalWrite(OVF_LED, !digitalRead(OVF_LED));
Serial.print(overflow_time);
Serial.println("us");
TCNT1 = tiempo;
}
/*
if (matched) {
noInterrupts();
matched = false;
interrupts();
digitalWrite(MATCH_LED, !digitalRead(MATCH_LED));
Serial.print(match_time);
Serial.print("us Matched TNCT1 == OCR1A == 0x");
Serial.println(OCR1A,HEX);
}
*/
//toggleTimerInterrupt();
//doOcr1aChanges();
} // end of loop