;MP3 Player kunio.h Ver8.0(CPU:8MHz,VS1011:12.288MHz) H26.8. ;**** includes **** .include "m8adef.inc" ; Load immediate word into the resister pair. ; ldiw Z(X,Y),var .macro ldiw ldi @0L,low(@1) ldi @0H,high(@1) .endm ; Output immediate outi port,var .macro outi ldi r16,@1 out @0,r16 .endm .MACRO cpi16 ;cpi16 ra,rb,0xHHHH ;ra:rb-0xHHHH set flags:N,C,Z push @0 push @1 subi @1,low(@2) sbci @0,high(@2) pop @1 pop @0 .ENDMACRO .MACRO addi16 ;addi16 ra,rb,0xHHHH subi @1,low(-@2) sbci @0,high(-@2) .ENDMACRO ;***************************** ;* レジスタ変数 設定 * ;***************************** .def temp1 = r16 .def temp2 = r17 .def temp3 = r18 .def temp4 = r19 .def mem_h = r13 .def mem_l = r14 .def mem_p0 = r15 ;***************************** ;*  ビット 設定  * ;** PORTB *** .equ mp3_dreq= 0 .equ mp3_cs = 1 .equ sd_cs = 2 ;SS .equ sd_in = 3 ;MOSI .equ sd_out = 4 ;MISO .equ sd_clk = 5 ;SCK .equ mp3_dcs = 6 ;mp3_bsync .equ mp3_reset=7 ;MP3~reset ;** PORTD ** .equ lcd_cs = 0 .equ lcd_rs = 1 .equ scl = 2 .equ sda = 3 .equ lcd_res= 4 ;.equ = 5 ;.equ = 6 ;.equ led = 7 ;** PORTC *** ;.epu play = 0 ;.epu ff = 1 ;.epu rew = 2 ;.epu vol+ = 3 ;.epu vol- = 4 .equ p_hold = 5;power hold .equ v_in = 7;batt volt ;key_in 76543210 .equ key_stop= 0b00011110 .equ key_ff = 0b00011101 .equ key_rew = 0b00011011 .equ key_vp = 0b00010111 .equ key_vm = 0b00001111 .equ key_d_pl= 0b11110000 .equ key_d_mi= 0b11100000 .dseg mode: .BYTE 1 ;0:1time,1:dir repeat,2:1file repeat fattype: .BYTE 1 ;FAT16:1,FAT12:0 datastart: .BYTE 4 ;DATAstart[3:0] dirstart: .BYTE 2 ;DIRstart[1:0] secpcl: .BYTE 1 ;sectorspercluster fatstart: .BYTE 2 ;FATstart[1:0] rdirent: .BYTE 2 ;rootdirentriescount[1:0] spi_arg: .BYTE 5 ;cmd,arg[3:0] read32_arg: .BYTE 4 ;adr[3:0] musiccount: .BYTE 1 ;MP3 file count playmusic: .BYTE 1 ;play music count musicsize: .BYTE 4 ;play file size cluster: .BYTE 2 ;play cluster remainsec: .BYTE 2 ;play remain sector buff: .BYTE 32 ;buff[31:0] secdat: .BYTE 512 ;sectorDATA volume: .BYTE 1 key_in: .BYTE 1 key_input: .BYTE 1 key_c: .BYTE 1 vol_t: .BYTE 1 v_t: .BYTE 2 play_time: .BYTE 2 ;PLAY TIME SAVE id3: .BYTE 128 ;TAG V1 ;led_time: .byte 1 dir_count: .byte 1 ;play dir dir_dat: .byte 30 ;root files H:L + cluster H:L x 14dir play_dat: .byte 20 ;song entry_No x 20 dir_dat_w: .byte 60 ;dir_dat_work dram: .byte 60 ;dsp ram(2nd line) kp_dat: .byte 18 ;kanji patarn .eseg ;EEPROM add rom_pm: .BYTE 1 ;play music rom_cl: .BYTE 2 ;cluster rom_re: .BYTE 2 ;remainsec rom_mu: .BYTE 3 ;musicsize rom_pt: .BYTE 2 ;play_time rom_vo: .BYTE 1 ;volume rom_mo: .BYTE 1 ;mode rom_dc: .BYTE 1 ;dir_count .cseg ;********************* ;* 割込みベクター * ;********************* rjmp start ;各種リセット reti ;RJMP EXT_INT0 ;外部割り込み要求0 reti ;EXT_INT1 ;外部割り込み要求1 reti ;TIM2_COMP ;タイマ/カウンタ2 比較一致 reti ;TIM2_OVF ;タイマ/カウンタ2 オーバーフロー reti ;TIM1_CAPT ;タイマ/カウンタ1 キャプチャ発生 mp3_dreq L→H sleep mood end reti ;TIM1_COMPA ;タイマ/カウンタ1 比較A 一致 reti ;TIM1_COMPB ;タイマ/カウンタ1 比較B 一致 rjmp TIM1_OVF ;タイマ/カウンタ1 オーバーフロー reti ;rjmp TIM0_OVF ;タイマ/カウンタ0 オーバーフロー reti ;SPI_STC ;SPI 転送完了 reti ;USART_RXC ;USART 受信完了 reti ;USART_DRE ;USART 送信バッファ空 reti ;USART_TXC ;USART 送信完了 reti ;ADC_E ;ADC 変換完了 reti ;EE_RDY ;EEPROM 操作可 reti ; ANA_COMP ;アナログ コンパレータ出力遷移 reti ;TWSI ;2 線式シリアル インターフェース状態変化 reti ;SPM_RDY ;SPM 命令操作可 ;********************* ;* メイン プログラム * ;********************* start: ldi temp1,low(RAMEND) out SPL,temp1 ldi temp1,high(RAMEND) out SPH,temp1 ;init Stack Pointer ldi temp1,0b00001111 out PORTB,temp1 ldi temp1,0b11101110 out DDRB,temp1 ldi temp1,0b00011111 out PORTC,temp1 ldi temp1,0b00100000 out DDRC,temp1 ldi temp1,0b01101111 out PORTD,temp1 ldi temp1,0b10011111 out DDRD,temp1 outi osccal,0xd0 ldi temp1,50 rcall wait_ms sbi PORTD,lcd_res outi SPCR,0x50 ;SPI master,CPOL0,CPHA=0,CK=8M/4=2M rcall lcd_int ; ldi temp1,0b00110000 ; out DDRC,temp1 ;tt: ; sbi portc,4 ; nop ; nop ; cbi portc,4 ; rjmp tt start1: sbic PINC,0 rjmp start1 sbi PORTC,p_hold ;power hold ; sbi PORTD,led ;LED ON ADC_int: outi ADMUX,(1< play top main_32: lds temp2,dir_count tst temp2 breq main_4 ;root_dir lds r22,dir_dat tst r22 breq main_5 ldi temp1,0xFF rcall search_dir_mp3 ;n(temp2) dir rjmp main_40 main_4: ldi temp1,20 ;dumy rcall search_mp3 ;sarch temp1 MP3 main_40: tst temp2 breq main_5 ;this_dir no mp3 sts musiccount,temp2 ;music count rcall sort_song lds temp1,playmusic lds temp2,dir_count rcall load_entry tst temp2 brmi main_5 main_41: lds temp1,buff+28 lds temp2,musicsize cp temp1,temp2 brne main_5 lds temp1,buff+29 lds temp2,musicsize+1 cp temp1,temp2 brne main_5 lds temp1,buff+30 lds temp2,musicsize+2 cp temp1,temp2 breq play_00 main_5: ldi temp1,1 ;play top sts playmusic,temp1 clr temp2 sts cluster,temp2 ;cluster int sts cluster+1,temp2 lds temp3,dir_dat+1 tst temp3 breq main_52 ;root mp3 nothing sts dir_count,temp2 ;root_dir -> 0 rcall search_mp3 rjmp main_59 main_52: ;sub No1_dir ldi r22,1 main_53: sts dir_count,r22 ldi temp1,0xff mov temp2,r22 rcall search_dir_mp3 ;sub No1_dir mp3 file count? tst temp2 brne main_59 inc r22 rjmp main_53 main_59: sts musiccount,temp2 ;music count rcall sort_song play_00: ;VOL draw ldi temp1,0xb2 //page address 2 ldi temp2,0x15 //column address 88 ldi temp3,0x08 // 0x58 rcall lcd_ad ldiw z,vol*2 ldi temp2,12 sbi PORTD,lcd_rs pl_v: lpm temp1,z+ rcall spi_out dec temp2 brne pl_v ;batt draw ldi temp1,0xb3 //page address 3 ldi temp2,0x17 //column address 113 ldi temp3,0x01 // 0x71 rcall lcd_ad sbi PORTD,lcd_rs ldi temp1,12 rcall spi_out ldi temp1,63 rcall spi_out ldi temp1,0xb3 //page address 3 ldi temp2,0x17 //column address 122 ldi temp3,0x0a // 0x7a rcall lcd_ad sbi PORTD,lcd_rs ldi temp1,63 rcall spi_out sbi PORTD,lcd_cs ;D T draw ldi temp1,0xb4 //page address 4 ldi temp2,0x11 //column address 21 ldi temp3,0x05 // 0x15 rcall lcd_ad ldiw z,d_t*2 ldi temp2,4 sbi PORTD,lcd_rs d_t_d: lpm temp1,z+ rcall spi_out dec temp2 brne d_t_d ldi temp1,0xb4 //page address 4 ldi temp2,0x13 //column address 51 ldi temp3,0x03 // 0x33 rcall lcd_ad ldi temp2,5 sbi PORTD,lcd_rs d_t_d1: lpm temp1,z+ rcall spi_out dec temp2 brne d_t_d1 sbi PORTD,lcd_cs timer1_int: ; outi TCCR1B,(1< play_No ldi temp1,1 ; < sts playmusic,temp1 lds temp4,mode tst temp4 breq play_0 lds r20,key_input cpi r20,key_ff breq play_0 cpi r20,key_d_pl breq play_0 rjmp play_1 ;mode 1 = dir repeet play_0: ;mode 0 = no repeet lds temp2,dir_count inc temp2 lds temp1,dir_dat ;sub dir count cp temp1,temp2 ; brcc play_01 ;>= next dir rjmp play_02 ;< dir end play_01: sts dir_count,temp2 ldi temp1,0xFF rcall search_dir_mp3 ;sub temp2_dir mp3 file count? tst temp2 ;files? breq play_0 rjmp play_04 play_02: clr temp2 sts dir_count,temp2 lds r20,key_input cpi r20,key_ff breq play_03 cpi r20,key_d_pl breq play_03 rjmp play_stop play_03: clr r20 ;ky_in clr sts key_input,r20 lds temp2,dir_dat+1 tst temp2 breq play_0 ldi temp1,20 ;dumy rcall search_mp3 play_04: sts musiccount,temp2 rcall sort_song play_1: clr r20 ;ky_in clr sts key_input,r20 ; outi TCNT1H,0x80 ;0x8000/(8M/256)=1.05s ; outi TCNT1L,0 ; outi TCCR1B,(1<= ret p_mp3_2: sts musicsize,r12 sts musicsize+1,r13 sts musicsize+2,r14 lds r10,buff+26 ;play start top lds r11,buff+27 ;cluster=r11:10 clr temp3 ;r14:13:12/512=r9:8 (remainsec) mov temp2,r14 ;r14:13:12 mod 512=r7:6(remain byte) mov temp1,r13 lsr temp2 ror temp1 brcc p_mp3_21 ;carry_flag =0 ldi temp3,1 ; =1 p_mp3_21: mov r8,temp1 mov r9,temp2 mov r6,r12 mov r7,temp3 push r9 push r8 lds r3,secpcl rcall tagv1 ldiw x,id3 ld temp1,x+ cpi temp1,'T' brne p_mp3_5n ld temp1,x+ cpi temp1,'A' brne p_mp3_5n ld temp1,x+ cpi temp1,'G' breq p_mp3_6 p_mp3_5n: ldiw x,id3+3 ldiw z,n_t*2 ldi temp2,20 p_mp3_5n1: lpm temp1,z+ st x+,temp1 dec temp2 brne p_mp3_5n1 ldiw x,id3+33 ldi temp2,6 ldi temp1,' ' p_mp3_5n2: st x+,temp1 dec temp2 brne p_mp3_5n2 ldiw x,id3+3 p_mp3_6: ldi temp1,0xb0 //page address 0 ldi temp2,0x10 //column address 0 ldi temp3,0x00 //column address 0 ldi r23,10 rcall lcd_k p_mp3_61: ldiw x,id3+33 ldi temp1,0xb2 //page address 2 ldi temp2,0x10 //column address 0 ldi temp3,0x00 //column address 0 ldi r23,6 rcall lcd_k rcall dt_dsp p_mp3_8: pop r8 pop r9 lds r10,buff+26 lds r11,buff+27 lds temp1,cluster lds temp2,cluster+1 clr temp3 or temp3,temp1 or temp3,temp2 brne p_mp3_29 sts cluster,r10 sts cluster+1,r11 sts remainsec,r8 sts remainsec+1,r9 clr temp1 sts play_time,temp1 sts play_time+1,temp1 rjmp p_mp3_3 p_mp3_29: mov r10,temp1 ;play cont mov r11,temp2 ; lds r8,remainsec lds r9,remainsec+1 p_mp3_3: mov temp1,r10 and temp1,r11 ;r11:10=0xFFFF? cpi temp1,0xFF breq p_mp3_4 tst r11 brne p_mp3_5 ldi temp1,2 cp r10,temp1 brcc p_mp3_5 p_mp3_4: ldi temp2,-2 ret p_mp3_5: lds temp1,mode rcall mode_dsp rcall sec_addr_set rcall mp3_int clr temp1 sts key_c,temp1 sts key_in,temp1 p_mp3_9: ldi temp1,1 clr temp2 sub r8,temp1 sbc r9,temp2 brcc p_mp3_91 rjmp p_mp3_30 p_mp3_91: sts spi_arg+1,r15 sts spi_arg+2,r14 sts spi_arg+3,r13 sts spi_arg+4,r12 rcall secdat_read ldiw y,secdat p_mp3_09: sbic PINB,mp3_dreq rjmp p_mp3_09n rcall Interrupt tst r20 brmi p_mp3_09 p_mp3_092: mov temp2,r20 ret p_mp3_09n: ld temp1,y+ cbi PORTB,mp3_dcs rcall spi_out sbi PORTB,mp3_dcs cpi yL,low(secdat+512) ;+512 brne p_mp3_09 cpi yH,high(secdat+512) brne p_mp3_09 dec r3 breq p_mp3_20 ldi temp1,0x02 clr temp2 add r13,temp1 adc r14,temp2 adc r15,temp2 rjmp p_mp3_9 p_mp3_20: rcall next_cluster ;cluster=r11:10,return=r5:4 mov r10,r4 mov r11,r5 mov temp1,r10 and temp1,r11 ;r11:10=0xFFFF? cpi temp1,0xFF breq p_mp3_201 tst r11 brne p_mp3_22 ldi temp1,2 cp r10,temp1 brcc p_mp3_22 p_mp3_201: ldi temp2,-2 ret p_mp3_22: lds r3,secpcl rcall sec_addr_set rjmp p_mp3_9 p_mp3_30: mov temp1,r6 or temp1,r7 brne p_mp3_31 clr temp2 ret ;remain btye=0 p_mp3_31: sts spi_arg+1,r15 sts spi_arg+2,r14 sts spi_arg+3,r13 sts spi_arg+4,r12 rcall secdat_read ldiw y,secdat add r6,yL adc r7,yH ;r7:r6 end byte set p_mp3_40: sbic PINB,mp3_dreq rjmp p_mp3_40n rcall Interrupt tst r20 brmi p_mp3_40 p_mp3_401: mov temp2,r20 ret p_mp3_40n: ld temp1,y+ cbi PORTB,mp3_dcs rcall spi_out sbi PORTB,mp3_dcs cp yL,r6 cpc yH,r7 brcs p_mp3_40 p_mp3_50: clr temp2 ret ;********************************************** dt_dsp:;dir & track dsp ldi temp1,0xb4 //page address 4 ldi temp2,0x11 //column address 28 ldi temp3,0x0c // 0x1c rcall lcd_ad sbi PORTD,lcd_rs lds temp1,dir_count clr r19 dt1: cpi temp1,10 brmi dt2 subi temp1,10 inc r19 rjmp dt1 dt2: mov r20,temp1 ldiw x,dram ldi temp2,14 tst r19 brne dt3 ldiw z,sp*2 rjmp dt4 dt3: ldiw z,n0*2 mul temp2,r19 add zl,r0 adc zh,r1 dt4: lpm temp1,z+ cpi temp2,8 brcs dt5 rcall spi_out rjmp dt6 dt5: st x+,temp1 dt6: dec temp2 brne dt4 clr temp1 rcall spi_out rcall spi_out st x+,temp1 st x+,temp1 ldiw z,n0*2 ldi temp2,14 mul temp2,r20 add zl,r0 adc zh,r1 dt7: lpm temp1,z+ cpi temp2,8 brcs dt8 rcall spi_out rjmp dt9 dt8: st x+,temp1 dt9: dec temp2 brne dt7 ldi temp1,0xb5 //page address 5 ldi temp2,0x11 //column address 28 ldi temp3,0x0c // 0x1c rcall lcd_ad sbi PORTD,lcd_rs ldiw x,dram ldi temp2,16 dt10: ld temp1,x+ rcall spi_out dec temp2 brne dt10 sbi PORTD,lcd_cs ldi temp1,0xb4 //page address 4 ldi temp2,0x13 //column address 58 ldi temp3,0x0a // 0x3a rcall lcd_ad sbi PORTD,lcd_rs lds temp1,playmusic clr r19 dt21: cpi temp1,10 brmi dt22 subi temp1,10 inc r19 rjmp dt21 dt22: mov r20,temp1 ldiw x,dram ldi temp2,14 tst r19 brne dt23 ldiw z,sp*2 rjmp dt24 dt23: ldiw z,n0*2 mul temp2,r19 add zl,r0 adc zh,r1 dt24: lpm temp1,z+ cpi temp2,8 brcs dt25 rcall spi_out rjmp dt26 dt25: st x+,temp1 dt26: dec temp2 brne dt24 clr temp1 rcall spi_out rcall spi_out st x+,temp1 st x+,temp1 ldiw z,n0*2 ldi temp2,14 mul temp2,r20 add zl,r0 adc zh,r1 dt27: lpm temp1,z+ cpi temp2,8 brcs dt28 rcall spi_out rjmp dt29 dt28: st x+,temp1 dt29: dec temp2 brne dt27 ldi temp1,0xb5 //page address 5 ldi temp2,0x13 //column address 58 ldi temp3,0x0a // 0x3a rcall lcd_ad sbi PORTD,lcd_rs ldiw x,dram ldi temp2,16 dt30: ld temp1,x+ rcall spi_out dec temp2 brne dt30 sbi PORTD,lcd_cs ret ;********************************************** time_dsp: ldi temp1,30 sts vol_t,temp1 ldi temp2,4 rcall mp3_read lds temp1,play_time lds temp2,play_time+1 add temp1,temp4 adc temp2,temp3 min: clr r22 ;10min clr r21 ;1min clr r20 ;10sec clr r19 ;1sec min0: cpi16 temp2,temp1,60 brmi sec0 subi temp1,60 sbci temp2,0 inc r21 rjmp min0 sec0: cpi temp1,10 brmi sec1 subi temp1,10 inc r20 rjmp sec0 sec1: mov r19,temp1 mov temp1,r21 min1: cpi temp1,10 brmi min2 subi temp1,10 inc r22 rjmp min1 min2: mov r21,temp1 ldi temp1,0xb4 //page address 4 ldi temp2,0x14 //column address 78 ldi temp3,0x0e // 0x4e rcall lcd_ad sbi PORTD,lcd_rs ldiw x,dram ldi temp2,14 tst r22 brne min3 ldiw z,sp*2 rjmp min4 min3: ldiw z,n0*2 mul temp2,r22 add zl,r0 adc zh,r1 min4: lpm temp1,z+ cpi temp2,8 brcs min5 rcall spi_out rjmp min6 min5: st x+,temp1 min6: dec temp2 brne min4 clr temp1 rcall spi_out rcall spi_out st x+,temp1 st x+,temp1 ldiw z,n0*2 ldi temp2,14 mul temp2,r21 add zl,r0 adc zh,r1 min7: lpm temp1,z+ cpi temp2,8 brcs min8 rcall spi_out rjmp min9 min8: st x+,temp1 min9: dec temp2 brne min7 ldiw z,co*2 ldi temp2,14 min10: lpm temp1,z+ cpi temp2,8 brcs min11 rcall spi_out rjmp min12 min11: st x+,temp1 min12: dec temp2 brne min10 ldiw z,n0*2 ldi temp2,14 mul temp2,r20 add zl,r0 adc zh,r1 min13: lpm temp1,z+ cpi temp2,8 brcs min14 rcall spi_out rjmp min15 min14: st x+,temp1 min15: dec temp2 brne min13 clr temp1 rcall spi_out rcall spi_out st x+,temp1 st x+,temp1 ldiw z,n0*2 ldi temp2,14 mul temp2,r19 add zl,r0 adc zh,r1 min16: lpm temp1,z+ cpi temp2,8 brcs min17 rcall spi_out rjmp min18 min17: st x+,temp1 min18: dec temp2 brne min16 ldi temp1,0xb5 //page address 5 ldi temp2,0x14 //column address 78 ldi temp3,0x0e // 0x4e rcall lcd_ad sbi PORTD,lcd_rs ldiw x,dram ldi temp2,39 min19: ld temp1,x+ rcall spi_out dec temp2 brne min19 sbi PORTD,lcd_cs ret ;********************************************** vol_dsp: ldi temp1,0xb3 //page address 3 ldi temp2,0x15 //column address 88 ldi temp3,0x08 // 0x58 rcall lcd_ad sbi PORTD,lcd_rs lds temp3,volume ldi temp2,0x8A sub temp2,temp3 swap temp2 andi temp2,0x0F inc temp2 ldi temp3,16 sub temp3,temp2 ldi temp1,0x0F vol_dsp0: rcall spi_out dec temp2 brne vol_dsp0 clr temp1 vol_dsp1: rcall spi_out dec temp3 brne vol_dsp1 sbi PORTD,lcd_cs ret ;********************************************** v_dsp: rcall v_read subi zl,low(300) sbci zh,high(300) ;zh=0 v_s1: subi zl,10 brcs v_s2 inc zh rjmp v_s1 v_s2: ldi temp1,0xb3 //page address 3 ldi temp2,0x17 //column address 115 ldi temp3,0x03 // 0x73 rcall lcd_ad sbi PORTD,lcd_rs ldi temp2,7 v_s3: cp zh,temp2 brcs v_s4 ldi temp1,63 rjmp v_s5 v_s4: ldi temp1,33 v_s5: rcall spi_out dec temp2 brne v_s3 sbi PORTD,lcd_cs ret ;********************************************** mode_dsp: ldiw z,mode_dat*2 lds temp1,mode ldi temp2,12 mul temp1,temp2 add zL,r0 adc zH,r1 ldi temp1,0xb4 //page address 4 ldi temp2,0x10 //column address 2 ldi temp3,0x02 // 02 rcall lcd_ad ldi temp2,12 sbi PORTD,lcd_rs m_d1: lpm temp1,z+ rcall spi_out dec temp2 brne m_d1 sbi PORTD,lcd_cs ret ;********************************************** lcd_ad: cbi PORTD,lcd_cs cbi PORTD,lcd_rs rcall spi_out mov temp1,temp2 //column address rcall spi_out mov temp1,temp3 rcall spi_out ret lcd_k: push temp3 push temp2 push temp1 rcall lcd_ad ldiw y,dram sbi PORTD,lcd_rs t3: ld temp1,x+ rcall moji ldiw z,kp_dat ldi r22,18 t4: ld temp1,z+ cpi r22,7 brmi t5 rcall spi_out rjmp t6 t5: st y+,temp1 t6: dec r22 brne t4 clr temp1 rcall spi_out dec r23 brne t3 t61: pop temp1 //page address +1 inc temp1 pop temp2 //column address pop temp3 //column address rcall lcd_ad subi yl,low(dram) sbci yh,high(dram) mov temp3,yl ldiw y,dram ldi temp4,6 sbi PORTD,lcd_rs t7: ld temp2,y+ mov temp1,temp2 swap temp1 andi temp1,0x0f rcall spi_out mov temp1,temp2 andi temp1,0x0f rcall spi_out dec temp4 brne t8 clr temp1 rcall spi_out ldi temp4,6 t8: dec temp3 brne t7 t99: sbi PORTD,lcd_cs ret ;********************************************** moji: clr mem_h clr mem_l clr mem_p0 mo0: cpi temp1,0x21 brcc mo1 rjmp mo_sp mo1: cpi temp1,0x80 brcs mo_ha cpi temp1,0xA0 brcs mo2 ;全角文字 cpi temp1,0xe0 brcc mo2 ;全角文字 mo_ha: ;半角→全角テーブル読込 0x25D4-0x2753 subi temp1,0x20 clr temp2 lsl temp1 rol temp2 mov mem_l,temp1 mov mem_h,temp2 ldi temp1,0xD4 ldi temp2,0x25 add mem_l,temp1 adc mem_h,temp2 rcall mem_r0 ;2byte ldiw z,kp_dat ld mem_h,z+ ld mem_l,z rjmp mo_en mo2: ld temp2,x+ cpi16 temp1,temp2,0x97b2 brcs mo3 inc mem_p0 inc mem_p0 mo3: mov mem_l,temp2 mov mem_h,temp1 cpi temp1,0x87 brcs mo81 breq mo87 cpi temp1,0x88 breq mo88 cpi temp1,0xa0 brcs mo89 moe0: cpi temp2,0x40 brcs mo_sp ldi temp2,0x40 ldi temp1,0xe0 rcall ad_cal ldi temp2,0x98 ldi temp1,0x6f add mem_l,temp2 adc mem_h,temp1 rjmp mo_en mo81: cpi temp2,0x40 brcs mo_sp cpi16 temp1,temp2,0x83e0 ;半角→全角変換テーブル brcs mo82 ;は読まない cpi16 temp1,temp2,0x83f6 brcs mo_sp mo82: ldi temp2,0x40 ldi temp1,0x81 rcall ad_cal ; mov mem_l,temp2 ; mov mem_h,temp1 rjmp mo_en mo87: cpi temp2,0x40 brcs mo_sp ldi temp2,0x40 sub mem_l,temp2 clr mem_h rcall ad_cal1 ldi temp2,0xcc ldi temp1,0x30 add mem_l,temp2 adc mem_h,temp1 rjmp mo_en mo88: cpi temp2,0x9f brcs mo_sp ldi temp2,0x9F sub mem_l,temp2 clr mem_h rcall ad_cal1 ldi temp2,0x56 ldi temp1,0x37 add mem_l,temp2 adc mem_h,temp1 rjmp mo_en mo89: cpi temp2,0x40 brcs mo_sp ldi temp2,0x40 ldi temp1,0x89 rcall ad_cal ldi temp2,0xf2 ldi temp1,0x3d add mem_l,temp2 adc mem_h,temp1 rjmp mo_en mo_sp: clr mem_p0 mo_en: rcall mem_r ret ad_cal: sub mem_l,temp2 sub mem_h,temp1 ldi temp1,189 mul temp1,mem_h clr mem_h add mem_l,r0 adc mem_h,r1 ad_cal1: mov temp2,mem_l mov temp1,mem_h lsl mem_l rol mem_h ;x2 swap temp1 andi temp1,0xf0 add mem_h,temp1 swap temp2 mov temp1,temp2 andi temp1,0x0f andi temp2,0xf0 add mem_l,temp2 adc mem_h,temp1 ;x2 + x16= x18 ret ;********************************************** start_c: sbi PORTD,scl ; ldi temp1,1;2 rcall wait_1us cbi PORTD,sda ; ldi temp1,1;3 rcall wait_1us ret stop_c: cbi PORTD,scl ; ldi temp1,1;2 rcall wait_1us cbi PORTD,sda ; ldi temp1,1;2 rcall wait_1us sbi PORTD,scl ; ldi temp1,1;5 rcall wait_1us sbi PORTD,sda ret send_dat_re: ;re_start ser r21 rjmp s_d0 send_dat: clr r21 s_d0: ldi temp4,8 s_d1: cbi PORTD,scl ; ldi temp1,1 ; rcall wait_1us lsl temp3 brcs s_d2 cbi PORTD,sda rjmp s_d3 s_d2: sbi PORTD,sda s_d3: ; ldi temp1,1 ; rcall wait_1us nop nop sbi PORTD,scl ; ldi temp1,1;4 ; rcall wait_1us dec temp4 brne s_d1 s_d4: cbi PORTD,scl nop cbi DDRD,sda ;input ; ldi temp1,1;3 ; rcall wait_1us tst r21 brne s_d5 cbi PORTD,sda rjmp s_d6 s_d5: sbi PORTD,scl ; ldi temp1,1;4 ; rcall wait_1us nop nop cbi PORTD,scl sbi PORTD,sda sbi DDRD,sda ;output ; ldi temp1,1;3 ; rcall wait_1us ret s_d6: sbi DDRD,sda ;output sbi PORTD,scl ; ldi temp1,1;3 ; rcall wait_1us ret read_last_dat: ser r21 read_dat: ldi temp4,8 clr temp3 r_d1: cbi PORTD,scl ; ldi temp1,1;4 ; rcall wait_1us nop cbi DDRD,sda ;input sbi PORTD,scl ; ldi temp1,1;2 ; rcall wait_1us clc sbic PIND,sda sec rol temp3 ; ldi temp1,1 ; rcall wait_1us dec temp4 brne r_d1 cbi PORTD,scl ; ldi temp1,1 ; rcall wait_1us cbi PORTD,sda ;ACK sbi DDRD,sda ;output tst r21 breq r_d2 sbi PORTD,sda ;last data >> NACK send r_d2: ; ldi temp1,1;2 ; rcall wait_1us nop sbi PORTD,scl ; ldi temp1,1;3 ; rcall wait_1us ret mem_r0: ldi r20,2-1 rjmp mem_r1 mem_r: ldi r20,18-1 mem_r1: clr r21 ldiw z,kp_dat rcall mem_w mov temp3,mem_h rcall send_dat mov temp3,mem_l rcall send_dat_re rcall start_c ;re_start ldi temp3,0b10100001 ;SLA_R or temp3,mem_p0 rcall send_dat mem_r2: rcall read_dat st z+,temp3 dec r20 brne mem_r2 rcall read_last_dat ;last data read,NACK send st z+,temp3 rcall stop_c ret mem_w: rcall start_c ldi temp3,0b10100000 ;SLA_W or temp3,mem_p0 rcall send_dat ret ;********************************************** lcd_int: cbi PORTD,lcd_cs cbi PORTD,lcd_rs ldi temp1,0xe2 //Internal reset rcall spi_out ldi temp1,1 rcall wait_ms ldi temp1,0xae //display off rcall spi_out ldi temp1,0xAE //Display = OFF rcall spi_out ldi temp1,0xA0 //ADC = normal rcall spi_out ldi temp1,0xC8 //Common output = revers rcall spi_out ldi temp1,0xA3 //bias = 1/7 rcall spi_out //--内部レギュレータを順番にONする--// ldi temp1,0x2C //power control 1 rcall spi_out ldi temp1,2 rcall wait_ms ldi temp1,0x2E //power control 2 rcall spi_out ldi temp1,2 rcall wait_ms ldi temp1,0x2F //power control 3 rcall spi_out //--コントラスト設定--// ldi temp1,0x23 //Vo voltage resistor ratio set rcall spi_out ldi temp1,0x81 //Electronic volume mode set rcall spi_out ldi temp1,0x1C //Electronic volume value set rcall spi_out //--表示設定--// ldi temp1,0xA4 //display all point = normal(全点灯しない) rcall spi_out ldi temp1,0x40 //display start line = 0 rcall spi_out ldi temp1,0xA6 //Display normal/revers = normal(白黒反転しない) rcall spi_out ldi temp1,0xAF //Display = ON rcall spi_out //Display clear ldi temp2,0xb7//page address 7 dc0: mov temp1,temp2 cbi PORTD,lcd_rs rcall spi_out ldi temp1,0x10 //column address 0 rcall spi_out ldi temp1,0x00 //column address 0 rcall spi_out ldi temp3,128 sbi PORTD,lcd_rs clr temp1 dc1: rcall spi_out dec temp3 brne dc1 dec temp2 cpi temp2,0xb0 brpl dc0 sbi PORTD,lcd_cs ret ;********************************************** Interrupt: ;割り込み処理  cli outi TCCR1B,0 lds zL,v_t lds zH,v_t+1 sbiw zL,1 breq inter95 inter94: sts v_t,zL sts v_t+1,zH rjmp inter96 inter95: ldi temp1,0 sts v_t,temp1 ldi temp1,10 sts v_t+1,temp1 rcall v_read cpi16 zH,zL,305 brcc inter96 ldi temp1,1 rcall wait_ms rcall v_read cpi16 zH,zL,305 brcc inter96 ldi temp1,10 mov r0,temp1 clr r1 rcall beep ;low 10times ldi temp1,key_stop sts key_input,temp1 rjmp inter_stop ;shut down mode inter96: lds temp1,vol_t tst temp1 breq inter961 dec temp1 sts vol_t,temp1 cpi temp1,15 breq inter962 rjmp inter97 inter961: rcall time_dsp rjmp inter97 inter962: rcall v_dsp inter97: in temp4,PINC andi temp4,0b00011111 cpi temp4,0b00011111 ;key_CK breq inter98 lds temp1,key_in cp temp1,temp4 breq inter0 inter98: sts key_in,temp4 clr temp1 sts key_c,temp1 rjmp inter99 inter0: lds temp4,key_c inc temp4 cpi temp4,7 breq inter01 sts key_c,temp4 rjmp inter99 inter01: sts key_input,temp1 clr temp4 sts key_in,temp4 sts key_c,temp4 cpi temp1,key_vp brne inter1 lds temp3,volume subi temp3,4 cpi temp3,0x12 brcc inter_vol ldi temp3,0x12 rjmp inter_vol inter1: cpi temp1,key_vm brne inter2 lds temp3,volume subi temp3,-4 cpi temp3,0x8A brcs inter_vol ldi temp3,0x8A rjmp inter_vol inter2: cpi temp1,key_ff brne inter3 ldi temp1,250 rcall wait_ms in temp4,PINC andi temp4,0b00011111;key_CK cpi temp4,key_ff brne inter21 ldi temp1,key_d_pl sts key_input,temp1 inter21: ldi r20,1 rjmp inter_end inter3: cpi temp1,key_rew brne inter4 ldi temp1,250 rcall wait_ms in temp4,PINC andi temp4,0b00011111;key_CK cpi temp4,key_rew brne inter31 ldi temp1,key_d_mi sts key_input,temp1 inter31: ldi r20,2 rjmp inter_end inter_vol: sts volume,temp3 ldi temp2,11 mov temp4,temp3 rcall mp3_cmd rcall vol_dsp inter99: outi TIMSK,1<= 128バイト? cp r6,temp1 brpl tagv1_z ;r6=>128  128バイト以上 tst r7 ;r7<1 ? brne tagv1_z ;r6<128 & r7<1 no ldi r21,1 ;Tagがセクタをまたぐ:フラグ設定 tagv1_z: tst r9 ;last-1 cluster & mod sec=1? brne tagv1_a ;r25 !=0 ,no tst r21 ;Tagがセクタをまたぐ? breq tagv1_a ;no cp r8,r20 breq tagv1_a0 ;クラスタをまたぎ&remain<128byte tagv1_a: rcall next_cluster ;cluster=r11:10,nextcluster=r5:4 clr temp1 sub r8,r3 sbc r9,temp1 ;last cluster brcs tagv1_a1 ;secpcl <= rimain breq tagv1_a1 mov r11,r5 mov r10,r4 rjmp tagv1_z tagv1_a1: ;クラスタをまたがない add r8,r3 ;端数セクタが0ならr8=secpcl mov r24,r8 ;remainsec tst r21 ;remain >= 128byte? brne tagv1_a2 ;no <128 mov r22,r6 ;yes read start addr set mov r23,r7 ;remain-128 から読む subi r22,128 sbci r23,0 rcall tagv1_b ret tagv1_a0: ;クラスタ(セクタ)をまたぐ mov r24,r3 ;(最終-1)クラスタの最終セクタ ポインタ(secpcl-1) ldi r22,low(384) ldi r23,high(384) ;read start addr set add r22,r6 ;512-(128-remain)=384+remain adc r23,r7 rcall tagv1_b ;(最終-1)セクタを384+remainバイトから読む push xH push xL rjmp tagv1_1 ;残りを最終クラスタのセクタ(最終セクタ)のはじめから読む tagv1_a2: ;セクタをまたぐ dec r24 ldi r22,low(384) ldi r23,high(384) ;read start addr set add r22,r6 ;512-(128-remain)=384+remain adc r23,r7 rcall tagv1_b ;(最終-2)セクタを384+remainバイトから読む push xH push xL ldi temp1,0x02 ;lastsec addr set clr temp2 add r13,temp1 ;addr+512 adc r14,temp2 adc r15,temp2 rjmp tagv1_1a ;残りを最終セクタのはじめから読む tagv1_b: ; cluster read rcall sec_addr_set ;r15:14:13:12 ldi temp1,0x02 dec r24 mul temp1,r24 clr temp1 add r13,r0 adc r14,r1 ;last or last-1 sector adc r15,temp1 ;addset ;r12=0 sts spi_arg+1,r15 sts spi_arg+2,r14 sts spi_arg+3,r13 sts spi_arg+4,r12 rcall spi_read_open ldiw y,0 ldiw x,id3 ldi temp3,low(id3+128) ldi temp4,high(id3+128) tagv1_01: rcall spi_in cp yL,r22 cpc yH,r23 brcs tagv1_02 ;remain-128 から cp xL,temp3 ; cpc xH,temp4 ;128byte読む brpl tagv1_02 st x+,temp2 tagv1_02: adiw yL,1 cpi yH,0x02 brne tagv1_01 rcall spi_read_close ret tagv1_1: rcall next_cluster mov r11,r5 mov r10,r4 rcall sec_addr_set ;r15:14:13:12 tagv1_1a: sts spi_arg+1,r15 sts spi_arg+2,r14 sts spi_arg+3,r13 sts spi_arg+4,r12 rcall spi_read_open ldiw y,0 pop xL pop xH ldi temp3,low(id3+128) ldi temp4,high(id3+128) tagv1_10: rcall spi_in cp xL,temp3 cpc xH,temp4 brpl tagv1_11 st x+,temp2 tagv1_11: adiw yL,1 cpi yH,0x02 brne tagv1_10 rcall spi_read_close ret ;********************************************** v_read: sbi ADCSR,ADEN ;adc on sbi ADCSR,ADIF ;Reset interrupt flag sbi ADCSR,ADSC ;Start A/D conversion v_read1: sbis ADCSR,ADIF rjmp v_read1 in zL,ADCL ; in zH,ADCH ; cbi ADCSR,ADEN ;adc off lsr zH ;V/2:256=X:1024 ror zL ;V=X/2 (uint0.01V) ret ;********************************************** mp3_hard_int: sbi PORTB,mp3_reset ;set H mp3_hard_int0: ldi temp1,15 rcall wait_ms sbi PORTB,mp3_dcs ;mp3_bsync daly 10ms+ from XRESET mp3_hard_int1: sbis PINB,mp3_dreq rjmp mp3_hard_int1 ret ;********************************************** mp3_int: ;soft reset clr temp4 ;'0' 2048byte(8x256) send to SDI mp3_int0: ldiw z,mp3_0*2 rcall mp3_sin inc temp4 brne mp3_int0 ldi temp2,0 ldi temp3,0x08 ;SM_SDINEW bit set VS1002 native SPI modes ldi temp4,0x04 ;reset bit set rcall mp3_cmd ;0,0x0804 ;cmd=temp2,arg[H:L]=temp3:temp4 mp3_int1: sbis PINB,mp3_dreq rjmp mp3_int1 ldi temp2,3 ldi temp3,0x98 ldi temp4,0x00 ;0x8000+12288000/2000 rcall mp3_cmd ;3,0x9800 ldi temp2,11 lds temp3,volume mov temp4,temp3 rcall mp3_cmd ;11,left/right ret ;********************************************** mp3_cmd: ;com=temp2,arg=temp3:4 cbi PORTB,mp3_cs ldi temp1,2 rcall spi_out mov temp1,temp2 rcall spi_out mov temp1,temp3 rcall spi_out mov temp1,temp4 rcall spi_out sbi PORTB,mp3_cs ldi temp1,10 rcall wait_us ret ;********************************************** mp3_read: ;com=temp2,data=temp3:4 cbi PORTB,mp3_cs ldi temp1,3 rcall spi_out mov temp1,temp2 rcall spi_out rcall spi_in mov temp3,temp2 rcall spi_in mov temp4,temp2 sbi PORTB,mp3_cs ldi temp1,10 rcall wait_us ret ;********************************************** mp3_sin: ;data_addr Z ldi r21,8 mp3_sin_0: sbis PINB,mp3_dreq rjmp mp3_sin_0 cbi PORTB,mp3_dcs lpm temp1,z+ rcall spi_out sbi PORTB,mp3_dcs dec r21 brne mp3_sin_0 ret ;********************************************** beep: ;times:r0,High/Low:r1(=1/0) rcall mp3_int ldi temp2,0 ldi temp3,0x08 ;SM_SDINEW bit set ldi temp4,0x20 ;SDI test set rcall mp3_cmd ldi temp1,100 ;wait rcall wait_ms beep_0: tst r1 breq beep_1 ldiw z,beep_H*2 rjmp beep_2 beep_1: ldiw z,beep_L*2 beep_2: rcall mp3_sin ldi temp1,100 ;音の長さ rcall wait_ms ldiw z,beep_s*2 rcall mp3_sin ldi temp1,30 ;無音の長さ rcall wait_ms dec r0 brne beep_0 rcall mp3_int ret ;********************************************** sec_addr_set: clr r12 lds r13,datastart lds r14,datastart+1 lds r15,datastart+2 mov temp1,r10 mov temp2,r11 subi temp1,2 sbci temp2,0 clr temp3 mul temp1,r3 add r13,r0 adc r14,r1 adc r15,temp3 mul temp2,r3 add r14,r0 adc r15,r1 lsl r13 rol r14 rol r15 ret ;********************************************** next_cluster: ;cluster=r11:10 FAT16 clr temp1 ;fatstart*512 -> lds temp2,fatstart ;temp4:3:2:1 lds temp3,fatstart+1 clr temp4 lsl temp2 rol temp3 rol temp4 mov r12,r10 mov r13,r11 clr r14 ;cluster*2 lsl r12 rol r13 rol r14 clr r15 add temp1,r12 adc temp2,r13 adc temp3,r14 adc temp4,r15 ;addr=temp4:3:2:1 ldiw z,0x01FF and zL,temp1 and zH,temp2 ;addr&511 -> Z clr temp1 andi temp2,0xFE sts spi_arg+1,temp4 sts spi_arg+2,temp3 sts spi_arg+3,temp2 sts spi_arg+4,temp1 rcall spi_read_open ;addr=spi_arg[4:1] tst temp2 breq n_c_1 rcall spi_read_close clr r4 clr r5 ret n_c_1: ldiw x,0 n_c_2: rcall spi_in cp xL,zL cpc xH,zH breq n_c_3 rcall spi_in adiw xL,2 rjmp n_c_2 n_c_3: mov temp3,temp2 rcall spi_in mov temp4,temp2 cpi temp4,0xff brne n_c_4 cpi temp3,0xf7 brcs n_c_4 ldi temp4,0xff ldi temp3,0xff n_c_4: mov r4,temp3 mov r5,temp4 n_c_5: adiw xL,2 cpi xH,0x02 breq n_c_6 rcall spi_in rcall spi_in rjmp n_c_5 n_c_6: rcall spi_read_close ret ;********************************************** secdat_read: ;512byte read -> secdat[511:0] rcall spi_read_open tst temp2 breq s_d_r0 ret s_d_r0: ldiw y,secdat s_d_r1: rcall spi_in st y+,temp2 cpi yL,low(secdat+512) ;512? brne s_d_r1 cpi yH,high(secdat+512) brne s_d_r1 rcall spi_read_close ret ;********************************************** sort_dir: ldiw x,dir_dat+2 ;dir_dat[2:29]=0 clr temp1 sort_dir_0: st x+,temp1 cpi xL,low(dir_dat+30) brne sort_dir_0 cpi xH,high(dir_dat+30) brne sort_dir_0 ldiw z,dir_dat_w lds r20,dir_dat sort_dir_1: lds r22,dir_dat clr r21 ldd temp1,z+2 ldd temp2,z+3 ldiw y,dir_dat_w sort_dir_2: ldd temp3,y+2 ldd temp4,y+3 cp temp4,temp2 cpc temp3,temp1 brcc sort_dir_3 ;fname(n) >= fname(x) inc r21 ; < sort_dir_3: dec r22 breq sort_dir_4 adiw yL,4 rjmp sort_dir_2 sort_dir_4: ldiw x,dir_dat+2 lsl r21 clr temp1 add xL,r21 adc xH,temp1 sort_dir_5: ld temp1,x+ ld temp2,x+ or temp1,temp2 ;temp1:2=0 ? brne sort_dir_5 sbiw xL,2 ld temp1,z ldd temp2,z+1 st x+,temp1 st x,temp2 dec r20 breq sort_dir_e adiw zL,4 rjmp sort_dir_1 sort_dir_e: ret ;********************************************** sort_song: ;r21 song count ldiw x,play_dat ;play_dat[0:19]=0 ldi temp1,0xFF sort_song_0: st x+,temp1 cpi xL,low(play_dat+20) brne sort_song_0 cpi xH,high(play_dat+20) brne sort_song_0 ldiw z,dir_dat_w mov r20,r21 sort_song_1: mov r22,r21 clr r23 ldd temp1,z+1 ldd temp2,z+2 ldiw y,dir_dat_w sort_song_2: ldd temp3,y+1 ldd temp4,y+2 cp temp4,temp2 cpc temp3,temp1 brcc sort_song_3 ;fname(n) >= fname(x) inc r23 ; < sort_song_3: dec r22 breq sort_song_4 adiw yL,3 rjmp sort_song_2 sort_song_4: ldiw x,play_dat clr temp1 add xL,r23 adc xH,temp1 sort_song_5: ld temp1,x+ cpi temp1,0xFF brne sort_song_5 ld temp1,z st -x,temp1 dec r20 breq sort_song_e adiw zL,3 rjmp sort_song_1 sort_song_e: ret ;********************************************** load_entry: ;temp1:playmusic,temp2:dir_count cpi temp1,21 brcc load_entry3 tst temp1 breq load_entry3 lds temp3,dir_dat cp temp3,temp2 brcc load_entry5 load_entry3: ldi temp2,-1 ret load_entry5: dec temp1 clr temp3 ldiw x,play_dat add xL,temp1 adc xH,temp3 ld temp3,x ;entry_No clr r22 ; x 32 -> lsl temp3 ; r22:temp3 rol r22 swap temp3 mov temp1,temp3 andi temp1,0x0F swap r22 or r22,temp1 andi temp3,0xF0 mov r20,temp3 ldi r21,0x01 and r21,r22 ;addr(0-511) -> r21:r20 andi r22,0xFE tst temp2 breq load_entry_20 ;root_dir load_entry_10: lsl temp2 clr temp1 ldiw z,dir_dat add zl,temp2 adc zH,temp1 ld r10,z+ ;cluster_No L ld r11,z ;cluster_No H mov temp1,r10 and temp1,r11 cpi temp1,0xFF breq load_entry_1a mov temp1,r10 or temp1,r11 brne load_entry_11 load_entry_1a: ldi temp2,-1 ret load_entry_11: lds r3,secpcl lsl r3 ;high(secpcl*512) -> 2 x secpcl mov r23,r22 load_entry_12: sub r23,r3 brcs load_entry_18 rcall next_cluster mov r10,r4 mov r11,r5 rjmp load_entry_12 load_entry_18: lds r3,secpcl rcall sec_addr_set rjmp load_entry_21 load_entry_20: clr r12 lds r13,dirstart ;dirstart[1:0]*512 lds r14,dirstart+1 ; -> r15:14:13:12 clr r15 lsl r13 rol r14 rol r15 load_entry_21: add r13,r22 ;+sector addr adc r14,r12 adc r15,r12 sts spi_arg+1,r15 sts spi_arg+2,r14 sts spi_arg+3,r13 sts spi_arg+4,r12 rcall secdat_read ldiw y,secdat add yL,r20 adc yH,r21 ldiw x,buff load_entry_e: ;entry dat -> buff[0:31] ld temp1,y+ st x+,temp1 cpi xL,low(buff+32) brne load_entry_e cpi xH,high(buff+32) brne load_entry_e clr temp2 ret ;********************************************** ;root MP3&sub_dir search temp1 file number ;temp2 found MP3 files ;max entry:256,sub_dir:14,mp3_file:20 search_mp3: mov r20,temp1 clr r21 ;return MP3_count clr r22 ;dir count clr r12 ;dirstart[1:0]*512 lds r13,dirstart ; -> r15:14:13:12 lds r14,dirstart+1 clr r15 lsl r13 rol r14 rol r15 sts spi_arg+1,r15 sts spi_arg+2,r14 sts spi_arg+3,r13 sts spi_arg+4,r12 clr r23 search_mp3_1: rcall secdat_read ldiw y,secdat search_mp3_3: ld temp1,y tst temp1 ;entry[0]=0? brne search_mp3_30 ;no rjmp search_mp3_e ;yes entry end search_mp3_30: cpi temp1,0xE5 ;deleted file? breq search_mp3_4 ;yes next entry ldd temp1,y+26 ldd temp2,y+27 or temp1,temp2 ;entry[26]=0 & entry[27]=0 breq search_mp3_4 ;yes next entry ldd temp1,y+11 ldi temp2,0x10 and temp2,temp1 ;entry[11] 4bit=1 breq search_mp3_31 ;dir entry? no cpi r20,0xFF ; brne search_mp3_4 ;dir dat no set inc r22 ; ldiw x,dir_dat_w clr temp1 mov temp2,r22 dec temp2 lsl temp2 lsl temp2 ;4(n-1) add xL,temp2 adc xH,temp1 ;X=dir_dat_w[4(n-1)] ldd temp1,y+26 ;cluster_No L -> st x+,temp1 ;dir_dat_w[4(n-1)] ldd temp1,y+27 ;cluster_No H -> st x+,temp1 ;dir_dat_w[4(n-1)+1] ld temp1,y ;file name[0] -> st x+,temp1 ;dir_dat_w[4(n-1)+2] ldd temp1,y+1 ;file name[1] -> st x,temp1 ;dir_dat_w[4(n-1)+3] cpi r22,14 ;max 14dirs brne search_mp3_4 rjmp search_mp3_e search_mp3_31: andi temp1,0x20 ;entry[11] 5bit=1 breq search_mp3_4 ;Volume or LFN_extension..etc yes next entry ldd temp1,y+8 ;file entry cpi temp1,'M' brne search_mp3_4 ;entry[8]="M" not next entry ldd temp1,y+9 cpi temp1,'P' brne search_mp3_4 ;entry[9]="P" not next entry ldd temp1,y+10 cpi temp1,'3' brne search_mp3_4 ;entry[10]="3" not next entry inc r21 ;MP3_file found,MP3_count++ cpi r20,0xFF breq search_mp3_39 ldiw x,dir_dat_w ldi temp1,3 mov temp2,r21 dec temp2 mul temp1,temp2 ;3(n-1) add xL,r0 adc xH,r1 ;X=dir_dat_w[3(n-1)] st x+,r23 ;entry_No ld temp1,y st x+,temp1 ;name[0] ldd temp1,y+1 st x,temp1 ;name[1] search_mp3_39: cpi r21,20 ;max 20files breq search_mp3_e search_mp3_4: inc r23 breq search_mp3_e ;entry =256 adiw yL,32 ;entry addr+32 cpi yL,low(secdat+512) ;512? breq search_mp3_5 rjmp search_mp3_3 search_mp3_5: cpi yH,high(secdat+512) breq search_mp3_6 rjmp search_mp3_3 ;sector end? not next entry search_mp3_6: ldi temp1,0x02 ;r15:14:13:12+=512 clr temp2 ;next sector addr set add r13,temp1 adc r14,temp2 adc r15,temp2 sts spi_arg+1,r15 sts spi_arg+2,r14 sts spi_arg+3,r13 rjmp search_mp3_1 search_mp3_e: cpi r20,0xFF brne search_mp3_e0 ldiw x,dir_dat st x+,r22 ;dir_dat[0]=sub dir count st x,r21 ;dir_dat[1]=root dir files search_mp3_e0: mov temp1,r20 mov temp2,r21 ret ;********************************************** ;MP3 dir search temp1 file num,temp2 dir number ;temp2 found MP3 files search_dir_mp3: mov r20,temp1 clr r23 clr r21 ;return MP3_count lsl temp2 ldiw z,dir_dat add zl,temp2 adc zH,r21 ld r10,z+ ;cluster_No L ld r11,z ;cluster_No H ldi temp1,0xFF and temp1,r11 and temp1,r10 cpi temp1,0xFF brne search_dir_mp3_1 ret search_dir_mp3_1: lds r3,secpcl rcall sec_addr_set search_dir_mp3_11: sts spi_arg+1,r15 sts spi_arg+2,r14 sts spi_arg+3,r13 sts spi_arg+4,r12 rcall secdat_read ldiw y,secdat search_dir_mp3_3: ld temp1,y tst temp1 ;entry[0]=0? breq search_dir_mp3_e ;yes entry end cpi temp1,0xE5 ;deleted file? breq search_dir_mp3_4 ;yes next entry ldd temp1,y+26 ldd temp2,y+27 or temp1,temp2 ;entry[26]=0 & entry[27]=0 breq search_dir_mp3_4 ;yes next entry ldd temp1,y+11 ; cpi temp1,0x10 ;entry[11]=0x10 ; breq search_dir_mp3_4 ;dir entry andi temp1,0x20 ;entry[11] 5bit=1 breq search_dir_mp3_4 ;LFN_extension..etc yes next entry ldd temp1,y+8 ;file entry cpi temp1,'M' brne search_dir_mp3_4 ;entry[8]="M" not next entry ldd temp1,y+9 cpi temp1,'P' brne search_dir_mp3_4 ;entry[9]="P" not next entry ldd temp1,y+10 cpi temp1,'3' brne search_dir_mp3_4 ;entry[10]="3" not next entry inc r21 ;MP3_file found MP3_count++ cp r20,r21 breq search_dir_mp3_e ldiw x,dir_dat_w ldi temp1,3 mov temp2,r21 dec temp2 mul temp1,temp2 ;3(n-1) add xL,r0 adc xH,r1 ;X=dir_dat_w[3(n-1)] st x+,r23 ;entry_No ld temp1,y st x+,temp1 ;name[0] ldd temp1,y+1 st x,temp1 ;name[1] cpi r21,20 breq search_dir_mp3_e search_dir_mp3_4: inc r23 breq search_dir_mp3_e ;entry_No =256 adiw yL,32 ;entry addr+32 cpi yL,low(secdat+512) ;512? brne search_dir_mp3_3 cpi yH,high(secdat+512) brne search_dir_mp3_3 ;sector end? not next entry dec r3 breq search_dir_mp3_5 ;cluster end ldi temp1,0x02 ;r15:14:13:12+=512 clr temp2 ;next sector addr set add r13,temp1 adc r14,temp2 adc r15,temp2 rjmp search_dir_mp3_11 search_dir_mp3_5: rcall next_cluster and temp3,temp4 ;=r4&r5 cpi temp3,0xFF ;next_cluster nothing breq search_dir_mp3_e mov r10,r4 mov r11,r5 rjmp search_dir_mp3_1 search_dir_mp3_e: mov temp1,r20 mov temp2,r21 ret ;********************************************** ;Vfat read sector=512 read_vfat: ldi temp1,BYTE4(446) sts read32_arg,temp1 ldi temp1,BYTE3(446) sts read32_arg+1,temp1 ldi temp1,BYTE2(446) sts read32_arg+2,temp1 ldi temp1,low(446) sts read32_arg+3,temp1 rcall read_32 ;(446) lds r2,buff+8 ;buff[9:8]-->r3:r2=bpb lds r3,buff+9 ;bpb top sec read clr temp1 mov temp2,r2 mov temp3,r3 clr temp4 lsl temp2 rol temp3 rol temp4 ;temp4:3:2:1 <= x 512(9bit left_shift) sts read32_arg,temp4 sts read32_arg+1,temp3 sts read32_arg+2,temp2 sts read32_arg+3,temp1 rcall read_32 ;(temp4:3:2:1) lds temp1,buff+11 ;buff[12:11]-->r11:10=sec_log lds temp2,buff+12 cpi16 temp2,temp1,0x0200 breq read_vfat1 ldi temp2,2 ;1sec not 512bytes ret read_vfat1: lds temp1,buff+13 sts secpcl,temp1 ;buff[13]->secpcl lds temp1,buff+14 lds temp2,buff+15 add temp1,r2 adc temp2,r3 sts fatstart,temp1 sts fatstart+1,temp2 ;buff[15:14]+bpb -> fatstart[1:0] lds temp1,buff+17 lds temp2,buff+18 sts rdirent,temp1 sts rdirent+1,temp2 ;buff[18:17] -> rdirent[1:0] lds r10,buff+22 lds r11,buff+23 ;buff[23:22] -> r11:10=fat_sectors tst r10 brne read_vfat2 tst r11 brne read_vfat2 ldi temp2,1 ;not FAT16/12(FAT32?) ret read_vfat2: lds temp3,buff+16 ;buff[16] mul r10,temp3 ;buff[16]*fat_sectors_L -> r1:r0 mov temp2,r1 ; mov temp1,r0 ;r1:r0 -> temp2:temp1 mul r11,temp3 ;buff[16]*fat_sectors_H -> r1:r0 (r1=0) add temp2,r0 ;temp2:temp1 +=r0:0x00 (fat_sectors*buff[16]) lds temp3,fatstart lds temp4,fatstart+1 ;temp4:temp3 <- fatstart[1:0] add temp1,temp3 adc temp2,temp4 ;temp2:temp1= fat_sectors*buff[16]+ fatstart[1:0] sts dirstart,temp1 sts dirstart+1,temp2 ;temp2:temp1 -> dirstart[1:0] lds temp1,rdirent lds temp2,rdirent+1 ;temp2:temp1/16 -> temp2:temp1...temp4 swap temp2 ;H2:H1 -> H1:H2 mov temp3,temp2 andi temp3,0xF0 ;H1:0 H1 save andi temp2,0x0F ;0:H2 ldi temp4,0x0F and temp4,temp1 ;L1 save (temp2:temp1 MOD 16) swap temp1 ;L2:L1 -> L1:L2 andi temp1,0x0F ;0:L2 or temp1,temp3 ;H1:L2 (n=temp2:temp1=0:H2:H1:L2) tst temp4 breq read_vfat3 addi16 temp2,temp1,1 read_vfat3: lds temp3,dirstart lds temp4,dirstart+1 clr r0 clr r1 add temp3,temp1 adc temp4,temp2 adc r0,r1 ;n+dirstart[1:0] -> r1:r0:temp4:temp3 sts datastart,temp3 ;datastart[3:0] <- r1:r0:temp4:temp3 sts datastart+1,temp4 sts datastart+2,r0 sts datastart+3,r1 lds temp1,buff+19 lds temp2,buff+20 ;all_sectors= buff[20:19] clr temp3 ;all_sectors=temp4:3:2:1 =0:0:XX:XX clr temp4 ; (16bytes long) clr r15 or r15,temp2 or r15,temp1 ;r15 <- r15|temp2|temp1 brne read_vfat4 ;(temp2:temp1=0)? not next ldi temp1,32 ;yes bpb=r3:r2 clr r15 ;arg <- 32+bpb*512 (9bit left_shift) lsl r2 rol r3 rol r15 sts read32_arg,r15 sts read32_arg+1,r3 sts read32_arg+2,r2 sts read32_arg+3,temp1 rcall read_32 ;(32+bpb*512) lds temp1,buff lds temp2,buff+1 lds temp3,buff+2 lds temp4,buff+3 ;all_sectors=temp4:3:2:1 read_vfat4: lds r13,fatstart lds r14,fatstart+1 clr r15 sub temp1,r13 sbc temp2,r14 sbc temp3,r15 sbc temp4,r15 ;all_sectors -= fatstart clr r20 ;spcpcl -> r23:22:21:20 (base r20) lds r21,secpcl ;***spcpcl*4096(12bit L_shift)*** mov r22,r21 ;r20->r21 8bit,r21=r22(H:L) copy swap r21 ;r21 H<->L andi r21,0xF0 ;r21 L0 (+4bit->12bit) swap r22 ;r22 H<->L andi r22,0x0F ;r22 0H clr r23 ;spcpcl*4096 -> r23:22:21:20 cp temp1,r20 cpc temp2,r21 cpc temp3,r22 cpc temp4,r23 ;sec:spcpcl*4096 brmi read_vfat5 ldi temp1,1 ;FAT16 rjmp read_vfat6 read_vfat5: clr temp1 ;FAT12 ldi temp2,3 ; ret ; read_vfat6: sts fattype,temp1 clr temp2 ret ;********************************************** ;read_32 read32_arg[3:0] read_32: lds r15,read32_arg lds r14,read32_arg+1 lds r13,read32_arg+2 lds r12,read32_arg+3 mov temp4,r15 mov temp3,r14 ldi temp2,0xFE and temp2,r13 clr temp1 sts spi_arg+1,temp4 sts spi_arg+2,temp3 sts spi_arg+3,temp2 sts spi_arg+4,temp1 rcall spi_read_open tst temp2 breq read_32_1 ret ;temp2=1 erro read_32_1: mov temp3,r12 ldi temp4,1 and temp4,r13 ;low_addr=temp4:3 <- addr&0x1FF clr yL clr yH ;Y:counter 0 to 511 ldiw x,buff ldiw z,buff+32 read_32_2: rcall spi_in cp yL,temp3 cpc yH,temp4 ;Y:low_addr brmi read_32_3 ;Y=low_addr cpc xH,zH ;x:buff+32 brpl read_32_3 ;x>=buff+32 st x+,temp2 ;Y>=low_addr & xtemp2 ldiw Y,2024 spi_com1: rcall spi_in cpi temp2,0xff breq spi_com2 sbiw YL,1 brne spi_com1 ldi temp2,1 ret ;busy error return=1 spi_com2: lds temp1,spi_arg mov temp2,temp1 ori temp1,0x40 rcall spi_out ;cmd lds temp1,spi_arg+1 rcall spi_out ;arg3 lds temp1,spi_arg+2 rcall spi_out ;arg2 lds temp1,spi_arg+3 rcall spi_out ;arg1 lds temp1,spi_arg+4 rcall spi_out ;arg0 tst temp2 brne spi_com3 ldi temp1,0x95 ;int CRC rjmp spi_com4 spi_com3: ldi temp1,1 spi_com4: rcall spi_out ;CRC ldiw Y,2024 spi_com5: rcall spi_in cpi temp2,0xFE breq spi_com6 ;data talken start ldi temp3,0x80 and temp3,temp2 breq spi_com6 ;cmd response (MSB=0) sbiw YL,1 brne spi_com5 spi_com6: ;return=temp2 ret ;********************************************** wait_us: ;base 8MHz temp1 us (8clocks) nop ; 1clocks nop ; 1clocks nop ; 1clocks nop ; 1clocks nop ; 1clocks dec temp1 ; 1clocks brne wait_us ; 2clocks wait_1us: ret ; wait_ms: ;temp1 ms ldi temp2,100 ;80*100=8000clocks wait_ms_01: ldi temp3,19 ;1clocks 4*(19+1)=80 wait_ms_02: nop ; 1clocks dec temp3 ; 1clocks brne wait_ms_02 ; 2clocks dec temp2 ; 1clocks brne wait_ms_01 ; 2clocks dec temp1 ; 1clocks brne wait_ms ; 2clocks ret ;********************************************* EEPROM_WR: rcall EEPROM_RD cp temp1,temp2 ;同じ値ならスキップ brne EEPROM_WR1 ret EEPROM_WR1: SBIC EECR,EEWE ;EEPROM書き込み完了ならばスキップ RJMP EEPROM_WR1 ;以前のEEPROM書き込み完了まで待機 OUT EEARH,ZH ;EEPROMアドレス上位バイト設定 OUT EEARL,ZL ;EEPROMアドレス下位バイト設定 OUT EEDR,temp1 ;EEPROM書き込み値を設定 SBI EECR,EEMWE ;EEPROMマスタ書き込み許可ビット設定 SBI EECR,EEWE ;EEPROM書き込み開始(書き込み許可ビット設定) RET ;呼び出し元へ復帰 ;********************************************* EEPROM_RD: SBIC EECR,EEWE ;EEPROM書き込み完了ならばスキップ RJMP EEPROM_RD ;以前のEEPROM書き込み完了まで待機 OUT EEARH,ZH ;EEPROMアドレス上位バイト設定 OUT EEARL,ZL ;EEPROMアドレス下位バイト設定 SBI EECR,EERE ;EEPROM読み出し開始(読み込み許可ビット設定) IN temp2,EEDR ;EEPROM読み出し値を取得 RET ;呼び出し元へ復帰 ;********************************************* TIM1_OVF: ldi temp1,low(RAMEND) out SPL,temp1 ldi temp1,high(RAMEND) out SPH,temp1 ;init Stack Pointer outi TCCR1B,0 rjmp main_5 ;********************************************* ;BEEP data beep_H: .db 0x53,0xEF,0x6E,0xF0,0,0,0,0 ;1500Hz beep_L: .db 0x53,0xEF,0x6E,0xE8,0,0,0,0 ; 750Hz beep_s: .db 0x45,0x78,0x69,0x74,0,0,0,0 ; stop mp3_0: .db 0,0,0,0,0,0,0,0 ;dsp_data mode_dat: .db 16,16,16,16,16,16,16,16,146,84,56,16 ;normal mode_dat1: .db 128,192,160,128,128,191,161,146,140,160,192,128 ;dir rep mode_dat2: .db 128,192,160,128,129,129,191,129,129,160,192,128 ;1 rep n0: .db 248,4,2,2,2,4,248,1,2,4,4,4,2,1 n1: .db 16,8,4,254,0,0,0,0,0,0,7,0,0,0 n2: .db 8,4,2,130,66,36,24,4,6,5,4,4,4,4 n3: .db 2,2,34,50,42,70,130,1,2,4,4,4,2,1 n4: .db 192,48,12,2,254,0,0,1,1,1,1,7,1,1 n5: .db 62,34,18,18,18,34,194,2,4,4,4,4,2,1 n6: .db 248,36,18,18,18,34,192,1,2,4,4,4,2,1 n7: .db 2,2,2,130,98,26,6,0,0,6,1,0,0,0 n8: .db 136,84,34,34,34,84,136,1,2,4,4,4,2,1 n9: .db 56,68,130,130,130,68,248,0,4,4,4,4,2,1 co: .db 0,0,48,48,0,0,0,0,0,3,3,0,0,0 sp: .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0 d_t: .db 252,132,72,48,4,4,252,4,4,0 vol: .db 28,32,28,0,60,36,60,0,60,32,32,0 n_t: .db "noID3V1Tag" ;"V","1","タ","グ","が","あ","り","ま","せ","ん" ;*********************************************