;4 chan DMX, PWM output

;On RB5, RB6, RB7, RA3

;Thijs Assies

__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC & _LVP_OFF

list P=16F628A

#INCLUDE <P16F628a.INC>

#DEFINE OUT1 PORTA,1 ;RA0 pin17

#DEFINE OUT2 PORTA,2 ;RA1 pin18

#DEFINE OUT3 PORTA,3 ;RA2 pin1

#DEFINE OUT4 PORTA,4 ;RA3 pin2

#DEFINE OUT5 PORTA,5 ;RA4 pin3

#DEFINE OUT6 PORTB,1 ;RB0 pin6

#DEFINE OUT7 PORTB,3 ;RB2 pin8

#DEFINE OUT8 PORTB,4 ;RB3 pin9

#DEFINE OUT9 PORTB,5 ;RB4 pin10

#DEFINE RCLED PORTB,6 ;RB5 pin11 - green led

#DEFINE RX PORTB,1 ;RB1 pin7

#DEFINE ERRLED PORTB,7 ;RB6 pin12 - red led

#DEFINE BREAK DMX_reg,0

#DEFINE STARTCODE DMX_reg,1

#DEFINE MOVED DMX_reg,2

#DEFINE ADDR9 DMX_reg,3

#DEFINE RC9 DMX_reg,4

DMX_reg EQU 020h

Reg1 EQU 021h

Reg2 EQU 022h

Reg3 EQU 023h

Reg4 EQU 024h

Reg5 EQU 025h

Reg6 EQU 026h

Reg7 EQU 027h

Reg8 EQU 028h

Reg9 EQU 029h

Count EQU 030h

W_SAVE EQU 031h

S_SAVE EQU 032h

P_SAVE EQU 033h

pwmcounter EQU 034h

flag EQU 02Ah

D_ADDR EQU 02Bh

temp EQU 02Ch

R_ADDR EQU 02Dh

Offset EQU 02Eh

temp2 EQU 02Fh

ORG 00h

GOTO INIT ;Initialize PIC

ORG 04h ;Interrupt vector

MOVWF W_SAVE ;save context,

MOVF STATUS,W ;save STATUS, PCLATH & W

MOVWF S_SAVE

MOVF PCLATH,W

MOVWF P_SAVE

GOTO INTHANDLER

INIT

MOVLW 0x07 ;turn analog comparators off

MOVWF CMCON

CLRF PORTA

CLRF PORTB

BSF STATUS,RP0 ;Select Bank1

CLRF TRISA ;porta output

CLRF TRISB ;portb output

BSF TRISB,1 ;B1 input (UART Recieve)

MOVLW 04h

MOVWF SPBRG ;Set baud rate

BSF TXSTA,BRGH ;high speed

BCF TXSTA,SYNC ;Async connection

CLRF PIE1 ;clear other interrupts

BSF PIE1,RCIE ;Set recieve interrupt

BCF STATUS,RP0 ;Return to bank0

BSF RCSTA,RX9 ;Enable 9bit data

MOVF RCREG,W ;clear RCREG FIFO

MOVF RCREG,W

MOVF RCREG,W

BSF RCSTA,CREN ;Enable recieve

BSF RCSTA,SPEN ;Enable UART

BSF INTCON,PEIE ;Enable interrupts

BSF INTCON,GIE

BCF RCLED

BCF ERRLED

CLRF Reg1

CLRF Reg2

CLRF Reg3

CLRF Reg4

CLRF Reg5

CLRF Reg6

CLRF Reg7

CLRF Reg8

CLRF Reg9

CLRF D_ADDR ;set our dmx adress to 0 (mogelijkheid voor dipswitch???)

BCF ADDR9

GOTO MAIN ;Goto Main Program

MAIN

BCF RCLED

BCF ERRLED

MOVLW 0FFh

MOVWF pwmcounter

BCF OUT1

BCF OUT2

BCF OUT3

BCF OUT4

BCF OUT5

BCF OUT6

BCF OUT7

BCF OUT8

BCF OUT9

CALL PWM_CYCLE

GOTO MAIN

PWM_CYCLE

MOVF Reg1,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT1

MOVF Reg2,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT2

MOVF Reg3,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT3

MOVF Reg4,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT4

MOVF Reg5,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT5

MOVF Reg6,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT6

MOVF Reg7,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT7

MOVF Reg8,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT8

MOVF Reg9,W

XORWF pwmcounter,W

BTFSC STATUS,Z

BSF OUT9

DECFSZ pwmcounter

