;*****************************************************************************************
; 
; Filename:	frequency_counter.src
;
; Author:	Alberto Geraci
;		BTX Sistemas	
;		Argentina.
;		
; Revision:	1.01
;
; Freq:		50MHz
;
; Compiled using: SX-Key.
;
; Date Written	: July 16, 2002
;
; Last Revised	: July 20, 2002
;
; Program Description:
;
;		Super Simple !! SX based 15Mhz frequency counter
;		Simple project to demostrate the SX power running at 50Mhz
;		working together with a PC serial port.
;		You can see the frequency test in a PC software window.
;
; Interface Pins:
;		
;		input	= rc	; entire port
;		input	= ra	; entire port
;		rescount= rb.7  ; to reset the external counter
;*****************************************************************************************
;
		device sx28l,stackx_optionx
		device oscxt5,turbo
		freq 50000000
		reset reset_entry
; I/O definition
tx_pin		 = 	rb.2	; RS232 transmiter pin
rescount	=	rb.7	; reset the external counter
;
; Variables
		org 20h
tx_high 	= 	$08
tx_low 		= 	$09
tx_count	=	$0A
tx_divide	= 	$0B
times		=	$0C		; variable para generar retardo
ddlycnt1	=	$0D
ddlycnt2	=	$0E
ddlycnt3	=	$0F
ddlycnt4	=	$10
ddlycnt5	=	$11
data1p		=	$12
data1s		=	$13
data2p		=	$14
data2s		=	$15
;
txdivisor 	equ 	32 	; 32 periods per bit

;
;****************************************************************************************************************
		org 0
interrupt
		test	 tx_count 		; busy?
		jz	 noisr			; no byte being sent
		dec	 tx_divide
		jnz 	 noisr
		mov 	 tx_divide,#txdivisor 	; ready for next
		stc 				; ready stop bit
		rr 	 tx_high		; go to next bit
		rr 	 tx_low
		dec	 tx_count 		; 
		movb	 tx_pin,/tx_low.6 	; output next bit
noisr		mov 	 w,#-163 		;interrupt every 163 clocks
		retiw
;****************************************************************************************************************
send_byte	
:wait 		test 	tx_count 			;wait for not busy
		jnz 	:wait
		mov 	tx_high,w
		clrb 	tx_low.7 			; set start bit
		mov 	tx_count,#10 			;1 start + 8 data + 1 stop bit
		ret
;****************************************************************************************************************
; jmp table
;****************************************************************************************************************
reset_entry 	mov	 rb,#%00000000 			;init rb 
		mov 	 !rb,#%00000000
	 	mov	 ra,#%00000000 			;init ra 
		mov 	 !ra,#%00001111
	 	mov	 rc,#%00000000 			;init rc 
		mov 	 !rc,#%11111111
		mov	w,#$0E		;
		mov	M,w		;
 		mov	!rc,#%00000000	;
		mov     !ra,#%00000000  ;
		mov	w,#$0F		;
		mov	M,w		;

		clr fsr 				;reset all ram banks
:loop 		setb 	 fsr.4
		clr 	 ind
		ijnz	 fsr,:loop
		mov	 tx_divide,txdivisor
		mov   	 !option,#%11011111   ; for RS232 disable
