;   CLOCK: Internal RC 4MHz (instruction execution time: 1usec)
;	To control H-Bridge direction and speed.
;   Read ADC GP0 write 10-bit value to PWM GP2
;	SW1 connected GP3, SW2 connected GP4
;	SW1 toggles GP1 ON-OFF
;	SW2 toggles GP5 ON-OFF
;	GP1 and GP5 connected to H-Bridge inputs.
;	If GP1 is LOW AND GP5 is LOW PWM turned off.
;	Lewis Loflin	
;   www.bristolwatch.com
;==================================================================================
           list     P=12F683, ST=OFF   ; Turnoff Symbol Table in List file.

        errorlevel  -302        ; Ignore error message when storing to Bank 1.
;==================================================================================

        #include   <p12f683.inc>

   __config _INTOSCIO & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_NSLEEP & _IESO_OFF & _FCMEN_OFF

;*****[ Data Storage Reg's ]*****
            CBLOCK  0x20        ; Assign each reg. from Bank 0 RAM area.
            count1              
            count2             
            count3
            count4
			temp
			RESULTHI
			RESULTLO
            ENDC                ; Conclude Bank 0 RAM assignments.

;**********************************************************************
	ORG     0x000             ; processor reset vector
	goto    setup              ; go to beginning of program
	
	ORG     0x004             ; interrupt vector location
	
;**********************************************************************
			
			
			
setup
        BANKSEL OSCCON          ; Switch to Bank 1.
        MOVLW   b'01100001'     ; 4MHz Clk, IntOsc, SysClk via IntOsc
        MOVWF   OSCCON
;
        BANKSEL CMCON0          ; Switch to Bank 0.
        MOVLW   b'00000111'     ; Turn off Comparator.
        MOVWF   CMCON0  
 
        BANKSEL ANSEL           ; Switch to Bank 1.
        CLRF    ANSEL           ; Set I/O pins to Digital.
;
        ; Define inputs & outputs.
        CLRF   TRISIO ; all output
        BSF	   TRISIO, GP3 ; GP3 input
		BSF	   TRISIO, GP4 
;
        BANKSEL GPIO            ; Switch to Bank 0.
        CLRF    GPIO            

; This code block configures the ADC for polling, 
; Vdd reference, Frc clock and GP0 input.

	BANKSEL TRISIO ; bank 1
	BSF     TRISIO, 0 ; Set GP0 for ADC input
	BANKSEL ANSEL ; 0x9F P32 
	MOVLW   0b01110001 ; ADC Frc clock,
	IORWF   ANSEL ; and GP0 as analog 
	BANKSEL ADCON0 ; 0x1F
	MOVLW   0b00000001 ; Left justify,
	MOVWF   ADCON0 ; Vdd Vref, AN0, On
	CALL    delay_1ms ; Acquisiton delay




; setup PWM
; CCP1CON in bank 0 bits 4-5 are LSB of 10-bit PWM


	movlw	b'00000111'
	movwf	T2CON ; turn on TMR2 prescale 16 - frequency
	movlw	d'127' ; duty cycle = TMR2 = CCPR1L:CCP1CON<5:4>

	movwf	CCPR1L
	movlw	b'00001100'
	movwf	CCP1CON 	; turn on PWM 
		
		goto loop
;
;==================================================================================

loop

 	CALL  ADCtoPWM
	BTFSS GPIO, GP3 ; SW1
	CALL  toggleGP1
	BTFSS GPIO, GP3
	GOTO $-1 ; wait for release


	BTFSS GPIO, GP4
	CALL  toggleGP5
	BTFSS GPIO, GP4
	GOTO $-1 ; wait for release

;	If GP1 is LOW AND GP5 is LOW PWM turned off.
	BTFSC GPIO, 1
	goto $+5
	BTFSC GPIO, 5
	goto $+3
	CALL PWMOFF
	goto loop
    Call PWMON

goto loop
		
; delay routines *************************************

; Calculating a 1mSec delay. 4mHz is divided by 4 internally to
; 1,000,000. Take reciprocal divide 1mSec by 1uSec = 1000.
; GOTO uses 2 cycles DECFSZ 1 cycle = 3 cycles or 3uSec.
; 3 * 167 * 2 = 1000uSec. or 1mSec.


delay_1ms
	; 4 mHz crystal
	movlw D'2'
	movwf count1
aa	movlw D'167'
	decfsz count2, F
	goto $-1 ; two cycles
	decfsz count1, F
	goto aa 
	return


delay_100ms
	movlw d'100'
	movwf count3
bb	call delay_1ms
	decfsz count3, F
	goto bb
	return
;============================================================	

PWMOFF
	BANKSEL TRISIO
	BSF TRISIO, GP2
	BANKSEL GPIO
	CALL delay_1ms
	RETURN

PWMON
	BANKSEL TRISIO
	BCF TRISIO, GP2
	BANKSEL GPIO
	CALL delay_1ms
	RETURN
	
;####################################

readADC0
	BSF     ADCON0,GO  ;Start conversion
	BTFSC   ADCON0,GO ;Is conversion done?
	GOTO    $-1  ;No, test again
	MOVF    ADRESH,W ;Read upper 8 bits
	MOVWF   RESULTHI ;Store in GPR space
; ADRESL bits 6, 7 LSB of ADC
	BANKSEL ADRESL
	MOVFW   ADRESL
	BANKSEL ADRESH ; bank 0
; right shift bits 7, 6 to bits 4, 5
	MOVWF   RESULTLO
	RRF     RESULTLO, f
	RRF     RESULTLO, f
	return	

;######################################

ADCtoPWM
	CALL  readADC0
	MOVFW RESULTHI
	MOVWF CCPR1L
; RESULTLO bits 5, 4 LSB of ADC
; CCP1CON bit 5,4 LSB PWM

	MOVLW	b'00001100'
	IORWF  RESULTLO, w
	MOVWF	CCP1CON 	; turn on PWM 
	return
	
;######################################

; XOR toggle
toggleGP1 ; LED on GP1
	movlw 2
	xorwf GPIO, f
	CALL delay_1ms
	return	


; non-XOR toggle
toggleGP5 ; LED on GP5

	BTFSS GPIO, 5
	goto $+3
	BCF GPIO, 5
	goto $+2	
    BSF GPIO, 5
	CALL delay_1ms
	return	
	
	
end