Created
February 9, 2010 02:45
-
-
Save nikolasco/298863 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <avr/io.h> | |
#include "heart.h" | |
// note that one second = F_CPU/1024 (currently 1000000/1024) | |
// also note that the maximum duration one frame = (2^16 - 1) * 1000000/1024 | |
// or about 1min | |
typedef struct {uint8_t leds[27]; uint16_t dur;} anim_frame; | |
typedef struct {uint16_t num_frames; anim_frame frames[];} anim; | |
static const anim ANIMATION = {2, { | |
{{ | |
255, 255, 255, 255, | |
255, 255, 255, 255, 255, 255, 255, | |
255, 255, 255, 255, 255, 255, 255, | |
255, 255, 255, 255, 255, | |
255, 255, 255, | |
255 | |
}, 976}, | |
{{ | |
0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, | |
0, 0, 0, | |
0 | |
}, 976} | |
}}; | |
int main() { | |
uint8_t mode_pushed = 0; | |
DDRA = ALL_INPUT; | |
PORTA = ALL_GND_PULL_OFF; | |
DDRB = ALL_INPUT; | |
PORTB = ALL_POS_PULL_ON; | |
// set prescaler to 1024 | |
TCCR1B = _BV(CS12) | _BV(CS10); | |
while (1) { | |
for (uint16_t f = 0; f < ANIMATION.num_frames; f++) { | |
for (TCNT1 = 0; TCNT1 < ANIMATION.frames[f].dur; /*nothing*/) { | |
for (uint8_t i = 0; i < 27; i++) { | |
uint8_t tmp_port = ALL_GND_PULL_OFF, tmp_ddr = ALL_INPUT; | |
if (ANIMATION.frames[f].leds[i]) { | |
turn_led_on(&tmp_ddr, &tmp_port, i); | |
} | |
DDRA = tmp_ddr; | |
PORTA = tmp_port; | |
} | |
DDRA = ALL_INPUT; | |
PORTA = ALL_POS_PULL_ON; | |
DDRB = ALL_INPUT; | |
PORTB = ALL_POS_PULL_ON; | |
if (debounce_passed()) { | |
//return 0; // works! | |
if (mode_pushed && bit_is_clear(MODE_PIN, MODE_BIT)) { | |
// just halt for now | |
return 0; // not happening :( | |
mode_pushed = 0; | |
} | |
} | |
if (bit_is_clear(MODE_PIN, MODE_BIT)) { | |
mode_pushed = 1; | |
start_debounce(); | |
} | |
} | |
} | |
} | |
DDRA = ALL_INPUT; | |
PORTA = ALL_GND_PULL_OFF; | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <inttypes.h> | |
#define LED_DEF(pi_pos, pi_gnd) \ | |
{ \ | |
pi_pos, pi_gnd \ | |
} | |
#define LED_PAIR(pi_pos, pi_gnd) \ | |
LED_DEF(pi_pos, pi_gnd), \ | |
LED_DEF(pi_gnd, pi_pos) | |
typedef struct {uint8_t pos, gnd;} led_pair_t; | |
static const led_pair_t | |
LED_PINS[] = { | |
LED_PAIR(5, 4), | |
LED_PAIR(5, 3), | |
LED_PAIR(5, 2), | |
LED_PAIR(5, 1), | |
LED_PAIR(5, 0), | |
LED_PAIR(4, 3), | |
LED_PAIR(4, 2), | |
LED_PAIR(4, 1), | |
LED_PAIR(4, 0), | |
LED_PAIR(3, 2), | |
LED_PAIR(3, 1), | |
LED_PAIR(3, 0), | |
LED_PAIR(2, 1), | |
LED_DEF(2, 0), | |
}; | |
static const uint8_t NUM_LEDS = 27; | |
#define POWER_DDR DDRB | |
#define POWER_PORT PORTB | |
#define POWER_PIN PINB | |
static const uint8_t POWER_BIT = 2; | |
#define MODE_DDR DDRA | |
#define MODE_PORT PORTA | |
#define MODE_PIN PINA | |
static const uint8_t MODE_BIT = 6; | |
#define DEBOUNCE_COUNTER TCNT0 | |
#define DEBOUNCE_CONTROL TCCR0B | |
static const uint8_t DEBOUNCE_DELAY = 20; | |
static inline void start_debounce() { | |
DEBOUNCE_COUNTER = 0; | |
DEBOUNCE_CONTROL = _BV(CS02) | _BV(CS00); | |
} | |
static inline uint8_t debounce_passed() { | |
if (DEBOUNCE_COUNTER <= DEBOUNCE_DELAY) return 0; | |
DEBOUNCE_CONTROL = 0; | |
DEBOUNCE_COUNTER = 0; | |
return 1; | |
} | |
static const uint8_t ALL_INPUT = 0, ALL_OUTPUT = ~0, | |
ALL_POS_PULL_ON = ~0, ALL_GND_PULL_OFF = 0; | |
static inline void set_output(uint8_t *ddr, uint8_t pin_no) { | |
*ddr |= _BV(pin_no); | |
} | |
static inline void set_input(uint8_t *ddr, uint8_t pin_no) { | |
*ddr &= ~_BV(pin_no); | |
} | |
static inline void set_pos(uint8_t *port, uint8_t pin_no) { | |
set_output(port, pin_no); | |
} | |
static inline void set_gnd(uint8_t *port, uint8_t pin_no) { | |
set_input(port, pin_no); | |
} | |
static inline void set_pull_on(uint8_t *port, uint8_t pin_no) { | |
set_output(port, pin_no); | |
} | |
static inline void set_pull_off(uint8_t *port, uint8_t pin_no) { | |
set_input(port, pin_no); | |
} | |
static inline void turn_led_on(uint8_t *ddr, uint8_t *port, uint8_t num) { | |
set_output(ddr, LED_PINS[num].pos); | |
set_output(ddr, LED_PINS[num].gnd); | |
set_pos(port, LED_PINS[num].pos); | |
set_gnd(port, LED_PINS[num].gnd); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment