2008-10-14 21:06:51 +02:00
# ifndef CONTIKI_CLOCK_AVR_H
# define CONTIKI_CLOCK_AVR_H
# if defined (__AVR_ATmega128__)
# define AVR_OUTPUT_COMPARE_INT TIMER0_COMP_vect
# define OCRSetup() \
/* Select internal clock */ \
ASSR = 0x00 ; \
\
/* Set counter to zero */ \
TCNT0 = 0 ; \
\
/* \
* Set comparison register : \
2011-08-05 21:14:35 +02:00
* Crystal freq . is F_CPU , \
* pre - scale factor is 1024 , we want CLOCK_CONF_SECOND ticks / sec : \
* F_CPU = 1024 * CLOCK_CONF_SECOND * OCR0 \
2008-10-14 21:06:51 +02:00
*/ \
2011-08-05 21:14:35 +02:00
OCR0 = F_CPU / 1024UL / CLOCK_CONF_SECOND ; \
2008-10-14 21:06:51 +02:00
\
/* \
* Set timer control register : \
* - prescale : 1024 ( CS00 - CS02 ) \
* - counter reset via comparison register ( WGM01 ) \
*/ \
TCCR0 = _BV ( CS00 ) | _BV ( CS01 ) | _BV ( CS02 ) | _BV ( WGM01 ) ; \
\
/* Clear interrupt flag register */ \
TIFR = 0x00 ; \
\
/* \
* Raise interrupt when value in OCR0 is reached . Note that the \
* counter value in TCNT0 is cleared automatically . \
*/ \
TIMSK = _BV ( OCIE0 ) ;
2011-02-07 19:46:34 +01:00
# elif defined (__AVR_ATmega128RFA1__) && 0
2011-08-17 19:15:26 +02:00
/* Uses the general routine below at present */
2011-02-07 19:46:34 +01:00
# define AVR_OUTPUT_COMPARE_INT TIMER0_COMPA_vect
# define OCRSetup() \
/* Select internal clock */ \
ASSR = 0x00 ; \
\
/* Set counter to zero */ \
TCNT0 = 0 ; \
\
/* \
* Set comparison register : \
2011-08-05 21:14:35 +02:00
* Crystal freq . is F_CPU , \
* pre - scale factor is 1024 , we want CLOCK_CONF_SECOND ticks / sec : \
* F_CPU = 1024 * CLOCK_CONF_SECOND * OCR0A , less 1 for CTC mode \
2011-02-07 19:46:34 +01:00
*/ \
2011-08-05 21:14:35 +02:00
OCR0A = F_CPU / 1024 / CLOCK_CONF_SECOND - 1 ; \
2011-02-07 19:46:34 +01:00
\
/* \
* Set timer control register : \
* - prescale : 1024 ( CS00 - CS02 ) \
* - counter reset via comparison register ( WGM01 ) \
*/ \
TCCR0A = _BV ( WGM01 ) ; \
TCCR0B = _BV ( CS00 ) | _BV ( CS02 ) ; \
\
/* Clear interrupt flag register */ \
TIFR0 = TIFR0 ; \
\
/* \
* Raise interrupt when value in OCR0 is reached . Note that the \
* counter value in TCNT0 is cleared automatically . \
*/ \
TIMSK0 = _BV ( OCIE0A ) ;
2016-02-22 20:14:06 +01:00
# elif defined (__AVR_ATmega1284P__) || (__AVR_AT90USB1287__) || (__AVR_ATmega1281__) || defined (__AVR_ATmega128RFA1__) || defined (__AVR_ATmega128RFR2__) || defined (__AVR_ATmega256RFR2__)
2010-06-18 19:30:30 +02:00
/*
The Raven has a 32768 Hz watch crystal that can be used to clock the timer
while the 1284 p is sleeping . The Jackdaw has pads for a crystal . The crystal
can be used to clock the 8 bit timer2 .
2010-12-22 18:09:03 +01:00
The 1284 p routine also uses TIMER2 to sleep a variable number of seconds .
It restores the values here after a wake .
2010-06-18 19:30:30 +02:00
*/
# if AVR_CONF_USE32KCRYSTAL
2010-06-22 18:17:24 +02:00
# define AVR_OUTPUT_COMPARE_INT TIMER2_COMPA_vect
2010-06-18 19:30:30 +02:00
# define OCRSetup() \
/* Clock from crystal on TOSC0-1 */ \
ASSR = _BV ( AS2 ) ; \
\
/* Set counter to zero */ \
TCNT2 = 0 ; \
\
/* \
* Set comparison register : \
* Crystal freq . is 32768 , \
2011-08-05 21:14:35 +02:00
* pre - scale factor is 8 , we want CLOCK_CONF_SECOND ticks / sec : \
* 32768 = 8 * CLOCK_CONF_SECOND * OCR2A , less 1 for CTC mode \
2010-06-18 19:30:30 +02:00
*/ \
2011-08-05 21:14:35 +02:00
OCR2A = 32768 / 8 / CLOCK_CONF_SECOND - 1 ; \
2010-06-18 19:30:30 +02:00
\
/* \
* Set timer control register : \
* - prescale : 8 ( CS21 ) \
* - counter reset via comparison register ( WGM21 ) \
*/ \
TCCR2A = _BV ( WGM21 ) ; \
TCCR2B = _BV ( CS21 ) ; \
\
/* Clear interrupt flag register */ \
TIFR2 = TIFR2 ; \
\
/* \
* Raise interrupt when value in OCR2 is reached . Note that the \
* counter value in TCNT2 is cleared automatically . \
*/ \
TIMSK2 = _BV ( OCIE2A ) ;
2011-08-17 19:15:26 +02:00
# else /* !AVR_CONF_USE32KCRYSTAL */
/* Determine the largest value that can be used with 8 bit timer0 */
# ifndef F_CPU
# error "Please define CPU clock speed for your platform. #define F_CPU 8000000UL is typical."
# endif
# if CLOCK_CONF_SECOND == 0
# error "Please define timer ticks per second for your platform. #define CLOCK_CONF_SECOND 128 is typical."
# endif
# ifdef AVR_CONF_TMR0_PRESCALE
# elif F_CPU / CLOCK_CONF_SECOND < 256
# define AVR_CONF_TMR0_PRESCALE 1
# elif F_CPU / CLOCK_CONF_SECOND < 256 * 8
# define AVR_CONF_TMR0_PRESCALE 8
# elif F_CPU / CLOCK_CONF_SECOND < 256 * 64
2011-08-18 19:58:20 +02:00
# define AVR_CONF_TMR0_PRESCALE 64
2011-08-17 19:15:26 +02:00
# elif F_CPU / CLOCK_CONF_SECOND < 256 * 256
# define AVR_CONF_TMR0_PRESCALE 256
# else
# define AVR_CONF_TMR0_PRESCALE 1024
# endif
# if F_CPU / CLOCK_CONF_SECOND / AVR_CONF_TMR0_PRESCALE > 255
# error "Can not prescale CPU clock to get specified ticks per second. F_CPU / CLOCK_CONF_SECOND / 1024 must be less than 256."
# endif
# if AVR_CONF_TMR0_PRESCALE == 1
# define AVR_TCCR0B_CONF _BV(CS00)
# elif AVR_CONF_TMR0_PRESCALE == 8
# define AVR_TCCR0B_CONF _BV(CS01)
# elif AVR_CONF_TMR0_PRESCALE == 64
# define AVR_TCCR0B_CONF _BV(CS01) | _BV(CS00)
# elif AVR_CONF_TMR0_PRESCALE == 256
# define AVR_TCCR0B_CONF _BV(CS02)
# elif AVR_CONF_TMR0_PRESCALE == 1024
# define AVR_TCCR0B_CONF _BV(CS02) | _BV(CS00)
2010-06-18 19:30:30 +02:00
# else
2011-08-17 19:15:26 +02:00
# error "Prescale factor not supported. Allowed values are 1,8,64,256,1024."
# endif
2010-06-22 18:17:24 +02:00
# define AVR_OUTPUT_COMPARE_INT TIMER0_COMPA_vect
2011-08-17 19:15:26 +02:00
2008-10-14 21:06:51 +02:00
# define OCRSetup() \
/* Select internal clock */ \
ASSR = 0x00 ; \
\
/* Set counter to zero */ \
TCNT0 = 0 ; \
\
/* \
* Set comparison register : \
2011-08-17 19:15:26 +02:00
* Crystal freq . is F_CPU , prescale is given , \
* We want CLOCK_CONF_SECOND ticks / sec : \
* F_CPU = AVR_CONF_TMR0_PRESCALE * CLOCK_CONF_SECOND * OCR2A , less 1 for CTC mode \
2008-10-14 21:06:51 +02:00
*/ \
2011-08-17 19:15:26 +02:00
OCR0A = F_CPU / AVR_CONF_TMR0_PRESCALE / CLOCK_CONF_SECOND - 1 ; \
2008-10-14 21:06:51 +02:00
\
/* \
* Set timer control register : \
2011-08-17 19:15:26 +02:00
* - prescale according to AVR_CONF_TMR0_PRESCALE \
2008-10-14 21:06:51 +02:00
* - counter reset via comparison register ( WGM01 ) \
*/ \
TCCR0A = _BV ( WGM01 ) ; \
2011-08-17 19:15:26 +02:00
TCCR0B = AVR_TCCR0B_CONF ; \
2008-10-14 21:06:51 +02:00
\
/* Clear interrupt flag register */ \
TIFR0 = TIFR0 ; \
\
/* \
* Raise interrupt when value in OCR0 is reached . Note that the \
* counter value in TCNT0 is cleared automatically . \
*/ \
TIMSK0 = _BV ( OCIE0A ) ;
2010-06-18 19:30:30 +02:00
# endif /* AVR_CONF_USE32KCRYSTAL */
2008-10-14 21:06:51 +02:00
2011-08-03 17:18:55 +02:00
# elif defined (__AVR_ATmega644__) || defined (__AVR_ATmega328P__)
# define OCRSetup() \
/* Set counter to zero */ \
TCNT0 = 0 ; \
\
/* \
* Set comparison register : \
2011-08-05 21:14:35 +02:00
* Crystal freq . is F_CPU , \
* pre - scale factor is 256 , want CLOCK_CONF_SECOND ticks / sec : \
2011-08-03 17:18:55 +02:00
*/ \
2011-08-05 21:14:35 +02:00
OCR0A = F_CPU / 256UL / CLOCK_CONF_SECOND - 1 ; \
2011-08-03 17:18:55 +02:00
\
/* \
* Set timer control register : \
* - prescale : 256 ( CS02 ) \
* - counter reset via comparison register ( WGM01 ) \
*/ \
TCCR0A = _BV ( WGM01 ) ; \
TCCR0B = _BV ( CS02 ) ; \
\
/* Clear interrupt flag register */ \
TIFR0 = 0x00 ; \
\
/* \
* Raise interrupt when value in OCR0 is reached . Note that the \
* counter value in TCNT0 is cleared automatically . \
*/ \
TIMSK0 = _BV ( OCIE0A ) ;
# define AVR_OUTPUT_COMPARE_INT TIMER0_COMPA_vect
# elif defined (__AVR_ATmega8515__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__)
# define AVR_OUTPUT_COMPARE_INT TIMER0_COMP_vect
# define OCRSetup() \
/* Set counter to zero */ \
TCNT0 = 0 ; \
\
/* \
* Set comparison register : \
2011-08-05 21:14:35 +02:00
* Crystal freq . is F_CPU , \
* pre - scale factor is 256 , we want CLOCK_CONF_SECOND ticks / sec : \
* F_CPU = 256 * CLOCK_CONF_SECOND * OCR0 \
2011-08-03 17:18:55 +02:00
*/ \
2011-08-05 21:14:35 +02:00
OCR0 = F_CPU / 256UL / CLOCK_CONF_SECOND ; \
2011-08-03 17:18:55 +02:00
\
/* \
* Set timer control register : \
* - prescale : 256 ( CS02 ) \
* - counter reset via comparison register ( WGM01 ) \
*/ \
TCCR0 = _BV ( CS02 ) | _BV ( WGM01 ) ; \
\
/* Clear interrupt flag register */ \
TIFR = 0x00 ; \
\
/* \
* Raise interrupt when value in OCR0 is reached . Note that the \
* counter value in TCNT0 is cleared automatically . \
*/ \
TIMSK = _BV ( OCIE0 ) ;
# elif defined (__AVR_ATmega8__)
# define AVR_OUTPUT_COMPARE_INT TIMER2_COMP_vect
# define OCRSetup() \
/* Set counter to zero */ \
TCNT2 = 0 ; \
\
/* \
* Set comparison register : \
2011-08-05 21:14:35 +02:00
* Crystal freq . is F_CPU , \
* pre - scale factor is 256 , we want CLOCK_CONF_SECOND ticks / sec : \
* F_CPU = 256 * CLOCK_CONF_SECOND * OCR2 \
2011-08-03 17:18:55 +02:00
*/ \
2011-08-05 21:14:35 +02:00
OCR2 = F_CPU / 256UL / CLOCK_CONF_SECOND ; \
2011-08-03 17:18:55 +02:00
\
/* \
* Set timer control register : \
* - prescale : 256 ( CS21 CS22 ) \
* - counter reset via comparison register ( WGM21 ) \
*/ \
TCCR2 = _BV ( CS22 ) | _BV ( CS21 ) | _BV ( WGM21 ) ; \
\
/* Clear interrupt flag register */ \
TIFR = 0x00 ; \
\
/* \
* Raise interrupt when value in OCR2 is reached . Note that the \
* counter value in TCNT2 is cleared automatically . \
*/ \
TIMSK = _BV ( OCIE2 ) ;
2008-10-14 21:06:51 +02:00
# else
# error "Setup CPU in clock-avr.h"
# endif
# endif //CONTIKI_CLOCK_AVR_H