ATtiny85 Counter/Timer0 - How to make it count up and move Millis() to Timer1

Hi,

I'm working with Counter/Timer0 to count pulses from an external source.

I'm using the HighLowTech core:http://highlowtech.org/?p=1695. I could not get the Arduino Tiny Core to work nor its bootloader to burn: Google Code Archive - Long-term storage for Google Code Project Hosting. The Arduino Tiny Core seems to have more things you can play with, so if anyone has any step-by-step tutorial for that, I'd appreciate it.

Anyway, From what I can tell, it's working somewhat, but I've lost the millis() functionality. I'm just looking for some feedback to see if I'm doing this correctly

#include <avr/io.h>
#include <avr/interrupt.h>


//ATTiny85 Chip
#if defined(__AVR_ATtiny85__)
  #define CAPTURE_USE_TIMER0 //	I think this is correct
  
#else
  #error "Unknown chip, please edit me with timer+counter definitions"

#endif

#if defined(CAPTURE_USE_TIMER0) //ATtiny85 Counter on T0

static uint8_t saveTCCR0A, saveTCCR0B; 

static inline void capture_init(void)
{
saveTCCR0A=TCCR0A; //save initial settings
saveTCCR0B=TCCR0B;
TCCR0A=0; //Timer Counter Control Register A Settings control register to 0=normal operation no compare 
TCCR0B=0; //Timer Counter Control Reg B //Bits 0,1,2 all zero stops clock 
TCNT0=0;//Actual Timer/Counter0 - 0 clears the 8-bit timer

//Interrupt setup
TIMSK= (1<<TOIE0);//Timer Counter Interrupt Mask Register - enable interrupt for overflow on t0
TIFR= (1<<TOV0) ;//TimerCounter InterruptFlag Register TOV0 clears interrupt flag 


}

static inline void capture_start(void)
{
	TCCR0B = (1<<CS02) | (1<<CS01) | (1<<CS00);// 1,1,1External clock source on T0 pin. Clock on rising edge.
	
}

static inline uint8_t capture_read(void)//changes to from 16 to 8 because tiny is 8bit
{
	return TCNT0; //read counter 8 bit value
}

/* from other code not used ??
static inline uint8_t capture_overflow(void)
{
	return TIFR & (1<<TOV0);//clear the interrupt
}

static inline uint8_t capture_overflow_reset(void)
{
	return TIFR = (1<<TOV0);
}
*/

static inline void capture_shutdown(void)
{
	TCCR0B = 0;//stop timer
	TIMSK = 0;
	TCCR0A = saveTCCR0A; //restore to original
	TCCR0B = saveTCCR0B; //
}

#define TIMER_OVERFLOW_VECTOR  TIM0_OVF_vect //location of T0 overflow  ISR routing/program code

//#endif //end ATtiny85

CPP File

void FreqMeasureClass::begin(void)
{
	capture_init();
	capture_ovf = 0;
	capture_start();
}

uint32_t FreqMeasureClass::read(void)
{
	uint32_t value;
	value= capture_read() + (capture_ovf*255);
	return value;
}

void FreqMeasureClass::end(void)
{
	capture_shutdown();
}


ISR(TIMER_OVERFLOW_VECTOR) //interrupt for overflow - COMPILE Vector 5 ERROR HERE Comment out to run. 
{
	capture_ovf++; //increment overflow count
}

Arduino Code This pulses Pin 4(control pin) into Pin2(timer0) 10 times, then the led is flashed the amount of times returned by the .read function. Timer 0 also has a 10k pulldown connected.

int led = 0;
int controlpin=4;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
//boot up
 pinMode(led, OUTPUT); 
 pinMode(controlpin, OUTPUT); 
  for (int i=0;i<3;i++)
  {
  digitalWrite(led, HIGH);
  delay(250);
  digitalWrite(led, LOW);
  delay(250);
  }
  digitalWrite(controlpin, LOW);
  FreqMeasure.begin();
}



