timer.h


// timer.h

#ifndef __TIMER_H
#define __TIMER_H

#include "iodefs.h"

#define PWM_ON  1
#define PWM_OFF 0

#define COM1A_OFF    0       /* disconnect timer/counter 1 from pin OC1A */
#define COM1A_TOG    1       /* toggle OC1A output line (non-PWM mode) */
#define COM1A_CLR    2       /* clear OC1A output line on match */
#define COM1A_SET    3       /* set OC1A output line on match */

//-------------------------------------------------------------------------

//
// watchdog timer clock rate (depends upon processor voltage)
//
#define WDCLOCK   (350000 + (((VCC_MV) - 3000) * (650000 / 2000)))

typedef enum {
  WD_16K           = 0,
  WD_32K           = 1,
  WD_64K           = 2,
  WD_128K          = 3,
  WD_256K          = 4,
  WD_512K          = 5,
  WD_1024K         = 6,
  WD_2048K         = 7,
} wd_clk;

#define SM_IDLE    0   /* MCUCR sleep idle mode (1 mA) */
#define SM_ADCNR   1   /* MCUCR ADC Noise Reduction mode */
#define SM_PWROFF  2   /* MCUCR sleep power-down mode (<1 uA) */

#define WDDELAY 64  /* reset startup delay */

//  x sec * (WDCLOCK clks / 1 sec) * (1 cnt / ((16<<wd_clk) * 1024) clks)
#define SEC2WDCYC(sec, x) ((unsigned char) \
   ((((sec) * (unsigned long)(WDCLOCK) >> 10) + (((16<<(x))+WDDELAY)/2)) / \
    (((16<<x))+WDDELAY)) \
   )

//-------------------------------------------------------------------------

typedef enum {
  T0_STOP          = 0,
  T0_CK            = 1,
  T0_CK8           = 2,
  T0_CK64          = 3,
  T0_CK256         = 4,
  T0_CK1024        = 5,
  T0_FALLING_EDGE  = 6,
  T0_RISING_EDGE   = 7
} t0_clk;

void timer0_init(void);

static inline void timer0_ctrl(unsigned int src)
{
    outb (src, TCCR0);
}

static inline void timer0_start(const unsigned char cw)
{
    outb (cw, TCCR0);
    outb (0, TCNT0);
}

static inline void timer0_stop(void)
{
    outb (T0_STOP, TCCR0);
}

static inline void timer0_set(unsigned char val)
{
    outb (val, TCNT0);
}

#define timer0_get() inp(TCNT0)

//-------------------------------------------------------------------------

typedef enum {
  T1_STOP          = 0,
  T1_PCK           = 1,
  T1_PCK8          = 2,
  T1_PCK64         = 3,
  T1_PCK256        = 4,
  T1_CK            = 5,
  T1_CK2           = 6,
  T1_CK4           = 7,
  T1_CK8           = 8,
  T1_CK16          = 9,
  T1_CK32          = 10,
  T1_CK64          = 11,
  T1_CK128         = 12,
  T1_CK256         = 13,
  T1_CK512         = 14,
  T1_CK1024        = 15,
} t1_clk;

static void inline timer1_init(
    unsigned char pwm_mode,   /* PWM_ON or PWM_OFF */
    unsigned char com1a_mode, /* COM1A_OFF, COM1A_TOG, COM1A_CLR, COM1A_SET */
    t1_clk clk,
    unsigned char compA,  // value for OCR1A
    unsigned char compB   // value for OCR1B
){
    outb((((pwm_mode)?1:0)<<PWM1) |
         (((com1a_mode)&3)<<COM1A0) |
         ((clk)&0xf), TCCR1);
    outb((pwm_mode) ? 0 : compA, OCR1A);     // zero if PWM mode
    outb((pwm_mode) ? 0xff : compB, OCR1B);  // full range if PWM mode
}

#define timer1_stop() outb(0, TCCR1)

#define dac_set(val) outb((unsigned char)(val), OCR1A)

//-------------------------------------------------------------------------

//  x usec * (1 sec / 1000000 usec) * (CLOCK clks / 1 sec) * (1 cnt / 8 clks)
#define US2T0CNT8(us) ((unsigned char) \
              (((us) * ((unsigned long)(CLOCK) / 8L) + 500000L) / 1000000L))

//  x usec * (1 sec / 1000000 usec) * (CLOCK clks / 1 sec) * (1 cnt / 64 clks)
#define US2T0CNT64(us) ((unsigned char) \
              (((us) * ((unsigned long)(CLOCK) / 64L) + 500000L) / 1000000L))

//  x usec * (1 sec / 1000000 usec) * (CLOCK clks / 1 sec) * (1 cnt / 256 clks)
#define US2T0CNT256(us) ((unsigned char) \
              (((us) * ((unsigned long)(CLOCK) / 256L) + 500000L) / 1000000L))

//  x usec * (1 sec / 1000000 usec) * (CLOCK clks / 1 sec) * (1 cnt / 1024 clks)
#define US2T0CNT1024(us) ((unsigned char) \
              (((us) * ((unsigned long)(CLOCK) / 1024L) + 500000L) / 1000000L))

//-------------------------------------------------------------------------

static void inline _delay_ms(
    unsigned char msecs      // number of  milliseconds to wait
){
    while (msecs--) {
        timer0_start(T0_CK8);
        while (timer0_get() != US2T0CNT8(1000)) ;
    }
}

#define __delay_ms(msecs) \
{ \
    outb (T0_CK1024, TCCR0); \
    outb (256-((msecs) * US2T0CNT1024(1000)), TCNT0); \
    while (!timer0_get()) ; \
}

static void inline _delay_cs(
    unsigned char csecs      // number of  centiseconds to wait (0.01 secs)
){
    while (csecs--) { 
        timer0_start(T0_CK64);
        while (timer0_get() != US2T0CNT64(10000)) ;
    }
}

void delay_ms(
    unsigned char msecs      // number of milliseconds to wait
);

void delay_cs(
    unsigned char csecs      // number of centiseconds to wait (0.01 secs)
);

#endif /* !__TIMER_H */

Back