GOTO PWM_CYCLE

RETURN

INTRETURN

MOVF P_SAVE,W ;restore context

MOVWF PCLATH

MOVF S_SAVE,W

MOVWF STATUS

SWAPF W_SAVE,F

SWAPF W_SAVE,W

RETFIE

INTHANDLER

BTFSS PIR1,RCIF

GOTO INTRETURN

GOTO DMX

DMX

BSF ERRLED

BTFSC RCSTA,OERR

GOTO OVERRUN

BTFSC RCSTA,FERR

GOTO FRAME

BTFSS BREAK

GOTO RET

BTFSS STARTCODE ;has a startcode passed ?

GOTO SC ;yes: go check for valid startcode

BTFSC STARTCODE

GOTO CHANNEL

RET

MOVF RCREG,W

GOTO INTRETURN

OVERRUN

BCF RCSTA,SPEN

BSF RCSTA,SPEN

MOVF RCREG,W

BSF ERRLED

GOTO LAST

FRAME

BCF BREAK

BCF STARTCODE

BCF RC9

CLRF R_ADDR

CLRF Offset

BTFSS RCSTA,RX9D

BSF BREAK

MOVF RCREG,W

GOTO INTRETURN

SC

MOVF RCREG,W

XORLW 00h

BTFSC STATUS,Z

BSF STARTCODE

GOTO INTRETURN

INCREASE

INCF R_ADDR (Ik weet niet hoe je dit 8 maal kan laten uitvoeren. 9 kanalen)

BTFSC STATUS,Z

BSF RC9

RETURN

CHANNEL

MOVF Offset,W

XORLW 00h ;check if offset != 0

BTFSS STATUS,Z

GOTO CHAN

MOVF R_ADDR,W ;else: check if chans match

XORWF D_ADDR,W

BTFSC STATUS,Z

GOTO NINTH ;if so: check for 9th bit

CALL INCREASE

GOTO RET ;if not: just return from interrupt

NINTH

BTFSC ADDR9

GOTO TRUE

MOVF RCREG,W

GOTO FALSE

TRUE ;our 9th bit is set

BTFSC RC9

GOTO CHAN

CALL INCREASE

GOTO RET

FALSE

BTFSS RC9

GOTO CHAN

CALL INCREASE

GOTO RET

CHAN

INCF Offset

MOVF Offset,W

XORLW 01h ;check if count = 0

BTFSC STATUS,Z

GOTO CHAN1

MOVF Offset,W

XORLW 02h

BTFSC STATUS,Z

GOTO CHAN2

MOVF Offset,W

XORLW 03h

BTFSC STATUS,Z

GOTO CHAN3

MOVF Offset,W

XORLW 04h

BTFSC STATUS,Z

GOTO CHAN4

MOVF Offset,W

XORLW 05h

BTFSC STATUS,Z

GOTO CHAN5

MOVF Offset,W

XORLW 06h

BTFSC STATUS,Z

GOTO CHAN6

MOVF Offset,W

XORLW 07h

BTFSC STATUS,Z

GOTO CHAN7

MOVF Offset,W

XORLW 08h

BTFSC STATUS,Z

GOTO CHAN8

MOVF Offset,W

XORLW 09h

BTFSC STATUS,Z

GOTO CHAN9

MOVF Offset,W

XORLW 10h ; was 05h

BTFSC STATUS,Z

GOTO LAST

CHAN1

MOVF RCREG,W

MOVWF Reg1

CALL INCREASE

GOTO INTRETURN

CHAN2

MOVF RCREG,W

MOVWF Reg2

CALL INCREASE

GOTO INTRETURN

CHAN3

MOVF RCREG,W

MOVWF Reg3

CALL INCREASE

GOTO INTRETURN

CHAN4

MOVF RCREG,W

MOVWF Reg4

CALL INCREASE

GOTO INTRETURN

CHAN5

MOVF RCREG,W

MOVWF Reg5

CALL INCREASE

GOTO INTRETURN

CHAN6

MOVF RCREG,W

MOVWF Reg6

CALL INCREASE

GOTO INTRETURN

CHAN7

MOVF RCREG,W

MOVWF Reg7

CALL INCREASE

GOTO INTRETURN

CHAN8

MOVF RCREG,W

MOVWF Reg8

CALL INCREASE

GOTO INTRETURN

CHAN9

MOVF RCREG,W

MOVWF Reg9

CALL INCREASE

GOTO INTRETURN

LAST

BCF BREAK

BCF STARTCODE

CLRF Offset

GOTO INTRETURN

END