; ; FIFO_CS8416 with AVR ATtiny26L ; ; ver 1.0 ; by UENO Tomohiro 2004/10/xx .include "tn26def.inc" .def tmp = R16 .def tmp2 = R17 .def tmp3 = R18 .def counter = R19 .def reg_address = R20 .def reg_data = R21 .def tmp4 = R22 .def btn1 = R23 .def ch = R0 .def current_btn = R1 .def current_freq = R2 .def current_ch = R3 .equ gpo0 = 7 ; portA .equ cdout = 6 ; portA .equ cdin = 5 ; portA .equ cclk = 4 ; portA .equ cs = 3 ; portA .equ dai_cs = 2 ; portA .equ btn = 1 ; portA .equ sel = 0 ; portA .equ avr_reset = 7 ; portB .equ cpld_reset = 6 ; portB .equ lcd_e = 5 ; portB .equ lcd_rs = 4 ; portB .equ lcd_d7 = 3 ; portB .equ lcd_d6 = 2 ; portB .equ lcd_d5 = 1 ; portB .equ lcd_d4 = 0 ; portB .equ freq_44_1 = 0 .equ freq_48_0 = 1 .equ freq_88_2 = 2 .equ freq_96_0 = 3 .equ freq_d_c = 4 .equ freq_32_0 = 5 .equ freq_no_signal = 0xff .equ ch_status_table = 0x60 .macro LCD_STR ldi ZL,low(@0) ldi ZH,high(@0) rcall lcd_put_str .endmacro rjmp reset ; $000 reset vector reti ; $001 EXT_INT0 reti ; $002 PIN_CHG reti ; $003 TIMER1 COMPA reti ; $004 TIMER1 COMPB reti ; $005 TIMER1 OVF1 reti ; $006 TIMER1 OVF0 reti ; $007 USI_STRT reti ; $008 USI_OVF reti ; $009 EE_RDY reti ; $00A ANA_COMP reti ; $00B ADCreset: ldi tmp,LOW(RAMEND) out SP,tmp rcall wait_1ms ; portA initialize ldi tmp,0b00111100 ; input out DDRA,tmp ldi tmp,0b00111100 ; bit 7-4,2-0 pullup out PORTA,tmp ; portB initialize ldi tmp,0b11111111 ; bit 7-5,3 output out DDRB,tmp ldi tmp,0b11111111 ; bit 2-0 pullup out PORTB,tmp rcall lcd_init rcall lcd_clear ; A/D converter initialize ldi tmp,0b11000111 ; ADEN=1,ADSC=1,ADFR=0(not continue),ADIF=0,ADIE=0,ASPS<2-0>=111 out ADCSR,tmp rcall eeprom_read ldi tmp,0x00+0 rcall lcd_pos LCD_STR(initial_str1) ldi tmp,0x40+0 rcall lcd_pos LCD_STR(initial_str2) ldi tmp,0x14+0 rcall lcd_pos LCD_STR(initial_str3) ldi tmp,0x54+0 rcall lcd_pos LCD_STR(initial_str4) reset_loop: ; cpld reset cbi PORTB,cpld_reset rcall wait_1ms sbi PORTB,cpld_reset rcall wait_10ms ; CS8416 reset ; ldi reg_address,9 ; ldi reg_data,0 ; rcall cpld_write ldi reg_address,9 ldi reg_data,1 rcall cpld_write rcall wait_1ms ldi reg_address,0x04 ldi reg_data,0x80 rcall dai_write ldi reg_address,0x05 ldi reg_data,0x88 rcall dai_write ; ldi reg_address,0x01 ; ldi reg_data,0x04 ; rcall dai_write ldi reg_address,0x7f rcall dai_read mov tmp,reg_data cbr tmp,0b00001111 cpi tmp,0x20 brne reset_loop ldi tmp,'?' cpi reg_data,0x27 brne PC+2 ldi tmp,'D' rcall lcd_put rcall wait_1s rcall wait_1s rcall wait_1s rcall lcd_clear ldi tmp,freq_no_signal mov current_freq,tmp ldi tmp,0xff mov current_ch,tmp ldi btn1,0 ldi tmp,0x00+0 rcall lcd_pos LCD_STR(str_input_ch) ldi tmp,0x40+0 rcall lcd_pos LCD_STR(str_receive) ldi tmp,0x14+0 rcall lcd_pos LCD_STR(str_fifo_out) ldi tmp,0x54+0 rcall lcd_pos LCD_STR(str_wordsync) rcall set_cpld_status main_loop: rcall wait_1ms mainloop_check_ch: rcall check_ch cp tmp,current_ch breq mainloop_check_ch_end mov current_ch,tmp ldi tmp,0x00+4 rcall lcd_pos mov tmp,current_ch inc tmp rcall lcd_put_hex rcall set_cpld_status rcall put_input rcall put_fifo_out rcall put_wordsync mainloop_check_ch_end: mainloop_check_button: rcall check_btn cpi tmp,0 brne PC+3 clr current_btn rjmp mainloop_check_button_end cp tmp,current_btn brne PC+2 rjmp mainloop_check_button_end mov current_btn,tmp cpi tmp,1 brne mainloop_check_button_btn2 ldi tmp,0x00 ldi tmp2,0 rcall put_selector ldi tmp,0x14 ldi tmp2,0 rcall put_selector ldi tmp,0x54 ldi tmp2,0 rcall put_selector inc btn1 cpi btn1,1 brne mainloop_check_button_btn1_2 mainloop_check_button_btn1_1: ldi tmp,0x00 ldi tmp2,1 rcall put_selector rjmp mainloop_check_button_end mainloop_check_button_btn1_2: cpi btn1,2 brne mainloop_check_button_btn1_3 ldi tmp,0x14 ldi tmp2,1 rcall put_selector rjmp mainloop_check_button_end mainloop_check_button_btn1_3: cpi btn1,3 brne mainloop_check_button_btn1_4 ldi tmp,0x54 ldi tmp2,1 rcall put_selector rjmp mainloop_check_button_end mainloop_check_button_btn1_4: ldi btn1,0 rcall eeprom_write rjmp mainloop_check_button_end mainloop_check_button_btn2: ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) add YL,current_ch ld tmp,Y cpi btn1,1 brne mainloop_check_button_btn2_2 mainloop_check_button_btn2_1: com tmp rcall set_input rcall put_input rcall set_cpld_status rjmp mainloop_check_button_end mainloop_check_button_btn2_2: cpi btn1,2 brne mainloop_check_button_btn2_3 swap tmp cbr tmp,0b11111000 inc tmp cpi tmp,5 brlo PC+2 ldi tmp,0 rcall set_fifo_out rcall put_fifo_out rcall set_cpld_status rjmp mainloop_check_button_end mainloop_check_button_btn2_3: cpi btn1,3 brne mainloop_check_button_end inc tmp cbr tmp,0b11111100 rcall set_wordsync rcall put_wordsync rcall set_cpld_status mainloop_check_button_end: mainloop_check_freq: rcall detect_rx_freq cp current_freq,tmp breq mainloop_check_freq_end mov current_freq,tmp ldi reg_address,0b00001010 ldi reg_data,0b00000011 cpi tmp ,freq_no_signal brne PC+2 ldi reg_data,0b00000010 rcall cpld_write ldi tmp,0x40+11 rcall lcd_pos mov tmp,current_freq rcall put_freq mov tmp,current_freq cpi tmp,freq_no_signal brne PC+3 rcall set_cpld_status rjmp mainloop_check_freq_end ; ldi reg_address,0b00001010 ; ldi reg_data,0b00000011 ; rcall cpld_write mainloop_check_freq_end: rjmp main_loop initial_str1: .db " -- DAC-U3 --",0 initial_str2: .db "Designed by T.UENO",0 initial_str3: .db "Software v1.0",0 initial_str4: .db "CS8416 revision ",0 str_input_ch: .db "Ch.",0 str_receive: .db "Receive",0 str_fifo_out: .db "FIFO out",0 str_wordsync: .db "WordSync",0 put_selector: push tmp subi tmp,-9 rcall lcd_pos ldi tmp,' ' cpi tmp2,0 breq PC+2 ldi tmp,'[' rcall lcd_put pop tmp subi tmp,-19 rcall lcd_pos ldi tmp,' ' cpi tmp2,0 breq PC+2 ldi tmp,']' rcall lcd_put ret detect_rx_freq: ldi reg_address,0x18 rcall dai_read rcall detect_rx_freq_sub cpi tmp,freq_no_signal breq PC+2 ret dec reg_data rcall detect_rx_freq_sub cpi tmp,freq_no_signal breq PC+2 ret inc reg_data inc reg_data rcall detect_rx_freq_sub ret detect_rx_freq_sub: ldi tmp,freq_no_signal cpi reg_data,0x84 brne PC+2 ldi tmp,freq_32_0 cpi reg_data,0x60 brne PC+2 ldi tmp,freq_44_1 cpi reg_data,0x58 brne PC+2 ldi tmp,freq_48_0 cpi reg_data,0x30 brne PC+2 ldi tmp,freq_88_2 cpi reg_data,0x2c brne PC+2 ldi tmp,freq_96_0 ret set_cpld_status: ldi reg_address,0b00001010 ldi reg_data,0b00000000 rcall cpld_write ldi reg_address,0x04 ldi reg_data,0b11000000 rcall dai_write ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) ldi reg_address,0 ld reg_data,Y+ cbr reg_data,0b11111000 rcall cpld_write inc reg_address cpi reg_address,8 brne PC-5 ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) add YL,current_ch ld reg_data,Y swap reg_data cbr reg_data,0b11111000 ldi reg_address,0b00001000 rcall cpld_write ldi reg_address,0b00001010 ldi reg_data,0b00000010 rcall cpld_write mov tmp,current_ch ldi tmp2,4 cp current_ch,tmp2 brsh PC+3 ldi tmp,3 sub tmp,current_ch lsl tmp lsl tmp lsl tmp sbr tmp,0b10000000 ldi reg_address,0x04 mov reg_data,tmp rcall dai_write ldi reg_address,0x7f rcall dai_read cpi reg_data,0x27 brne PC-7 ldi tmp3,50 rcall wait_10ms dec tmp3 brne PC-2 ldi reg_address,0b00001010 ldi reg_data,0b00000011 mov tmp,current_freq cpi tmp,freq_no_signal brne PC+2 ldi reg_data,0b00000010 rcall cpld_write ; ldi reg_address,0b00001010 ; ldi reg_data,0b00000011 ; rcall cpld_write ret set_input: ; tmp2; value (000/100 = coaxica/optical) push tmp2 ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) add YL,current_ch ld tmp2,Y cbr tmp2,0b00000100 or tmp2,tmp st Y,tmp2 pop tmp2 ret set_fifo_out: ; tmp: value (0000/0001/0010/0011/0100 = 44.1/48/88.2/96/free) push tmp2 ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) add YL,current_ch ld tmp2,Y cbr tmp2,0b01110000 swap tmp cbr tmp,0b10001111 or tmp2,tmp st Y,tmp2 pop tmp2 ret set_wordsync: ; tmp2; value (00/01/10/11 = 44.1/48.0/88.2/96.0) push tmp2 ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) add YL,current_ch ld tmp2,Y cbr tmp2,0b00000011 or tmp2,tmp st Y,tmp2 pop tmp2 ret put_input: ldi tmp,0x00+11 rcall lcd_pos ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) add YL,current_ch ld tmp,Y cbr tmp,0b11111011 cpi tmp,0 brne put_input_optical put_input_coaxial: LCD_STR(str_coaxial) ret put_input_optical: LCD_STR(str_optical) ret str_coaxial: .db "Coaxial",0 str_optical: .db "Optical",0 put_fifo_out: ldi tmp,0x14+11 rcall lcd_pos ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) add YL,current_ch ld tmp,Y swap tmp cbr tmp,0b11111000 cpi tmp,0 brne put_fifo_out_48_0 put_fifo_out_44_1: LCD_STR(str_freq_44_1) ret put_fifo_out_48_0: cpi tmp,1 brne put_fifo_out_88_2 LCD_STR(str_freq_48_0) ret put_fifo_out_88_2: cpi tmp,2 brne put_fifo_out_96_0 LCD_STR(str_freq_88_2) ret put_fifo_out_96_0: cpi tmp,3 brne put_fifo_out_d_c LCD_STR(str_freq_96_0) ret put_fifo_out_d_c: LCD_STR(str_freq_d_c) ret put_wordsync: ldi tmp,0x54+11 rcall lcd_pos ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) add YL,current_ch ld tmp,Y cbr tmp,0b11111100 cpi tmp,0 brne put_wordsync_48_0 put_wordsync_44_1: LCD_STR(str_freq_44_1) ret put_wordsync_48_0: cpi tmp,1 brne put_wordsync_88_2 LCD_STR(str_freq_48_0) ret put_wordsync_88_2: cpi tmp,2 brne put_wordsync_96_0 LCD_STR(str_freq_88_2) ret put_wordsync_96_0: LCD_STR(str_freq_96_0) ret ; ; CPLD register write ; ; reg_address : address (bit7-4) ; reg_data : data (bit2-0) ; cpld_write: mov tmp,reg_address lsl tmp lsl tmp lsl tmp or tmp,reg_data cbi PORTA,cs rcall write_sub sbi PORTA,cs rcall wait_1ms ret ; ; dai register write ; ; tmp : address (bit7-0) ; tmp2 : data (bit7-0) ; dai_write: cbi PORTA,dai_cs ldi tmp,0b00100000 rcall write_sub mov tmp,reg_address rcall write_sub mov tmp,reg_data rcall write_sub sbi PORTA,dai_cs ret ; ; dai register read ; ; tmp : address (bit7-0) ; tmp2 : data (bit7-0) ; dai_read: cbi PORTA,dai_cs ldi tmp,0b00100000 rcall write_sub mov tmp,reg_address rcall write_sub sbi PORTA,dai_cs nop nop cbi PORTA,dai_cs ldi tmp,0b00100001 rcall write_sub ldi tmp2,8 dai_read_loop: lsl reg_data cbr reg_data,0x01 sbic PINA,cdout sbr reg_data,0x01 sbi PORTA,cclk cbi PORTA,cclk dec tmp2 brne dai_read_loop sbi PORTA,dai_cs rcall wait_1ms ret write_sub: ldi tmp2,8 write_sub_loop: sbi PORTA,cdin rol tmp brcs PC+2 cbi PORTA,cdin sbi PORTA,cclk cbi PORTA,cclk dec tmp2 brne write_sub_loop ret eeprom_write: ldi tmp2,0 ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) eeprom_write_loop: sbic EECR,EEWE rjmp PC-1 out EEAR,tmp2 ld tmp,Y+ out EEDR,tmp sbi EECR,EEMWE sbi EECR,EEWE rcall wait_1ms inc tmp2 cpi tmp2,8 brne eeprom_write_loop ret eeprom_read: ldi tmp2,0 ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) eeprom_read_loop: sbic EECR,EEWE rjmp PC-1 out EEAR,tmp2 sbi EECR,EERE in tmp,EEDR st Y+,tmp rcall wait_1ms inc tmp2 cpi tmp2,8 brne eeprom_read_loop ldi YH,high(ch_status_table) ldi YL,low(ch_status_table) ld tmp,Y cpi tmp,0xff breq PC+2 ret ldi tmp,0b01000000 st Y+,tmp st Y+,tmp st Y+,tmp st Y+,tmp st Y+,tmp st Y+,tmp st Y+,tmp st Y+,tmp rcall eeprom_write ret check_btn: ldi tmp,0b00100001 ; REFS1=0,REFS0=0(AVCC),ADLAR=1(left adjust),convert=ADC1 out ADMUX,tmp sbi ADCSR,ADSC sbic ADCSR,ADSC rjmp PC-1 in tmp2,ADCH ldi tmp,0 cpi tmp2,0x90 brlo PC+2 ret ldi tmp,1 cpi tmp2,0x60 brlo PC+2 ret ldi tmp,2 ret check_ch: ldi tmp,0b00100000 ; REFS1=0,REFS0=0(AVCC),ADLAR=1(left adjust),convert=ADC0 out ADMUX,tmp sbi ADCSR,ADSC sbic ADCSR,ADSC rjmp PC-1 in tmp2,ADCH ldi tmp,0 cpi tmp2,18 brsh PC+2 ret ldi tmp,1 cpi tmp2,54 brsh PC+2 ret ldi tmp,2 cpi tmp2,90 brsh PC+2 ret ldi tmp,3 cpi tmp2,128 brsh PC+2 ret ldi tmp,4 cpi tmp2,164 brsh PC+2 ret ldi tmp,5 cpi tmp2,200 brsh PC+2 ret ldi tmp,6 cpi tmp2,238 brsh PC+2 ret ldi tmp,7 ret put_freq: cpi tmp,freq_32_0 brne put_freq_44_1 LCD_STR(str_freq_32_0) ret put_freq_44_1: cpi tmp,freq_44_1 brne put_freq_48_0 LCD_STR(str_freq_44_1) ret put_freq_48_0: cpi tmp,freq_48_0 brne put_freq_88_2 LCD_STR(str_freq_48_0) ret put_freq_88_2: cpi tmp,freq_88_2 brne put_freq_96_0 LCD_STR(str_freq_88_2) ret put_freq_96_0: cpi tmp,freq_96_0 brne put_freq_no_signal LCD_STR(str_freq_96_0) ret put_freq_no_signal: LCD_STR(str_freq_no_signal) ret str_freq_32_0: .db "32.0kHz ",0 str_freq_44_1: .db "44.1kHz ",0 str_freq_48_0: .db "48.0kHz ",0 str_freq_88_2: .db "88.2kHz ",0 str_freq_96_0: .db "96.0kHz ",0 str_freq_no_signal: .db "NoSignal",0 str_freq_d_c: .db "------- ",0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; LCD (SUNLIKE SC1602BS-B) initialize ; lcd_init: ldi counter,10 rcall wait_1ms dec counter brne PC-2 ldi tmp,0x03 rcall lcd_control_out rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms ldi tmp,0x03 rcall lcd_control_out rcall wait_1ms ldi tmp,0x03 rcall lcd_control_out rcall wait_1ms ldi tmp,0x02 rcall lcd_control_out ldi tmp,0x28 rcall lcd_control ldi tmp,0x0c rcall lcd_control ldi tmp,0x06 rcall lcd_control ldi tmp,0x01 ret ; ; LCD screen clear and move position (0,0) ; lcd_clear: ldi tmp,0x01 rcall lcd_control ret ; ; LCD move position : (0,0)=0x00, (0,1)=0x01, (1,0)=0x40 ; lcd_pos: sbr tmp,0x80 rcall lcd_control ret ; ; LCD put character ; lcd_put: push tmp swap tmp rcall lcd_data_out pop tmp rcall lcd_data_out ret ; ; LCD put number in hex ; lcd_put_hex: ldi tmp2,7 push tmp swap tmp cbr tmp,0xf0 sbr tmp,0x30 cpi tmp,0x3a brcs PC+2 add tmp,tmp2 rcall lcd_put pop tmp cbr tmp,0xf0 sbr tmp,0x30 cpi tmp,0x3a brcs PC+2 add tmp,tmp2 rcall lcd_put ret ; ; LCD put number in decimal ; lcd_put_decimal: mov tmp2,tmp ldi tmp,0 lcd_put_decimal_loop: cpi tmp2,10 brlo lcd_put_decimal_skip subi tmp2,10 inc tmp rjmp lcd_put_decimal_loop lcd_put_decimal_skip: sbr tmp,0x30 rcall lcd_put mov tmp,tmp2 sbr tmp,0x30 rcall lcd_put ret lcd_put_str: ; ldi ZL,LOW(vol_data_2) ; ldi ZH,HIGH(vol_data_2) lsl ZL rol ZH lcd_put_str_loop: lpm tmp,Z cpi tmp,0 brne PC+2 ret rcall lcd_put adiw ZL,1 rjmp lcd_put_str_loop lcd_control: push tmp swap tmp rcall lcd_control_out pop tmp rcall lcd_control_out rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms ret lcd_control_out: cbr tmp,0x10 ;rs sbr tmp,0xe0 ;e out PORTB,tmp rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms cbi PORTB,lcd_e sbi PORTB,lcd_e rcall wait_1ms ret lcd_data_out: sbr tmp,0xf0 ;rs,e out PORTB,tmp rcall wait_1ms cbi PORTB,lcd_e sbi PORTB,lcd_e ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; wait 1 second ; wait_1s: push tmp ldi tmp,250 wait_1s_a: rcall wait_1ms dec tmp brne wait_1s_a ldi tmp,250 wait_1s_b: rcall wait_1ms dec tmp brne wait_1s_b ldi tmp,250 wait_1s_c: rcall wait_1ms dec tmp brne wait_1s_c ldi tmp,250 wait_1s_d: rcall wait_1ms dec tmp brne wait_1s_d pop tmp ret ; ; wait 1 ms ; wait_1ms: push tmp ldi tmp,255 wait_1ms_loop: nop nop dec tmp brne wait_1ms_loop pop tmp ret ; ; wait 10 us ; wait_10us: push tmp ldi tmp,10 nop dec tmp brne PC-2 pop tmp ret ; ; wait 10 ms ; wait_10ms: rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms ret