;vfo.asm for FDIM/2004 Buildathon
;version 1.00 May 4th, 2004
;author: W8DIZ Dieter (Diz) Gentzow
;email: kitsales@partsandkits.com
;signal generator demo
;5 Hz to 19,999,999 Hz output
;with 1 Hz resolution
;accuracy based on the 50 MHz ref osc
;on power up, the LCD displays 10,000,000 Hz
;and the DDS chip outputs 10 MHz
;at about half a volt peak-to-peak (300 ohms)
;the cursor on the LCD display is under the 10s
;press the encoder and the cursor moves right
;hold down S2 and press the encoder and the 
;cursor moves left
;turn the encoder clockwise to increment the value
;under the cursor position and CCW to decrement.
;DDS output is from 1 Hz up to 19,999,999 Hz
;LEDs blink when encoder is turned or pushed.
;S1,S4 and S5 are not used

.device AT90S2313

;***** I/O Register Definitions
.equ SREG =$3f
.equ SPH  =$3e
.equ SPL  =$3d
.equ GIMSK =$3b
.equ GIFR =$3a
.equ TIMSK =$39
.equ TIFR =$38
.equ MCUCR =$35
.equ TCCR0 =$33
.equ TCNT0 =$32
.equ TCCR1A =$2f
.equ TCCR1B =$2e
.equ TCNT1H =$2d
.equ TCNT1L =$2c
.equ OCR1AH =$2b
.equ OCR1AL =$2a
.equ ICR1H =$25
.equ ICR1L =$24
.equ WDTCR =$21
.equ EEAR =$1e
.equ EEARL =$1e
.equ EEDR =$1d
.equ EECR =$1c
.equ PORTB =$18
.equ DDRB =$17
.equ PINB =$16
.equ PORTD =$12
.equ DDRD =$11
.equ PIND =$10
.equ UDR =$0c
.equ USR =$0b
.equ UCR =$0a
.equ UBRR =$09
.equ ACSR =$08


;***** Bit Definitions
.equ SP7 =7
.equ SP6 =6
.equ SP5 =5
.equ SP4 =4
.equ SP3 =3
.equ SP2 =2
.equ SP1 =1
.equ SP0 =0

.equ INT1 =$80
.equ INT0 =$40
.equ INTF1 =7
.equ INTF0 =6

.equ TOIE1 =7
.equ OCIE1A =6
.equ TICIE =3
.equ TOIE0 =1

.equ TOV1 =7
.equ OCF1A =6
.equ ICF1 =3
.equ TOV0 =1

.equ SE =32
.equ SM =16
.equ ISC11 =8
.equ ISC10 =4
.equ ISC01 =2
.equ ISC00 =1

.equ CS02 =2
.equ CS01 =1
.equ CS00 =0

.equ COM1A1 =7
.equ COM1A0 =6
.equ PWM11 =1
.equ PWM10 =0

.equ ICNC1 =7
.equ ICES1 =6
.equ CTC1 =3
.equ CS12 =2
.equ CS11 =1
.equ CS10 =0

.equ WDTOE =4
.equ WDE =3
.equ WDP2 =2
.equ WDP1 =1
.equ WDP0 =0

.equ EEMWE =2
.equ EEWE =1
.equ EERE =0

.equ PB7 =7
.equ PB6 =6
.equ PB5 =5
.equ PB4 =4
.equ PB3 =3
.equ PB2 =2
.equ PB1 =1
.equ PB0 =0

.equ DDB7 =7
.equ DDB6 =6
.equ DDB5 =5
.equ DDB4 =4
.equ DDB3 =3
.equ DDB2 =2
.equ DDB1 =1
.equ DDB0 =0

.equ PINB7 =7
.equ PINB6 =6
.equ PINB5 =5
.equ PINB4 =4
.equ PINB3 =3
.equ PINB2 =2
.equ PINB1 =1
.equ PINB0 =0

.equ PD6 =6
.equ PD5 =5
.equ PD4 =4
.equ PD3 =3
.equ PD2 =2
.equ PD1 =1
.equ PD0 =0

