;***********************************************************************
;*   This file is the firmware to implement a pause width modulated    *
;*   at GPIO 2 Transistor output driver                                *
;***********************************************************************
;*                                                                     *
;*    					                               *
;*                                                                     *
;*    File Version: A.0                                               *
;*                                                                     *
;*    Author:       g michael                                          *
;*                  Principal Applications Engineer                    *
;*    Company:      Michaels Prototype                                 *
;*                                                                     *
;***********************************************************************

	list      p=12F683	; list directive to define processor
	#include <p12f683.inc>	; processor specific variable definitions

	#include macros1.asm
 __CONFIG  _CP_OFF & _WDT_OFF & _BOD_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF

;	ERRORLEVEL -302				; Get rid of banking messages...

;******************************************************************************

#define Bank0		0x00
#define	Bank1		0x80

;******************************************************************************
;General Purpose Registers (GPR's) 
;******************************************************************************

	cblock	0x20
	SystemStatus
	AL,AH:3,BL,BH,CL,CH,DL,DH
	EEcount	
	CLH:2,DLH:2,CLM:2,DLM:2
	
	endc

#define	iodir	 b'11111011'
				; GP5	inp 
				; GP4	inp  ; AN3
				; GP3	inp
				; GP2	outp
				; GP1	inp
				; GP0	inp

#define analog 	B'01111011' 		;ADC Frc clock,
					;and GP0+1, 3 as analog
;******************************************************************************
;Reset Vector 
;******************************************************************************
	ORG     0x000		; processor reset vector
	nop			; required by in circuit debugger
	goto    Init		; go to beginning of program

;******************************************************************************
;Interrupt Vector     
;******************************************************************************
	ORG     0x004
	return			;IRQ TRAP
;******************************************************************************
;Subroutines
;******************************************************************************

movdutyAL	clrf	AH
		clrC			;CRLRC
		mov	CCPR1L,AL	;load
		shll	AL
		shll	AL
		btfsc	CCP1CON,DC1B0
		 bsf	AL,0
		btfsc	CCP1CON,DC1B1
		 bsf	AL,1
		retlw 0


movALduty	clrC
		shrr	AL		;unload
		bcf	CCP1CON,DC1B0
		skpNC
		 bsf 	CCP1CON,DC1B0
		clrC
		shrr	AL
		bcf	CCP1CON,DC1B1
		skpNC
		 bsf 	CCP1CON,DC1B1
		mov	AL, CCPR1L
		retlw	0


subtrisio	bsf	STATUS,5	;BANKSEL	Bank1		; 
		movwf	TRISIO		;
		BANKSEL	Bank0
		return


displaybits	eq	DL, .10
		call	wak2delay


		eq	DH, .15
firstbit	movf	DH,F
		exe_any AH, 7, STATUS, Z
		 goto nextbit-1
		clrC
		rlf	AL,F
		rlf	AH,F
		decf	DH,F
		goto	firstbit

		incf	DH,F
nextbit		clrC				;restore AL
		rlf	AL,F
		rlf	AH,F

		bcf	GPIO,5
		movlw	1
		skpC
		 goto	wdelay
		movlw	5
		bsf	AL,0			;restore AL
		bsf	GPIO,5

wdelay		movwf	DL

		movlw	iodir &	b'11011111'			;GP5 outout
	
		call	subtrisio

;		movlw	b'00001100'
;		iorwf	 CCP1CON, F	 ; enable PWM
;
		call	wak2delay
	
;dis		movlw	b'11110011'
;		andwf	 CCP1CON, F	 ; disable PWM
;
		movlw	iodir |	b'00100000'		;GP5 input
	
		call	subtrisio

		eq	DL,1
		call	wak2delay
		decfsz	DH,F
		 goto nextbit
		retlw	0		

		
wak2delay	clrwdt
		decfsz	CL,F
		 goto	$-2
		decfsz	CH,F
		 goto	$-4
		decfsz	DL,F
		 goto	$-6
		retlw	0


;******************************************************************************
;Initialization
;******************************************************************************


Init	movlw	b'00000000' 	; all GPIO Low 
	movwf	GPIO

	BANKSEL	Bank1		; BANK1


	movlw	iodir     ; set direction bits 
	movwf	TRISIO		;
				
 
	movlw	B'11011000'	; Timer0 internal clock, 1:1 prescale
	movwf	OPTION_REG	; set option register for Timer0 functions
				;OPTION_REG  OPTION REGISTER (ADDRESS: 81h)
				;Note: To achieve a 1:1 prescaler assignment for
				;TMR0, assign the prescaler to the WDT by
				;setting PSA bit to 1 (Option<3>). See
				;Section 5.4 Prescaler.
				;R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1
				;GPPU INTEDG T0CS  T0SE   PSA   PS2   PS1   PS0
				;  7     6     5     4      3    2     1     0
				;bit 7 GPPU: GPIO Pull-up Enable bit
				;1 = GPIO pull-ups are disabled
				;0 = GPIO pull-ups are enabled by individual port latch 
				;   values   in WPU register
				;
				;bit 6 INTEDG: Interrupt Edge Select bit
				;1 = Interrupt on rising edge of GP2/INT pin
				;0 = Interrupt on falling edge of GP2/INT pin
				;
				;bit 5 T0CS: TMR0 Clock Source Select bit
				;1 = Transition on GP2/T0CKI pin
				;0 = Internal instruction cycle clock (CLKOUT)
				;
				;bit 4 T0SE: TMR0 Source Edge Select bit
				;1 = Increment on high-to-low transition on GP2/T0CKI pin
				;0 = Increment on low-to-high transition on GP2/T0CKI pin
				;
				;bit 3 PSA: Prescaler Assignment bit
				;1 = Prescaler is assigned to the WDT
				;0 = Prescaler is assigned to the Timer0 module
				;bit 2-0 PS<2:0>: Prescaler Rate Select bits
				;Note 1: A dedicated 16-bit WDT postscaler is available 
				;for the PIC12F683. See
				;Section 12.6 Watchdog Timer (WDT) for more information.
				;
			
				;Bit Value   TMR0 Rate 	   WDT Rate(1)
				;000		1:2		1:1	
				;001		1:4		1 : 2
				;010		1:8		1:4
				;011		1:16		1:8
				;100		1:32		1:16
				;101		1:64		1:32
				;110		1:128		1:64
				;111		1:256		1:128
				;  1,000,000 /64 /125 /125 = 1sec
	;	

	movlw	analog
	movwf	ANSEL		; configure A/D 
				;ANSEL  ANALOG SELECT REGISTER (ADDRESS: 9Fh)
				;U-0 R/W-0 R/W-0 R/W-0 R/W-1 R/W-1 R/W-1 R/W-1
				;   ADCS2 ADCS1 ADCS0  ANS3  ANS2  ANS1  ANS0
				; 7     6    5     4     3      2     1  bit 0
				;bit 7 Unimplemented: Read as 0
				;bit 6-4 ADCS<2:0>: A/D Conversion Clock Select bits
				;000 = FOSC/2
				;001 = FOSC/8
				;010 = FOSC/32
				;x11 = FRC (clock derived from a dedicated internal 
				;		oscillator = 500 kHz max)
				;100 = FOSC/4
				;101 = FOSC/16
				;110 = FOSC/64
				;bit 3-0 ANS<3:0>: Analog Select bits
				;Analog select between analog or digital function on pins 
				;ANS<3:0>, respectively.
				;1 = Analog input. Pin is assigned as analog input(1).
				;0 = Digital I/O. Pin is assgn to port or special function.
				;Note1:Setting a pin to an analog input automatically 
				;	disables the digital input circuitry,
				;	weak pull-ups and interrupt-on-change if available. 
				;The corresponding TRISIO bit
				;must be set to input mode in order to allow external 
				;control of the voltage on the pin.
 
	movlw	b'01100001'
	movwf	OSCCON		; 4MHz
				;OSCCON  OSCILLATOR CONTROL REGISTER (ADDRESS: 8Fh)
				;Note: Due to the wide range of oscillator start-up
				;times, the Fail-Safe circuit is not active
				;during oscillator start-up (i.e., after exiting
				;Reset or Sleep). After an appropriate
				;amount of time, the user should check the
				;OSTS bit (OSCCON<3>) to verify the
				;oscillator start-up and system clock
				;switchover has successfully completed.
				;U-0 R/W-1 R/W-1 R/W-0  R-1    R-0 R-0 R/W-0
				;   IRCF2 IRCF1 IRCF0 OSTS(1) HTS LTS SCS
				; 7    6     5     4     3      2   1   0
				;bit 7 Unimplemented: Read as 0
				;
				;bit 6-4 IRCF<2:0>: Internl Oscillator Frequency Select bits
				;000 = 31 kHz
				;001 = 125 kHz
				;010 = 250 kHz
				;011 = 500 kHz
				;100 = 1 MHz
				;101 = 2 MHz
				;110 = 4 MHz
				;111 = 8 MHz
				;
				;bit 3 OSTS: Oscillator Start-up Time-out Status bit
				;1 = Device is running from the external system clock 
				;    defined by FOSC<2:0>
				;0 = Device is running from the internal system clock 
				;    (HFINTOSC or LFINTOSC)
				;
				;bit 2 HTS: HFINTOSC (High Frequency  8 MHz to 125 kHz) 
				;1 = HFINTOSC is stable
				;0 = HFINTOSC is not stable
				;
				;bit 1 LTS: LFINTOSC (Low Frequency  31 kHz) Stable bit
				;1 = LFINTOSC is stable
				;0 = LFINTOSC is not stable
				;
				;bit 0 SCS: System Clock Select bit
				;1 = Internal oscillator is used for system clock
				;0 = Clock source defined by FOSC<2:0>
				;Note 1: Bit resets to 0 with Two-Speed Start-up and LP, 
				;XT or HS selected as the oscillator
				;mode or Fail-Safe mode is enabled.
	movlw	b'00000000'
	movwf	PIE1		;

	;			REGISTER 3-4: PIE1: PERIPHERAL INTERRUPT ENABLE REGISTER 1
	;			R/W-0 R/W-0 R/W-0 U-0 R/W-0 R/W-0 R/W-0  R/W-0
	;			EEIE  ADIE  CCP1IE   CMIE  OSFIE TMR2IE TMR1IE
	;			  7     6      5    4   3      2    1      0it 0

	;			bit 7 EEIE: EE Write Complete Interrupt Enable bit
	;			1 = Enables the EE write complete interrupt
	;			0 = Disables the EE write complete interrupt

	;			bit 6 ADIE: A/D Converter (ADC) Interrupt Enable bit
	;			1 = Enables the ADC interrupt
	;			0 = Disables the ADC interrupt

	;			bit 5 CCP1IE: CCP1 Interrupt Enable bit
	;			1 = Enables the CCP1 interrupt
	;			0 = Disables the CCP1 interrupt

	;			bit 4 Unimplemented: Read as 0

	;			bit 3 CMIE: Comparator Interrupt Enable bit
	;			1 = Enables the Comparator 1 interrupt
	;			0 = Disables the Comparator 1 interrupt

	;			bit 2 OSFIE: Oscillator Fail Interrupt Enable bit
	;			1 = Enables the oscillator fail interrupt
	;			0 = Disables the oscillator fail interrupt

	;			bit 1 TMR2IE: Timer2 to PR2 Match Interrupt Enable bit
	;			1 = Enables the Timer2 to PR2 match interrupt
	;			0 = Disables the Timer2 to PR2 match interrupt

	;			bit 0 TMR1IE: Timer1 Overflow Interrupt Enable bit
	;			1 = Enables the Timer1 overflow interrupt
	;			0 = Disables the Timer1 overflow interrupt


	banksel	Bank0		; switch back to PORT memory bank


	movlw	b'00000111'     ;comparator off
	movwf	CMCON0		
				; comparator enable input GP1 - Internal reference
				;CMCON0  COMPARATOR CONTROL REGISTER 0 (ADDRESS: 19h)
				;U-0 R-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
				;   COUT    CINV  CIS   CM2   CM1   CM0
				; 7    6  5     4    3     2     1     0
				;
				;bit 6 COUT: Comparator Output bit
				;When CINV = 0:
				;1 = VIN+ > VIN-
				;0 = VIN+ < VIN-
				;When CINV = 1:
				;1 = VIN+ < VIN-
				;0 = VIN+ > VINbit
				;
				;bit 4 CINV: Comparator Output Inversion bit
				;1 = Output inverted
				;0 = Output not inverted
				;
				;bit 3 CIS: Comparator Input Switch bit
				;When CM<2:0> = 110 or 101:
				;1 = VIN- connects to CIN+   GP0
				;0 = VIN- connects to CINbit GP1
				;
				;2 CM<2:0>: Comparator Mode bits
				;
				;FIGURE 8-3: COMPARATOR I/O OPERATING MODES
				;Note: Comparator interrupts should be disabled
				;during a Comparator mode change.
				;Otherwise, a false interrupt may occur.
				;Comparator Reset (POR Default Value  Low Power)         	
				;CM<2:0> = 000
				;                                                 
				;Comparator Off (Lowest Power)
				;CM<2:0> = 111

				;Comparator without Output                                	
				;CM<2:0> = 010 							
				;
				;Comparator w/o Output and with Internal Reference
				;CM<2:0> = 100
				;
				;Comparator with Output and Internal Reference 			
				;CM<2:0> = 011 							
				;
				;Multiplexed Input with Internal Reference and Output
				;CM<2:0> = 101
				;
				;Comparator with Output 					
				;CM<2:0> = 001 	
				
				;Multiplexed Input with Internal Reference
				;CM<2:0> = 110
				;
				
	movlw	b'00000000'	;disable interrupts
	movwf	INTCON		;
	;			REGISTER 3-3: INTCON: INTERRUPT CONTROL REGISTER
	;			R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
	;			GIE   PEIE  T0IE  INTE  GPIE  T0IF  INTF  GPIF
	;			 7     6     5     4     3     2     1     0
	;			
	;			bit 7 GIE: Global Interrupt Enable bit
	;			1 = Enables all unmasked interrupts
	;			0 = Disables all interrupts

	;			bit 6 PEIE: Peripheral Interrupt Enable bit
	;			1 = Enables all unmasked peripheral interrupts
	;			0 = Disables all peripheral interrupts
	;
	;			bit 5 T0IE: Timer0 Overflow Interrupt Enable bit
	;			1 = Enables the Timer0 interrupt
	;			0 = Disables the Timer0 interrupt

	;			bit 4 INTE: GP2/INT External Interrupt Enable bit
	;			1 = Enables the GP2/INT external interrupt
	;			0 = Disables the GP2/INT external interrupt

	;			bit 3 GPIE: GPIO Change Interrupt Enable bit(1)
	;			1 = Enables the GPIO change interrupt
	;			0 = Disables the GPIO change interrupt

	;			bit 2 T0IF: Timer0 Overflow Interrupt Flag bit(2)
	;			1 = Timer0 register has overflowed 
	;			    (must be cleared in software)
	;			0 = Timer0 register did not overflow

	;			bit 1 INTF: GP2/INT External Interrupt Flag bit
	;			1 = The GP2/INT external interrupt occurred 
	;			(must be cleared in software)
	;			0 = The GP2/INT external interrupt did not occur

	;			bit 0 GPIF: GPIO Change Interrupt Flag bit
	;			1 = When at least one of the GPIO <5:0> pins changed state 
	;			(must be cleared in software)
	;			0 = None of the GPIO <5:0> pins have changed state

	;			Note 1: IOC register must also be enabled.
	;			2: T0IF bit is set when TMR0 rolls over. 
	;			TMR0 is unchanged on Reset 
	;			and should be initialized before
	;			clearing T0IF bit.
	;
	banksel	Bank1
	movlw	b'00000000'	;enable interrupt
	movwf	IOC
				;REGISTER 4-4: IOC  INTERRUPT-ON-CHANGE GPIO REGISTER 
				;(ADDRESS: 96h)
				;U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
				;       IOC5  IOC4  IOC3  IOC2  IOC1  IOC0
				;bit 7 bit 0
				;bit 7-6 Unimplemented: Read as 0
				;bit 5-0 IOC<5:0>: Interrupt-on-change GPIO Control bit
				;1 = Interrupt-on-change enabled
				;0 = Interrupt-on-change disabled
				;Note 1: Global Interrupt Enable (GIE) must be enabled for
				;       individual interrupts to be recognized.

	movlw	b'00000000'	;enable weak pullup 
	movwf	WPU







	movlw	.255
	movwf	PR2			; min 256us = 0.976 *4kHz 
	banksel Bank0


	eq CCP1CON, b'00001100'	 ; enable PWM
;                     7  4   0   ;  clr duty cycle
	eq	CCPR1L, 0x04	 ;  4 * prescaler = 16 values from 250ns to 4.750us

			;CCP1CON  CCP CONTROL REGISTER 1 (ADDRESS: 15h)
		
			; U-0 U-0 R/W-0 R/W-0 R/W-0  R/W-0   R/W-0  R/W-0
			;       DC1B1 DC1B0 CCP1M3 CCP1M2 CCP1M1 CCP1M0
			;  7    6   5     4     3      2      1      0     
			;bit7
			;Unimplemented: Read as 0
			;bit6
			;Unimplemented: Read as 0
			
			;bit5 , bit4
			;DC1B<1:0>: PWM Least Significant bits
			;Capture mode:
			;Unused.
			;Compare mode:
			;Unused.
			;PWM mode:
			;These bits are the two LSbs of the PWM duty cycle. 
			;The eight MSbs are found in CCPR1L.
			
			;bit 3
			;CCP1M<3:0>: CCP1 Mode Select bits
			;0000 = Capture/Compare/PWM disabled (resets CCP1 module)
			;0100 = Capture mode, every falling edge
			;0101 = Capture mode, every rising edge
			;0110 = Capture mode, every 4th rising edge
			;0111 = Capture mode, every 16th rising edge
			;1000 = Compare mode, set output on match (CCP1IF bit is set)
			;1001 = Compare mode, clear output on match (CCP1IF bit is set)
			;1010 = Compare mode, generate software interrupt on match 
			;	(CCP1IF bit is set,
			;	CCP1 pin is unaffected)
			;1011 = Compare mode, trigger special event (CCP1IF bit is set, 
			;	CCP1 pin is unaffected);
			;	CCP1 resets TMR1 and starts an A/D conversion 
			;	(if A/D module is enabled)
			;11xx = PWM mode
			;
	
	;bcf	PIR1,TMR2IF	
	eq	T2CON, b'00000100'	; switch on TMR2

	;		REGISTER 7-1: T2CON  TIMER2 CONTROL REGISTER (ADDRESS: 12h)
	;		U-0 R/W-0   R/W-0    R/W-0   R/W-0   R/W-0  R/W-0   R/W-0
	;		   TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0
	;		 7    6        5       4       3       2      1    bit 0
	;		bit 7 Unimplemented: Read as 0
	;		bit 6-3 TOUTPS<3:0>: Timer2 Output Postscale Select bits
	;		0000 = 1:1 postscale
	;		0001 = 1:2 postscale
	;		
	;		
	;		
	;		1111 = 1:16 postscale
	;		bit 2 TMR2ON: Timer2 On bit
	;		1 = Timer2 is on
	;		0 = Timer2 is off
	;		bit 1-0 T2CKPS<1:0>: Timer2 Clock Prescale Select bits
	;		00 = Prescaler is 1    <----- for spoton
	;		01 = Prescaler is 4    <----- for campinglight
	;		1x = Prescaler is 16
	;	

	BANKSEL ADCON0 ;
			;	REGISTER 9-1: ADCON0: A/D CONTROL REGISTER 0
			
			;R/W-0 R/W-0 U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0
			;ADFM  VCFG         CHS1 CHS0 GO/DONE ADON
			;bit 7                                bit 0
			;Legend:
			;R = Readable bit W = Writable bit U = Unimplemented bit, read as 0
			;-n = Value at POR 1 = Bit is set 0 = Bit is cleared x = Bit is unknown
			
			;bit 7 ADFM: A/D Conversion Result Format Select bit
			;1 = Right justified
			;0 = Left justified
			
			;bit 6 VCFG: Voltage Reference bit
			;1 = VREF pin
			;0 = VDD
			
			;bit 5-4 Unimplemented: Read as 0
			
			;bit 3-2 CHS<1:0>: Analog Channel Select bits
			;00 = AN0
			;01 = AN1
			;10 = AN2
			;11 = AN3
			
			;bit 1 GO/DONE: A/D Conversion Status bit
			;1 = A/D conversion cycle in progress. Setting this bit starts an A/D conversion cycle.
			;This bit is automatically cleared by hardware when the A/D conversion has completed.
			;0 = A/D conversion completed/not in progress
			
			;bit 0 ADON: ADC Enable bit
			;1 = ADC is enabled
			;0 = ADC is disabled and consumes no operating current

	clrf	case

moreadc	MOVLW 	B'00001101' 		;left justify,
	MOVWF 	ADCON0 			;Vdd Vref, AN3, On
	goto	$+1	
	goto	$+1
	goto	$+1			;Acquisiton delay
	BSF 	ADCON0,GO 			;Start conversion
	BTFSC 	ADCON0,GO 		;Is conversion done?
	GOTO 	$-1 			;No, test again
 			;
	MOVF 	ADRESH,W 		;Read upper 8 bits
	MOVWF 	AL 			;Store in GPR space

;	BANKSEL ADRESL 			;
;	MOVF 	ADRESL,W 		;Read lower 8 bits
;	BANKSEL AL	
;	MOVWF 	AL 			;Store in GPR space

;
;	shrr	AL			;max 9 bit
;	shrr	AL			;max 8 bit
;	call	movALduty		;leaves AL = AL div 4
	
	clrf	AH
	call displaybits

	movfw	case
	addwf	PCL,F
	 goto	case0
	 goto	case1
	 goto	case2
	

case0	exelsl	AL,.192
	 goto	moreadc	

	movlw	b'11110011'
	andwf	 CCP1CON, F	 ; disable PWM
	incf	case,F
	goto	moreadc

case1	exegrl	AL,.180
	 goto	moreadc
	movlw	b'00001100'
	iorwf	 CCP1CON, F	 ; enable PWM
	incf	case,F

case2	exelsl	AL,.160
	 goto	make0
	exelsl	AL,.182
	 goto	moreadc	

run	eq	AL,.4

	MOVLW 	B'00000101' 		;left justify,
	MOVWF 	ADCON0 			;Vdd Vref, AN1, On
	goto	$+1	
	goto	$+1
	goto	$+1			;Acquisiton delay
	BSF 	ADCON0,GO 		;Start conversion
	BTFSC 	ADCON0,GO 		;Is conversion done?
	GOTO 	$-1 			;No, test again
 			;
	MOVF 	ADRESH,W 		;Read 8 bits
	MOVWF 	BL 			;Store in GPR space

	shr	BL			;PR2 = 0..128 + Duty
	inc	BL,AL
	movfw	BL
	banksel	PR2
	Movwf	PR2
	banksel AL

;	clrf	AL
;	clrf	BL
;	clrwdt
;	decfsz	AL,F
;	 goto	$-2
;	decfsz	BL,F
;	 goto	$-4
	
	goto moreadc

	end
