Skip to content

Instantly share code, notes, and snippets.

@nikolasco
Created February 9, 2010 02:45
Show Gist options
  • Save nikolasco/298863 to your computer and use it in GitHub Desktop.
Save nikolasco/298863 to your computer and use it in GitHub Desktop.
#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;
}
#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