.equ DDD6 =6
.equ DDD5 =5
.equ DDD4 =4
.equ DDD3 =3
.equ DDD2 =2
.equ DDD1 =1
.equ DDD0 =0

.equ PIND6 =6
.equ PIND5 =5
.equ PIND4 =4
.equ PIND3 =3
.equ PIND2 =2
.equ PIND1 =1
.equ PIND0 =0

.equ RXC =7
.equ TXC =6
.equ UDRE =5
.equ FE =4
.equ OR =3

.equ RXCIE =7
.equ TXCIE =6
.equ UDRIE =5
.equ RXEN =4
.equ TXEN =3
.equ CHR9 =2
.equ RXB8 =1
.equ TXB8 =0

.equ ACD =7
.equ ACO =5
.equ ACI =4
.equ ACIE =3
.equ ACIC =2
.equ ACIS1 =1
.equ ACIS0 =0

.equ RAMEND  =$DF    ;Last On-Chip SRAM Location
.equ XRAMEND =$DF
.equ E2END =$7F
.equ FLASHEND=$3FF

.equ INT0addr=$001 ;External Interrupt0 Vector Address
.equ INT1addr=$002 ;External Interrupt1 Vector Address
.equ ICP1addr=$003 ;Input Capture1 Interrupt Vector Address
.equ OC1addr =$004 ;Output Compare1 Interrupt Vector Address
.equ OVF1addr=$005 ;Overflow1 Interrupt Vector Address
.equ OVF0addr=$006 ;Overflow0 Interrupt Vector Address
.equ URXCaddr=$007 ;UART Receive Complete Interrupt Vector Address
.equ UDREaddr=$008 ;UART Data Register Empty Interrupt Vector Address
.equ UTXCaddr=$009 ;UART Transmit Complete Interrupt Vector Address
.equ ACIaddr =$00a ;Analog Comparator Interrupt Vector Address

.equ PORTLCD = PORTB
.equ DDRLCD  = DDRB
.equ PINLCD  = PINB

.equ DDSport = PORTB
.equ DDSenable = PB6
.equ DDSclock  = PB7
.equ DDSdata   = PB5

.equ LEDUP =PD6
.equ LEDDN =PD5
.equ PHASE =PD4
.equ STATE =PD2

;Define register name
; r0 is used by Z-registor

.def temp1 =r16
.def temp2 =r17
.def temp3 =r18
.def temp4 =r19
.def temp5 =r20
.def StepRate =r21
.def LCDPOINTER=r22
.def press =r23
.def delay =r24
.def encoder =r25
.def XL  =r26
.def XH  =r27
.def YL  =r28
.def YH  =r29
.def ZL  =r30
.def ZH  =r31

.dseg
.org $060
LCDrcve0: .byte 8 ; buffer for decimal freq readout
rcve0: .byte 4    ; buffer for DDS freq numbers
freq0: .byte 4    ; buffer for 1 freq numbers
freq1: .byte 4    ; buffer for 10 freq numbers
freq2: .byte 4    ; buffer for 100 freq numbers
freq3: .byte 4    ; buffer for 1,000 freq numbers
freq4: .byte 4    ; buffer for 10,000 freq numbers
freq5: .byte 4    ; buffer for 100,000 freq numbers
freq6: .byte 4    ; buffer for 1,000,000 freq numbers
freq7: .byte 4    ; buffer for 10,000,000 freq numbers

.cseg ;This tells the assembler that what follows is code, and goes in ROMspace
.org $000
 rjmp RESET
 rjmp EXT_INT0 ; IRQ0
 rjmp EXT_INT1 ; IRQ1
 rjmp TIM1_CAPT ; Timer1 Capture
 rjmp TIM1_COMP ; Timer1 Compare
 rjmp TIM1_OVF ; Timer1 Overflow
 rjmp TIM0_OVF ; Timer0 Overflow
 rjmp UART_RXC ; UART Receive
 rjmp UART_DRE ; UART empty
 rjmp UART_TXC ; UART Transmit
 rjmp ANA_COMP ; Analog comparator

