;File name: vlfcwm8.inc;Copyright 2004 Richard Cappels, projects@cappels.org   www.project.cappels.org;Instructions for use and initialization code are afer the firs .exit statement. ;Reload and prescale values.equ	XmtTimerReload	= $CC 	;Timer 0 reload value for T 1 1200 baud value.equ	RcvTimerReload	= $F3	;Timer 0 reload value for T/4 1200 baud value .equ	RecThresh	= 10 	;Minimum number of counts to detect carrier..equ	RecHighThres	= 65 	;1+ maximum counts for valid carrier.equ	Timer0Prescale	= $03	;Timer 0 prescaler selector -clock/64..equ	delaytime	=  20	;Waiting time after transmit mode before receiving..equ	rcvmultiplier 	=   7	;Number of delaytimes to wait bafter receiving before transmitting.;//////////////BEGIN BASIC RF COUPLER ROUTINES\\\\\\\\\\\\\\\		.macro	pushall	push	r2	;		push	r18		;	push	r17		;	push	r19;							.endmacro																						.macro	popall						pop	r19;		;Temporaty storage of status register	pop	r17		;General purpose scratch register	pop	r18		;General purpose scratch register.	pop	r2	;	;Comparitor interrupt counters											.endmacro																						PostXmitDelay:	push	r18	push	r17	ldi	r18,delaytime	rcall	delay	pop	r17	pop	r18	retPostRCVDelay:	push	r18	push	r17	ldi	r18, rcvmultiplier * delaytime	rcall	delay	pop	r17	pop	r18	ret				delay:					;Delay - load 00 into r18 for max delay, 01 for minimum delay.					;r18 and r17 destroyed.lptrf1:	clr	r17lptrf12:dec	r17	brne	lptrf12	dec	r18	brne	lptrf1	ret	ReceiveRFByte:				;Receive a byte by RF and put into RFChar					;Returs with carry set if data received, otherwise cleared.	pushall				;Save  working registers on stack	ldi 	r18,Timer0Prescale	;Initaize prescaler.	out 	TCCR0, r18	ldi 	r18, RcvTimerReload	;Initialize counter.	out 	TCNT0,r18	in 	r18,TIMSK 		;Enable interrupts TIMSK.	ori	r18,0b00000001	out 	TIMSK,r18	clr	r2			;Zero comparitor interrupt counter.	ldi	r17,0b00001011		;Comparitor setup: enable interrupt on positive edge.	out	ACSR,r17	clr	r17			;Clear start bit test counter.	wfsbrf1:					;Wait for start bit.	rcall	QCDrf1			;Sample for 1/4 bit time.	dec	r17			;See if too many consecutive unsuccessful samples.	breq	bailrf1		mov	r18,r2	cpi	r18,RecThresh		;Check number of carrier cycles against threshold.	brmi	wfsbrf1	cpi	r18,RecHighThres	;Check to see if too many received.	brpl	wfsbrf1											rcall	QCDrf1			;Wait T/4.	rcall	QCDrf1			;Wait T/4.	ldi	r17,8			;Set number of bits: 8 data.nbrf1:	sbi	LEDOutPort,LEDOutPin		rcall	QCDrf1			;Wait T/4.	rcall	QCDrf1			;Wait T/4.	rcall	QCDrf1			;Wait T/4.	clr	r2	rcall	QCDrf1			;Sample for 1/4 bit time <== use this sample			mov	r18,r2	cpi	r18,RecThresh		;Set carry true if threshold exceeded.	brpl	oirf1	clc	rjmp	zeinrf1oirf1:	seczeinrf1:	ror	RFChar		;Get carry into lsb of RFChar.		dec	r17	brne	nbrf1	sec				;Data received - set carry flagrcxtrf1:	ldi	r18,0	out	TCCR0,r18		;Turn off timer0 interrupt	out	ACSR,r18		;Turn off Comparitor interrupt		cbi	LEDOutPort,LEDOutPin				popall	retbailrf1:clc				;No data received - clear carry and return		rjmp	rcxtrf1			SendRFByte:				;Shift byte in RFChar out through RF channel.					;RFChar changed by routine.	pushall				;Save all working registers except RFChar.	sbi	LEDOutPort,LEDOutPin	;For indication purposes	ldi 	r18,Timer0Prescale	;Initaize prescaler	out 	TCCR0, r18	ldi 	r18, XmtTimerReload	;Initialize counter 	out 	TCNT0,r18	in 	r18,TIMSK 			;Enable interrupts TIMSK.	ori	r18,1	out 	TIMSK,r18		ldi	r17,11			;Set number of bits:1 start, 8 data, 2 stop	sec				;Start bit					nxbtrf1:	brcs	bitsonerf1		rcall	szerorf1		rjmp	iwzrf1bitsonerf1:	sbi	RFSigDDR,RFSigPin 	;Set signal output pin to output.	rcall	SendOnerf1	cbi	RFSigDDR,RFSigPin 	;Set signal output pin to input.iwzrf1:	lsr	RFChar			;Shift next bit into carry.	dec	r17			;Decrement bit counter.	brne	nxbtrf1			;If not all done, then continue.	out	TCCR0,RFChar		;(RFChar was cleared by shifting.)		cbi	RFSigPort,RFSigPin 	;Set signal output low (no pullup).	cbi	LEDOutPort,LEDOutPin	popall				;Restore all working registes except RFChar.	retszerorf1:				;Send no carrier for for one bit time.	ldi 	r18, XmtTimerReload	;Initialize counter 	out 	TCNT0,r18WaitNotSend:	rjmp	WaitNotSend		;Do nothing but wait for interrupt to yank out of loop.SendOnerf1:				;Send carrier for T us	ldi 	r18, XmtTimerReload	;Initialize counter 	out 	TCNT0,r18		;Send carrier until next interruputMakeRF1:				;Make 181.8181 Mhz	sbi	RFSigPort,RFSigPin	;Output High sbi and cbi are 2 clock instructions.	sbi	RFSigPort,RFSigPin		sbi	RFSigPort,RFSigPin	sbi	RFSigPort,RFSigPin	sbi	RFSigPort,RFSigPin	nop				;(need this nop for timing)	cbi	RFSigPort,RFSigPin	;Output Low	cbi	RFSigPort,RFSigPin	cbi	RFSigPort,RFSigPin	cbi	RFSigPort,RFSigPin	nop	rjmp	MakeRF1			;Interrupt will yank out of loop.	QCDrf1:				;Send no carrier for T/4 us	ldi 	r18, RcvTimerReload	;Initialize counter 	out 	TCNT0,r18WaitHere1:	rjmp	WaitHere1		;Send no carrier until next interruputtimer0service:				;Return to routine that called interrupted routine. The processor 					;must be in a subroutine when this interrupt occurs!  Disable 					;the timer the rest of the time.	pop	r18	pop	r18	reti				;Return from interrupt.to routine before interrupt		comparitorservice:			;Increment r18 upon comparitor interrupt.		in	r19,sreg		;Save status register.	inc	r2		;Increment SigCount.	out	sreg,r19		;Restore status register.	reti				;Return from interrupt. Total of 7 cycles including the return.	;//////////////END BASIC RF COUPLER ROUTINES\\\\\\\\\\\\\\\						.exit;*************** Following are instructions for use and starter code for the calling .inc file***************;Inlcude the code below in the calling file. It may be customized. ;Copy the code from "START OF INITIALIZATION CODE" TO "END OF INITIALIZATION CODE", ;below into the assembler source document, then modify as needed.	;REFERENCE CIRCUIT:;AT<ega8 microcontroller with 4 MHz clock. Timer 0 (8 bit) and the comparitor interrupt are used.;if this code moved to another controller, the include file code relating to these peripherals will;most likely have to be modified.;A resonant loop antennat tuned to 182 kHz is connected across the comparitor intputs.;The comparitor is used to receive data, The bit configured as the RFSigPort (Port D, pin 6,;the + input of the comparitor inputs) is used to send data.;One example resonant circuit is 14 turns of #30 emammeled wire on 5.5 cm in diameter, air core, ;brought into resonance with a .033 uf capacitor in parallel with it.;The - (non-inverting) input of the comparitor is also connected to the tap on a 2:1 resistive voltage devider, ;which serves to bias the resonant circuit at half the supply voltage. Both resistors in the devider are ;of the same vlaue and may range from about 220 Ohms to 2 k Ohms each. The value of these resistors determines;the maximum possible transmitter power.;The voltage devider may be power from the microcontroller's positive power supply, or optionally,;powered from one of its output pins  The constants realted to BridgePowerPort designate this pin.;Powering from an output pin allows power reduction during sleep. The example initialization code sets;this pin high. Additoinal code would be needed to set this pin low.;The LEDOutPort pin is intended to drive an activity indicator LED. It goes high briefly while transmitting;and receiving data over the RF link. The example initialization code sets this pin as an output.;If this pin is needed for some other function, code that controls the pin will have to be removed;from the initialization and the include file.;CALLABLE SUBROUTINES:;Four callable routines are available. Each of these routines saves all working registers on the ;stack and restores thme before returning to the calling routines. The sole exception is, ;RFChar, which is used to transfer the data between the RF routines and calling routines.;RFchar needs to be assigned to a high register (r16..r31),but CANNOT be r17, r18. or r19.;RFChar is only modified by the RF routines while one of the four callable routines is being executed, and;may be used freely in other parts of the program.;Here is a list of the callable routines:;SendRFByte	(subroutine)	Sends contents of RFChar;Sends contents of RFChar via RF. Modifies RFChar.;Example;	ldi	RFChar,$2A		;Send astersik via RF link.;	rcall	SendRFByte		;;ReceiveRFByte	(subroutine)	Receive 	RF singal into RFChar, carry set if successful.;Waits for start bit on RF channel for 63.75 bit times. Returns with carry set and ;data in RFChar if character received. Returns with carry clear if no byte received within;that time.;Example;getchar:;	rcall	ReceiveRFByte		;Wait for character to be received;	brcc	getchar;	;PostXmitDelay	(subroutine)	;Wait for antenna to stop ringing from transmit operation.;Use this delay after transmitting if listening is to follow. The delay allows;ringing in the antenna to die down so that the received does not mistake ringing as data.;This is meant to be used when between sending mode and receiving modes, not to be ;used on a character-by-character basis, as this would needlessly reduce the data;rate.;See example below "PostRCVDelay".;PostRCVDelay	(subroutine)	;Wait for far end receiver to recover.	;Use this after receiving data, before sending to give the receiver associated;with the transmitter that just sent data time to recover. This is meant to be used;when switching between receiving mode and sending modes, not to be used on a;character-by-character basis, as this might result in the loss of garbling;of characters within a stream.;	;Example				;Receive a character via RF and echo it back via RF.;;wait:	rcall	ReceiveRFByte		;Wait for a character to be received;	brcc	wait		;	rcall	PostRCVDelay		;Wait for rining in far end transmitter to stop.;	rcall	SendRFByte		;Echo character to far end.;	rcall	PostXmitDelay		;Wait for rining in local antenna to die down.;	rjmp	wait			;Go back to top and get another character.;////////////////// START OF INITIALIZATION CODE \\\\\\\\\\\\\\\\\\\\\\\\\;Copyright 2004 Richard Cappels, projects@cappels.org;vlfcw initialization code..include "m8def.inc"		;Include file in same directory as project.;How to connect this chip:;Pin 7 to + 5 V;Pins 8 and 22 to ground.;Pin 21 connected to +5V through a decoupling network. For example a 33 uh choke \;	from +5V to pin 21 and a 0.22 uf monolithinc capacitor from pin 21 to ground.;Pin 6 connects to one end of a 22 uh loop antenna in parallel with a .033 uf capacitor.;Pin 7 the other end of the loop antenna and capcaitor connect to pin 7, Pin 7 is also;	connected to the center tap of a pair of 220 t 1,000 Ohm resistors connected in series  ;	between +5V to ground. ;;The four A/D inputs have an input range of 0 to 5 Volts. ;Pin 23 Analog input A;Pin 24 Analog input B;Pin 25 Analog input C;Pin 26 Analog input D;;The output is on-off keyed 182.818181 kHz RF, keyed by serial ASCII;(1200 baud, 1 start bit, 2 stop bits, no parity, lsb first);.include "m8def.inc"		;Include file in same directory as project.;definition of I/O;B0	(not assigned - configure as INPUT with weak pullup);B1	(not assigned - configure as INPUT with weak pullup);B2	(not assigned - configure as INPUT with weak pullup);B3	(not assigned - configure as INPUT with weak pullup);B4	(not assigned - configure as INPUT with weak pullup);B5	(not assigned - configure as INPUT with weak pullup);B6	(not assigned - configure as INPUT with weak pullup)	;B7	(not assigned - configure as INPUT with weak pullup)		.equ	PORTBdata	=0b11111111	;Initial data	.equ	DDRBdata	=0b00000000	;Initial data		;C0	A/D A	configure as INPUT;C1	A/D B	configure as INPUT;C2	A/D C	configure as INPUT;C3	A/D D	configure as INPUT;C4	(not assigned - configure as INPUT with weak pullup);C5	(not assigned - configure as INPUT with weak pullup);C6	(not assigned - configure as INPUT with weak pullup);C7		(not assigned - configure as INPUT with weak pullup)	.equ	PORTCdata	=0b11110000	;Initial data		.equ	DDRCdata	=0b000000O0	;Initial data;D0	(not assigned - configure as INPUT with weak pullup);D1	(not assigned - configure as INPUT with weak pullup);D2	(not assigned - configure as INPUT with weak pullup);D3	(not assigned - configure as INPUT with weak pullup);D4	(not assigned - configure as INPUT with weak pullup);D5	(not assigned - configure as INPUT with weak pullup);D6	AN0;D7	AN1	.equ	PORTDdata	=0b00000000	;Initial data		.equ	DDRDdata	=0b00000000	;Initial data;The statements below establish I/O pins needed for RF operation.	.equ	RFSigPort	= PORTD	;Port output signal is to appear on.	.equ	RFSigDDR	= DDRD	;Data Direction Register for signal output	.equ	RFSigPin	= 6	;Pin output signal is to appear on.	.equ	LEDOutPort	= PORTD	;Indicator LED	.equ	LEDOutDDR	= DDRD	.equ	LEDOutPin	= 2	.equ	CompPlusPort	= PORTB	;Comparitor noninverting input (input 0)	.equ	CompPlusDDR	= DDRB	.equ	CompPlusPin	= 6	.equ	BridgePowerPort	= PORTB	;Power for voltage devider (bridging resistors)	.equ	BridgePowerDDR	= DDRB	.equ	BridgePowerPin	= 3	.def	RFChar		= r16	;RF character I/O buffer (must be a high register)	.def	temp		= r17	;General purpose scratch register..cseg	.ORG $0000			;Initializaton code	rjmp start.org $0009	rjmp	timer0service	    	.org $0010		rjmp	comparitorservice		.include 	"vlfcwm8.inc"		;Include file to be in same directory as this file.		start:					;Entry point after reset -initialize everything   	ldi	temp,high(ramend) 	;Initialize 16 bit Stack Pointer	out	sph,temp		ldi     temp,low(ramend)		out     spl,temp 						ldi	temp,DDRBdata		;Set PORTB.		out	DDRB,temp	ldi	temp,PORTBdata	out	PORTB,temp				ldi	temp,DDRCdata		;Set PORTC	out	DDRC,temp	ldi	temp,PORTcdata	out	PORTc,temp				ldi	temp,DDRDdata		;Set PORTD.		out	DDRD,temp	ldi	temp,PORTDdata	out	PORTD,temp	sei				;Enable interrupts.	;////////////////// END OF INITIALIZATION CODE \\\\\\\\\\\\\\\\\\\\\\\\\		.exit