summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2012-05-17 02:28:03 +0200
committerDavid Lamparter <equinox@diac24.net>2012-05-17 02:28:03 +0200
commit937ce1ef539a7a73d481e9392c27b860d9b5eb14 (patch)
treeea68b5d3bce7da3824a0533cb3f03cf88197b878
parent3ae67269dc61d0ebb2b0a8c78af8fc4348755afb (diff)
dali: rewrite
-rw-r--r--can.c2
-rw-r--r--dali2.c252
2 files changed, 253 insertions, 1 deletions
diff --git a/can.c b/can.c
index b8cb21f..1772c30 100644
--- a/can.c
+++ b/can.c
@@ -22,7 +22,7 @@ const uint8_t __signature[3] __attribute__((section (".signature"), used)) =
#define D_LED1 5
#define D_LED2 6
-#include "dali.c"
+#include "dali2.c"
#define spi_ss(x) PORTB = ((x) << B_SS) | 0x3;
diff --git a/dali2.c b/dali2.c
new file mode 100644
index 0000000..e8c89de
--- /dev/null
+++ b/dali2.c
@@ -0,0 +1,252 @@
+#define DALI_INVALID 0xa0cc
+
+enum dali_state {
+ DALI_IDLE = 0,
+ DALI_SPACE, // 1
+ DALI_DEAD_SPACE, // 2
+
+ DALI_RX_SBIT, // 3
+ DALI_RX_DATA, // 4
+
+ DALI_TX_SBIT0, // 5
+ DALI_TX_SBIT1, // 6
+ DALI_TX_0, // 7
+ DALI_TX_1, // 8
+ DALI_TX_STOP, // 9
+};
+static volatile uint8_t dali_state;
+
+static volatile uint8_t dali_rx;
+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;
+
+#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;
+#define hist_size 5
+#define hist_mask ((1 << hist_size) - 1)
+#define hist_majority_1() (((history | (history + 1)) & hist_mask) == hist_mask)
+#define hist_majority_0() (((history & (history - 1)) & hist_mask) == 0)
+
+ static uint8_t bitpos = 0;
+ static uint8_t rx_prevstate_errs, rx_data;
+
+ static uint16_t tx_data;
+
+ uint8_t bit = 0;
+ static uint8_t subsamp = 0;
+
+ subsamp++;
+ subsamp &= 7;
+
+ /* CTC mode didn't work, CBA to debug */
+ TCNT0 = 0;
+
+ history <<= 1;
+ history |= (PIND >> D_DALII) & 1;
+
+ /*
+ * subsamp 1 2 3 4 5 6 7 0 ||
+ * ^ state trigger
+ * /edge/ <----------- stable / sample ---------->
+ */
+ if (dali_s_cdr()) {
+ if (subsamp >= 3 && subsamp <= 5 && ((history & 0x0f) == 0x03 || (history & 0x0f) == 0x0c)) {
+// uart_puts("<CDR>");
+ subsamp = 4;
+ }
+ }
+ if (dali_s_listening() && hist_majority_1()) {
+ rx_prevstate_errs = dali_state;
+ dali_state = DALI_RX_SBIT;
+ subsamp = 1;
+ }
+
+ if (subsamp)
+ return;
+
+ if (dali_state != DALI_IDLE && dbufpos < XBUF) {
+ sbuf[dbufpos] = dali_state;
+ dbuf[dbufpos++] = history;
+ }
+
+ switch (dali_state) {
+ case DALI_SPACE:
+ case DALI_DEAD_SPACE:
+ if (bitpos > 0) {
+ bitpos--;
+ return;
+ }
+ dali_state = DALI_IDLE;
+ case DALI_IDLE:
+ break;
+
+ case DALI_RX_SBIT:
+ if (!hist_majority_0()) {
+ uart_puts("<FSE>");
+ dali_state = rx_prevstate_errs;
+ return;
+ }
+ dali_state = DALI_RX_DATA;
+ rx_prevstate_errs = 0;
+ rx_data = 0;
+ bitpos = 0;
+ break;
+
+ case DALI_RX_DATA:
+ if (!(hist_majority_1() || hist_majority_0())) {
+ rx_prevstate_errs++;
+ uart_puts("<MJE>");
+ bit = 0;
+ } else
+ bit = hist_majority_1();
+
+ if (bitpos & 1) {
+ if (bit == (rx_data & 1)) {
+ rx_prevstate_errs++;
+ uart_puts("<MAF>");
+ }
+ } else {
+ rx_data <<= 1;
+ rx_data |= bit;
+ }
+ bitpos++;
+ if (bitpos == 16) {
+ bitpos = 20;
+ dali_state = DALI_DEAD_SPACE;
+ if (!rx_prevstate_errs) {
+ dali_rx = rx_data;
+ dali_rx_avail = 1;
+ }
+ }
+ break;
+
+ case DALI_TX_SBIT0:
+ bit = 1;
+ dali_state = DALI_TX_SBIT1;
+ break;
+ case DALI_TX_SBIT1:
+ bit = 0;
+ dali_state = DALI_TX_0;
+ break;
+ case DALI_TX_0:
+ if (bitpos == 16) {
+ bitpos = 8;
+ dali_state = DALI_TX_STOP;
+ PORTD |= (1 << D_DALIO);
+ } else {
+ bit = (tx_data & (1 << (15 - bitpos))) ? 1 : 0;
+ dali_state = DALI_TX_1;
+ }
+ break;
+ case DALI_TX_1:
+ bit = (tx_data & (1 << (15 - bitpos))) ? 0 : 1;
+ bitpos++;
+ dali_state = DALI_TX_0;
+ break;
+
+ case DALI_TX_STOP:
+ if (bitpos == 0) {
+ dali_tx_rq = 0;
+ bitpos = 25;
+ dali_state = DALI_SPACE;
+ } else
+ bitpos--;
+ break;
+ }
+
+ if ((dali_state == DALI_TX_SBIT1) || (dali_state == DALI_TX_0) || (dali_state == DALI_TX_1)) {
+ if (bit) {
+ PORTD &= ~(1 << D_DALIO);
+ } else {
+ 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;
+ bitpos = 0;
+ dali_tx = DALI_INVALID;
+ dali_tx_rq = 2;
+ dali_state = DALI_TX_SBIT0;
+ subsamp = 7;
+ }
+}
+
+static void dali_send(uint16_t word)
+{
+ uart_wait();
+ uart_puts("\n\n\ndali_send ");
+ uart_puthex(word >> 8);
+ uart_puthex(word & 0xff);
+ uart_puts("\n");
+ uart_wait();
+ dbufpos = 0;
+
+ dali_rx_avail = 0;
+ dali_tx = word;
+ asm volatile ("" ::: "memory");
+ dali_tx_rq = 1;
+ while (dali_tx_rq || dali_state != DALI_IDLE) {
+ asm volatile ("" ::: "memory");
+ }
+
+ uart_wait();
+ uart_puts("dali_sent ");
+ uart_puthex(word >> 8);
+ uart_puthex(word & 0xff);
+ uart_puts(" ");
+ if (dali_rx_avail)
+ uart_puthex(dali_rx);
+ else
+ uart_puts("norx");
+ uart_puts("\n");
+ uart_wait();
+ for (uint8_t x = 0; x < dbufpos; x++)
+ uart_puthex(sbuf[x]);
+ uart_puts("\n");
+ uart_wait();
+ for (uint8_t x = 0; x < dbufpos; x++)
+ uart_puthex(dbuf[x]);
+ uart_puts("\n");
+ uart_wait();
+
+}
+
+static void dali_twice(uint16_t word)
+{
+ dali_send(word);
+ dali_send(word);
+}
+
+static void dali_init(void)
+{
+ PORTD |= (1 << D_DALII) | (1 << D_DALIO);
+
+ dali_state = DALI_IDLE;
+ dali_tx_rq = 0;
+ dali_rx_avail = 0;
+
+ TIFR0 = (1 << OCF0A);
+ TCNT0 = 0;
+ OCR0A = 52; // 8 MHz / 8 / 52 = 19230.
+ asm volatile ("" ::: "memory");
+ TIMSK0 = (1 << OCIE0A);
+ TCCR0A = 0;
+ asm volatile ("" ::: "memory");
+ TCCR0B = (0 << CS02) | (1 << CS01) | (0 << CS00); // 8 MHz / 8 = 1MHz
+}