; darts_usb_main.asm
;
; DARTS USB interface main file
;
; Copyright (c) 2003 Jeffrey M. Laughlin, n1ywb@arrl.org
;
; Portions (c) 2002 Microchip Technology Incorporated

	list		p=16c745	; list directive to define processor
	#include	<p16c745.inc>	; processor specific variable definitions
	#include    "usb_defs.inc"
	
	__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_OFF & _H4_OSC

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.


;***** VARIABLE DEFINITIONS
unbanked	udata_shr
W_save		res	1	; register for saving W during ISR

bank0	udata
Status_save	res	1	; registers for saving context 
PCLATH_save	res	1	;  during ISR
FSR_save	res	1
CUR_STAT	res	1	; Direction cursor moves on the screen
BUFFER		res	1	; Location for data to be sent to host
COUNTER		res	1   
INNER		res	1
OUTER		res	1
PIRmasked	res	1
PORTA_BUFFER res 1 ; A simple counter for sending test data

	extern	InitUSB
	extern	PutEP1
	extern	GetEP1
	extern	ServiceUSBInt
	extern	CheckSleep
	extern	RemoteWakeup	; Remote Wakeup works with the use of the RA4 pin (active low)

;**********************************************************************
STARTUP	code
	pagesel	Main
	goto	Main
	nop
	
InterruptServiceVector
	movwf	W_save		; save W
	movf	STATUS,W
	clrf	STATUS		; force to page 0
	movwf	Status_save	; save STATUS
	movf	PCLATH,w
	movwf	PCLATH_save	; save PCLATH
	movf	FSR,w
	movwf	FSR_save	; save FSR
	pagesel TMR0TEST

; *************************************************************
; Interrupt Service Routine
; First we step through several stages, attempting to identify the source 
; of the interrupt.
; ******************************************************************

Process_ISR
TMR0TEST
	btfsc	INTCON,T0IE
	btfss	INTCON,T0IF
	goto	INTTEST
	banksel PORTA
	movfw	PORTA
	pagesel TMR0_ISR
	call	TMR0_ISR
INTTEST
	btfsc	INTCON,INTE
	btfss	INTCON,INTF
	goto	RBTEST
	nop			; insert RB0/INT code call here
RBTEST
	btfsc	INTCON,RBIE
	btfss	INTCON,RBIF
	goto	PERIPHERALTEST
	nop			; insert PORTB Change code call here

PERIPHERALTEST
	btfss	INTCON,PEIE	; is there a peripheral interrupt?
	goto	EndISR		; all done....

TEST_PIR1
	banksel	PIR1
	movf	PIR1,w
	banksel	PIE1
	andwf	PIE1,w		; mask the enables with the flags
	banksel	PIRmasked
	movwf	PIRmasked
	pagesel	ServiceUSBInt
	btfsc	PIRmasked,USBIF	; USB interrupt flag
	call	ServiceUSBInt	; Service USB interrupt
	btfsc	PIRmasked,ADIF	; AD Done?
	nop
	btfsc	PIRmasked,RCIF
	nop
	btfsc	PIRmasked,TXIF
	nop
	btfsc	PIRmasked,CCP1IF
	nop
	btfsc	PIRmasked,TMR2IF
	nop
	btfsc	PIRmasked,TMR1IF
	nop
TEST_PIR2
	banksel	PIR2
	movf	PIR2,w
	banksel	PIE2
	andwf	PIE2,w
	banksel	PIRmasked
	movwf	PIRmasked
	btfsc	PIRmasked,CCP2IF
	nop

; ******************************************************************
; End ISR, restore context and return to the Main program
; ******************************************************************
EndISR
	clrf	STATUS		; select bank 0
	movf	FSR_save,w	; restore the FSR
	movwf	FSR
	movf	PCLATH_save,w	; restore PCLATH
	movwf	PCLATH
	movf	Status_save,w	; restore Status
	movwf	STATUS
	swapf	W_save,f	; restore W without corrupting STATUS
	swapf	W_save,w
	retfie

	code

Main
; RDF USB Interface Pseudo-code
; RA4/T0CKI - RDF unit clock signal
; RA0	- Direction LSB
; RA1	- Direction bit 2
; RA2	- Direction bit 3
; RA3	- Direction MSB

; General initialization
	movlw	.30		; delay 16 uS to wait for USB to reset
	movwf	W_save		; SIE before initializing registers
	decfsz	W_save,f	; inner is merely a convienient register
	goto	$-1		; to use for the delay counter.

; Initialize IO pins
	banksel	PORTA
	clrf	PORTB
	clrf PORTA      ; Initialize PORTB by clearing output data latches
	
	banksel	TRISA
	clrf	TRISB		; Set PORTB as all outputs, used for status LEDs

	movlw	0xFF		; Configure PORTA as all digital inputs
	movwf	TRISA
	banksel	ADCON1
	movwf	ADCON1

; Initialize USB UART
	pagesel	InitUSB		; These six lines of code show the appropriate
	call	InitUSB		;  way to initialize the USB. First, initialize
				        ;  the USB (wait for host enumeration) then wait
	ConfiguredUSB		;  until the enumeration process to complete.
	
; Init timer 0
	banksel TMR0
	movlw		0x00
	movwf		TMR0
	banksel OPTION_REG

; Uncomment these 3 lines to slow down the rate at which data is sent
;	bcf	OPTION_REG, PSA	; Assign prescaler to TMR0
;	bcf	OPTION_REG, PS0	; Select 1:8 prescaler value
;	bcf	OPTION_REG, PS1

	banksel INTCON
	bsf	INTCON, T0IE		; Enable TMR0 interrupt

	bcf	STATUS,RP0	    ; Make sure you include all pagesels and return to
	bcf	STATUS,RP1	    ;  the desired bank (in this case Bank 0.)

; Wait for clock signal
main_loop
   pagesel	main_loop
	goto main_loop

TMR0_ISR

	banksel	BUFFER
	movwf		BUFFER
	andlw		b'00001111' ; Clear all but the 4 counter pins
	bcf		STATUS,IRP
	movlw		BUFFER  ; send one byte to the PC at BUFFER
	movwf		FSR
	movlw		1
	pagesel	PutEP1
	call		PutEP1
	banksel	TMR0
;	movlw		0xFF - 0x20	; Smaller values make the data rate slower. 0xFF is full speed
	movlw		0xFF 
	movwf		TMR0
	banksel	INTCON
	bcf		INTCON, T0IF
	retlw 0


	END                       ; directive 'end of program'