;****************************************************************************************************************
;****************************************************************************************************************
MAIN
;****************************************************************************************************************
;****************************************************************************************************************
;
begin		setb	rescount	; clr the counter
		call	res_delay	; delay for the counter reset
		clrb	rescount	; finish clr the counter.
		call	half_sec	; let's the input freq to run the counter for 1/2 sec.
		mov	data1p,rc	; mov to data1p variable, the content of rb register.
		mov	data1s,ra	; mov to data1s variable, the content of ra register.
		setb	rescount	; clr the counter
		call	res_delay	; delay for the counter reset
		clrb	rescount	; finish clr the counter.
		call	short_time	; let's the input freq to run the counter for 1/4096 sec.
		mov	data2p,rc	; mov to data2p variable, the content of rb register.
		mov	data2s,ra	; mov to data2s variable, the content of ra register.
		; at this point we finished to measure the input frequency. Now we'll send it to serial port.
		mov   	!option,#%10011111   ; for RS232 enable
		mov	w,data1p
		call	send_byte
		call	send_delay
		and	data1s,#%00001111 ; to avoid the undesired data at high niblle of port RA.
		mov	w,data1s
		call	send_byte
		call	send_delay
		mov	w,data2p
		call	send_byte
		call	send_delay
		and	data2s,#%00001111 ; to avoid the undesired data at high niblle of port RA.
		mov	w,data2s
		call	send_byte
		call	send_delay
		mov   	 !option,#%11011111   ; for RS232 disable
		; finished to sent the data to serial port, all begins again.
		mov	data1p,#0	; 
		mov	data1s,#0	; 
		mov	data2p,#0	; 
		mov	data2s,#0	; 
		jmp	begin
;
;****************************************************************************************************************
;****************************************************************************************************************
SUBROUTINES
;****************************************************************************************************************
	;*********************************************************************************
	; Function: 			half_sec ( half of second delay )
half_sec	
		mov 	w,#191		; 1
		mov 	ddlycnt3,W	; 1
dsloop3	       ;**************************** 130887 *********************	
		mov 	w,#78		; 1
		mov 	ddlycnt2,W	; 1
dsloop2	       ;**************************** 1675 ***********************
		mov 	w,#209		; 1
		mov 	ddlycnt1,W	; 1
dsloop; 				; ******************
		nop			;
		nop			;
		nop			;
		nop			;
		decsz 	ddlycnt1	;
		jmp 	dsloop		; ***** 209 x 8 ***
 		jmp 	again		; 1
again	       ;*********************************************************
		decsz 	ddlycnt2	;
		jmp 	dsloop2		; 
 		jmp 	again2		; 1
again2	       ;*********************************************************
		decsz 	ddlycnt3	;
		jmp 	dsloop3		; 
 		jmp 	again3		; 1
again3		nop			; 1
		retp			; 3
	;*********************************************************************************
;
	;*********************************************************************************
	; Function: 			short_time  (12207 cicles at 50 MIPS=1/4096 sec)
short_time
		mov 	w,#91		; 1
		mov 	ddlycnt5,W	; 1
dsloop5	       ;**************************** 131 *************************
		mov 	w,#32		; 1
		mov 	ddlycnt4,W	; 1
dsloop4; 				; ******************
		decsz 	ddlycnt4	;
		jmp 	dsloop4		; ***** 32 x 4 *****
 		jmp 	again4		; 1
again4	     	;*********************************************************
		decsz 	ddlycnt5	; 1
		jmp 	dsloop5		; 3
 		jmp 	again5		; 1
again5
		nop			; 1
		nop			; 1
		nop			; 1
		nop			; 1
		retp			; 3
	;*********************************************************************************
;
	;*********************************************************************************
	; Function: 			res_delay ( reset counter delay )
	       ;********************************************************
res_delay
		mov 	w,#200		; 
		mov 	ddlycnt4,W	; 
dsloop6; 				; 
		decsz 	ddlycnt4	;
		jmp 	dsloop6		; 
		retp
	;*********************************************************************************
;
	;*********************************************************************************
	; Function: 			send_delay ( send data delay )
	       ;********************************************************
;
send_delay
		mov	 ddlycnt4,#$FF	;	
cagain		mov	 times,#$FF	;
tagain		nop			;
		nop			;
		nop			; add some delay to let the PC software to get values
		decsz	 times		;
		jmp	 tagain		;
		decsz	 ddlycnt4	;	
		jmp	 cagain		;
;
		retp
	;*********************************************************************************
;****************************************************************************************************************
;
;****************************************************************************************************************
end
;
;  NOTES:
;








