summaryrefslogtreecommitdiff
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
parent203a267ade0bca9316ba2ba37e438a5a226aa903 (diff)
dali: initial implementation
-rw-r--r--can.c50
-rw-r--r--dali.c117
2 files changed, 165 insertions, 2 deletions
diff --git a/can.c b/can.c
index 4e41fe8..c2307a9 100644
--- a/can.c
+++ b/can.c
@@ -16,6 +16,14 @@ const uint8_t __signature[3] __attribute__((section (".signature"), used)) =
#define B_MOSI 3
#define B_SS 2
+#define D_TXD 1
+#define D_DALII 3
+#define D_DALIO 4
+#define D_LED1 5
+#define D_LED2 6
+
+#include "dali.c"
+
#define spi_ss(x) PORTB = ((x) << B_SS) | 0x3;
static volatile bool canint = false;
@@ -177,6 +185,8 @@ int main(void)
uart_init();
+ DDRD |= (1 << D_LED1) | (1 << D_LED2 ) | (1 << D_TXD) | (1 << D_DALIO);
+
spi_ss(1);
DDRB = (1 << B_SCK) | (1 << B_MOSI) | (1 << B_SS);
@@ -190,7 +200,10 @@ int main(void)
sei();
uart_puts("\nspi: init ok\n");
- _delay_ms(50);
+ _delay_ms(25);
+
+ dali_init();
+ _delay_ms(25);
spi_ss(0);
spi_wrrd(0xc0);
@@ -208,12 +221,45 @@ int main(void)
can_init();
can_CANSTAT();
+ cli();
+ dali_word = 0xff08; /* ON */
+ dali_state = 1;
+ sei();
+ _delay_ms(25);
+
+ cli();
+ dali_word = 0xff08; /* OFF */
+ dali_state = 1;
+ sei();
+
+ for (int i = 0; i < 40; i++)
+ _delay_ms(25);
+
+ uint8_t ctr = 0;
while (1) {
if (canint) {
canint = false;
can_int();
}
- _delay_ms(25);
+ _delay_ms(40);
+ ctr++;
+ if (ctr == 40) {
+ dali_word = 0xff91;
+ dali_state = 1;
+ }
+ if (ctr == 80) {
+ dali_word = 0xff99;
+ dali_state = 1;
+ }
+ if (ctr == 120) {
+ dali_word = 0xffa0;
+ dali_state = 1;
+ }
+ if (ctr == 160) {
+ dali_word = 0xff90;
+ dali_state = 1;
+ ctr = 0;
+ }
}
}
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
+}