X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=tinyboard.git;a=blobdiff_plain;f=projects%2Fled-blinker%2Fmain.c;fp=projects%2Fled-blinker%2Fmain.c;h=70491edcf029f30f9fa1bacded8ce4ed192cf7f2;hp=0000000000000000000000000000000000000000;hb=c4ebe9bfc347f0acaa1319e982d9a999eb9063cb;hpb=85a869857e315a5f4b4b20dee7d44429c1d0cc1c diff --git a/projects/led-blinker/main.c b/projects/led-blinker/main.c new file mode 100644 index 0000000..70491ed --- /dev/null +++ b/projects/led-blinker/main.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include + +/* + * Overview: + * three LEDs: + * PB1/OC1A yellow + * PB2 yellow + * PB4/OC1B red + */ + +static void init() +{ + DDRB |= _BV(PB1) | _BV(PB2) | _BV(PB4); + + // PWM setup, use T/C 1 + TCCR1 = _BV(CS10) // clock at CLK/1 + | _BV(PWM1A) // OCR1A in PWM mode + | _BV(COM1A1); // clear on compare match + GTCCR = _BV(PWM1B) // OCR1B in PWM mode + | _BV(COM1B1); // clear on compare match) + + OCR1C = 255; + OCR1A = 0; + OCR1B = 0; +} + + +static unsigned char levels[] = { + 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 255 +}; +#define N_LEVELS (sizeof(levels)/sizeof(levels[0])) + +static void led_set(unsigned char led, unsigned char val) +{ + switch (led) { + case 0: + OCR1A = val < N_LEVELS ? levels[val] : levels[N_LEVELS-1]; + break; + case 1: + if (val) { + PORTB |= _BV(PB2); + } else { + PORTB &= ~_BV(PB2); + } + break; + case 2: + OCR1B = val < N_LEVELS ? levels[val] : levels[N_LEVELS-1]; + break; + } +} + +static unsigned char rand[] = { +193, 33, 133, 97, 139, 225, 40, 105, 110, 238, 57, 250, 26, 221, 166, 247, 138, 23, 107, 122, 154, 33, 201, 66, 154, 78, 137, 198, 86, 232, 38, 182, 16, 198, 73, 231, 58, 114, 58, 105, +}; +#define N_RAND (sizeof(rand)/sizeof(rand[0])) + +static void led0() +{ + static unsigned char r, l, exp; + +again: + if (l == exp) { + r++; + if (r > N_RAND-7) + r = 0; + exp = rand[r] >> 4; + if (exp >= N_LEVELS-4) + goto again; + } + + if (l < exp) { + l++; + } else if (l > exp) { + l--; + } + + led_set(0, l); +} + +static void led1() +{ + static unsigned char r; + unsigned char exp; + + led_set(1, 1); +#if 0 +again: + r++; + if (r > N_RAND) + r = 0; + exp = rand[r]; + + led_set(1, ((exp >> 3) & 1) ^ ((exp >> 5) & 1)); +#endif +} + +static void led2() +{ + static unsigned char r, l, exp; + +again: + if (l == exp) { + r++; + if (r > N_RAND) + r = 0; + exp = rand[r] & 0xF; + if (exp >= N_LEVELS) + goto again; + } + + if (l < exp) { + l++; + } else if (l > exp) { + l--; + } + + led_set(2, l); +} + +int main(void) +{ + init(); + + while (1) { + led0(); + led1(); + led2(); + _delay_ms(40); + } + +}