Skip to content

Commit

Permalink
Transfer svn project to git
Browse files Browse the repository at this point in the history
  • Loading branch information
claziss committed Jul 5, 2013
0 parents commit 7cb1dfb
Show file tree
Hide file tree
Showing 6 changed files with 670 additions and 0 deletions.
Empty file added README.md
Empty file.
305 changes: 305 additions & 0 deletions dali_drv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
/********************************************************************
;
; DALI master
;
; For transmit, this module uses GPIO - P0.28 (DALI send pin)
; DALI forward frame format:
;
; | S | 8 address bits | 8 command bits | stop |
; | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | | |
;
; ---+ +-+ +---+ +-+ +-+ +-+ +-+ +-+ +---+ +-+ +-+ +-+ +---+ +-+ +-+ +------------
; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
; +-+ +-+ +-+ +-+ +-+ +-+ +---+ +-+ +---+ +-+ +-+ +-+ +-+ +-+ +-+
;
; |2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE| 4TE |
;
;
; For receive, this module uses T0-CAP0 input (capture and interrupt on both edges)
; CAP0.0 (P0.30) is connected to P0.29 (to check high / low level by software)
; DALI slave backward frame format:
;
; | S | 8 data bits | stop |
; | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | | |
;
; +---------------+ +-+ +---+ +-+ +-+ +-+ +-+ +-+ +-------------
; | | | | | | | | | | | | | | | | |
; -+ +-+ +-+ +-+ +-+ +-+ +-+ +---+ +-+
;
; |4 + 7 to 22 TE |2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE|2TE| 4TE |
;
; 2TE = 834 usec (1200 bps)
;
*******************************************************************************************/

#include "dali_drv.h"
#include <avr/interrupt.h>

static int low_time; //<! captured puls low time
static int high_time; //<! captured puls high time

static BYTE value; //<! used for dali send bit
BYTE position; //<! keeps track of sending bit position
static BYTE previous; //<! previous received bit
static WORD frame; //<! holds the received slave backward frame
static BYTE f_repeat; //<! flag command shall be repeated
static BYTE f_busy; //<! flag DALI transfer busy
BYTE f_error; //<! flag DALI transfer error
WORD f_dbg;

/*
extern WORD forward; //<! DALI forward frame
extern BYTE answer; //<! DALI slave answer
extern BYTE f_dalitx;
extern BYTE f_dalirx;
*/

static void
DALI_Shift_Bit(BYTE val)
{
if (frame & 0x100) // frame full ?
{
frame = 0; // yes, ERROR
f_error = 1;
//TIMSK &= ~0x20; //stop capture interrupts
}
else
frame = (frame << 1) | val; // shift bit
}

/************************************************************************
; DALI_Decode (we only take action at a rising edge)
;
; Half(prev) Bit Low Time High Time Action New Half Bit
; -------------------------------------------------------------------
; 0 0 0 Shift 0 0
; 0 0 1 -ERROR- *
; 0 1 0 Shift 0,1 1
; 0 1 1 -ERROR- *
; 1 0 0 Shift 1 1
; 1 0 1 Shift 0 0
; 1 1 0 -ERROR- *
; 1 1 1 Shift 0,1 1
;
***********************************************************************/
static void
DALI_Decode(void)
{
BYTE action;

action = previous << 2;

if ((high_time > MIN_2TE) && (high_time < MAX_2TE))
action = action | 1; // high_time = long
else if (!((high_time > MIN_TE) && (high_time < MAX_TE)))
{
frame = 0; // DALI ERROR
f_error = 1;
//TIMSK &= ~0x20; //stop capture interrupts
return;
}

if ((low_time > MIN_2TE) && (low_time < MAX_2TE))
action = action | 2; // low_time = long
else if (!((low_time > MIN_TE) && (low_time < MAX_TE)))
{
frame = 0; // DALI ERROR
f_error = 1;
//TIMSK &= ~0x20; //stop capture interrupts
return;
}

switch (action)
{
case 0:
DALI_Shift_Bit(0); // short low, short high, shift 0
break;
case 1:
frame = 0; // short low, long high, ERROR
f_error = 1;
//TIMSK &= ~0x20; //stop capture interrupts
break;
case 2:
DALI_Shift_Bit(0); // long low, short high, shift 0,1
DALI_Shift_Bit(1);
previous = 1; // new half bit is 1
break;
case 3:
frame = 0; // long low, long high, ERROR
f_error = 1;
//TIMSK &= ~0x20; //stop capture interrupts
break;
case 4:
DALI_Shift_Bit(1); // short low, short high, shift 1
break;
case 5:
DALI_Shift_Bit(0); // short low, long high, shift 0
previous = 0; // new half bit is 0
break;
case 6:
frame = 0; // long low, short high, ERROR
f_error = 1;
//TIMSK &= ~0x20; //stop capture interrupts
break;
case 7:
DALI_Shift_Bit(0); // long low, long high, shift 0,1
DALI_Shift_Bit(1);
break;
default:
break; // invalid
}
}

/*! \brief Timer capture interrupt service routine
*
*/
ISR(TIMER1_CAPT_vect)
{
RESET_DALI_TIMER();
f_dbg++;
if (TCCR1B & _BV(ICES1))
{
if (!DALI_RX())
PORTC &= !(1<<PC1); /* LED on */
}
else
{
if (DALI_RX())
PORTC &= !(1<<PC1); /* LED on */
}

if (DALI_RX()) // check rising or falling edge
{
/* Handle the rising edge*/
if (frame != 0) // not first pulse ?
{
low_time = ICR1; // rising, so capture low time
DALI_Decode(); // decode received bit
}
else
{
previous = 1; // first pulse, so shift 1
DALI_Shift_Bit(1);
}
SET_DALI_FALLING_EDGE(); //wait for the next falling edge
}
else
{
/* Handle the falling edge*/
high_time = ICR1; // falling, so capture high time
SET_DALI_RAISING_EDGE(); //wait for the next rising edge
}
}

/*! \brief Timer compare interrupt service routine
*
* This interrupt is triggered when the compare
* register equals the timer. It increments the
* counter and handles the transmission of each
* bit.
*/
ISR(TIMER1_COMPA_vect)
{
// reset timer
if (value)
SET_DALI_TX(); // DALI output pin high
else
RESET_DALI_TX(); // DALI output pin low

if (position == 0) // 0TE second half of start bit = 1
{
value = 1;
}
else if (position < 33) // 1TE - 32TE, so address + command
{
value = (forward >> ((32 - position) / 2)) & 1;
if (position & 1)
value = !value; // invert if first half of data bit
}
else if (position == 33) // 33TE start of stop bit (4TE)
{ // and start of minimum settling time (7TE)
value = 1;
}
else if (position == 44) // 44TE, end of stopbits and settling time
{
if (!DALI_RX())
f_error = 1;
SET_DALI_TIMER_COMPARE_22TE(); // receive slave answer, timeout of 22TE = 9,174 msec
SET_DALI_FALLING_EDGE(); //wait for the falling edge next capture
CLEAR_DALI_PENDING_CAPTURE(); //reset any pending captures
ENABLE_DALI_CAPT_INTR(); //enable capture interrupts
}
else if (position == 45) // end of transfer
{
/* stop and reset timer */
DISABLE_DALI_INTERRUPT();
DISABLE_DALI_CAPT_INTR();
STOP_DALI_TIMER();
RESET_DALI_TIMER();

if (frame & 0x100) // backward frame (answer) completed ?
{
answer = (BYTE) frame; // OK ! save answer
f_dalirx = 1; // and set flag to signal application
}
frame = 0; // reset receive frame
f_busy = 0; // end of transmission
if (f_repeat) // repeat forward frame ?
f_dalitx = 1; // yes, set flag to signal application
}
position++;
}

void
DALI_Send(void)
{
if (f_repeat) // repeat last command ?
{
f_repeat = 0;
}
else if ((forward & 0xE100) == 0xA100 || (forward & 0xE100) == 0xC100)
{
if ((forward & 0xFF00) == INITIALISE || forward == RANDOMISE)
{
f_repeat = 1; // special command shall be repeated within 100 ms
}
}
else if ((forward & 0x1FF) >= 0x120 && (forward & 0x1FF) <= 0x180)
{
f_repeat = 1; // configuration command shall be repeated within 100 ms
}

while (f_busy)
; // Wait until dali port is idle

frame = 0;
value = 0; // first half of start bit = 0
position = 0;
f_error = 0;
f_busy = 1; // Activate the timer module to transfer
f_dbg = 0;

SET_DALI_TIMER_COMPARE_WAIT_ONE(); // ~2400 Hz
DISABLE_DALI_CAPT_INTR(); // disable capture interrupt
ENABLE_DALI_INTERRUPT(); // Enable interrupt on match, CTC
RESET_DALI_TIMER(); // reset timer
START_DALI_TIMER(); // enable timer. I assume the interrupts are enabled
}