RESET: ;init everything here
 ldi temp1,low(RAMEND)
 out SPL,temp1  ; Set stack pointer to last internal RAM location
 ldi temp1,high(RAMEND)
 out SPH,temp1

 ldi temp1,$60
 out DDRD,temp1  ;make PD5 and PD6 pin an output
 ldi temp1,$FF   ;set pullup resistors
 out PORTD,temp1 ;turn off leds
 ldi temp1,$E0   ;portb setup
 out DDRB,temp1  ;PB7, PB6, PB5 used for DDS
 ldi temp1,$1F
 out DDSport,temp1 ;PB4,3,2,1 and 0 use pullups

 ldi StepRate,1 ;set to the 10's position
 clr encoder    ;clear encoder interrupt counts
 clr press      ;clear press interrupt counts

 ldi temp1,0b00000101 ;set timer0 prescale divisor to 1024
 out TCCR0,temp1   ;using 10.24 XTAL you get 10,000 Hz/100uS
 ldi temp1,0b00000010
 out TIMSK,temp1   ;enable TIMER0 overflow interrupts

 ldi temp1,INT0+INT1
 out GIMSK,temp1 ; enable int0 and int1 interrupts

 ldi temp1,ISC01+ISC00+ISC11 ; int0 on rising edge and int1 on falling edge
 sbic PIND,STATE ; test state of encoder
 ldi temp1,ISC01+ISC11 ; int0 on falling edge and int1 on falling edge
 out MCUCR,temp1

 ldi temp1,$F8 ;reset AD9835
 rcall shift16 ;output to DDS chip
 ldi temp1,$B0 ;select software control
 rcall shift16 ;output to DDS chip
 rcall default_freq1 ;move default freq to buffers
 rcall FreqOut ;set DDS and LCD

 sei ;global all interrupt enable

 rcall initlcd
 rcall lcdclear
 ldi ZH,high(2*msg1)
 ldi ZL,low(2*msg1)
 rcall ShowLine1
 ;rcall ShowStepRate
 rcall ShowFreq

menu: ;main program
 tst encoder ;check for encoder pulses
 breq menu5  ;exitif no pulses
 brpl menu1   ;branch if positive
 cbi PORTD,LEDDN ;turn DN LED on
 inc encoder
 rcall DecFreq0
 cpi temp1,55 ; if 55 then all is OK
 brne menu05
 rcall IncFreq0 ;correct overflow
 rjmp menu2
menu05:
 rcall DecFreq9 ;update the DDS
 rcall FreqOut
 rcall ShowFreq
 rjmp menu2
menu1:
 cbi PORTD,LEDUP ;turn UP LED on
 dec encoder
 rcall IncFreq0
 cpi temp1,55 ; if 55 then all is OK
 brne menu15
 rcall DecFreq0 ;correct overflow
 rjmp menu2
menu15:
 rcall IncFreq9 ;update the DDS
 rcall FreqOut
 rcall ShowFreq
menu2:
 ldi delay,20
 rcall wait
 sbi PORTD,LEDUP  ;turn LEDs off
 sbi PORTD,LEDDN  ;turn LEDs off
ldi delay,20
 rcall wait
menu5:
 tst press
 breq menu9
 dec press
 in temp1,PIND ; look for reverse StepRate
 ldi temp2,2
 and temp1,temp2
 cpi temp1,2
 breq menu55
 inc StepRate
 cpi StepRate,8
 brne menu6
 ldi StepRate,0
 rjmp menu6
menu55:
 dec StepRate
 brpl menu6
 ldi StepRate,7
 rjmp menu6
menu6:
 ;rcall ShowStepRate
 rcall ShowCursor
 cbi PORTD,LEDUP ;turn UP LED on
 cbi PORTD,LEDDN ;turn DN LED on
 ldi delay,20
 rcall wait
 sbi PORTD,LEDUP  ;turn LEDs off
 sbi PORTD,LEDDN  ;turn LEDs off
 rcall wait
