;*********************************************************************************************** ;DMX-DIMMER by DjMUIS ;DATE 26-02-2003 ;Use internal 8 Mhz RC OSC, startuptime 64 uSEC ;*********************************************************************************************** .include "m8def.inc" ;Const .equ Phase_Time_L =low(319) ;phasetime 10mS/250 = 40uSec =320 .equ Phase_Time_H =high(319) .equ cZc_error=10 ;zero cross error window +-(15/250)*10ms .equ cSafety_Min=15 ;safety margin minimal .equ cSafety_Max=240 ;safety margin maximal .equ zero_crossing_pin=PD2 .equ cStartcode=0x00 ;dmx start code .equ cWait_for_Break=0x01 ;wait for Break .equ cWait_for_Start=0x02 ;wait for Start code .equ cWait_for_Byte=0x00 ;wait for Byte .equ cMax_Channels = 6 ;maximum channels ;***** global register variables ; ZL, ZH, XL and XH used for memory-comtrolling ; R0 used for memory-operations (lpm) ; R1 used as NULL-register .def NULL =R1 .def PHM0 =R2 ;PHase Modulator regiser 0-7 .def PHM1 =R3 .def PHM2 =R4 .def PHM3 =R5 .def PHM4 =R6 .def PHM5 =R7 .def start_adress=R8 ;set start adress .def TEMP_REG =R9 ;used to safe the status register in interrupt routine .def phase_register =R14 ;PHase Modulator actual register .def phase_counter =R16 ;PHase Modulator counter .def temp =R17 .def rx_data =R18 ;value of received byte .def valid_count_in=R20 ;counter for valid dmx-byte .def byte_count =R21 ;counter for incomming byte's .def dmx_status =R22 ;status of incomming data ;0x00 -> wait for Byte ;0x01 -> wait for Break ;0x02 -> wait for Start code .def tempL =R24 ;temporary storage register .def tempH =R25 ; ;ram location for received dmxdata: .dseg dmx_data_field: .byte cMax_Channels ;reserve bytes .CSEG .org 0x0 rjmp start ;Reset handler .org INT0addr rjmp ext_int0 ;External interrupt handler .org OC1Aaddr ; Output Compare1A Interrupt Vector Address rjmp PHM .org URXCaddr ; USART Receive Complete Interrupt Vector Address rjmp get_byte .org 0x200 ;power compensation table DIM1: ;Uavg ;==== .DB 4, 11, 15, 17, 20, 22, 24, 27, 29, 30, 32, 33, 35, 36, 38, 39 .DB 40, 42, 43, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 55, 56, 57 .DB 58, 59, 59, 60, 61, 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 70 .DB 71, 72, 73, 74, 74, 75, 76, 77, 77, 78, 79, 80, 80, 81, 82, 83 .DB 84, 84, 85, 86, 86, 87, 88, 88, 89, 90, 90, 91, 92, 92, 93, 94 .DB 94, 95, 96, 96, 97, 98, 98, 99,100,100,101,102,102,103,104,104 .DB 105,106,106,107,108,108,109,109,110,111,111,112,113,113,114,114 .DB 115,116,116,117,118,118,119,119,120,121,121,122,123,123,124,124 .DB 125,126,126,127,127,128,129,129,130,131,131,132,132,133,134,134 .DB 135,136,136,137,137,138,139,139,140,141,141,142,142,143,144,144 .DB 145,146,146,147,148,148,149,150,150,151,152,152,153,154,154,155 .DB 156,156,157,158,158,159,160,160,161,162,162,163,164,164,165,166 .DB 166,167,168,169,170,170,171,172,173,173,174,175,176,176,177,178 .DB 179,180,180,181,182,183,184,184,185,186,187,188,189,190,191,191 .DB 192,193,194,195,196,197,198,199,200,202,203,204,205,206,207,208 .DB 210,211,212,214,215,217,218,220,221,223,226,228,230,233,235,239 start: ldi temp,low(RAMEND) out SPL,temp ldi temp,high(RAMEND) out SPH,temp ;init Stack Pointer ldi temp,0x00 mov NULL,temp ldi temp,0b00111111 out DDRB,temp ;set outputs of port B to"1" (leds or moc3021) xtal1, xtal2 as input ldi temp,0xFF out PORTB,temp ; ldi temp,0x00 ;Set all inputs out DDRC,temp ;set data direction of port C ldi temp,0xFF out PORTC,temp ;set pull up to inputs PORT C ldi temp,0x00 ;Set all inputs (rxd, int0, dipswitch out DDRD,temp ;set data direction of port D ldi temp,0xFF out PORTD,temp ;set pull up to inputs PORT D ; ldi temp, 0x0E ;activate watchdog on 1024ms ; out WDTCR,temp ;timer1 compare ldi temp,(1<cSafety_Max then phase_counter:=0 safety margin brlo Clear_Phase ;safety margin is used to avoid triggering in wrong cpi phase_counter,cSafety_Max brlo Com_Phase Clear_Phase:clr phase_register Com_Phase: com phase_register ;invert phase_register ldi temp,0b11000000 ;keep pb7 and pb6 as pull up inputs or phase_register,temp out PORTB,phase_register ;set phase output cpi phase_counter,cSafety_Max brne Inc_Phase rcall fill_phm ;store new values to PHM-regs wdr Inc_Phase: inc phase_counter cpi phase_counter,250 brne Ret_PHM clr phase_counter ;RESET COUNTER Ret_PHM: out SREG,TEMP_REG ;recall SREG reti ;*********************** fill_phm: ldi ZH,high(dmx_data_field) ;set data-pointer ldi ZL,low(dmx_data_field); ld PHM0,Z+ ;get data ld PHM1,Z+ ld PHM2,Z+ ld PHM3,Z+ ld PHM4,Z+ ld PHM5,Z+ ret ;*************************************************************************** ;* ;* RxD Interupt: get dmx-byte from uart-data-register ;* ;*************************************************************************** get_byte: IN TEMP_REG, SREG sbic UCSRA,DOR ;check for overrun rjmp overrun sbic UCSRA,FE ;check for receive error rjmp frame_error in rx_data,UDR ;save received data cpi dmx_status,cWait_for_Break ;wait for Break? breq wait_break cpi dmx_status, cWait_for_Start ;wait for Start code? breq wait_start check_adress: cp byte_count,start_adress ;compare adress and byte_count brlo wait_byte ;if lower then return wait for next byte cpi valid_count_in,cMax_Channels;if maximal channel reached brsh wait_break ;if same or higher then wait for next break save_byte: inc valid_count_in com rx_data ;complement ldi ZH,0x04 ;set Z-pointer to fire-angle mov ZL,rx_data ; lpm ;get fire-angle st X+,r0 ;set fire-angle wait_byte: inc byte_count ;set adress to next channel OUT SREG, TEMP_REG reti frame_error:in rx_data,UDR ;clear uart receive interrupt flag ldi byte_count,0 ;reset byte_counter ldi valid_count_in,0 ;reset valid_counter ldi XL,low(dmx_data_field) ;set pionter naar ram ldi XH,high(dmx_data_field) ldi dmx_status,cWait_for_Start ;set status byte to 'wait for Start' cbi UCSRA,FE ;clear frame-error flag OUT SREG, TEMP_REG reti overrun: in rx_data,UDR ;clear uart receive interrupt flag wait_break: ldi dmx_status,cWait_for_Break ;set status byte to 'wait for Break' OUT SREG, TEMP_REG reti ;return wait_start: cpi rx_data,cStartcode ;startbyte==cStartcode ? brne wait_break ;no then wait for next Break ldi dmx_status,cWait_for_Byte ;else set status byte to 'wait for Byte' ; ldi timeout_counter,0 ;reset timeout ; cbi PORTB,cDmxReceiveLed ;DmxReceiveLed=0 (led on) rjmp wait_byte ;******************************************************************* ;Start adres ;bit0 = PB6 ;bit1 = PB7 ;bit2 = PD5 ;bit3 = PD6 ;bit4 = PD7 ;bit5 = PD1 ;bit6 = PD3 ;bit7 = PD4 start_adress: ldi temp,0x00 sbis PINB,PB6 ;skip branch if set sbr temp, 0x01 ;set bit in temp sbis PINB,PB7 sbr temp, 0x02 sbis PIND,PD5 sbr temp, 0x04 sbis PIND,PD6 sbr temp, 0x08 sbis PIND,PD7 sbr temp, 0x10 sbis PIND,PD1 sbr temp, 0x20 sbis PIND,PD3 sbr temp, 0x40 sbis PIND,PD4 sbr temp, 0x80 mov start_adress,temp ;save adres for future ret ;*******************************************************************