📄 avr pocsag rev 1_1.asm
字号:
rjmp send_char_l ; keep looping
rcall del_dah ; inter char delay
ret
;---
dit: sbr flags,(1 << cw_tone)
rcall del_dit
rjmp dit_dah_end
dah: sbr flags,(1 << cw_tone)
rcall del_dah
dit_dah_end: cbr flags,(1 << cw_tone)
rcall del_dit
ret
del_word: rcall del_dah ; dit times 6
del_dah: rcall del_dit ; dit times three
rcall del_dit
del_dit: clr sec_01
mov temp,morse_rate ;
rcall del_hunds
ret
;--- translate ascii to morse encoded data table
;--- 0=dit 1=dah data is clocked out from the left and terminated by a 1
morse_xlate: ldi zl,low(2 * morse_table) ;Init Z-pointer
ldi zh,high(2 * morse_table)
mov temp,poc_char
rcall to_upper
subi temp,0x20 ; subtract unused lower 32 chars
andi temp,0b00111111 ; mask off any upper bits, keep in range
lsl temp ; temp * 2 to convert to byte counter
add zl,temp
clr temp
adc zh,temp ; handle carry
lpm
mov poc_char,r0
ret
;--- multiply mant1 by decimal 10
mul_10: mov mant2,mant1 ; save mant1
mov mant2m,mant1m
mov mant2h,mant1h
rcall rol_mant ; * 2
rcall rol_mant ; * 4
add mant1,mant2 ; * 5
adc mant1m,mant2m
adc mant1h,mant2h ; fall through to final multiply
;--- rotate mant1 left by one position
rol_mant:
lsl mant1
rol mant1m
rol mant1h
rol mant1hh
ret
;--- convert ascii string to int (24 bits max)
;--- enter with z pointing to string
asc2bin: clr mant1 ; start at zero
clr mant1m
clr mant1h
clr mant1hh ; not used
a2b_l: ld temp,z+ ; get char
cpi temp,'9'+1
brsh a2b_end
cpi temp,'0'
brlo a2b_end
rcall mul_10
subi temp,'0'
add mant1,temp ; add new digit
clr temp ; just add 0+Carry
adc mant1m,temp
adc mant1h,temp
rjmp a2b_l
a2b_end: ret
;--- get cr terminated string from console, store as zero terminated string in ram
;--- if terminated by ctrl-c, zero length, set carry
;--- try to support back space, may not work on all terminals
get_string: ldi zl,ram_begin
get_str_loop: rcall getc
cpi temp,cr
breq get_str_done
cpi temp,ctrl_c
breq get_str_abort
cpi temp,bs
brne save_str_char
_send ' '
_send bs
dec zl
cpi zl,ram_begin ; we don't want to be able to dec past beginning of ram
brsh pc + 2
ldi zl,ram_begin
rjmp get_str_loop
save_str_char: cpi zl,ram_begin + max_str_len
breq get_str_loop
st z+,temp
rjmp get_str_loop
get_str_abort: ldi zl,0
sec
get_str_done: ldi temp,0
st z,temp
ret
;--- set zl to first char of arg, ii
pos_zl: ldi zl,ram_begin ; point to beginning
pos_zl_loop: rcall next_arg
dec ii
brne pos_zl_loop
ret
;--- count total number of parameters in string, parameters are seperated by ' ' or ','
count_param: clr byte_cnt
ldi zl,ram_begin ; point to beginning of string
count_p_loop: rcall next_arg
ld temp,z
brne pc + 2
ret
inc byte_cnt
rjmp count_p_loop
; inc zl till a non-white char or ',' is encountered
discard_white: ld temp,z
cpi temp,' '
breq discard_loop
cpi temp,','
breq discard_loop
ret
discard_loop: inc zl ; point to to next location
rjmp discard_white
; inc zl till a ' ',',', or end of string
discard_nw: ld temp,z
tst temp ; test for zero termination
breq discard_end
cpi temp,','
breq discard_end
cpi temp,' '
breq discard_end
inc zl
rjmp discard_nw
discard_end: ret
; position zl at first char of next argument
next_arg: ld temp,z
tst temp
brne pc + 2 ; test for end of string
ret
cpi temp,' '
breq pc + 2
rcall discard_nw
rcall discard_white
next_arg_end: ret
;----------------------------------------------------
;---- delay temp * 10 ms (approx)
del_hunds: add temp,sec_01
del_h_loop: cpse temp,sec_01
rjmp del_h_loop
ret
;----------------------------------------------------
;--- send a cr and lf to console
crlf: ldi temp,cr
rcall putc
ldi temp,lf
rcall putc
ret
;--- wait for char from console, returns in temp, and u_data
;--- will time out return a ctr-c
getc: ldi temp,1
mov sec_01,temp
ldi temp,getc_to_val
getc_loop: tst sec_01
brne getc_a
inc sec_01
dec temp
breq getc_timeout ; timed out
getc_a: sbrs flags,uart_rx ; check for data
rjmp getc_loop
cbr flags,(1<<uart_rx) ; clear bit flag
mov temp,u_data ; move data to temp
rcall putc
ret
getc_timeout: ldi temp,ctrl_c ;
mov u_data,temp
ret
;---- put char to console
putc: sbis USR,UDRE ;Is UART transmitter ready?
rjmp putc ;If not, wait
out UDR,temp ;Put character to UART
ret
;--- convert temp to upper case
to_upper: cpi temp,'a'
brlo toupper_end
cpi temp,'z'+1
brsh toupper_end
subi temp,' '
toupper_end: ret
;--------------------------------------
;send byte via serial as two asc chars
send_byte: push temp ; save temp
rcall send_hi_nibble ; send hi nibble
pop temp ; reget data
push temp ; and save it again
rcall send_nibble
pop temp ; just restores temp
ret
; fall into send nibble
;----------------------------------------
;-send low nibble as ascii
send_hi_nibble: swap temp
send_nibble: rcall hex_asc
rcall putc
ret
;******************************************************************
;routine converts 0-f hex in temp to 0 to F ascii
;*****************************************************************
hex_asc: andi temp,0b00001111 ;lower nybble only
cpi temp,10 ;0-9 or A-F?
brlo hex_asc_1 ;
subi temp,-7 ;adjust A-F
hex_asc_1: subi temp,-48 ;add offset to convert to ascii
ret
;----------------------------------------------------
;--- internal eeprom routines
;--- read eeprom (post incs EEAR!)
EERead: cli
sbic EECR,EEWE ; if EEWE not clear
rjmp EERead ; keep waiting
out EEAR,EEaddr
sbi EECR,EERE ; set EEPROM Read strobe
in EEdata,EEDR ; get data
rjmp inc_eear ; bump address and exit
;--- write EEPROM (post incs EEAR!)
EEWrite: cli
sbic EECR,EEWE ; if EEWE not clear
rjmp EEWrite ; keep waiting
out EEAR,EEaddr
out EEDR,EEdata ; output the data
sbi EECR,EEMWE ; set master write enable
sbi EECR,EEWE ; set EEPROM Write strobe
inc_eear: inc EEaddr
sei
ret
;--- send zero terminated strings from eeprom to console
;serial_string: out EEAR,temp ; move temp to addr
;next_ser_char: rcall EERead ; get char from eeprom
; tst EEdata ; test for eom
; brne pc + 2 ; skip nz
; ret
; mov temp,EEdata ;
; rcall putc ; ship it
; rjmp next_ser_char ; loop it
;--- copy message pin and flags to registers and message data to ram :
;--- EEaddr must point to first byte of pin
get_ee_msg: ldi zl,at_bin+1 ; point to binh
ee_msg_l1: rcall EEread
st z+,EEdata
cpi zl,at_bin + 4 ; done with pin?
brne ee_msg_l1
rcall EEread ; get flags
mov poc_flags,EEdata
ldi zl,ram_begin ; point to ram
ee_msg_l2: rcall EEread ; copy messsage data
st z+,EEdata
tst EEdata ; test for end
brne ee_msg_l2 ; keep looping
ret
;--- copy 4 bin working registers to poc output buffer
bin2buff: tst poc_bit_cnt ; test to see if output reg is empty
brne bin2buff
mov poc_buff_hh,binhh
mov poc_buff_h,binh
mov poc_buff_m,binm
mov poc_buff,bin
rjmp _2buff_end
;--- copy 4 flash bytes to poc_buffer
flash2buff: tst poc_bit_cnt ; test to see if output reg is empty
brne flash2buff
ldi yl,at_poc_buff ; destination
f2p_loop: lpm ; get byte
st y+,r0 ;
adiw zl,1 ; zl++
cpi yl,at_poc_buff + 4 ; 4 bytes done?
brne f2p_loop
_2buff_end: sbrc flags,debug ; check debug flag
rjmp _dump_buff
ldi poc_bit_cnt,32 ; no debug, just send
ret
;--- debugging, echo pocsag message to console
_dump_buff: push poc_buff ; quick save data
push poc_buff_m
push poc_buff_h
push poc_buff_hh
ldi poc_bit_cnt,32 ; start isr
rcall crlf ; make pretty
pop temp
rcall send_byte
pop temp
rcall send_byte
pop temp
rcall send_byte
pop temp,
rcall send_byte
ret
;--- send zero terminated strings from flash to console
; use z for pointer
ser_ram_str: lpm ;
tst r0 ;
brne pc + 2 ;
ret
mov temp,R0 ;
rcall putc
adiw zl,1
rjmp ser_ram_str
;*********************************************************************
; codespace stored string storage
;*********************************************************************
;--- message strings----------------
_hello: .db cr,lf,"AVR_POCSAG 1.0 Copyright Henry Carl Ott N2RVQ",cr,lf,0
_error: .db bel,cr,lf,"ERROR",0
_debug: .db cr,lf,"DEBUG=",0
_frame_sync: .db 0x7C,0xD2,0x15,0xD8 ; pocsag frame sync word
_idle: .db 0x7A,0x89,0xC1,0x97 ; pocsag idle word
_0xaa: .db 0xaa,0xaa,0xaa,0xaa ; alternating bit stream for preamble
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 '0' _____
.db 0b01111100 ;31 '1' .____
.db 0b00111100 ;32 '2' ..___
.db 0b00011100 ;33 '3' ...__
.db 0b00001100 ;34 '4' ...._
.db 0b00000100 ;35 '5' .....
.db 0b10000100 ;36 '6' _....
.db 0b11000100 ;37 '7' __...
.db 0b11100100 ;38 '8' ___..
.db 0b11110100 ;39 '9' ____.
.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 '_' ..__._
;*********************************************************************
; EEPROM
;*********************************************************************
.eseg
.org 0x00
empty: .db 0x00 ; leave empty, may get corrupted do to possible bug
msg1_pin: .db 0x12,0xd6,0x87
msg1_flags: .db (1 << m_baud_2400) | (1 << m_type_num)
msg1_data: .db "212 555-1212",0x00
.org 0x40
msg2_pin: .db 0x12,0xd6,0x87
msg2_flags: .db (1 << m_fun_1) | (1<< m_fun_1) | (1 << m_type_alpha)
msg2_data: .db "AVR POCSAG TEST cap=1234567",0x00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -