;
; PIC12F683 LEDs v1 Beta
; Copyright (c) 2014 by Wojciech Kokot <wojciech_kokot@wp.eu>
;
    LIST P=12F683, R=DEC
    ; W=2, X=ON, 
    #INCLUDE P12F683.INC
;	__CONFIG 0x0C14 ; = _INTOSCIO & _WDT_OFF & _PWRTE_OFF & _BOD_OFF & _MCLRE_OFF & _CP_ON & _CPD_ON
    __CONFIG _INTOSCIO & _WDT_OFF & _PWRTE_OFF & _BOD_OFF & _MCLRE_OFF & _CP_ON & _CPD_ON
;			 & _MCLRE_OFF ; MCLR as Pin
;			 & _CP_OFF & _CPD_OFF ; Code/Data Protection Disabled
;			 & _FCMEN_OFF ; Fail-Safe Clock Monitor is disabled

; Constants
OUT		Equ 	2	; pin for led
WHI		Equ 	4	; pin for led

DAY		Equ		7	; if no input, Out = 30%
TAIL	Equ		5	; 5% day mode
LONG	Equ 	4	; 100% long mode
ADJUST	Equ 	3	; Start 10%, next push +10%
STROBO	Equ 	1	; Stroboscop
EXHIB	Equ 	0	; Exhibit Strobo 2x min delay

DIGITAL	Equ     2	; is digital flag (0 = no, 1 = yes) 

; PWM = [(period) + 1] x 4 x TOSC x TMR2 Prescaler. period from 0 to 255
; DC Ratio = CCPR1L / (PR2 + 1), Manual page 81
;PWMPR	Equ		30	; PWM = [30 + 1] x 4 x (1/125e3) x 1 = 0,992ms (1,008kHz)
;DCTail	Equ		1	; 3,2%
;DCDay	Equ		6	; 20%
;DCLong	Equ		31	; 100%
PWMPR	Equ		199	; PWM = [199 + 1] x 4 x (1/125e3) x 1 = 6,4ms (156,25Hz)
DCTail	Equ		4	; 2%
DCDay	Equ		20	; 10%
DCLong	Equ		200	; 100%

TBLK	Equ		3 	; Time of Blink
TOFF	Equ		6	; Time of led off
TEXH	Equ		11	; Time of exhibition period

cblock	0x20	; start of general purpose registers
	mode		; mode set
	strobo		; strobo counter
    exhib		; exhib counter
	dxms		; delay x times 10/100ms
	dc_a		; used in delay routine
	dc_b		; used in delay routine
	temp		; temp storage
endc

	ORG 0x0000 ; Reset Vector
	GOTO Start

	ORG 0x0004
;	GOTO Start ; Interupt Vector

Start:
	CALL InitMCU

	CLRF	mode
	CALL	Delay250ms

Main: ; MAIN LOOP
	; Mode strobo?
	BTFSC	GPIO, STROBO
	GOTO Strobo

	; Mode exhibition?
	BTFSC	GPIO, EXHIB
	GOTO Exhibition

	CALL	Delay250ms

	; Mode long?
	BTFSC	GPIO, LONG
	GOTO SetLong

	BTFSS	mode, DIGITAL	; last mode was digital?
	GOTO PWMs				; no! -> go further
	; yes - turn on PWM
	MOVLW	b'00001100'
	MOVWF	CCP1CON			; PWM mode active high
	BSF		T2CON, TMR2ON	; Start PWM

PWMs:
	; Mode tail?
	BTFSC	GPIO, TAIL
	GOTO SetTail

	; if nothing then day mode shud be
	BTFSS	mode, DAY
	GOTO SetDay

	GOTO Main 			; End of Main loop

