1
0
Fork 0
mirror of https://codeberg.org/SiB64/blinkenlights.git synced 2026-06-28 16:19:49 +02:00

Compare commits

..

No commits in common. "leonie" and "master" have entirely different histories.

2 changed files with 89 additions and 39 deletions

View file

@ -27,7 +27,8 @@ CC=avr-gcc -Wall -Wno-parentheses -MMD -std=c99 -O3 \
-fpack-struct \ -fpack-struct \
-fshort-enums \ -fshort-enums \
-mtiny-stack \ -mtiny-stack \
-mint8 -mint8 \
-fverbose-asm
SN = $(SN_$(PROJ)) SN = $(SN_$(PROJ))
CFLAGS = $($*_CFLAGS) $(DEBUG) -I. -DSN="$(SN)" CFLAGS = $($*_CFLAGS) $(DEBUG) -I. -DSN="$(SN)"

View file

@ -9,77 +9,126 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/sleep.h> #include <avr/sleep.h>
#define Bit(x) (1<<(x))
#define SetPORT(x) PORTB |= Bit(x)
#define ClrPORT(x) PORTB &=~ Bit(x)
#define GetPORT(x) (PINB & Bit(x))
#define RES_PORT 0 #define RES_PORT 0
#define TRIG_PORT 1 #define TRIG_PORT 1
#define OUT_PORT 2 #define OUT_PORT 2
#define LED2_PORT 3 #define LED2_PORT 3
#define LED1_PORT 4 #define LED1_PORT 4
uint8_t tick; #define START_PORT OUT_PORT
// 9.6MHz/8/240 = 5kHz
#define MAX_DC 240
#define DC_EXP 12
static uint32_t led1_dc;
static inline
uint8_t get_dc(uint32_t dc) {
return dc >> 24;
}
static inline
uint32_t set_dc(uint8_t dc) {
return ((uint32_t)dc << 24) - 1;
}
static inline
uint32_t fade(uint32_t dc)
{
uint32_t diff = dc >> (8*((DC_EXP+4)>>3));
if (DC_EXP & 4)
diff <<= 8 - (DC_EXP&7);
else
diff >>= DC_EXP & 3;
return dc - diff;
}
ISR(TIM0_COMPB_vect) ISR(TIM0_COMPB_vect)
{ {
PORTB |= 1 << LED2_PORT; SetPORT(LED1_PORT);
} }
ISR(TIM0_COMPA_vect) ISR(TIM0_COMPA_vect)
{ {
PORTB &=~ (1 << LED2_PORT); TIFR0 = Bit(OCF0B);
TIFR0 = (1<<OCF0B); ClrPORT(LED1_PORT);
tick = 1; OCR0B = MAX_DC + 1 - (uint8_t)(led1_dc >> 24);
} }
void set_dc(uint8_t dc) static inline
void pulse_led1(uint8_t dc)
{ {
OCR0B = 255 - dc; led1_dc = set_dc(dc);
} OCR0B = MAX_DC + 1 - dc;
uint8_t get_dc()
{
return 255 - OCR0B;
} }
static inline static inline
void init_timer() void init_timer()
{ {
DDRB = (1<<LED1_PORT) | (1<<LED2_PORT); DDRB = Bit(LED1_PORT) | Bit(LED2_PORT);
ClrPORT(LED1_PORT);
TCCR0A = 0x02; // CTC TOP=OCRA TOV=MAX TCCR0A = 0x02; // CTC TOP=OCRA TOV=MAX
TCCR0B = 0x02; // clk_IO/8 TCCR0B = 0x02; // clk_IO/8
OCR0A = 254; OCR0A = MAX_DC;
set_dc(10); OCR0B = 255; // off
TIMSK0 = (1<<OCIE0A) | (1<<OCIE0B); TIMSK0 = Bit(OCIE0A) | Bit(OCIE0B);
} }
static const uint8_t nticks = 50; ISR(PCINT0_vect)
{
SetPORT(LED2_PORT);
if (!GetPORT(START_PORT))
pulse_led1(MAX_DC);
ClrPORT(LED2_PORT);
}
static inline
void init_trig()
{
PCMSK = Bit(START_PORT);
GIMSK = Bit(PCIE);
}
void init_wdt(uint8_t wdt_period)
{
#ifdef WDT_TRIGGERED
uint8_t cr = Bit(WDE) | (wdt_period&7) << WDP0 | (wdt_period&8) << (WDP3-3);
__asm__("STS %[CSR], %[CE]" "\n\t"
"STS %[CSR], %[WE]" "\n"
::[CSR] "n" (&WDTCR),
[CE] "r" ((Bit(WDCE) | Bit(WDE))),
[WE] "r" (cr)
);
#endif // WDT_TRIGGERED
}
int main() int main()
{ {
init_timer(); init_timer();
init_trig();
pulse_led1(MAX_DC);
init_wdt(7);
set_sleep_mode(SLEEP_MODE_IDLE); set_sleep_mode(SLEEP_MODE_IDLE);
uint8_t n = 0; uint16_t debug = 0;
while (1) { while (1) {
if (!debug) {
// debug = 0xff00L | OCR0B;
ClrPORT(LED2_PORT);
}
else {
if (debug&1)
SetPORT(LED2_PORT);
else
ClrPORT(LED2_PORT);
debug >>= 1;
}
sei(); sei();
sleep_mode(); sleep_mode();
led1_dc = fade(led1_dc);
if (PINB & (1 << TRIG_PORT))
PORTB &=~ (1 << LED1_PORT);
else
PORTB |= (1 << LED1_PORT);
uint8_t dc = get_dc();
if (dc == 0 && !(PINB & (1 << OUT_PORT)))
set_dc(255);
if (tick) {
tick = 0;
n = n - 1;
if (n == 0) {
n = nticks;
if (dc)
set_dc(dc-1);
}
}
} }
} }