diff options
author | David Lamparter <equinox@diac24.net> | 2012-05-11 01:53:08 +0200 |
---|---|---|
committer | David Lamparter <equinox@diac24.net> | 2012-05-11 01:53:08 +0200 |
commit | 5a9f9a5932915a5752acc79a97b1f16982e3ec5a (patch) | |
tree | 187770986f9bab829190e4bf00f2b6fc58433343 | |
parent | 203a267ade0bca9316ba2ba37e438a5a226aa903 (diff) |
dali: initial implementation
-rw-r--r-- | can.c | 50 | ||||
-rw-r--r-- | dali.c | 117 |
2 files changed, 165 insertions, 2 deletions
@@ -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; + } } } @@ -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 +} |