// the loop routine runs over and over again forever:
void loop() {
  FreqMeasure.begin();
  for (int j=0;j<10;j++)
  {
    digitalWrite(controlpin, HIGH);
   digitalWrite(led, HIGH);
    //delay(1000);

    digitalWrite(controlpin, LOW);
   digitalWrite(led, LOW);
   //delay(1000);
         
}
  long ticks=FreqMeasure.read();
  FreqMeasure.end();
  digitalWrite(led, LOW);
 delay(100);
  for (int i=0;i<ticks;i++);
  {
    digitalWrite(led, HIGH);
    delay(150);
    digitalWrite(led, LOW);
    delay(150);
  }

The delay function does not work after I call FreqMeasure.Begin() Any value causes the program to hang during execution. I comment them out and the LED has a steady lower brightness, which makes me think something is working. I did some other tests too, but this one would be nice to get some actual feedback, without more hardware involved.

How do I get millis moved Timer1? Or just how do i get it back after I end FreqMeasure at least?

edit: I see there are some things in Wiring.C, but I don't want to break anything as it's not super clear to me where to plug in.
Thanks!

gismo:
I could not get the Arduino Tiny Core to work nor its bootloader to burn

With a problem description of "couldn't get it to work" it is impossible for anyone to help you.

When Burning Bootloader:

avrdude: can't open input file C:\Users\Chad\Documents\Arduino\hardware\tiny\bootloaders\empty\empty85at8.hex: No such file or directory
avrdude: read from file 'C:\Users\Chad\Documents\Arduino\hardware\tiny\bootloaders\empty\empty85at8.hex' failed

I fixed this by moving the "bootloaders" folder into the "tiny" folder. Fixed.

When Compiling Excerpt:

Blink.ino: In function 'void setup()':
Blink:22: error: 'OUTPUT' was not declared in this scope
Blink:22: error: 'pinMode' was not declared in this scope
Blink:26: error: 'HIGH' was not declared in this scope
Blink:26: error: 'digitalWrite' was not declared in this scope
Blink:27: error: 'delay' was not declared in this scope
Blink:28: error: 'LOW' was not declared in this scope
Blink:31: error: 'LOW' was not declared in this scope

I've got all the includes at the top, but maybe I'm doing it wrong nor could I find an example.

Thanks!

I fixed this by moving the "bootloaders" folder into the "tiny" folder. Fixed.

Which means you installed the core in the wrong location.

Will you please tell me where they go? I'm on windows.

They are currently here C:<Sketchbook location folder>\Hardware\tiny\avr\cores

BTW, I read the readme as well.

Update: Upon re-reading the README - it seems the extracted directory as listed do not work for me, but the following does work:

Original:

After extracting, the following files / folders should exist...

C:\Projects\Arduino\hardware\tiny\avr\license.txt
C:\Projects\Arduino\hardware\tiny\avr\platform.txt
C:\Projects\Arduino\hardware\tiny\avr\Prospective Boards.txt
C:\Projects\Arduino\hardware\tiny\avr\README
C:\Projects\Arduino\hardware\tiny\avr\bootloaders
C:\Projects\Arduino\hardware\tiny\avr\cores\

The following folder should contain the source files for the Arduino-Tiny
core...

C:\Projects\Arduino\hardware\tiny\avr\cores\tiny\

  • Create a new file named "boards.txt" in the tiny\avr directory. Following
    from the examples above, the file would be here...

C:\Projects\Arduino\hardware\tiny\avr\boards.txt

What I Changed to make it compile:

After extracting, the following files / folders should exist...

C:\Projects\Arduino\hardware\tiny\avr\license.txt
C:\Projects\Arduino\hardware\tiny\avr\platform.txt
C:\Projects\Arduino\hardware\tiny\avr\Prospective Boards.txt
C:\Projects\Arduino\hardware\tiny\avr\README
*C:\Projects\Arduino\hardware\tiny\bootloaders*
*C:\Projects\Arduino\hardware\tiny\cores*

The following folder should contain the source files for the Arduino-Tiny
core...

*C:\Projects\Arduino\hardware\tiny\cores\tiny*

  • Create a new file named "boards.txt" in the \hardware\tiny directory. Following
    from the examples above, the file would be here...

C:\Projects\Arduino\hardware\tiny\avr\boards.txt

...now back to the main focus with Timer0 and millis()

By default, Tiny Core puts millis on timer 1 for the ATtiny85 processor.

Yea, I gathered that from reading core_build_options.h..which is why I was more excited to use this core for my project.

So, after getting this working and able to get some visual feedback from my the counter, I've having a couple of problems.

First, millis() works fine until I call FreqMeasure.begin(). After that to get Millis(60000) is appx 1 second. So something happened. Also, when ending the counter, FreqMeasure.end() the millis behavior does not return to expected behavior.

Second, The counter is not counting up. It only seems to count one value. Am I setting up the registers correctly? I've read the Atmel datasheet forwards and backwards, but maybe I'm missing something fundamental? Is there something in the tiny core affecting this?

Thanks!

Edit: I think I've fixed the millis() problem by changing these two lines in the init routine and adding the OR because TIMSK and TIFR are shared by both Timer0 and Timer1

TIMSK |= (1<<TOIE0);//Timer Counter Interrupt Mask Register - enable interrupt for overflow on t0
TIFR |= (1<<TOV0) ;//TimerCounter InterruptFlag Register TOV0 clears interrupt flag

Now I just need to get it to count...

I'm wondering if there is something that I need to do to map the port PB2 to T0.

Edit:
It's working as is for now!
First Problem:

for (int i=0;i<ticks;i++);

The semicolon at the end of this line was hiding in plain sight. So the code pulses a signal into pin7/PB2. Then the code flashes the led back with the amount in the counter. Cool. This works

Next step I tested the overflow function. I modified the code to pull in the overflow count. After going back and forth,tweaking things, I thought the overflow wasn't resetting because I was getting 0 overflows returned. I have a function FreqMeasure.OverflowCount() which pulls the overflow count in the CPP file.

In the arduino program I created a loop to blink the LED N times for N overflows. I created a this

long ovf=FreqMeasure.OverflowCount(); //<-ovf=0
for (int j=0; j < ovf;j++)
{
blinkled;
}

//above wasn't working, so I tried this:
for (int j=0; j< FreqMeasure.OverflowCount() ; j++)//<- this works!
{
blinkled;
}

Can anyone explain this behavior?