.cseg .org 0 .include "tn2313def.inc" .equ stack=RAMEND ;PB0 SDI ;PB1 SDO ;PB2 SCK ;PB3 SEL .equ sdi=0 .equ sdi_port=PORTB .equ sdo=1 .equ sdo_port=PINB .equ sck=2 .equ sck_port=PORTB .equ sel=3 .equ sel_port=PORTB .equ button=2 .equ button_port=PIND .equ led_wrk=3 .equ led_wrk_port=PORTD .equ led_hamm=4 .equ led_hamm_port=PORTD .equ led_err=5 .equ led_err_port=PORTD .equ reset=6 .equ reset_port=PORTD .equ tbuf_size=57 .equ rbuf_size=57 .macro ldw ldi R24,LOW(@0) ldi R25,HIGH(@0) .endm ldi R16,stack rjmp start correct_hamming_table: .db 2,$80,$20,0,8,0,0,0 .org 6 rjmp timer rjmp recv_int rjmp trans_int hamming_table: .db $15,$02,$49,$5E,$64,$73,$38,$2F,$D0,$C7,$8C,$9B,$A1,$B6,$FD,$EA bitrate_table: .db 129,64,32,21,15,10 data_rate_table: .db 20,10,5,4,3,2 base_frequency_table: .dw $a578,$a5a0,$a5c8,$a5f0,$a618,$a640,$a668,$a690,$a6b8,$a6e0 serial_settings_table: .db 6,$e,$26,$2e,$36,$3e,4,$24,$34,0 start: out SPL,R16 clr ZH ldi R16,-1 out PORTB,R16 out PORTD,R16 ldi R16,0b00011101 out DDRB,R16 ldi R16,0b01111000 out DDRD,R16 cbi led_wrk_port,led_wrk cbi reset_port,reset ldw $2000 rcall delay sbi reset_port,reset sbi led_wrk_port,led_wrk cbi led_hamm_port,led_hamm cbi led_err_port,led_err ldw 0 rcall delay sbi led_hamm_port,led_hamm sbi led_err_port,led_err ldi R26,rbuf_size-1 ldi R27,rbuf_size-1 ldi R28,tbuf_size-1 ldi R29,tbuf_size-1 clr ZL eepr_rd: sbic EECR,EEPE rjmp eepr_rd out EEAR,ZL sbi EECR,EERE in R16,EEDR st Z+,R16 cpi ZL,max_menu brne eepr_rd clr R16 out UBRRH,R16 ldi ZL,bitrate_table<<1 add ZL,R0 lpm R16,Z out UBRRL,R16 ldi R16,0b01000010 out UCSRA,R16 ldi R16,0b10011000 out UCSRB,R16 ldi ZL,serial_settings_table<<1 add ZL,R1 lpm R16,Z out UCSRC,R16 clr R16 out TCCR0A,R16 ldi R16,0b00000100 out TCCR0B,R16 ldi R16,0b00000010 out TIMSK,R16 clr R14 clr R15 ldw $c0e0 rcall spi ;10 MHz external clock sbis button_port,button rjmp config sei ldw $80d7 rcall spi ldi ZL,base_frequency_table<<1 add ZL,R3 add ZL,R3 lpm R24,Z+ lpm R25,Z rcall spi ldi R25,$c6 ldi ZL,data_rate_table<<1 add ZL,R2 lpm R24,Z rcall spi mov R24,R5 inc R24 com R24 andi R24,7 swap R24 lsl R24 ldi R25,$94 rcall spi ldw $c2e8 or R24,R7 rcall spi ldw $ca81 rcall spi ldw $c483 rcall spi mov R24,R4 add R24,R4 inc R24 swap R24 add R24,R6 ldi R25,$98 rcall spi ldw $e000 rcall spi ldw $c800 rcall spi main_loop: ldw $8238 rcall spi ldi R16,$2d rcall transmit_byte ldi R16,$d4 rcall transmit_byte mov R19,R27 sub R19,R26 brpl transmit1 subi R19,-rbuf_size transmit1: mov R16,R19 rcall code_hamm transmit_lp: tst R19 breq transmitx rcall get_char tst R8 brne transmit2 rcall code_hamm rjmp transmit3 transmit2: rcall transmit_byte transmit3: dec R19 rjmp transmit_lp transmitx: ldi R16,$aa rcall transmit_byte ldi R16,$aa rcall transmit_byte ldw $82d8 rcall spi ldw $ca81 rcall spi ldw $ca83 rcall spi rcall receive_byte_hamm in R18,led_wrk_port ldi R17,1<uncorrectable transmission error tst R16 ;block length==0? breq main_loop ;no data to receive cpi R16,tbuf_size+1 ;block length>transmit buffer? brcc main_loop ;implausible block length mov R19,R16 receive_lp: tst R8 brne receive1 rcall receive_byte_hamm brcs main_loop rjmp receive2 receive1: rcall receive_byte brcs main_loop mov R16,R24 receive2: rcall put_char dec R19 brne receive_lp rjmp main_loop code_hamm: push R16 swap R16 rcall get_hamm pop r16 get_hamm: andi R16,15 ldi ZL,LOW(hamming_table<<1) add ZL,R16 lpm R16,Z transmit_byte: cbi sdi_port,sdi cbi sel_port,sel nop transmit_wait: sbis sdo_port,sdo rjmp transmit_wait send1: ldi R25,$b8 mov R24,R16 rjmp spi receive_byte_hamm: rcall receive_nibble swap R17 push R17 rcall receive_nibble pop R16 or R16,R17 ret receive_byte: cbi sdi_port,sdi cbi sel_port,sel ldw 0 receive_wait: sbic sdo_port,sdo rjmp receive_byte1 sbiw R25:R24,1 brne receive_wait sec ret receive_byte1: ldw $b000 rjmp spi receive_nibble: cbi sdi_port,sdi cbi sel_port,sel ldw 0 receive_wait1: sbic sdo_port,sdo rjmp receive_nibble1 sbiw R25:R24,1 brne receive_wait1 sec ret receive_nibble1: ldw $b000 rcall spi mov R16,R24 rjmp check_hamming spi: cbi sck_port,sck cbi sel_port,sel ldi R16,16 spi_loop: sbrs R25,7 cbi sdi_port,sdi sbrc R25,7 sbi sdi_port,sdi sbi sck_port,sck lsl R24 rol R25 sbic sdo_port,sdo ori R24,1 cbi sck_port,sck dec R16 brne spi_loop sbi sel_port,sel clc ret delay: sbiw R25:R24,1 brne delay ret check_hamming: clr R18 ldi R17,$a3 and R17,R16 rcall parity rol R18 ldi R17,$8e and R17,R16 rcall parity rol R18 ldi R17,$3a and R17,R16 rcall parity rol R18 mov R17,R16 rcall parity brcc correct_hamming cpi R18,7 breq decode_hamming cbi led_err_port,led_err clr R15 dec R15 clr R17 rjmp check_hammingx decode_hamming: clr R17 lsl R16 rol R17 lsl R16 lsl R16 rol R17 lsl R16 lsl R16 rol R17 lsl R16 lsl R16 rol R17 sez check_hammingx: clc ret correct_hamming: ldi ZL,LOW(correct_hamming_table<<1) add ZL,R18 lpm R18,Z eor R16,R18 cbi led_hamm_port,led_hamm clr R14 dec R14 rjmp decode_hamming parity: mov R20,R17 swap R17 eor R17,R20 mov R20,R17 lsr R17 lsr R17 eor R17,R20 mov R20,R17 lsr R17 eor R17,R20 ror R17 ret put_char: cli push ZL ldi ZL,LOW(trans_buffer) add ZL,R29 st Z,R16 mov R16,R29 dec R16 brpl put_char1 ldi R16,tbuf_size-1 put_char1: cpse R16,R28 mov R29,R16 sbi UCSRB,5 sei pop ZL ret get_char: cp R26,R27 breq get_charx push ZL ldi ZL,LOW(recv_buffer) add ZL,R27 cli dec R27 brpl get_char1 ldi R27,rbuf_size-1 get_char1: ld R16,Z sei pop ZL get_charx: ret recv_int: in R23,SREG in R22,UCSRA andi R22,0b00010100 ;check frame and parity errors in R22,UDR brne recv_intx push ZL ldi ZL,LOW(recv_buffer) add ZL,R26 st Z,R22 mov R22,R26 dec R22 brpl recv_int1 ldi R22,rbuf_size-1 recv_int1: cpse R22,R27 mov R26,R22 pop ZL recv_intx: out SREG,R23 reti trans_int: in R23,SREG cp R28,R29 breq trans_intx1 push ZL ldi ZL,LOW(trans_buffer) add ZL,R28 ld R22,Z out UDR,R22 dec R28 brpl trans_int1 ldi R28,tbuf_size-1 trans_int1: pop ZL trans_intx: out SREG,R23 reti trans_intx1: cbi UCSRB,5 rjmp trans_intx timer: in R23,SREG tst R14 breq timer1 dec R14 brne timer1 sbi led_hamm_port,led_hamm timer1: tst R15 breq timerx dec R15 brne timerx sbi led_err_port,led_err timerx: out SREG,R23 reti config: ldw -1 c_wt_spc: sbic PIND,0 rjmp c_wt_spc c_wt_rc: sbis PIND,0 rjmp c_wt_rc c_wt_rc1: adiw R25:R24,1 ;2 nop ;1 nop ;1 nop ;1 sbic PIND,0 ;1 rjmp c_wt_rc1 ;2 8 cylces=0.8us@10MHz out UBRRH,R25 out UBRRL,R24 ldi R16,0b00000110 ;8n1 out UCSRC,R16 config_lp: clr R16 rcall c_send_str rcall c_getchar tst R16 breq config_lp cpi R16,max_menu+1 brcc config_lp mov XL,R16 dec XL subi R16,-$30 rcall c_putchar mov R16,XL lsl R16 ldi ZL,LOW(m_table<<1) ldi ZH,HIGH(m_table<<1) add ZL,R16 brcc config1 inc ZH config1: rcall c_nl lpm R16,Z+ lpm R19,Z rcall c_send_str ldi R16,cv_tx rcall c_send_str c_eepr_rd: sbic EECR,EEPE rjmp c_eepr_rd out EEAR,XL sbi EECR,EERE in R16,EEDR subi R16,-$31 rcall c_putchar rcall c_nl ldi R16,nv_tx rcall c_send_str rcall c_getchar push R16 subi R16,-$30 rcall c_putchar rcall c_nl pop R16 dec R16 brmi config_lp cp R16,R19 brcc config_lp c_wt_tx: sbis UCSRA,6 ;wait until tx buffer is empty rjmp c_wt_tx ldi R17,$80 out CLKPR,R17 ldi R17,3 ;divide clock by 8 out CLKPR,R17 ldw $100 rcall delay c_eepr_wr: sbic EECR,EEPE rjmp c_eepr_wr out EEAR,XL out EEDR,R16 sbi EECR,EEMPE sbi EECR,EEPE ldw $2000 rcall delay ldi R17,$80 out CLKPR,R17 clr R17 ;no clock division out CLKPR,R17 rjmp config_lp c_send_str: ldi ZL,LOW(strings<<1) ldi ZH,HIGH(strings<<1) c_send_strlp2: dec R16 brmi c_send_str1 c_send_strlp1: lpm R17,Z+ tst R17 brpl c_send_strlp1 rjmp c_send_strlp2 c_send_str1: lpm R16,Z+ push R16 andi R16,$7f rcall c_putchar pop R16 tst R16 brpl c_send_str1 ret c_nl: ldi R16,13 rcall c_putchar ldi R16,10 c_putchar: sbis UCSRA,5 rjmp c_putchar out UDR,R16 ret c_getchar: sbis UCSRA,7 rjmp c_getchar in R16,UDR subi R16,$30 brcs c_getchar cpi R16,10 brcc c_getchar ret ;string# ;range m_table: .db 1,6,2,9 .db 3,6,4,9 .db 5,8,6,6 .db 7,8,8,8 .db 9,2 .equ max_menu=9 .equ cv_tx=10 .equ nv_tx=11 strings: .db 13,10,"Serial Bridge V0.1",13,10,10,"1-Serial Bitrate",13,10,"2-Serial Interface Settings ",13,10,"3-Radio Data Rate",13,10,"4-Base Frequency",13,10,"5-FSK Range",13,10,"6-Receiver Bandwidth",13,10,"7-Output Power Setting",13,10,"8-DQD Threshold",13,10,"9-Protection",13,10+$80 .db 13,10,"Set Serial Bitrate",13,10,"1- 9600 bit/s",13,10,"2- 19200 bit/s",13,10,"3- 38400 bit/s",13,10,"4- 57600 bit/s",13,10,"5- 76800 bit/s",13,10,"6-115200 bit/s",13,10+$80 .db 13,10,"Set Serial Interface Parameters",13,10,"1-8n1",13,10,"2-8n2",13,10,"3-8e1",13,10,"4-8e2",13,10,"5-8o1",13,10,"6-8o2",13,10,"7-7n1",13,10,"8-7e1",13,10,"9-7o1",13,10+$80 .db 13,10,"Set Radio Data Rate",13,10,"1-16 kbit/s",13,10,"2-31 kbit/s",13,10,"3-57 kbit/s",13,10,"4-69 kbit/s",13,10,"5-86 kbit/s",13,10,"6-115 kbit/s",13,10+$80 .db 13,10,"Set Base Frequency",13,10,"433.4+0.1*N MHz (N=1...9) ",13,10+$80 .db 13,10,"Set FSK Range",13,10,"30+N*30 kHz (N=1...8)",13,10+$80 .db 13,10,"Set Receiver Bandwidth",13,10,"1- 67 kHz",13,10,"2-134 kHz",13,10,"3-200 kHz",13,10,"4-270 kHz",13,10,"5-340 kHz",13,10,"6-400 kHz",13,10+$80 .db 13,10,"Set Output Power Attenuation ",13,10,"-(N-1)*3 dB (N=1...8)",13,10+$80 .db 13,10,"Set DQD Threshold",13,10,"1...8",13,10+$80 .db 13,10,"Set Protection",13,10,"1- on",13,10,"2-off",13,10+$80 .db "Current Value",':'+$80 .db "New Value",':'+$80 .dseg .org $60 trans_buffer: .byte tbuf_size recv_buffer: .byte rbuf_size