;Dick Cappels' project pages sap@cappels.org - you should be able to copy and paste this text into an assembler file.
;©2002, 2004 Richard Cappels All Rights Reserved. email projects@cappels.org
;Use of information presented on this page is for personal, nonprofit educational
;and noncommercial use only. This material (including object files) is copyrighted
;by Richard Cappels and may not be republished or used directly for commercial
;purposes without explicit permission For commercial license, click HERE.
;
;HOME
;******************************************************
; Generate fm for data transmission
;TURN ON, SEND $A5 THEN DELAY THEN SEND $5A THEN KEEP FLOPPING BACK AND FORTH AS LONG AS THE POWER IS ON.
;FOR ATTINY 12 TEST TRANSMITTER
;
;A word to anyone who might be looking at this to pick up some style pointers: DON'T. This is just
;something tossed together that servs a need. Don't don't inflict these poor practices on another
;project.
;
;******************************************************
; fm for data transmission
;******************************************************
;
;Bytes are shifted out with a start bit followed by msb though lsb.
;The start bit is a "one"
;channel idle is a "ones"
;Run-in code will be a enough zeros for the analog circuit to settle, then at least nine more
;zeros so the run-in can be distinguesed from data that might contain a lot of zeros.
;Following the runin code is a hdedder byte followed by a data byte. each byte starts with a start
;bit which is a one. After the data byte, an additional one is sent to terminate the last pulse.
;After the byte is sent, and idle signal of 1 or more ones will be sent to provide the final transitio
;on the last data bit.
;A one will be one cycle of 2f, where f is the data toggle rate.
;A zero will be one cycle of f.
; ===RUNIN CODE (> 12 ZEROS)===HEDDER (8 DATA + START) ===DATA (8 DATA + START)===TERMINATION BIT===
;Minimize stack usage so can be used with AT90S1200 or ATtiny12.
.include "tn12def.inc"
;.include "2313def.inc"
.def bitsout = r01 ;counter for bits sent (couple also use a delay counter)
.def temp = r16 ;scratch register -noninterrupt time
.def basicdelay = r17 ;delay counter
.def delaymult = r18 ;delay counter
.def delaymult2 = r19 ;another delay counter
.def wirelessdat = r20 ;data to be sent via wireless port
.def outbyte = r21
.def loopcounter = r22 ;for the fun so there is somehting changing ont the output
.equ hedderbytevalue = $10 ;test value
.ORG $0000
ldi temp,$FF
out DDRB,temp
ldi temp,$00 ;weak pullups on PORTB
out PORTB,temp
Loop:
;delay BETWEEN BYTES
; ldi delaymult2,$00
; ldi basicdelay,$00
; ldi delaymult,$00
Delayfirst:
; dec basicdelay
; brne Delayfirst
; dec delaymult
; brne Delayfirst
;Decide what data to send. Sent the counter except when the butto non B3 is down,
; and don't send counter value $A5 because that one is reserved for when the
; button is down, so send $00 and extra time instead.
ldi wirelessdat,$A5
;SEND RUNIN CODE (16 ZEROS)
ldi outbyte,$00 ;get ready to send 16 zeros
ldi temp,$0F ;$0F databits plus a zero "start bit"
mov bitsout,temp
clc ;no start bit (it goes as another zero)
rcall LateTransmitAByte ;jump into byte sending routine
;Send the hedder byte. The first and last bit in the headder is always a "1". Its the law.
ldi outbyte,hedderbytevalue
rcall TransmitAByte
;(Ok, now the 16 bits of runin, the start bit, and the 8 bits of hedder have been sent.
;Time to send the data byte.
mov outbyte,wirelessdat
rcall TransmitAByte
ldi outbyte,$FF ;get ready to send 1 one, channel idle, to finish the last data bit.
ldi temp,$02 ;$01 databits plus a start bit
mov bitsout,temp
sec ;no start bit
rcall LateTransmitAByte ;jump into byte sending routine
;delay BETWEEN BYTES
ldi basicdelay,$00
ldi delaymult,$00
ldi delaymult2,$0A
Delayfirst2:
dec basicdelay
brne Delayfirst2
dec delaymult
brne Delayfirst2
dec delaymult2
brne Delayfirst2
;Decide what data to send. Sent the counter except when the butto non B3 is down,
; and don't send counter value $A5 because that one is reserved for when the
; button is down, so send $00 and extra time instead.
ldi wirelessdat,$5A
;SEND RUNIN CODE (16 ZEROS)
ldi outbyte,$00 ;get ready to send 16 zeros
ldi temp,$0F ;$0F databits plus a zero "start bit"
mov bitsout,temp
clc ;no start bit (it goes as another zero)
rcall LateTransmitAByte ;jump into byte sending routine
;Send the hedder byte. The first and last bit in the headder is always a "1". Its the law.
ldi outbyte,hedderbytevalue
rcall TransmitAByte
;(Ok, now the 16 bits of runin, the start bit, and the 8 bits of hedder have been sent.
;Time to send the data byte.
mov outbyte,wirelessdat
rcall TransmitAByte
ldi outbyte,$FF ;get ready to send 1 one, channel idle, to finish the last data bit.
ldi temp,$02 ;$01 databits plus a start bit
mov bitsout,temp
sec ;no start bit
rcall LateTransmitAByte ;jump into byte sending routine
;delay BETWEEN BYTES
ldi basicdelay,$00
ldi delaymult,$00
ldi delaymult2,$0A
Delayfirst3:
dec basicdelay
brne Delayfirst3
dec delaymult
brne Delayfirst3
dec delaymult2
brne Delayfirst3
rjmp Loop
TransmitAByte: ;send a byte out the wireless port
ldi temp,$09
mov bitsout,temp
sec ;start bit is a "one"
LateTransmitAByte:
SendACycle: ;a one or a zero, depending on the state of carry bit
ldi temp,$FF
out PORTB,temp
ldi basicdelay,$00
ldi delaymult,$04
brcs notazero1
ldi delaymult,$08
notazero1:
Delay:
dec basicdelay
brne Delay
dec delaymult
brne delay
ldi temp,$00
out PORTB,temp
ldi basicdelay,$00
ldi delaymult,$04
brcs notazero2
ldi delaymult,$08
notazero2:
Delay2:
dec basicdelay
brne Delay2
dec delaymult
brne delay2
rol outbyte ;sent start bit and all 8 data bits yet?
dec bitsout
brne SendACycle ;if not send another bit
ret
;Updated (spurious comment deleted) April, 2004.
;http://projects.cappels.org/
;HOME