From: Pat Thoyts Date: Wed, 12 Aug 2015 23:15:53 +0000 (+0100) Subject: Implemented a 'breathe' style pulse pattern for the PWM LED. X-Git-Url: https://privyetmir.co.uk/gitweb.cgi?a=commitdiff_plain;h=91afd8af0d9e37aeec03fae58e2fc04fff8d1f65;p=avr%2Ftimer-demo.git Implemented a 'breathe' style pulse pattern for the PWM LED. Signed-off-by: Pat Thoyts --- diff --git a/timer-demo.c b/timer-demo.c index 83fe5e6..4824a89 100644 --- a/timer-demo.c +++ b/timer-demo.c @@ -15,6 +15,9 @@ #include #include +static void init_timer2(void); +static void init_pwm_pin9(void); + /* * timer2: * Using a /64 prescaler with 1 16MHz clock and counting from @@ -34,22 +37,56 @@ const uint8_t TIMER_INIT = 6; const uint16_t PWM_TOP = 212; const uint16_t PWM_MATCH = 212/2; /* square wave, 50% */ +/* + * "breathe" pattern to match Apple's sleep indicator. + * Should use 100-200 Hz PWM, from 0 to 25% duty over a 1.7s period + * generated using exp(sin(x)) + */ +const uint8_t Pattern[255] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, + 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 12, 13, 13, 14, 15, + 16, 17, 19, 20, 21, 22, 23, 25, 26, 28, 29, 31, 32, 34, + 36, 37, 39, 41, 43, 45, 47, 49, 51, 53, 56, 58, 61, 63, 66, + 68, 71, 74, 77, 79, 82, 85, 88, 92, 95, 98, 101, 105, 108, 112, + 115, 119, 122, 126, 130, 134, 137, 141, 145, 149, 153, 157, 160, + 164, 168, 172, 176, 180, 184, 187, 191, 195, 198, 202, 205, 209, + 212, 215, 219, 222, 225, 227, 230, 233, 235, 238, 240, 242, 244, + 246, 247, 249, 250, 251, 252, 253, 253, 254, 254, 254, 254, 253, + 253, 252, 251, 250, 249, 248, 246, 245, 243, 241, 239, 236, 234, + 232, 229, 226, 223, 220, 217, 214, 211, 207, 204, 200, 197, 193, + 189, 185, 182, 178, 174, 170, 166, 162, 159, 155, 151, 147, 143, + 139, 135, 132, 128, 124, 121, 117, 113, 110, 107, 103, 100, 96, + 93, 90, 87, 84, 81, 78, 75, 72, 70, 67, 64, 62, 59, 57, 55, 52, + 50, 48, 46, 44, 42, 40, 38, 36, 35, 33, 31, 30, 28, 27, 25, 24, + 23, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 10, 9, 8, 8, + 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0 +}; + volatile uint16_t counter = 0; +volatile uint8_t pulse_delay = 0, pulse_index = 0; ISR(TIMER2_OVF_vect) { cli(); TCNT2 = TIMER_INIT; /* reset the timer */ + + if (++pulse_delay == 7) + { + int v; + ++pulse_index; + v = (int)(uint8_t)pgm_read_byte_near(Pattern + pulse_index); + OCR1A = (v * PWM_TOP) / 256; /* table value scaled to PWM_TOP range */ + pulse_delay = 0; + } if (++counter >= 250) { PORTD ^= _BV(PD5); - OCR1A = (OCR1A == 0) ? PWM_MATCH : 0; counter = 0; } sei(); } -static void init_timer2() +static void init_timer2(void) { cli(); /* 18.9: Disable the timer2 overflow interrupt for configuration */ @@ -69,7 +106,7 @@ static void init_timer2() sei(); } -static void init_pwm_pin9() +static void init_pwm_pin9(void) { /* * PD5,PD6 (5,6) are attached to timer0 (8 bit)