Absolute Position Encoder Electronics Upgrade - Appendix B.1
February 18th, 2000 - Bob Broilo

B.1 Encoder.asm

	list	p=16C55
;*******************************************************************
;			    ENCODER.ASM
; Local controller for the VLA absolute position encoder
;*******************************************************************
;Copyright (C) 2002 Bob Broilo, National Radio Astronomy Observatory
;
;This program is free software;  you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation;  either version 2
;of the License, or (at your option) any later version.
;
;This program is distributed in the hope that it will be useful,
;but WITHOUT ANY WARRANTY;  without even the implied warranty of
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;GNU General Public License for more details.
;
;You should have received a copy of the GNU General Public License
;along with this program; if not, write to the Free Software
;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
;
;Bob Broilo - bbroilo@nrao.edu
;PO Box 0, Socorro NM  87801
;
;*******************************************************************
; Reads the Coarse and Fine Resolver-to-Digital converters,
; stores the 4 byte postion, encodes data to send over fiber
; optic cable to data converter (data receiver).
;
; Clock freq 4MHz => inst speed 1MHz => cycle time 1us
;
; Bob Broilo
; 7/7/99
;*******************************************************************
;
;
;
;*******************************************************************
; defines
;*******************************************************************
; status register
status	equ	3		; status register
scarry	equ	0		; 0	s0	carry bit
sdigit	equ	1		; 1	s1	digit carry bit
szero	equ	2		; 2	s2	zero bit
;
; I/O ports - These may seem a bit disorganized but they are assigned
;             to simplify PCB layout
; porta
porta	equ	05		; pins	porta
csb	equ	0		; 6	a0	coarse serial data in
losb	equ	1		; 7	a1	Loss of Signal
clkb	equ	2		; 8	a2	clock data out
fiberb	equ	3		; 9	a3	fiber xmit
trisa	equ	B'11110011'	; set porta I/O: bits 0-1 in, 2-3 out
;
; portb
portb	equ	06		;	portb
sync	equ	0		; 10	b0	fiber stream sync output
highb	equ	5		; 15	b5	select high(1)/low(0) fine byte
fineb	equ	6		; 16	b6	select fine(0)/coarse(1)
busyb	equ	7		; 17	b7	chip busy, data invalid (busybee)
trisb	equ	B'10011100'	; set portb I/O: bit 0 out, 1-4 in, 5-6 out, 7 in
;
; portc
portc	equ	07		; 18-25	portc	data in
trisc	equ	B'11111111'	; set portc I/O: bits 0-7 in
;
; registers
cshi	equ	10	; coarse high byte
cslo	equ	11	; coarse low byte
fnhi	equ	12	; fine high byte
fnlo	equ	13	; fine low byte
ccount	equ	14	; generic counter dudie
temp	equ	15	; temp storage for fiber byte
;
wdtpre	equ	B'00111000'	; WDT prescaler value 1:1
reseth	equ	B'00001111'	; reset header
;
;
;
;*******************************************************************
; Macros
;*******************************************************************
DELAY	macro arg		; insert arg nops
	variable a = arg
	while a > 0
	  nop
	  a -= 1
	endw
endm
;
;
;
;*******************************************************************
; Initialization
;*******************************************************************
start	clrwdt			; set up watchdog timer
	movlw wdtpre
	option 
	clrw			; clear data registers
	clrf cshi
	clrf cslo
	clrf fnhi
	clrf fnlo
	movlw trisa		; configure ports
	tris porta
	movlw trisb
	tris portb
	movlw trisc
	tris portc
	bsf porta,fiberb	; send reset header out fiber
	DELAY 10
	bcf porta,fiberb
;
;
;
;*******************************************************************
; Main
;*******************************************************************
;
; First read fine bytes
main	btfss porta,losb	; wait for LOS to clear
	goto main
	bcf portb,fineb	; select fine data
	bcf portb,highb	; select low byte
dvalid1 btfsc portb,busyb	; wait for valid data
	goto dvalid1
	movf portc,0		; read byte
	movwf fnlo		; store fine low byte
	bsf portb,highb	; select high byte
dvalid2 btfsc portb,busyb	; wait for valid data
	goto dvalid2
	movf portc,0		; read byte
	movwf fnhi		; store fine high byte
;
; Now read coarse bytes
	bsf portb,fineb	; select coarse data
	clrf cshi		; clear cshi and cslo
	clrf cslo
	movlw 08		; read 8 MSBs
	movwf ccount
	bcf status,scarry	; clear carry bit
cloop1	rlf cshi,1		; rotate left (x2)
	bsf porta,clkb		; toggle clock high
	bcf porta,clkb		; initiate read
	DELAY 1
	btfsc porta,csb	; if input bit is 1
	incf cshi,1		; increment register
	decfsz ccount,1 	; are we done?
	goto cloop1		; if not, get next bit
	movlw 08		; read next 8 bits (only 4 valid)
	movwf ccount
cloop2	rlf cslo,1		; rotate left (x2)
	bsf porta,clkb		; toggle clock high
	bcf porta,clkb		; initiate read
	DELAY 1
	btfsc porta,csb	; if input bit is 1
	incf cslo,1		; increment register
	decfsz ccount,1 	; are we done?
	goto cloop2		; if not, get next bit
;
; Now prepare and send the data stream
	bsf portb,sync		; turn on sync pulse
	bsf porta,fiberb 	; send header pulse (2x marker)
	DELAY 9
	bcf porta,fiberb
	DELAY 3
	movf cshi,0		; fine low
	call fbyte
	movf cslo,0		; fine high
	call fbyte
	movf fnhi,0		; coarse low
	call fbyte
	movf fnlo,0		; coarse high
	call fbyte
	bcf portb,sync		; turn off sync pulse
	clrwdt			; prod the watchdog to prevent reset
	goto main		; do it all again
;
;
; Send the byte in w over the fiber line, MSB first
fbyte	movwf temp
	movlw 08		; send eight bits over fiber
	movwf ccount
	bsf porta,fiberb 	; send marker bit
	DELAY 4
	bcf porta,fiberb
	DELAY 3
floop	btfsc temp,7		; see if next bit is one or zero
	bsf porta,fiberb 	; if '1', turn on LED
	DELAY 4
	bcf porta,fiberb	; turn off LED
	rlf temp,1		; scoot up next bit
	decfsz ccount,1 	; are we done?
	goto floop		; if not, get next bit
	retlw 0			; return to main
	
	END