

;rftruly040802A  Minor correction - explicitly initialized DDRD.
;rftruly040731C	;Fixed greeting message
;rftruly040731B	;Working with RF and UART (UART has buffer).
;rftruly040731A	;Working with RF receiver.


;Receive data to 16 char buffer. Write to display after time-out or return.
;Scroll after character after lf is received. Echo a null after receiving return.



; Character receive and display for Truly MTC-C162DPLY-2N 2 line X 16 char LCD.
; Requires AT90S2313 or equivalent with 4 MHz clock.
; 
; Below are the connections to the Truly Display
; Pin 	Function (connection)
; 1	GND
; 2	VCC (+5V)
; 3	Contrast (0to +5V from wiper of 10 pot)
; 4	RS (Register Select 1=data 0=command)
; 5	R/W (tie to ground for write-only)
; 6	OE (Enable - data clocked on neg transition)
; 7-10	D0 - D3 lower 4 data bits (not used - ground these)
; 11-14	D4-D7	upper 4 data bits (connects to AVR90S2313 PB4 through PB7 respectively).
; 
; The AT90S2313 routines to control the display, based on the Hitachi HD44780, and the initialization 
; code in particular, are based on code originally published by Richard Hosking. 
; The display is driven in the 4 bit mode. The Truly display uses a Samsung KS0070B controller
; that appears to differ from the Hitachi HD44780 controller in that the Samsung requires an
; additional 4 bit write operation during "Function set" when in 4 bit mode. This was accomplished 
; by writing the "Function set" command twice to the controller twice instead of once.
; I suspect that this would work without modification with the Hitachi
; controller as the second write would be a redundant command for the Hitachi controller. 
; 
; Note that 
; 
; Below re the connections for the AT90S2313
; Pin		Function (Connection)
; VCC		+5V (decoupled)
; GND		ground
; XTAL1		Clock (see data sheet)
; XTAL2		Clcok (see data sheet)
; TXD		Serial out (RS-232 inverting buffer to remote device - NOT USED)
; RXD		Serial in (RS-232 inverting receive buffer)
; PD2-PD6	Unassigned (not connected)
; PB0,PB1	For RF link.
; PB2		R/S pin on Truly LCD (Truly module pin 4)
; PB3		OE pin on Truly LCD (Truly module pin 6)
; PB4-PB7	D4-D7 on Truly LCD (Truly module pins 11-14 respectively)
; 

;definition of I/O
;B0	+ comparitor input - Antenna Signal
;B1	- comparitor input - Antenna reference
;B2	Devider (bridge power) optional.MUST CHANGE		
;B3	LED (high to turn LED on) MUST CHANGE	.	



.include "2313def.inc"


.def	charcount	=r1	;Number of characters displayed on line being written
.def    temp    	=r19    ;Temporary register.(May not be R17).
.def	RFChar		=r16	;RF character I/O buffer (must be a high register)
.def	flagreg		=r21	;Flags
.def	gpcount		=r23	;Genral purpose counter (was YH in earlier version)
;	YL			;UART circular buffer write ponter.
;	ZL			;UART circultar buffer read pointer
;	XL			;16 char line buffer pointer

;The statements below establish I/O pins needed for RF operation.
.equ	RFSigPort	= PORTB	;Port output signal is to appear on.
.equ	RFSigDDR	= DDRB	;Data Direction Register for signal output
.equ	RFSigPin	= 0	;Pin output signal is to appear on.

.equ	LEDOutPort	= PORTD	;Indicator LED
.equ	LEDOutDDR	= DDRD
.equ	LEDOutPin	= 4

.equ	CompPlusPort	= PORTB	;Comparitor noninverting input (input 0)
.equ	CompPlusDDR	= DDRB
.equ	CompPlusPin	= 0

.equ	BridgePowerPort	= PORTD	;Power for voltage devider (bridging resistors)
.equ	BridgePowerDDR	= DDRD
.equ	BridgePowerPin	= 5

.equ	lbufsiz		=10
.equ	circbufsiz	=64
.equ    OE		=8	;Bit 3 port B display enable (also directly addressed).
.equ    RS		=4	;Bit 2 in port B display register select (also directly addressed).

.equ	cbufbot		=$60	;Bottom of circular UART receive buffer.
.equ	cbuftop		=$67	;Top of circular UART receive buffer.

.equ	lbufbot		=$70	;Bottom of display line buffer.
.equ	lbuftop		=$7F	;Top of display line buffer.


		;Baudrate Calculation
.equ	clock		= 4000000		;clock frequency
.equ	baudrate	= 9600			;choose a baud rate
.equ	baudconstant	= (clock/(16*baudrate))-1



;Flagreg bit assignments
;	bit	0		Pending linefeed if high.
;	bit	1		
;	bit	2
;	bit	3
;	bit	4
;	bit	5
;	bit	6
;	bit	7

;Memory uage:
;Ring buffer from $60 through $67
;Line buffer from $70 to $7F

;******************************

.cseg
.org	$00
	rjmp	start			;Reset 
.ORG $0006 	
	rjmp	timer0service		;Timer/counter compare interrupt
.ORG $0007
	rjmp	UartRecInt
.ORG $000A
	rjmp	comparitorservice	;Service comparitor interupt




.include "2x16lcd.inc"
.include "vlfcw2313.inc"	;Load VLFCW routines after last vector assignment
				;but before start of application code..


HelloString:	;TEXT TO BE TYPED ON FIRST LINE WHEN POWER IS APPLIED
.db	"9600 1 N 040802A"
.db	00,00