InitMCU:
	; Init Inputs/Outputs
	; GP5 = Day, GP4 = Long, GP3 = Fade, GP2 = PWM/Led
	BANKSEL GPIO
	CLRF	GPIO		; Init GPIO
	MOVLW   b'00000111'
	MOVWF   CMCON0		; Disable comparator
	
	BANKSEL	ANSEL
	CLRF	ANSEL		; No Analog
	MOVLW	b'00111011' ; GP5 = Tail, GP4 = Long, GP3 = Adjust, GP2 = PWM/Led
	MOVWF	TRISIO		; Set GP<3-5> as inputs and GP<0-2,6,7> as outputs
	MOVWF	IOC			; interupt on-change enabled on inputs
	BSF		INTCON, GPIE; GPIO Interupt = Enable

	; Default Clock 4MHz (x110 xxx)
	; Default OSCCON = 0110 1000
	MOVLW	b'00010000' ; = 125kHz
	MOVWF	OSCCON

	; PWM period
	MOVLW	PWMPR		; PWM = [(period) + 1] x 4 x TOSC x TMR2 Prescaler. period from 0 to 255
	MOVWF	PR2			; PWM = [39 + 1] x 4 x (1/4e6) x 1 = 0,04ms (25kHz)

	; Set CCP1 as PWM
	BANKSEL CCP1CON
	MOVLW	b'00001100'
	MOVWF	CCP1CON		; PWM mode active high

	BCF		PIR1, TMR2IF; disable interupt
	CLRF	T2CON		; Pre & Postscaler to 1, Timer Off 
	BSF		T2CON, TMR2ON	; Start the timer2 running

	RETURN

SetDay:
	CLRF mode
	BSF mode, DAY
	MOVLW	DCDay
	MOVWF	CCPR1L		; Update Power Settings
	
	GOTO Main

SetTail:
	BTFSC	mode, TAIL	; mode tail?
	GOTO Main			; go back to main

	CLRF mode
	BSF mode, TAIL
	MOVLW	DCTail
	MOVWF	CCPR1L		; Update Power Settings
	
	GOTO Main

SetLong:
	BTFSC	mode, LONG	; mode long?
	GOTO Main			; go back to main

	CLRF mode
	BSF mode, LONG
	BSF mode, DIGITAL

	CLRF	CCP1CON
	BCF		T2CON, TMR2ON	; Stop PWM
	BSF		GPIO, OUT

;	MOVLW	DCLong
;	MOVWF	CCPR1L		; Update Power Settings
	
	GOTO Main

Strobo:
	BTFSC	mode, STROBO	; strobo init done?
	GOTO Check				; go further
	
	CLRF	CCP1CON
	BCF		T2CON, TMR2ON	; Stop PWM
	CLRF	strobo

	CLRF mode
	BSF mode, DIGITAL
	BSF mode, STROBO

Check:
	MOVLW	10			; put the value to compare with in W
    SUBWF	strobo, W	; subtract W from the File Register and Set result in W
	BTFSC   STATUS,C	; if i >= 10
	GOTO Delay			; yes

Blink:
	CALL DelayBlink
	BTFSC	strobo, 0
	GOTO	LedOff
LedOn:
	BSF		GPIO, OUT
	GOTO	Loop
LedOff:
	BCF		GPIO, OUT
	GOTO	Loop

Delay:
	BCF		GPIO, OUT
	CALL DelayStrobo

Loop:
	INCF	strobo
	BTFSC	strobo, 4
	CLRF	strobo

	GOTO Main

Exhibition:
	BTFSC	mode, EXHIB		; exhib init done?
	GOTO LoopEx				; go further
	
	CLRF	CCP1CON
	BCF		T2CON, TMR2ON	; Stop PWM
	CLRF	strobo
	CLRF 	exhib

	CLRF mode
	BSF mode, DIGITAL
	BSF mode, STROBO
	BSF mode, EXHIB

LoopEx:
	INCF	exhib

	MOVLW	32			; put the value to compare with in W
    SUBWF	exhib, W	; subtract W from the File Register and Set result in W
	BTFSC   STATUS,C	; if exhib >= 10
	GOTO DelayEx			; yes

	; Make strobo!
	GOTO Strobo

DelayEx:
	BCF		GPIO, OUT
	CALL DelayExhib

	GOTO Main

DelayExhib
	MOVLW	TEXH
	GOTO DLInit
DelayStrobo	; At 125KHz (3088 instructions = 98,816ms)
	MOVLW	TOFF
	GOTO DLInit
DelayBlink	; At 125KHz (3088 instructions = 98,816ms)
	MOVLW	TBLK
	GOTO DLInit
Delay250ms	; At 125KHz (7708 instructions = 246,65ms)
	MOVLW	10
	GOTO DLInit
Delay1s	; At 125kHz (33116 instructions = 1,059s)
	MOVLW	43
DLInit
	MOVWF	dc_b
	CLRF	dc_a
DLoop
	DECFSZ	dc_a, f
	GOTO	DLoop
	DECFSZ	dc_b, f
	GOTO DLoop

	RETURN

	END
