summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.h2
-rw-r--r--led.c58
-rw-r--r--led.h9
-rw-r--r--main.c103
4 files changed, 85 insertions, 87 deletions
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..1d25abc
--- /dev/null
+++ b/config.h
@@ -0,0 +1,2 @@
+#define PIN_LED PB0
+#define NUM_LEDS 50
diff --git a/led.c b/led.c
new file mode 100644
index 0000000..b0f9c1c
--- /dev/null
+++ b/led.c
@@ -0,0 +1,58 @@
+#include "config.h"
+#include "led.h"
+
+#include <avr/io.h>
+
+void signal_bit_0() {
+ asm volatile (
+ "sbi %0, %1\n\t"
+ "cbi %0, %1\n\t"
+ "rjmp .+0\n\t"
+ "rjmp .+0\n\t"
+ "rjmp .+0\n\t"
+ "nop\n\t"
+ :
+ : "I" (_SFR_IO_ADDR(PORTB)), "I" (PIN_LED)
+ );
+}
+
+void signal_bit_1() {
+ asm volatile (
+ "sbi %0, %1\n\t"
+ "rjmp .+0\n\t"
+ "nop\n\t"
+ "cbi %0, %1\n\t"
+ "rjmp .+0\n\t"
+ "rjmp .+0\n\t"
+ :
+ : "I" (_SFR_IO_ADDR(PORTB)), "I" (PIN_LED)
+ );
+}
+
+void signal_byte(unsigned char byte) {
+ for (unsigned char mask = 0x80; mask != 0; mask >>= 1) {
+ if (byte & mask)
+ signal_bit_1();
+ else
+ signal_bit_0();
+ }
+}
+
+void signal_led(struct colour *c) {
+ signal_byte(c->r);
+ signal_byte(c->g);
+ signal_byte(c->b);
+}
+
+void signal_led_sequence(int num_leds, struct colour *seq, int num_seq, int width, int start) {
+ for(int i = 0; i < num_leds; ++i) {
+ int j, p = i - start;
+
+ if (p >= 0)
+ j = (p / width % num_seq);
+ else
+ j = (num_seq - ((p + 1) / -width % num_seq) - 1);
+
+ signal_led(&seq[j]);
+ }
+}
diff --git a/led.h b/led.h
new file mode 100644
index 0000000..585f297
--- /dev/null
+++ b/led.h
@@ -0,0 +1,9 @@
+struct colour {
+ unsigned char r, g, b;
+};
+
+void signal_bit_0();
+void signal_bit_1();
+void signal_byte(unsigned char);
+void signal_led(struct colour *);
+void signal_led_sequence(int, struct colour *, int, int, int);
diff --git a/main.c b/main.c
index abc31d4..d1a466d 100644
--- a/main.c
+++ b/main.c
@@ -4,101 +4,30 @@
#include <stdlib.h>
#include <util/delay.h>
-#define PIN_LED PB0
-#define NUM_LEDS 50
+#include "config.h"
+#include "led.h"
-struct led {
- unsigned char r, g, b;
-};
-
-void signal_high() {
- asm volatile (
- "sbi %0, %1\n\t"
- "rjmp .+0\n\t"
- "nop\n\t"
- "cbi %0, %1\n\t"
- "rjmp .+0\n\t"
- "rjmp .+0\n\t"
- :
- : "I" (_SFR_IO_ADDR(PORTB)), "I" (PIN_LED)
- );
-}
-
-void signal_low() {
- asm volatile (
- "sbi %0, %1\n\t"
- "cbi %0, %1\n\t"
- "rjmp .+0\n\t"
- "rjmp .+0\n\t"
- "rjmp .+0\n\t"
- "nop\n\t"
- :
- : "I" (_SFR_IO_ADDR(PORTB)), "I" (PIN_LED)
- );
-}
-
-void signal_byte(unsigned char byte) {
- for (unsigned char mask = 0x80; mask != 0; mask >>= 1) {
- if (byte & mask)
- signal_high();
- else
- signal_low();
- }
-}
-
-void signal_led(struct led *led) {
- signal_byte(led->r);
- signal_byte(led->g);
- signal_byte(led->b);
-}
-
-void signal_led_sequence(int num_leds, struct led **seq, int num_seq) {
- for(int i = 0; i < num_leds; ++i) {
- int j = i % num_seq;
- signal_led(seq[j]);
- }
-}
+static struct colour seq[6];
int main() {
DDRB |= (1 << PIN_LED);
PORTB &= ~(1 << PIN_LED);
- struct led **seq = calloc(3, sizeof(*seq));
-
- seq[0] = calloc(1, sizeof(struct led));
- seq[1] = calloc(1, sizeof(struct led));
- seq[2] = calloc(1, sizeof(struct led));
+ seq[0].r = 255;
+ seq[1].r = 255;
+ seq[1].g = 127;
+ seq[2].r = 255;
+ seq[2].g = 255;
+ seq[3].g = 255;
+ seq[4].b = 255;
+ seq[5].r = 127;
+ seq[5].b = 255;
while (1) {
- seq[0]->g = 0;
- seq[1]->b = 0;
- seq[2]->r = 0;
- seq[0]->r = 255;
- seq[1]->g = 255;
- seq[2]->b = 255;
-
- signal_led_sequence(NUM_LEDS, seq, 3);
- _delay_ms(250);
-
- seq[0]->r = 0;
- seq[1]->g = 0;
- seq[2]->b = 0;
- seq[0]->b = 255;
- seq[1]->r = 255;
- seq[2]->g = 255;
-
- signal_led_sequence(NUM_LEDS, seq, 3);
- _delay_ms(250);
-
- seq[0]->b = 0;
- seq[1]->r = 0;
- seq[2]->g = 0;
- seq[0]->g = 255;
- seq[1]->b = 255;
- seq[2]->r = 255;
-
- signal_led_sequence(NUM_LEDS, seq, 3);
- _delay_ms(250);
+ for (int i = 0; i < NUM_LEDS; ++i) {
+ signal_led_sequence(NUM_LEDS, seq, 6, 4, i);
+ _delay_ms(100);
+ }
}
return 0;