start: 
	ldi 	temp,RAMEND      ;Init Stack Pointer
	out 	SPL,temp

	ldi	temp,0b00000000	;No weak pullups.
	out	PORTB,temp
	ldi     temp,0b11111100    
        out     DDRB,temp	;PORTB = all outputs except bits 0,1 
        
        ldi	temp,0b11111111	;Weak pullups on inputs
        out	PORTD,temp
        ldi	temp,0b00000000	;PORTD - all inputs
        out	DDRD,temp		
        
	ldi	flagreg,$00	;Set all flags to zero.
	ldi	temp,$00
	mov	charcount,temp

	ldi	temp,baudconstant	
	out	ubrr,temp	;load baudrate
	sbi	ucr,rxen	;Enable the receiver..

	rcall	ClearLineBuffer	;Initialize line buffer.
	rcall	InitDisplay	;Initialize LCD display module,

  	rcall	sendhello	;write line 1 power-up information
	rcall	Hometwo		;Position cursor for input on line two.	
	
	
	clr	XH		;Clear XH, YH, ZY for processors with 16 bit RAM addressing
	clr	YH
	clr	ZH
	ldi	YL,cbufbot	;Set Y and Z circ buff pointers to bottom.
	ldi	ZL,cbufbot
	sbi	UCR,7		;Enable UART Interrupt.
	sei			;Global interrupt flag set (enabled).

forever:	;Waiting for new data from circular buffer


getchar:
	rcall	ReceiveRFByte		;Wait for character to be received
	brcs	RFcharRec

	 			;Get waiting char from circular buffer if there is one.
	cp	YL,ZL		;Is circular buffer read pointer alredy pointing to latest entry?
	breq	getchar		;If so, there is no new data in the buffer.
	ld	RFchar,Z+	;If pointers are not equal, then read next char in buffer.
	cpi	ZL,cbuftop + 1	;Advance circular buffer read pointer to next value.
	brne	NoZeroZL	;If end of buffer, wrap around to start of buffer.
	ldi	ZL,cbufbot
NoZeroZL:

RFcharRec:

	cpi	RFchar,$1F	;If not a control char branch to displayable char routine..
	brpl	ItsDisplayable
				
	cpi	RfChar,$0D	;If this is a carriage return character, 
	brne	noCR		;Set cursor to start of bottom line.
	ldi	XL,lbufbot	;Its a CR so set ponters back to start of line.
	ldi	temp,$00
	mov	charcount,temp
	rcall	hometwo		;Put cursor back in first column of line two.	
noCR:
	
	cpi	RfChar,$0A	;If its a linfeed char then
	brne	NotALineFeed	;set linfeed pending flag.
	ori	flagreg,0b00000001	
NotALineFeed:
	
	rjmp	Buffdone

				


ItsDisplayable:	;If not a control char then do line feed if pending then
			;write to display and to line buffer.
		
	sbrc	flagreg,0	;If linefeed i spending, then do it	
	rcall	linefeed
		
	cpi	XL,lbuftop+1	;Don't store if buffer at limit.
	breq 	Xfull
	st	X+,RFchar
	mov	temp,RFchar
	rcall	SendData	
Xfull:
	
Buffdone:
Buffempty:
	rjmp	forever	


	
SendHello:	;Send HelloString	
  	rcall	Homeone
	ldi     ZH,high(2*HelloString)	; Load high part of byte address into ZH
	ldi     ZL,low(2*HelloString)	; Load low part of byte address into ZL
moretosend:
	lpm				; Load byte from program memory into r0
	tst	r0			; Check if we've reached the end of the message
	breq	finishsendstering	; If so, return
	mov	temp,r0
	rcall	SendData
	adiw	ZL,1			; Increment Z registers
	rjmp	moretosend
finishsendstering:
    	ret
     




linefeed:	;Handle a linefeed char
		;Clear line 1 (top line), copy line two to line one, clear
		;line two, the position the cursor in first column of line two.
	push	gpcount
	rcall	hometwo		;Put cursor at start of line 2 so it can be cleared.
	ldi	gpcount,$10		;Number of chars in line.
clearmore:

	ldi	temp,$20	;Fill line with spaces (erase).
	rcall	SendData
	dec	gpcount
	brne	clearmore

	rcall	homeone		;Copy line buffer to line 1, reset XL to bottom.
	ldi	XL,lbufbot
	ldi	temp,$00
	mov	charcount,temp
MoreToCopy:
	ld	temp,X+
	rcall	SendData
	cpi	XL,lbuftop + 1
	brne	MoreToCopy
	rcall	ClearLineBuffer
	andi	flagreg,$0b11111100	;Clear linefeed pending and enable flagsb.
	rcall	hometwo
	pop	gpcount
	ret			;Done

	
ClearLineBuffer:	;Fill line buffer with spaces, set XL to bottom.
	ldi	XL,lbufbot
	ldi	temp,$00
	mov	charcount,temp
	ldi	temp,$20
MoreToSpace:
	st	X+,temp
	cpi	XL,lbuftop + 1
	brne	MoreToSpace
	ldi	XL,lbufbot
	ret
	



recchar:			
	sbis	usr,rxc		;Wait for a char.
	rjmp	recchar
	in	RFchar,udr	;Read the char.
	ret			
	
	

UartRecInt:	;Uart interrupt service -Write received char into a circular buffer
	rcall	recchar			;Get the char from the UART.
	st	Y+,RFchar
	cpi	YL,cbuftop + 1
	brne	NoZeroYL2
	ldi	YL,cbufbot
NoZeroYL2:
	reti