void
DALI_Init(void)
{
CLEAR_DALI_TIMER_ON_COMPARE_MATCH();
RESET_DALI_TIMER();
SET_DALI_TIMER_COMPARE_WAIT_ONE();
f_busy = 0;
f_error = 0;

SETUP_DALI_TX_DIR; /* set DALi TX to output */
SET_DALI_TX();

/*TODO: set the CAPTURE input*/
/* CAPTURE pin is set as input*/
SETUP_DALI_RX_DIR;

}
74 changes: 74 additions & 0 deletions dali_drv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* dali_drv.h
*
* Created on: Jan 31, 2012
* Author: eu
*/

#ifndef DALI_DRV_H_
#define DALI_DRV_H_
// Global definitions

#define NULL ((void *)0)
#define FALSE (0)
#define TRUE (1)

typedef unsigned char BYTE; /* 0 to 255 */
typedef unsigned short WORD; /* 0 to 2^16-1 */
typedef unsigned long LONG; /* 0 to 2^32-1 */
typedef unsigned int BOOL;

extern WORD forward;
extern BYTE answer;
extern BYTE f_dalitx;
extern BYTE f_dalirx;

extern void DALI_Init(void);
extern void DALI_Send(void);

#define INITIALISE 0xA500 //<! command for starting initialization mode
#define RANDOMISE 0xA700 //<! command for generating a random address
#define TE 834/2 //<! half bit time = 417 usec
#define MIN_TE TE - 60 //<! minimum half bit time
#define MAX_TE TE + 60 //<! maximum half bit time
#define MIN_2TE 2*TE - 60 //<! minimum full bit time
#define MAX_2TE 2*TE + 60 //<! maximum full bit time


#define SET_DALI_TIMER_COMPARE_22TE() (OCR1A = 9174) //<! receive slave answer, timeout of 22TE = 9,174 msec
#define SET_DALI_TIMER_COMPARE_WAIT_ONE() (OCR1A = TE) //!< Sets the timer compare register to one period.

#define RESET_DALI_TIMER() (TCNT1 = 0x00) //<! Clear Timer1
#define DISABLE_DALI_INTERRUPT() (TIMSK1 &= ~(1<< OCIE1A)) //<! Disable Output Compare A Match interrupt
#define ENABLE_DALI_INTERRUPT() (TIMSK1 |= 1<< OCIE1A) //<! Enable Output Compare A Match interrupt
#define CLEAR_DALI_TIMER_ON_COMPARE_MATCH() (TCCR1B |= (1<< WGM12)) //<! Set timer control register to clear timer on compare match (CTC).

#define CLEAR_DALI_PENDING_CAPTURE() (TIFR1 |= _BV(ICF1)) //<! Reset any pending captures
#define ENABLE_DALI_CAPT_INTR() (TIMSK1 |= 1<< ICIE1) //<! Enable capture interrupts
#define DISABLE_DALI_CAPT_INTR() (TIMSK1 &= ~(1<< ICIE1)) //<! Disable capture interrupts
#define SET_DALI_FALLING_EDGE() (TCCR1B &= ~(1<< ICES1)) //<! Set capture for the next falling edge
#define SET_DALI_RAISING_EDGE() (TCCR1B |= (1<< ICES1)) //<! Set capture for the next raising edge

#define START_DALI_TIMER() (TCCR1B |= 1<< CS11) //<! Start Timer1: DIV8 prescaling: Fuse internal 8Mhz Clk => ~1Mhz)
/*(0 << CS12) | (0 << CS11) | (1 << CS10)) // prescale /1 */
#define STOP_DALI_TIMER() (TCCR1B &= ~(1<< CS11)) //<! Stop Timer1

#if defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__)
/* Set the DALI TX pin as outputs*/
#define SETUP_DALI_TX_DIR DDRD |= _BV(PD4)

/* Set the DALI RX pins as input */
#define SETUP_DALI_RX_DIR \
{ \
DDRD &= ~(_BV(PD3)); \
DDRD &= ~(_BV(PD6)); \
}

#define SET_DALI_TX() (PORTD |= 1<<PD4) //<! Set the DALI TX pin high
#define RESET_DALI_TX() (PORTD &= !(1<<PD4)) //<! Set the DALI TX pin low

#define DALI_RX() (PIND & (1<<PD3)) //<! Check the DALI RX pin

#endif /*Endif def ATmega644*/

#endif /* DALI_DRV_H_ */
Loading

0 comments on commit 7cb1dfb

Please sign in to comment.