menu9:
 rjmp menu

initlcd:
 ldi temp1,0
 out PORTLCD,temp1 ;turn off any pullup resistors
 ldi temp1,$FF
 out DDRLCD, temp1 ;set LCD port for output
 ldi delay,14   ;wait at least 15ms after Vcc=4.5V
 rcall wait
 ldi temp1,3  ;function set
 out PORTLCD,temp1
 rcall toggleE
 ldi delay,10  ;wait 10 ms
 rcall wait
 ldi temp1,3  ;function set
 out PORTLCD,temp1
 rcall toggleE
 ldi delay,10  ;wait 10 ms
 rcall wait
 ldi temp1,3  ;function set
 out PORTLCD,temp1
 rcall toggleE
 ldi temp1,2  ;function set, 4 line interface
 out PORTLCD,temp1
 rcall toggleE
 ldi temp1,$F0 ;make 4 data lines inputs
 out DDRLCD,temp1
 ldi temp1,$28 ;function set 4-wire, 2-line, 5x7
 rcall lcdcmd
 ;ldi temp1,$0C ;display on, cursor off, blink off
 ldi temp1,$0E ;display on, cursor on, blink off
 ;ldi temp1,$0D ;display on, cursor off, blink on
 rcall lcdcmd
 ldi temp1,$06 ;address inc, no scroll
 rcall lcdcmd
 rcall lcdclear
 ret

lcdwait:    ;wait for lcd not busy
 push temp1
 push temp2
 ldi temp1,$F0  ;make 4 data lines input
 out PORTLCD,temp1
 sbi PORTLCD,PB5  ;set r/w to read
 cbi PORTLCD,PB6  ;set register select to command
 nop     ;wait for data setup time
 nop     ;delay 140 ns
waitloop:
 sbi PORTLCD,PB4  ;set E high
 nop     ;delay 450 ns
 nop
 nop
 nop
 nop
 cbi PORTLCD,PB4  ;set E low
 in  temp2,PINLCD ;read busy flag
 rcall toggleE
 sbrc temp2,3 ;loop until done 
 rjmp waitloop
 pop temp2
 pop temp1
 ret

lcdcmd: ;send cmd in temp1
 rcall lcdcmd2
lcdcmd2:
 mov temp2,temp1
 rcall lcdwait
 ldi temp1,$FF
 out DDRLCD,temp1 ;set LCD port for output
 mov temp1,temp2
 swap temp1
 andi temp1,$0F
 out PORTLCD,temp1
 rcall toggleE
 mov temp1,temp2
 andi temp1,$0F  ;strip off upper bits
 out PORTLCD,temp1
 rcall toggleE
 ldi temp1,$F0  ;make 4 data lines input
 out DDRLCD,temp1
 mov temp1,temp2
 ret

lcdput:
 push temp1
 push temp2
 cpi temp1,$0A
 brsh lcdput2
 ldi temp2,$30
 add temp1,temp2
lcdput2:
 mov temp2,temp1
 rcall lcdwait
 ldi temp1,$FF
 out DDRLCD,temp1 ;set LCD port for output
 mov temp1,temp2
 mov temp2,temp1
 swap temp1
 andi temp1,$0F  ;send upper nibble data
 out PORTLCD,temp1 ;send data to LCD
 sbi PORTLCD,PB6  ;set register select to data
 rcall toggleE
 cbi PORTLCD,PB6  ;set register select to data
 mov temp1,temp2
 andi temp1,$0F  ;send lower nibble data
 out PORTLCD,temp1 ;send data to LCD
 sbi PORTLCD,PB6  ;set register select to data
 rcall toggleE
 cbi PORTLCD,PB6  ;set register select to data
 ldi temp1,$F0  ;make 4 data lines input
 out DDRLCD,temp1
 pop temp2
 pop temp1
 ret

