📄 mpc.asm
字号:
;----------------------------------------------------------------------------;
; MP3 player embedded controller R0.94 ;
; for 4MHz operation ;
; Copyright(C) 1999-2000 ChaN(Takeshi Akamatsu) ;
;----------------------------------------------------------------------------;
; These are program source files that attached to avobe document.
; For details, please refer to the following page.
;
; http://elm-chan.org/
;
; Don't use for any commercial products or distribution without permission.
;
; Email: chan@elm-chan.org
.nolist
.include "8515def.inc" ; This file is contained in "AVR Family Assembler".
.include "avr.inc"
.include "mpc.inc"
.list
;----------------------------------------------------------;
; SRAM area definitions
.dseg
.org RAMTOP
;-Timer Interrupt-------;
KeyReg: .byte 2 ; Anti-chattering and edge detection reg.
KeyCmd: .byte 1 ; Key command
FtmMr: .byte 1 ; Muting delayed release timer (500Hz)
.byte 1 ; Timer divider (/4)
StmVs: .byte 1 ; Volt sens timer (125Hz)
MskBp: .byte 1 ; Beep drive (125Hz)
StmBp: .byte 1 ; /
MskLed: .byte 1 ; Led drive (125Hz)
StmLed: .byte 1 ; /
Stm1: .byte 1 ; System timer (125Hz)
Stm2: .byte 1 ; /
;-System Monitor--------;
LineBuf:.byte 16 ; Command input buffer
;-Memory Card-----------;
SmSign: .byte 2 ; SM device codes
SmPages:.byte 2 ; Number of pages (2nd,3rd byte)
SmPPB: .byte 1 ; Pages par block -1
;-Play Back-------------;
Volume: .byte 1 ; Volume
Random: .byte 1 ; Random base
TrkIdx: .byte 1 ; Track index
TrkTbl: .byte NTRK ; Track number table
;-File System-----------;
Tracks: .byte 1 ; Number of tracks (0..)
IdxTbl: .byte 6*NTRK ; Track parameter table
TocCrc: .byte 2 ; CRC for detect medium change
Bbt: .byte 2*NBBT ; Bad block table
;----------------------------------------------------------;
; EEPROM area definitions
.eseg
.byte 1 ; Dummy (to prevent data collaption)
eeVolume: .byte 1 ; Volume setting
eeTrack: .byte 1 ; Previous track
eeTrkPrm: .byte 6 ; Previous Track parms
eeTocCrc: .byte 2 ; TOC CRC (for detecting medium change)
eeRandom: .byte 1 ; Randomize base
;----------------------------------------------------------;
; Program code
.cseg
; Interrupt Vectors
rjmp initial ; Reset
rjmp 0 ; Extrenal INT0
rjmp 0 ; External INT1
rjmp 0 ; TC1 Capture
rjmp 0 ; TC1 CMA
rjmp 0 ; TC1 CMB
rjmp 0 ; TC1 Overflow
rjmp int_tc0 ; TC0 Overflow
rjmp 0 ; SPI
rjmp 0 ; UART Rx
rjmp 0 ; UART Udre
rjmp 0 ; UART Tx
rjmp 0 ; Analog Comparator
initial:
clr _0
ldiw Y,RAMTOP ; Clear RAM (512bytes)
clr r17 ;
st Y+,_0 ;
st Y+,_0 ;
dec r17 ;
brne PC-3 ; /
outi SPL,low(RAMEND) ; Initialize SP
outi SPH,high(RAMEND) ; /
outi PORTB,0b10100000 ; Initialize Port B
outi DDRB, 0b01000000 ; /
outi PORTC,0b11010100 ; Initialize Port C
outi DDRC, 0b10111111 ; /
outi PORTD,0b10100011 ; Initialize Port D
outi DDRD, 0b00101011 ; /
clr _PbStat ; Initialize variables
stsi StmVs,60 ;
stsi MskLed,0xff ;
in r16,PINB ;
com r16 ;
sts KeyReg+1,r16 ; /
out OCR1AH,_0 ; OCR1A = 31
outi OCR1AL,31 ; /
out OCR1BH,_0 ; OCR1B = 1
outi OCR1BL,1 ; /
outi TCCR1B,0b00001011 ; Start TC1 with CK/64 = 62.5k
outi TCCR0,0b100 ; Start TC0 with CK/256 = 15.6k
outi TIMSK,0b00000010 ; Enable TMR0 interrupt
sei ; Enalbe all inerrupts
rcall dac_off ; DAC3550A: DAC off, AUX1 on-mono
rcall dac_iiscfg ; DAC3550A: IIS config
rcall set_dcdc ; MAS3507D: Set DC-DC output voltage
rcall load_volume ; Restore previos volume setting
rcall set_volume ; /
rcall sm_reset ; Reset SM
ldi _Err,0 ; Clear error status
rcall sm_gettype ; Get SM type & initialize parms
brne err_smt ; if unknown SM type -> error
rcall load_bbt ; Load bad block table
brne err_fmt ; if unformated -> error
rcall load_toc ; Load TOC
sbis PINB,MOSI ; If MOSI = "L" (connected to HOST)
rjmp monitor ; - > Enter system monitor
lds r16,Tracks ; If no track
tst r16 ; -> error
breq err_ntrk ; /
rcall pb_start ; Start to playback !
rjmp power_off
err_smt: ; Error: Unknown SM type
ldi _Err,1 ; Set error code
ldi r16,0b10000000 ; 4 times of error beep
rjmp err_wait
err_fmt: ; Error: Unformatted
ldi _Err,2 ; Set error code
ldi r16,0b01100000 ; 3 times of error beep
rjmp err_wait
err_ntrk: ; Error: No track to play
ldi r16,0b01000000 ; 2 times of error beep
err_wait: ; Start beep
sts StmBp,r16 ;
stsi MskBp,0b00010000 ; /
lds r16,StmBp ; Wait for end of beep
cpi r16,0 ;
brne PC-3 ; /
sbis PINB,MOSI ; If MOSI = "L"
rjmp monitor ; Enter System Monitor
; else Power Off.
power_off: ;---SHUT DOWN
cli ; Disable intrerupt
sbi PORTC,CE ; Disable Medium
cbi PORTD,POWER ; Release power hold
rjmp PC ; halt
;--------------------------------------;
; 500Hz timer interrupt
int_tc0:
in _SrgTmp,SREG ; Save status flag
push r16 ; Save regs
push r17 ;
push r18 ;
push r19 ;
push _Loop ;
push YL ;
push YH ; /
outi TCNT0,-31 ; Reload clock divisor value
rcall mpeg_xfer ; MPEG data xfer
ldiw Y,FtmMr ; Decrement FtmMr with zero stopping
ld r17,Y ; If FtmMr becomes zero, release muting
dec r17 ;
brne PC+2 ;
rcall dac_on ;
cpi r17,-1 ;
brne PC+2 ;
ldi r17,0 ;
st Y+,r17 ; /
ld r16,Y ; Divide interrupt rate by 4
inc r16 ; and branch for each jobs
st Y,r16 ; - tm_led
andi r16,0b11 ; - tm_beep
breq tm_volt ; - tm_key
cpi r16,1 ; - tm_volt
breq tm_beep ;
cpi r16,2 ;
breq tm_key ; /
tm_led:
ldi YL,Stm1 ; Decrement Stm1 and Stm2
ld r16,Y
subi r16,1
brcs PC+2
st Y,r16
ldd r16,Y+1
subi r16,1
brcs PC+2
std Y+1,r16
ldi YL,MskLed ; LED drive
ld r17,Y+
ld r16,Y
dec r16
brne PC+2
dec r16
st Y,r16
and r16,r17
brne PC+3
cbi PORTD,LED
rjmp end_int_tc0
sbi PORTD,LED
rjmp end_int_tc0
tm_beep:
ldi YL,MskBp
ld r17,Y+
ld r16,Y
subi r16,1
adc r16,YH
st Y,r16
and r16,r17 ; If zero, Set TC1 OC1B stop mode
ldi r16, 0b00010000 ; If not, Set TC1 OC1B toggle mode
brne PC+2 ;
ldi r16, 0b00100000 ;
out TCCR1A, r16 ; /
rjmp end_int_tc0
tm_key: ; Key scan
ldi YL,KeyReg
ld r17,Y ; Read and store key input
in r16,PINB ;
com r16 ; negative polarity
andi r16,0b10011 ; key bit mask
st Y+,r16 ; /
cp r17,r16 ; Check input stabled
brne end_int_tc0 ; if not, exit
ld r16,Y ; Check key press edge
st Y+,r17 ;
eor r16,r17 ;
and r16,r17 ; If not detect key press edge, exit
breq end_int_tc0 ; /
st Y,r16 ; Send key command to main proc.
rjmp end_int_tc0 ; /
tm_volt:
ldi YL,StmVs
ld r16,Y
sbic ACSR,ACO ; When VBAT has been below than VREF for 400ms,
rjmp tmv_n ; trigger low battery events.
dec r16 ;
brne tmv_e ; /
sbis DDRD,VREF ; If VREF is 2.0V, warning beep
rjmp PC+5 ; If VREF is 1.8V, shut off
stsi KeyCmd,K_STOP ; Shut off: generate stop command
rjmp end_int_tc0
ldi YL,MskBp ; Warning beep: 0.5s, 4 times, LED fast brink
sti Y+,0b00100000 ;
sti Y+,0b11111111 ;
sti Y+,0b00100000 ;
out OCR1AH,_0 ;
outi OCR1AL,31 ; /
sbi DDRD,VREF ; Set VREF = 1.8V
tmv_n: ldi r16,50
tmv_e: sts StmVs,r16
end_int_tc0:
pop YH ; Restore regs
pop YL ;
pop _Loop ;
pop r19 ;
pop r18 ;
pop r17 ;
pop r16 ; /
out SREG,_SrgTmp ; Restore status flags
reti
;--------------------------------------;
; Other modules
.include "mpc_mon.asm" ; System monitor
.include "mpc_play.asm" ; Playback control
.include "mpc_fs.asm" ; File System
.include "mpc_sm.asm" ; Medium access
.include "mpc_iic.asm" ; IIC functions
.include "mpc_comm.asm" ; Communications
.include "mpc_eep.asm" ; EEPROM functions
.include "mpc_mess.asm" ; Constants
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -