; ** at90s2333 assembly language file **
.include "2333def.inc"
.def morse_ele = r14
.def morse_cnt = r15
.def tm1_status = r17
.def morse_bits = r18
.equ cw_tone_on = 7
.equ afsk_tone_on = 6
.dseg
.org 0x60
sine_ptr: .byte 2
.cseg
.org 0
rjmp init
reti ; external 0 interrupt vector
reti ; external 1 interrupt vector
reti ; timer 1 capture interrupt vector
reti ; timer 1 comparea interrupt vector
rjmp tim1_ovf ; timer 1 overflow interrupt vector
rjmp tim0_ovf ; timer 0 overflow interrupt vector
rjmp spi_handle ; spi transmit interrupt vector
reti ; uart rx complete interrupt vector
reti ; udr empty interrupt vector
reti ; uart tx complete interrupt vector
rjmp adc_comp ; adc conversion complete interrupt vector
rjmp ee_rdy ; eeprom ready interrupt vector
reti ; analogue comparator interrupt vector
tim1_ovf: ; timer 1 overflow interrupt code here
push r0
push zl
push zh
push xl
push xh
in zl, sreg
push zl
sbrs tm1_status, cw_tone_on
rjmp sene_afsk_tone
ldi xh, high(sine_ptr)
ldi xl, low(sine_ptr)
ld zl, x+ ; load sine table pointer
ld zh, x
adiw zl, 1 ; increase sine table pointer
lpm ; load new table vaule
cpi zl, low((end_of_cw_sine_tbl<<1)-1)
brne cw_load_pwm ; branch if end of sine table not reached
; reset sine table pointer
ldi zl, low((cw_sine_tbl<<1)-1)
ldi zh, high((cw_sine_tbl<<1)-1)
cw_load_pwm:
st x, zh ; save sine table pointer
st -x, zl
out ocr1l, r0 ; load new pwm vaule
rjmp tim1_ovf_ret
sene_afsk_tone:
sbrs tm1_status, afsk_tone_on
rjmp tim1_ovf_ret
tim1_ovf_ret:
pop zl
out sreg, zl
pop xh
pop xl
pop zh
pop zl
pop r0
reti
tim0_ovf: ; timer 0 overflow interrupt code here
dec morse_cnt ; decrease morse timer every 1/450 second
brne tim0_ovf_ret ; branch if one element not sent
ldi zl, morse_ele_tm
rcall read_eeprom
mov morse_cnt, r0 ; reload element timer from eeprom preset
sbr tm1_status, (1<<cw_tone_on)
lsl morse_bits
breq load_morse_ele ; branch if morse elements have been sent out
brcs tim0_ovf_ret ; 1 - cw tone one, 0 - cw tone off
cbr tm1_status, (1<<cw_tone_on)
rjmp tim0_ovf_ret
load_morse_ele:
lsl morse_ele
breq load_morse_char ; branch if one character has been sent out
brcs load_dash ; 1 - send dash, 0 - send dot
lsl morse_ele ; test morse_ele, if morse_ele = 0x80, then add space between characters
ldi morse_bits, 0b10001000
breq recover_ele ;
ldi morse_bits, 0b10100000
rjmp recover_ele
load_dash:
lsl morse_ele
ldi morse_bits, 0b11100010
breq recover_ele
ldi morse_bits, 0b11101000
recover_ele: ror morse_ele ; recover damaged value of morse_ele
rjmp tim0_ovf_ret
tim0_ovf_ret:
rjmp tim1_ovf_ret
load_morse_char:
spi_handle: ; spi transmit interrupt code here
reti
adc_comp: ; adc conversion complete interrupt code here
reti
ee_rdy: ; eeprom ready interrupt code here
; note: eeprom ready interrupt bit not set (eecr.3) - see data book
reti
; if emulation is to be used, do not insert code in marked block
; **************** start of block*******************************************
init:
; stack pointer setup code
; add following code only when at90s4433 used
; ldi r16, 0x00 ; stack pointer setup
; out sph,r16 ; stack pointer high byte
ldi r16, 0xdf ; stack pointer setup
out spl, r16 ; stack pointer low byte
; **************** end of block ********************************************
; ******* watchdog timer setup code ****
ldi r16, 0b00001110 ; wdt setup
; bit 4 - wdtoe: watch dog turn-off enable
; bit 3 - wde: watch dog enable
; bits 2..0 - wdp2, wdp1, wdp0: watch dog timer prescaler 2, 1 and 0
; wdp2 wdp1 wdp0 number of wdt oscillator cycles typical time-out(3v,5v)
; 0 0 0 16k cycles 47 ms 15 ms
; 0 0 1 32k cycles 94 ms 30 ms
; 0 1 0 64k cycles 0.19 s 60 ms
; 0 1 1 128k cycles 0.38 s 0.12 s
; 1 0 0 256k cycles 0.75 s 0,24 s
; 1 0 1 512k cycles 1.5 s 0.49 s
; 1 1 0 1,024k cycles 3.0 s 0.97 s
; 1 1 1 2,048k cycles 6.0 s 1.9 s
out wdtcr, r16 ; wdt enabled - 0.97s
; ******* timer0 setup code ****
ldi r16, 0b00000011 ; timer 0 setup 7.3728mhz t0ovf 450hz
; bits 2,1,0 - cs02, cs01, cs00: clock select0, bit 2,1 and 0
; cs02 cs01 cs00 description
; 0 0 0 stop, timer/counter0 is stopped.
; 0 0 1 ck
; 0 1 0 ck / 8
; 0 1 1 ck / 64
; 1 0 0 ck / 256
; 1 0 1 ck / 1024
; 1 1 0 external pin t0, falling edge
; 1 1 1 external pin t0, rising edge
out tccr0, r16 ; timer - ck
; ******* interrupts setup code ****
ldi r16, 0b00000000 ; external interrupt enables
; bit 7 - int1: external interrupt request 1 enable
; bit 6 - int0: external interrupt request 0 enable
out gimsk, r16 ; int0 enabled int1 disabled
ldi r16, 0b00001010 ; sleep and interrupt edges
; bit 5 - se: sleep enable
; bit 4 - sm: sleep mode
; bits 3, 2 - isc11, isc10: interrupt sense control 1 bit 1 and bit 0
; isc11 isc10 description
; 0 0 the low level of int1 generates an interrupt request.
; 0 1 any logical change on int1 generates an interrupt request.
; 1 0 the falling edge of int1 generates an interrupt request.
; 1 1 the rising edge of int1 generates an interrupt request.
; bits 1, 0 - isc01, isc00: interrupt sense control 0 bit 1 and bit 0
; isc01 isc00 description
; 0 0 the low level of int0 generates an interrupt request.
; 0 1 any logical change on int0 generates an interrupt request.
; 1 0 the falling edge of int0 generates an interrupt request.
; 1 1 the rising edge of int0 generates an interrupt request.
out mcucr, r16 ; int0 - falling edge int1 - falling edge
ldi r16, 0b10000010 ; timer interrupt enables
; bit 7 - toie1: timer/counter1 overflow interrupt enable
; bit 6 - ocie1: timer/counter1 output compare match interrupt enable
; bit 3 - ticie1: timer/counter1 input capture interrupt enable
; bit 1 - toie0: timer/counter0 overflow interrupt enable
out timsk, r16 ; timer 1: overflow, timer 0: overflow enabled
; ******* comparator setup code ****
ldi r16,0b10000010 ; interrupt enabled on falling o/p edge
; bit 7 - acd: analog comparator disable
; bit 6 - ainbg: analog comparator bandgap select
; bit 5 - aco: analog comparator output
; bit 4 - aci: analog comparator interrupt flag
; bit 3 - acie: analog comparator interrupt enable
; bit 2 - acic: analog comparator input capture enable
; bits 1,0 - acis1, acis0: analog comparator interrupt mode select
; acis1 acis0 interrupt mode
; 0 0 comparator interrupt on output toggle
; 0 1 reserved
; 1 0 comparator interrupt on falling output edge
; 1 1 comparator interrupt on rising output edge
out acsr, r16 ; comparator disabled, input capture disabled
; ******* adc setup code ****
ldi r16,0b10001110 ; adc interrupt enabled, adc enabled
; bit 7 - aden: adc enable
; bit 6 - adsc: adc start conversion
; bit 5 - adfr: adc free run select
; bit 4 - adif: adc interrupt flag
; bit 3 - adie: adc interrupt enable
; bits 2..0 - adps2..adps0: adc prescaler select bits
; adps2 adps1 adps0 division factor
; 0 0 0 2
; 0 0 1 2
; 0 1 0 4
; 0 1 1 8
; 1 0 0 16
; 1 0 1 32
; 1 1 0 64
; 1 1 1 128
out adcsr, r16 ; adc single conversion mode, prescaler:ck/64 115khz
ldi r16,0x00
; bit 6 - adcbg: adc bandgap select
; bits 2..0 - mux2..mux0: analog channel select bits 2-0
;
out admux, r16 ; channel 00 selected
; ******* uart setup code ****
; uart baud rate setup
; ldi r16, 0x17 ; baud rate 19200 osc is 7.3728 mhz
; out ubrr, r16 ; uart baud rate generator
ldi r16, 0b00000000 ; uart interrupt enables and uart settings
; bit 7 - rxc: uart receive complete
; bit 6 - txc: uart transmit complete
; bit 5 - udre: uart data register empty
; bit 4 - fe: framing error
; bit 3 - or: overrun
; bit 0 - mpcm: multi-processor communication mode
out ucsra, r16 ; interrupts: rx complete, udr empty, tx complete, -settings: rx enable, tx enable, 9-bit disable
; ******* spi setup code ****
ldi r16, 0b00000000 ; spi setups- spi disable, msb 1st, cpol - sck low, cpha clear
; bit 7 - spie: spi interrupt enable
; bit 6 - spe: spi enable
; bit 5 - dord: data order
; bit 4 - mstr: master/slave select
; bit 3 - cpol: clock polarity
; bit 2 - cpha: clock phase
; bits 1,0 - spr1, spr0: spi clock rate select 1 and 0
; spr1 spr0 sck frequency
; 0 0 fcl / 4
; 0 1 fcl / 16
; 1 0 fcl / 64
; 1 1 fcl / 128
out spcr, r16 ; slave , spi interrupt enabled
; ******* port b setup code ****
ldi r16, 0xf2 ; ain0+ain1,
out ddrb , r16 ; port b direction register
ldi r16, 0x00 ; init value
out portb, r16 ; port b value
; ******* port c setup code ****
ldi r16, 0xff ; i/o direction values
out ddrc, r16 ; port c direction register
ldi r16, 0x00 ; init value
out portc, r16 ; port c value
; ******* port d setup code ****
ldi r16, 0xb2 ; i/o: rxd,txd, int0, int1, oc1b, icp-pb6,
out ddrd, r16 ; port d direction register
ldi r16, 0x00 ; init value
out portd, r16 ; port d value
; ******* timer1 setup code ****
ldi r16, 0b00000001 ; 8-bit pwm mode comparea o/p non-inverting
; bits 7,6 - com11, com10: compare output mode1, bits 1 and 0
; com11 com10 description
; 0 0 timer/counter1 disconnected from output pin oc1
; 0 1 toggle the oc1 output line.
; 1 0 clear the oc1 output line (to zero).
; 1 1 set the oc1 output line (to one).
; bits 1,0 - pwm11, pwm10: pulse width modulator select bits
; pwm11 pwm10 description
; 0 0 pwm operation of timer/counter1 is disabled
; 0 1 timer/counter1 is an 8-bit pwm
; 1 0 timer/counter1 is a 9-bit pwm
; 1 1 timer/counter1 is a 10-bit pwm
out tccr1a, r16 ; compareb o/p non-inverting
ldi r16, 0x00 ; pwm value match a
out ocr1h, r16 ; high byte
ldi r16, 0xff ; pwm value match a
out ocr1l, r16 ; low byte
ldi r16, 0b00000001 ; timer : ck
; bit 7 - icnc1: input capture1 noise canceler (4 cks)
; bit 6 - ices1: input capture1 edge select
; bit 3 - ctc1: clear timer/counter1 on compare match
; bits 2,1,0 - cs12, cs11, cs10: clock select1, bit 2,1 and 0
; cs12 cs11 cs10 description
; 0 0 0 stop, the timer/counter1 is stopped.
; 0 0 1 ck
; 0 1 0 ck / 8
; 0 1 1 ck / 64
; 1 0 0 ck / 256
; 1 0 1 ck / 1024
; 1 1 0 external pin t1, falling edge
; 1 1 1 external pin t1, rising edge
out tccr1b, r16 ; input capture on rising edge
ldi xh, high(sine_ptr)
ldi xl, low(sine_ptr)
ldi r16, low((cw_sine_tbl<<1)-1)
st x+, r16
ldi r16, high((cw_sine_tbl<<1)-1)
st x+, r16
sbr tm1_status, (1<<cw_tone_on)
sei ; enable all interrupts
main:
rjmp main
;************************************************
;* read *
;* zl - eeprom address, return increased *
;* r0 - value got *
;************************************************
read_eeprom:
out eearl,zl
sbi eecr,eere
in zl,eedr
inc zl
ret
cw_sine_tbl: ; 800 hz sine table for cw
.db 255,247,225,191,150,105,64,30,8,0,8,30,64,105,150,191,225,247
end_of_cw_sine_tbl:
.eseg
.org 0x30
morse_ele_tm:
.db.0x80
.org 0x40
morse_table:
.db 0b00000000 ;20 space
.db 0b10101110 ;21 '!' _._.__
.db 0b01001010 ;22 '"' ._.._.
.db 0b00000000 ;23 '#'
.db 0b00010011 ;24 '$' ..._.._
.db 0b00000000 ;25 '%'
.db 0b00000000 ;26 '&'
.db 0b01111010 ;27 ''' .____.
.db 0b10110110 ;28 '(' _.__._
.db 0b10110110 ;29 ')' _.__._
.db 0b00000000 ;2a '*'
.db 0b01010100 ;2b '+' ._._.
.db 0b11001110 ;2c ',' __..__
.db 0b10000110 ;2d '-' _...._
.db 0b01010110 ;2e '.' ._._._
.db 0b10010100 ;2f '/' _.._.
.db 0b11111100 ;30 Ɔ' _____
.db 0b01111100 ;31 Ƈ' .____
.db 0b00111100 ;32 ƈ' ..___
.db 0b00011100 ;33 Ɖ' ...__
.db 0b00001100 ;34 Ɗ' ...._
.db 0b00000100 ;35 Ƌ' .....
.db 0b10000100 ;36 ƌ' _....
.db 0b11000100 ;37 ƍ' __...
.db 0b11100100 ;38 Ǝ' ___..
.db 0b11110100 ;39 Ə' ____.
.db 0b11100010 ;3a ':' ___...
.db 0b10101010 ;3b '' _._._.
.db 0b00000000 ;3c '<'
.db 0b10001100 ;3d '=' _..._
.db 0b00000000 ;3e '>'
.db 0b00110010 ;3f '?' ..__..
.db 0b00000000 ;40 '@'
.db 0b01100000 ;41 'a' ._
.db 0b10001000 ;42 'b' _...
.db 0b10101000 ;43 'c' _._.
.db 0b10010000 ;44 'd' _..
.db 0b01000000 ;45 'e' .
.db 0b00101000 ;46 'f' .._.
.db 0b11010000 ;47 'g' __.
.db 0b00001000 ;48 'h' ....
.db 0b00100000 ;49 'i' ..
.db 0b01111000 ;4a 'j' .___
.db 0b10110000 ;4b 'k' _._
.db 0b01001000 ;4c 'l' ._..
.db 0b11100000 ;4d 'm' __
.db 0b10100000 ;4e 'n' _.
.db 0b11110000 ;4f 'o' ___
.db 0b01101000 ;50 'p' .__.
.db 0b11011000 ;51 'q' __._
.db 0b01010000 ;52 'r' ._.
.db 0b00010000 ;53 's' ...
.db 0b11000000 ;54 't' _
.db 0b00110000 ;55 'u' .._
.db 0b00011000 ;56 'v' ..._
.db 0b01110000 ;57 'w' .__
.db 0b10011000 ;58 'x' _.._
.db 0b10111000 ;59 'y' _.__
.db 0b11001000 ;5a 'z' __..
.db 0b00000000 ;5b '['
.db 0b00000000 ;5c '\'
.db 0b00000000 ;5d ']'
.db 0b00000000 ;5e '^'
.db 0b00110110 ;5f '_' ..__._