toggleE:
 nop     ;wait for data setup time
 nop     ;delay 140 ns
 sbi PORTLCD,PB4  ;set E high
 nop     ;delay 450 ns
 nop
 nop
 nop
 nop
 cbi PORTLCD,PB4  ;set E low
 ret

lcdclear:
 ldi temp1,1
 rcall lcdcmd
 ret

lcdhome:
 ldi temp1,2
 rcall lcdcmd
 ret

ShowLine1:
 ldi temp1,$80
 rcall lcdcmd
 rcall loadbytes
 ret

loadbytes:
 lpm
 tst r0
 breq bytesloaded
 mov temp1,r0
 rcall lcdput
 adiw ZL,1
 rjmp loadbytes
bytesloaded:
 ret

ShowStepRate:
 ldi temp1,$8F
 rcall lcdcmd
 mov temp1,StepRate
 rcall lcdput
 ret

FreqOut:
 ldi temp1,$60 ;sel freg0
 rcall shift16
 ldi yl,low(rcve0)
 ldi temp1,$30 ;dds register address
 rcall shift16
 ldi  temp1,$21 ;dds register address
 rcall shift16
 ldi temp1,$32 ;dds register address
 rcall shift16
 ldi temp1,$23 ;dds register address
 rcall shift16
 ;ldi temp1,$34 ;rest are for ALT register
 ;rcall shift16
 ;ldi temp1,$25
 ;rcall shift16
 ;ldi temp1,$36
 ;rcall shift16
 ;ldi temp1,$27
 ;rcall shift16
 ldi temp1,$c0 ;enable output
 rcall shift16
 ret

IncFreq0:
 mov temp2,StepRate
 ldi ZH,high(rcve0)
 ldi ZL,low(rcve0)
 ldi temp1,9
IncFreq1:
 dec temp1
 dec ZL
 dec temp2
 brpl IncFreq1
IncFreq2:
 ld temp3,Z
 inc temp3
 cpi temp3,10
 clc
 brne IncFreq3
 sec
 clr temp3
IncFreq3:
 st Z,temp3
 brcc IncFreq7
 dec ZL
 dec temp1
 rjmp IncFreq2
IncFreq7:
 ldi ZH,high(LCDrcve0)
 ldi ZL,low(LCDrcve0)
 ld temp1,Z
 cpi temp1,2
 brlo IncFreq8
 ldi temp1,55
IncFreq8:
 ret

IncFreq9:
 ldi ZH,high(freq0)
 ldi ZL,low(freq0)
 mov temp2,StepRate
 lsl temp2
 lsl temp2
 add ZL,temp2
 ldi YH,high(rcve0)
 ldi YL,low(rcve0)
 ld temp1,Z+
 ld temp2,Y
 add temp1,temp2
 st Y+,temp1
 ld temp1,Z+
 ld temp2,Y
 adc temp1,temp2
 st Y+,temp1
 ld temp1,Z+
 ld temp2,Y
 adc temp1,temp2
 st Y+,temp1
 ld temp1,Z+
 ld temp2,Y
 adc temp1,temp2
 st Y+,temp1
 ret

DecFreq0:
 mov temp2,StepRate
 ldi ZH,high(rcve0)
 ldi ZL,low(rcve0)
 ldi temp1,9
DecFreq1:
 dec temp1
 dec ZL
 dec temp2
 brpl DecFreq1
DecFreq2:
 ld temp3,Z
 dec temp3
 cpi temp3,255
 clc
 brne DecFreq3
 sec
 ldi temp3,9
DecFreq3:
 st Z,temp3
 brcc DecFreq7
 dec ZL
 dec temp1
 rjmp DecFreq2

DecFreq7:
 ldi ZH,high(LCDrcve0)
 ldi ZL,low(LCDrcve0)
 ld temp1,Z
 cpi temp1,2
 brlo DecFreq8
 ldi temp1,55
DecFreq8:
 ret

