You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.4 KiB
84 lines
2.4 KiB
5 years ago
|
/*
|
||
|
|| @author Paul Stoffregen (paul at pjrc dot com)
|
||
|
|| @contribution Brett Hagman <bhagman@wiring.org.co>
|
||
|
|| @url http://wiring.org.co/
|
||
|
||
|
||
|
|| @description
|
||
|
|| | A Software PWM Library
|
||
|
|| |
|
||
|
|| | Simple timer abstractions.
|
||
|
|| #
|
||
|
||
|
||
|
|| @license Please see the accompanying LICENSE.txt file for this project.
|
||
|
||
|
||
|
|| @name Software PWM Library support
|
||
|
|| @type Library support
|
||
|
|| @target Atmel AVR 8 Bit
|
||
|
||
|
||
|
|| @version 1.0.1
|
||
|
||
|
||
|
*/
|
||
|
|
||
|
#include <avr/io.h>
|
||
|
#include <avr/interrupt.h>
|
||
|
|
||
|
// allow certain chips to use different timers
|
||
|
#if defined(__AVR_ATmega32U4__)
|
||
|
#define USE_TIMER4_HS // Teensy 2.0 lacks timer2, but has high speed timer4 :-)
|
||
|
#elif defined(__arm__) && defined(TEENSYDUINO)
|
||
|
#define USE_INTERVALTIMER // Teensy 3.x has special interval timers :-)
|
||
|
#else
|
||
|
#define USE_TIMER1
|
||
|
#endif
|
||
|
|
||
|
// for each timer, these macros define how to actually use it
|
||
|
#if defined(USE_TIMER1)
|
||
|
#define SOFTPWM_TIMER_INTERRUPT TIMER1_COMPA_vect
|
||
|
#define SOFTPWM_TIMER_SET(val) (TCNT1 = (val))
|
||
|
#define SOFTPWM_TIMER_INIT(ocr) ({\
|
||
|
cli(); \
|
||
|
TCCR1A = 0; \
|
||
|
TCCR1B = (1 << WGM12); \
|
||
|
TCCR1B |= ((1 << CS10) | (1 << CS12)); \
|
||
|
TIMSK1 = (1 << OCIE1A); \
|
||
|
OCR1A = 15624; \
|
||
|
sei(); \
|
||
|
})
|
||
|
|
||
|
#elif defined(USE_TIMER2)
|
||
|
#define SOFTPWM_TIMER_INTERRUPT TIMER2_COMPA_vect
|
||
|
#define SOFTPWM_TIMER_SET(val) (TCNT2 = (val))
|
||
|
#define SOFTPWM_TIMER_INIT(ocr) ({\
|
||
|
TIFR2 = (1 << TOV2); /* clear interrupt flag */ \
|
||
|
TCCR2B = (1 << CS21); /* start timer (ck/8 prescalar) */ \
|
||
|
TCCR2A = (1 << WGM21); /* CTC mode */ \
|
||
|
OCR2A = (15624); /* We want to have at least 30Hz or else it gets choppy */ \
|
||
|
TIMSK2 = (1 << OCIE2A); /* enable timer2 output compare match interrupt */ \
|
||
|
})
|
||
|
#elif defined(USE_TIMER4_HS)
|
||
|
#define SOFTPWM_TIMER_INTERRUPT TIMER4_COMPA_vect
|
||
|
#define SOFTPWM_TIMER_SET(val) (TCNT4 = (val))
|
||
|
#define SOFTPWM_TIMER_INIT(ocr) ({\
|
||
|
TCCR4A = 0; \
|
||
|
TCCR4B = 0x04; /* CTC Mode */\
|
||
|
TCCR4C = 0; \
|
||
|
TCCR4D = 0; \
|
||
|
TCCR4E = 0; \
|
||
|
OCR4C = 0; \
|
||
|
OCR4C = (ocr); \
|
||
|
TIMSK4 = (1 << OCIE4A); \
|
||
|
})
|
||
|
#elif defined(USE_INTERVALTIMER)
|
||
|
#define SOFTPWM_TIMER_INTERRUPT softpwm_interval_timer
|
||
|
#ifdef ISR
|
||
|
#undef ISR
|
||
|
#endif
|
||
|
#define ISR(f) void f(void)
|
||
|
#define SOFTPWM_TIMER_SET(val)
|
||
|
#define SOFTPWM_TIMER_INIT(ocr) ({\
|
||
|
IntervalTimer *t = new IntervalTimer(); \
|
||
|
t->begin(softpwm_interval_timer, 1000000.0 / (float)(SOFTPWM_FREQ * 256)); \
|
||
|
})
|
||
|
#endif
|
||
|
|