summaryrefslogtreecommitdiff
path: root/dali.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2012-05-11 01:53:08 +0200
committerDavid Lamparter <equinox@diac24.net>2012-05-11 01:53:08 +0200
commit5a9f9a5932915a5752acc79a97b1f16982e3ec5a (patch)
tree187770986f9bab829190e4bf00f2b6fc58433343 /dali.c
parent203a267ade0bca9316ba2ba37e438a5a226aa903 (diff)
dali: initial implementation
Diffstat (limited to 'dali.c')
-rw-r--r--dali.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/dali.c b/dali.c
new file mode 100644
index 0000000..d53675b
--- /dev/null
+++ b/dali.c
@@ -0,0 +1,117 @@
+static uint16_t dali_word;
+static uint8_t dali_subctr, dali_state, dali_bit;
+static uint8_t dali_prevpin;
+
+ISR(TIMER0_COMPA_vect)
+{
+ uint8_t inv = 1, data;
+
+ TCNT0 = 0;
+
+ if (PIND & D_DALII) {
+ PORTD |= (1 << D_LED2);
+ } else {
+ PORTD &= ~(1 << D_LED2);
+ }
+
+ data = (PIND >> D_DALII) & 1;
+ if (dali_state == 0 && data) {
+ uart_puts("dali rxbegin\n");
+ dali_state = 17;
+ dali_subctr = 4;
+ dali_word = 1;
+ }
+
+ /* really simple CDR - resync clock on edge.
+ * this is ABSOLUTELY neccessary. */
+ if (dali_state >= 16 && (dali_prevpin ^ data)) {
+ if (dali_subctr >= 2 && dali_subctr <= 5)
+ dali_subctr = 4;
+ }
+ dali_prevpin = data;
+
+ dali_subctr++;
+ dali_subctr &= 7;
+ if (dali_subctr)
+ return;
+
+ switch (dali_state) {
+ /* idle */
+ case 0:
+ return;
+
+ /* write */
+ /* 1 + 2: start bit */
+ case 1:
+ uart_puts("dali[");
+ uart_puthex(dali_word >> 8);
+ uart_puthex(dali_word & 0xff);
+ uart_puts("]\n");
+
+ PORTD |= (1 << D_DALIO);
+ dali_state++;
+ return;
+ case 2:
+ PORTD &= ~(1 << D_DALIO);
+ dali_state = 4;
+ dali_bit = 0;
+ return;
+ case 4:
+ inv = 0;
+ case 5:
+ dali_state ^= 1;
+
+ data = (dali_word >> (15 - dali_bit)) & 1;
+ data ^= inv;
+ if (data)
+ PORTD |= (1 << D_DALIO);
+ else
+ PORTD &= ~(1 << D_DALIO);
+
+ if (inv)
+ dali_bit++;
+ if (dali_bit == 16)
+ dali_state = 6;
+ break;
+ case 6:
+ PORTD &= ~(1 << D_DALIO);
+ dali_state = 0;
+ uart_puts("dali sent\n");
+ return;
+
+ /* read */
+ case 16:
+ dali_word <<= 1;
+ dali_word |= 1 - data;
+ dali_state = 17;
+ if (dali_word & 0x1000) {
+ dali_state = 0;
+ dali_word >>= 3;
+
+ uart_puts("dali_rx ");
+ uart_puthex(dali_word & 0xff);
+ uart_puts("\n");
+ }
+ break;
+ case 17:
+ dali_state = 16;
+ break;
+ }
+}
+
+static void dali_init(void)
+{
+ PORTD |= (1 << D_DALII);
+ PORTD &= ~(1 << D_DALIO);
+
+ dali_subctr = 0;
+ dali_state = 0;
+ dali_prevpin = 0;
+
+ TCNT0 = 0;
+ OCR0A = 52; // 8 MHz / 8 / 52 = 19230.
+ TIMSK0 = (1 << OCIE0A);
+ TIFR0 = (1 << OCF0A);
+ TCCR0A = 0;
+ TCCR0B = (0 << CS02) | (1 << CS01) | (0 << CS00); // 8 MHz / 8 = 1MHz
+}