DecFreq9:
 ldi ZH,high(freq0)
 ldi ZL,low(freq0)
 mov temp2,StepRate
 lsl temp2
 lsl temp2
 add ZL,temp2
 ldi YH,high(rcve0)
 ldi YL,low(rcve0)
 ld temp2,Z+
 ld temp1,Y
 sub temp1,temp2
 st Y+,temp1
 ld temp2,Z+
 ld temp1,Y
 sbc temp1,temp2
 st Y+,temp1
 ld temp2,Z+
 ld temp1,Y
 sbc temp1,temp2
 st Y+,temp1
 ld temp2,Z+
 ld temp1,Y
 sbc temp1,temp2
 st Y+,temp1
 ret

ShowFreq: ;display freq on LCD
 ldi temp1,$C1
 rcall lcdcmd
 ldi ZH,high(LCDrcve0)
 ldi ZL,low(LCDrcve0)
 clr temp2
 ld temp1,Z+
 add temp2,temp1
 brne ShowFreq1
 ldi temp1,' '
ShowFreq1:
 rcall lcdput
 ld temp1,Z+
 add temp2,temp1
 brne ShowFreq2
 ldi temp1,' '
ShowFreq2:
 rcall lcdput
 ldi temp1,','
 tst temp2
 brne ShowFreq3
 ldi temp1,' '
ShowFreq3:
 rcall lcdput
 ld temp1,Z+
 add temp2,temp1
 brne ShowFreq4
 ldi temp1,' '
ShowFreq4:
 rcall lcdput
 ld temp1,Z+
 add temp2,temp1
 brne ShowFreq5
 ldi temp1,' '
ShowFreq5:
 rcall lcdput
 ld temp1,Z+
 add temp2,temp1
 brne ShowFreq6
 ldi temp1,' '
ShowFreq6:
 rcall lcdput
 ldi temp1,','
 tst temp2
 brne ShowFreq7
 ldi temp1,' '
ShowFreq7:
 rcall lcdput
 ld temp1,Z+
 add temp2,temp1
 brne ShowFreq8
 ldi temp1,' '
ShowFreq8:
 rcall lcdput
 ld temp1,Z+
 add temp2,temp1
 brne ShowFreq9
 ldi temp1,' '
ShowFreq9:
 rcall lcdput
 ld temp1,Z+
 rcall lcdput
 ldi temp1,' '
 rcall lcdput
 ldi temp1,'H'
 rcall lcdput
 ldi temp1,'z'
 rcall lcdput
 rcall ShowCursor
 ret

ShowCursor: ;position cursor to active position
 ldi temp1,$CA
 sub temp1,StepRate
 cpi temp1,$C8
 brsh ShowCursor1
 dec temp1
ShowCursor1:
 cpi temp1,$C4
 brsh ShowCursor2
 dec temp1
ShowCursor2:
 rcall lcdcmd
 ret

EXT_INT0:
 push temp1 ;save temp1 register
 in  temp1,SREG ;save the status register
 push temp1

 in temp1,MCUCR
 cpi temp1,ISC01+ISC11 ; test falling edge
 breq int05

 ldi temp1,ISC01+ISC11 ; set int0 for falling edge and int1 on falling edge
 out MCUCR,temp1
 sbis PIND,PHASE ; test PHASE
 rjmp int01
 dec encoder
 rjmp int09
int01:
 inc encoder
 rjmp int09

int05:
 ldi temp1,ISC01+ISC00+ISC11 ; set int0 for rising edge and int1 on falling edge
 out MCUCR,temp1
 sbis PIND,PHASE ; test PHASE
 rjmp int06
 inc encoder
 rjmp int09
int06:
 dec encoder

int09:
 pop temp1
 out  SREG,temp1 ;restore the status register
 pop  temp1   ;restore temp1 register
 reti

EXT_INT1:
 push temp1
 in temp1,SREG
 inc press
 out SREG,temp1
 pop  temp1
 reti

TIM1_CAPT:
 push temp1
 in temp1,SREG
 
 out SREG,temp1
 pop  temp1
 reti

