The main example file.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <string.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/fuse.h>
#include <util/atomic.h>
#include "config.h"
#include "macros.h"
FUSES =
{
(FUSE_SUT0 & FUSE_CKSEL3 & FUSE_CKSEL1 & FUSE_CKSEL0),
(FUSE_SPIEN & FUSE_BOOTSZ1 & FUSE_BOOTSZ0)
};
volatile uint16_t g_animDelay;
const __flash uint8_t g_ledColorTable[][3] =
{
{ 0, 0, 0},
{255, 0, 0},
{255,127, 0},
{255,255, 0},
{ 0,255, 0},
{ 0,255,255},
{ 0, 0,255},
{127, 0,255},
{255, 0,255},
{255,255,255}
};
uint8_t g_animColor = 0;
uint8_t g_animPos = 0;
static inline uint8_t getButtonState(void)
{
}
static inline uint8_t animMerge(uint8_t pos, uint8_t from, uint8_t to)
{
return
((uint16_t)from*(ANIMATION_STEPS-pos) +
(uint16_t)to*pos)
/
ANIMATION_STEPS;
}
static inline void animDelaySet(double time) __attribute__((always_inline));
static inline void animDelaySet(double time) __attribute__((always_inline));
void animDelaySet(double time)
{
uint16_t val;
time *= 31250.0;
if(time >= UINT16_MAX)
val = UINT16_MAX;
else if(time <= 1.0)
val = 1;
else
val = (uint16_t)time;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
g_animDelay = val;
}
}
static inline uint8_t animDelayCheck(void)
{
uint8_t ret;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
ret = (0 == g_animDelay) ? 1 : 0;
}
return ret;
}
int main(void)
{
unsigned int loopcnt = 0;
);
TIMSK = 1<<TOIE0;
TCCR0 = 1<<CS00;
sei();
while(1)
{
uint8_t n;
utoa(loopcnt, buffer, 10);
for(n=strlen(buffer); n<5; n++)
if(getButtonState())
else
if(animDelayCheck())
{
const __flash uint8_t *pfrom, *pto;
uint8_t n;
animDelaySet(ANIMATION_FRAME_TIME/ANIMATION_STEPS);
pfrom = &g_ledColorTable[g_animColor][0];
pto = &g_ledColorTable[(g_animColor+1)%
ELEMS(g_ledColorTable)][0];
for(n=0; n<3; n++)
spwm_set(n, animMerge(g_animPos, *pfrom++, *pto++));
if(++g_animPos >= ANIMATION_STEPS)
{
g_animPos = 0;
if(++g_animColor >=
ELEMS(g_ledColorTable))
g_animColor = 0;
}
}
++loopcnt;
}
return 0;
}
ISR(TIMER0_OVF_vect)
{
uint16_t animDelay = g_animDelay;
if(0 < animDelay)
g_animDelay = g_animDelay - 1;
}