From 5eabc7da65b07e5915e19c31112754eabf76853c Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 18 May 2012 00:51:49 +0200 Subject: more code --- Makefile | 2 +- can.c | 82 ++++----------------------------------------------- dali2.c | 54 ++++++++++++++++++++++------------ dali_ctl.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dim.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ lightctrl.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ uart.c | 6 ++++ 7 files changed, 305 insertions(+), 95 deletions(-) create mode 100644 dali_ctl.c create mode 100644 dim.c create mode 100644 lightctrl.c diff --git a/Makefile b/Makefile index 23fc0af..9dc7daa 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: flash love -TARGET=can +TARGET=lightctrl CFLAGS_OPT=-Os \ -fpredictive-commoning -fmerge-all-constants -fmodulo-sched -fmodulo-sched-allow-regmoves \ -fgcse-sm -fgcse-las -fgcse-after-reload -fconserve-stack \ diff --git a/can.c b/can.c index 1772c30..c764d9b 100644 --- a/can.c +++ b/can.c @@ -1,29 +1,3 @@ -#define F_CPU 8000000 -#include -#include -#include -#include -#include -#include - -const uint8_t __signature[3] __attribute__((section (".signature"), used)) = - { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 }; - -#include "uart.c" - -#define B_SCK 5 -#define B_MISO 4 -#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 "dali2.c" - #define spi_ss(x) PORTB = ((x) << B_SS) | 0x3; static volatile bool canint = false; @@ -179,14 +153,8 @@ static void can_int(void) spi_perform(MCP2515_WRITE, A_CANINTF, 0x00); } -int main(void) +static void can_preinit(void) { - uint8_t status; - - 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); @@ -197,59 +165,21 @@ int main(void) EICRA = (1 << ISC01); EIMSK = (1 << INT0); - sei(); - - uart_puts("\nspi: init ok\n"); - _delay_ms(25); - - dali_init(); - _delay_ms(25); + _delay_ms(5); + /* chip reset */ spi_ss(0); spi_wrrd(0xc0); spi_ss(1); - _delay_ms(50); + _delay_ms(5); + spi_ss(0); spi_wrrd(0xb0); - status = spi_wrrd(0xff); + uint8_t status = spi_wrrd(0xff); spi_ss(1); uart_puts("can: status "); uart_puthex(status); uart_puts("\n"); - - can_init(); - can_CANSTAT(); - - dali_send(0xff08); - while (dali_queue_busy()) - ; - dali_send(0xff08); - - for (int i = 0; i < 40; i++) - _delay_ms(25); - - uint8_t ctr = 0; - while (1) { - if (canint) { - canint = false; - can_int(); - } - _delay_ms(40); - ctr++; - if (ctr == 40) - dali_send(0xff91); - if (ctr == 80) - dali_send(0xff99); - if (ctr == 120) - dali_send(0xffa0); - if (ctr == 160) { - dali_send(0xff90); - ctr = 0; - } - } } -void __do_copy_data(void) __attribute__((naked, section (".init4"), used)); -void __do_copy_data(void) { } - diff --git a/dali2.c b/dali2.c index e8c89de..b0fbcc0 100644 --- a/dali2.c +++ b/dali2.c @@ -22,14 +22,22 @@ static volatile bool dali_rx_avail; static volatile uint16_t dali_tx; static volatile bool dali_tx_rq; -#define XBUF 48 -static uint8_t dbuf[XBUF], sbuf[XBUF], dbufpos; +static uint16_t dalistat_falsestart, dalistat_noise, dalistat_manchester, dalistat_rxok; + + +#undef DEBUG + +#ifdef DEBUG +#define XBUF 36 +static uint8_t dbuf[XBUF], sbuf[XBUF], fbuf[XBUF]; +static int8_t dbufpos; +#define F_MAJ 0x01 +#define F_MCH 0x10 +#endif #define dali_s_listening() (dali_state <= DALI_SPACE) #define dali_s_cdr() (dali_state == DALI_RX_DATA) -#define DEBUG 0 - ISR(TIMER0_COMPA_vect) { static uint8_t history = 0; @@ -45,6 +53,7 @@ ISR(TIMER0_COMPA_vect) uint8_t bit = 0; static uint8_t subsamp = 0; + uint8_t flags = 0; subsamp++; subsamp &= 7; @@ -61,10 +70,8 @@ ISR(TIMER0_COMPA_vect) * /edge/ <----------- stable / sample ----------> */ if (dali_s_cdr()) { - if (subsamp >= 3 && subsamp <= 5 && ((history & 0x0f) == 0x03 || (history & 0x0f) == 0x0c)) { -// uart_puts(""); + if (subsamp >= 2 && subsamp <= 6 && ((history & 0x0f) == 0x03 || (history & 0x0f) == 0x0c)) subsamp = 4; - } } if (dali_s_listening() && hist_majority_1()) { rx_prevstate_errs = dali_state; @@ -75,10 +82,15 @@ ISR(TIMER0_COMPA_vect) if (subsamp) return; +#ifdef DEBUG if (dali_state != DALI_IDLE && dbufpos < XBUF) { - sbuf[dbufpos] = dali_state; - dbuf[dbufpos++] = history; + if (dbufpos >= 0) { + sbuf[dbufpos] = dali_state; + dbuf[dbufpos] = history; + } + dbufpos++; } +#endif switch (dali_state) { case DALI_SPACE: @@ -93,7 +105,7 @@ ISR(TIMER0_COMPA_vect) case DALI_RX_SBIT: if (!hist_majority_0()) { - uart_puts(""); + dalistat_falsestart++; dali_state = rx_prevstate_errs; return; } @@ -106,7 +118,7 @@ ISR(TIMER0_COMPA_vect) case DALI_RX_DATA: if (!(hist_majority_1() || hist_majority_0())) { rx_prevstate_errs++; - uart_puts(""); + dalistat_noise++; bit = 0; } else bit = hist_majority_1(); @@ -114,7 +126,7 @@ ISR(TIMER0_COMPA_vect) if (bitpos & 1) { if (bit == (rx_data & 1)) { rx_prevstate_errs++; - uart_puts(""); + dalistat_manchester++; } } else { rx_data <<= 1; @@ -127,6 +139,7 @@ ISR(TIMER0_COMPA_vect) if (!rx_prevstate_errs) { dali_rx = rx_data; dali_rx_avail = 1; + dalistat_rxok++; } } break; @@ -172,10 +185,6 @@ ISR(TIMER0_COMPA_vect) PORTD |= (1 << D_DALIO); } } -#if DEBUG - if (dali_state != DALI_IDLE || bitpos != 0) - uart_puts("\n"); -#endif if (dali_state == DALI_IDLE && dali_tx_rq) { tx_data = dali_tx; @@ -189,13 +198,15 @@ ISR(TIMER0_COMPA_vect) static void dali_send(uint16_t word) { +#if 0 uart_wait(); uart_puts("\n\n\ndali_send "); uart_puthex(word >> 8); uart_puthex(word & 0xff); uart_puts("\n"); uart_wait(); - dbufpos = 0; + dbufpos = -35; +#endif dali_rx_avail = 0; dali_tx = word; @@ -205,6 +216,7 @@ static void dali_send(uint16_t word) asm volatile ("" ::: "memory"); } +#if 0 uart_wait(); uart_puts("dali_sent "); uart_puthex(word >> 8); @@ -224,7 +236,11 @@ static void dali_send(uint16_t word) uart_puthex(dbuf[x]); uart_puts("\n"); uart_wait(); - + for (uint8_t x = 0; x < dbufpos; x++) + uart_puthex(fbuf[x]); + uart_puts("\n"); + uart_wait(); +#endif } static void dali_twice(uint16_t word) @@ -241,6 +257,8 @@ static void dali_init(void) dali_tx_rq = 0; dali_rx_avail = 0; + dalistat_falsestart = dalistat_noise = dalistat_manchester = dalistat_rxok = 0; + TIFR0 = (1 << OCF0A); TCNT0 = 0; OCR0A = 52; // 8 MHz / 8 / 52 = 19230. diff --git a/dali_ctl.c b/dali_ctl.c new file mode 100644 index 0000000..50dc77c --- /dev/null +++ b/dali_ctl.c @@ -0,0 +1,97 @@ +#define DALI_C_TERMINATE 0xa100 +#define DALI_C_DTR 0xa300 +#define DALI_C_INITIALISE 0xa500 +#define DALI_C_RANDOMISE 0xa700 +#define DALI_C_COMPARE 0xa900 +#define DALI_C_WITHDRAW 0xab00 + +#define DALI_C_SADDR_H 0xb100 +#define DALI_C_SADDR_M 0xb300 +#define DALI_C_SADDR_L 0xb500 + +#define DALI_C_PROGSHORT 0xb701 +#define DALI_C_VRFYSHORT 0xb901 +#define DALI_C_QURYSHORT 0xbb00 + +static uint8_t dali_s_byte, dali_sh, dali_sm, dali_sl; +static bool dali_s_notfound; + +static bool dali_compare(void) +{ + dali_send(DALI_C_COMPARE); + asm volatile ("" ::: "memory"); + return dali_rx_avail && dali_rx == 0xff; +} + +static void dali_search_byte(uint16_t cmd) +{ + dali_s_byte = 0xff; + uint8_t bit = 0x80; + + uart_puthex(cmd >> 8); + uart_puts("dali byte\n"); + while (bit) { + uart_puts("dali sb "); + uart_puthex(dali_s_byte & ~bit); + uart_puts("\n"); + + dali_twice(cmd | (dali_s_byte & ~bit)); + if (dali_compare()) { + uart_puts("cx1\n"); + dali_s_byte &= ~bit; + } else if (dali_compare()) { + uart_puts("cx2\n"); + dali_s_byte &= ~bit; + } + bit >>= 1; + } + dali_twice(cmd | dali_s_byte); +} + +static void dali_search_single(void) +{ + dali_twice(DALI_C_SADDR_H | 0xff); + dali_twice(DALI_C_SADDR_M | 0xff); + dali_twice(DALI_C_SADDR_L | 0xff); + + if (!dali_compare()) { + dali_s_notfound = 1; + return; + } + + dali_search_byte(DALI_C_SADDR_H); + if (dali_s_notfound) + return; + dali_sh = dali_s_byte; + dali_search_byte(DALI_C_SADDR_M); + if (dali_s_notfound) + return; + dali_sm = dali_s_byte; + dali_search_byte(DALI_C_SADDR_L); + if (dali_s_notfound) + return; + dali_sl = dali_s_byte; +} + +static void dali_search(void) +{ + dali_twice(DALI_C_INITIALISE); + dali_twice(DALI_C_RANDOMISE); + + do { + dali_search_single(); + if (!dali_s_notfound) { + uart_puts("dali scan found\t\t"); + uart_puthex(dali_sh); + uart_puthex(dali_sm); + uart_puthex(dali_sl); + uart_puts("\n"); + dali_send(DALI_C_QURYSHORT); + dali_send(DALI_C_WITHDRAW); + } + } while (!dali_s_notfound); + + dali_twice(DALI_C_TERMINATE); + uart_puts("dali scan end\n"); +} + diff --git a/dim.c b/dim.c new file mode 100644 index 0000000..6414d5f --- /dev/null +++ b/dim.c @@ -0,0 +1,74 @@ +static uint8_t dim_state; +static int8_t dim_dir; + +#define DALI_ADDR 0xfe00 + +static void tast_click(void) +{ + uart_puts("# click\n"); + if (dim_state) { + dim_state = 0; + dali_send(0xff00); + PORTD |= (1 << D_LED1); + } else { + dim_state = 0xfe; + dali_send(DALI_ADDR | 0x108); + dali_send(DALI_ADDR | dim_state); + PORTD &= ~(1 << D_LED1); + } +} + +static void do_tick(void) +{ + static uint8_t history; + static uint8_t downctr; + + history <<= 1; + history |= (PIND >> D_TAST) & 1; + + if (history & 0x3f) { + if (!downctr) + return; + if (downctr < 60) { + PORTD &= ~(1 << D_LED1); + tast_click(); + } else + dim_dir = -dim_dir; + + downctr = 0; + return; + } + + if (downctr < 60) { + PORTD |= (1 << D_LED1); + downctr++; + } else if (downctr == 60) { + if (!dim_state) { + dali_send(DALI_ADDR | 0x108); + dim_dir = 1; + } + downctr++; + } else { + PORTD &= ~(1 << D_LED1); + + uart_puts("\t# dim "); + uart_puthex(dim_state); + uart_puts(" "); + uart_puthex(dim_dir); + uart_puts("\n"); + for (int i = 0; i < 3; i++) { + dim_state += dim_dir; + if (dim_state == 0xff) + dim_state = 0xfe; + if (dim_state < 0x40) + dim_state = 0x40; + } + dali_send(DALI_ADDR | dim_state); + } +} + +static void dim_init(void) +{ + dim_state = 0; + dim_dir = 1; +} diff --git a/lightctrl.c b/lightctrl.c new file mode 100644 index 0000000..c36f035 --- /dev/null +++ b/lightctrl.c @@ -0,0 +1,85 @@ +#define F_CPU 8000000 +#include +#include +#include +#include +#include +#include + +const uint8_t __signature[3] __attribute__((section (".signature"), used)) = + { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 }; + +#define B_SCK 5 +#define B_MISO 4 +#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 +#define D_TAST 7 + +#include "uart.c" +#include "dali2.c" +#include "dali_ctl.c" +#include "dim.c" +#include "can.c" + +int main(void) +{ + DDRD |= (1 << D_LED1) | (1 << D_LED2 ) | (1 << D_TXD) | (1 << D_DALIO); + PORTD |= (1 << D_LED1) | (1 << D_TAST); + PORTD &= ~(1 << D_LED1); + + uart_init(); + can_preinit(); + dali_init(); + dim_init(); + + sei(); + uart_puts("\ninit done\n"); + + can_init(); + can_CANSTAT(); + + dali_search(); + + uint8_t ctr = 0; + while (1) { + if (canint) { + canint = false; + can_int(); + } + _delay_ms(5); + do_tick(); + + ctr++; + if (ctr % 64 == 0) { + dali_send(0xffa0); + if (dali_rx_avail) { + uart_puts("ll "); + uart_puthex(dali_rx); + uart_puts("\n"); + } else + uart_puts("ll noans\n"); + } + + if (ctr == 255) { + uart_puts("dali stats: "); + uart_puthex16(dalistat_rxok); + uart_puts(" ok "); + uart_puthex16(dalistat_falsestart); + uart_puts(" f-start "); + uart_puthex16(dalistat_noise); + uart_puts(" noise "); + uart_puthex16(dalistat_manchester); + uart_puts(" mch-err\n"); + } + } +} + +void __do_copy_data(void) __attribute__((naked, section (".init4"), used)); +void __do_copy_data(void) { } + diff --git a/uart.c b/uart.c index feb9619..1f2656a 100644 --- a/uart.c +++ b/uart.c @@ -76,6 +76,12 @@ static void uart_puthex(uint8_t val) SREG = sreg; } +static void uart_puthex16(uint16_t val) +{ + uart_puthex(val >> 8); + uart_puthex(val & 0xff); +} + static void uart_init(void) { UBRR0 = 12; /* 38461 ~ 38400 */ -- cgit v1.2.1