TIM1_COMP:
 push temp1
 in temp1,SREG
 
 out SREG,temp1
 pop  temp1
 reti

TIM1_OVF:
 push temp1
 in temp1,SREG
 
 out SREG,temp1
 pop  temp1
 reti

TIM0_OVF:
 push temp1
 in temp1,SREG
 push temp1

;this is for a 10,240 KHz Xtal
 ldi temp1,246 ;1 ms
 ;ldi temp1,236 ;2 ms
 ;ldi temp1,216 ;4 ms
 ;ldi temp1,206 ;5 ms
 ;ldi temp1,156 ;10 ms
 ;ldi temp1,56  ;20 ms
 out TCNT0,temp1 ;set for next overflow

 tst delay
 breq TIM0_X

 dec delay

TIM0_X:
 pop temp1
 out SREG,temp1
 pop  temp1
 reti

UART_RXC:
 push temp1
 in temp1,SREG
 
 out SREG,temp1
 pop  temp1
 reti

UART_DRE:
 push temp1
 in temp1,SREG
 
 out SREG,temp1
 pop  temp1
 reti

UART_TXC:
 push temp1
 in temp1,SREG
 
 out SREG,temp1
 pop  temp1
 reti

ANA_COMP:
 push temp1
 in temp1,SREG
 
 out SREG,temp1
 pop  temp1
 reti

shift16:    ;16 bit serial out msb first
 ldi temp3,2   ; 2 bytes
shift8:
 ldi temp4,8   ; 8 bits
 cbi DDSport,DDSenable ;FSYNC goes LOW
movebits:
 sbi DDSport,DDSdata ;set port bit
 rol temp1    ;shift dds address byte
 brcs clockbit   ;check for 1/0
 cbi DDSport,DDSdata ;clear port bit
clockbit:
 cbi DDSport,DDSclock ;clock dds
 sbi DDSport,DDSclock
 dec temp4    ;decrement bit counter
 brne movebits   ;branch if not done
 dec temp3    ;decrement byte counter
 breq sox    ;all done - 16 bits sent
 ld temp1,y+   ;load DDS phase word
 rjmp shift8   ;write data bits
sox:
 sbi PORTB,DDSenable ;FSYNC goes HIGH
 ret

wait:
 tst delay
 brne wait
 ret

default_freq1: ;FlashToRam
 ldi zh,high(FreqHex*2) ;load default freq
 ldi zl,low(FreqHex*2)
 ldi yl,rcve0
 clr yh
 ldi temp1,36
df1:
 lpm   ;get value in R0
 st Y+,r0  ;store in SRAM and increment Y-pointer
 adiw ZL,1  ;increment Z-pointer
 dec temp1  ;decrememnt counter
 brne df1  ;if not end of table, loop more

 ldi zh,high(FreqLCD*2) ;load default freq
 ldi zl,low(FreqLCD*2)
 ldi yl,LCDrcve0
 clr yh
 ldi temp1,8
df2:
 lpm   ;get value in R0
 st Y+,r0  ;store in SRAM and increment Y-pointer
 adiw ZL,1  ;increment Z-pointer
 dec temp1  ;decrememnt counter
 brne df2  ;if not end of table, loop more
 ret    

FreqHex: .db 0x33,0x33,0x33,0x33 ;10,000,000 Hz
.db 0x56,0x00,0x00,0x00 ; units
.db 0x5B,0x03,0x00,0x00 ;10
.db 0x8E,0x21,0x00,0x00 ;100
.db 0x8B,0x4F,0x01,0x00 ;1;000
.db 0x71,0x1B,0x0D,0x00 ;10,000
.db 0x6F,0x12,0x83,0x00 ;100,000
.db 0x52,0xB8,0x1E,0x05 ;1,000,000
.db 0x33,0x33,0x33,0x33 ;10,000,000

FreqLCD: .db 1,0,0,0,0,0,0,0 ;LCD for 10,000,000 Hz

msg1:
;     1234567890123456
.db  "FDIM Buildathon",0