?? cfmp3_3.asm
字號:
title "CompactFlash"
;
;
;
;
LIST P=16F877, R=DEC
; errorlevel 0,-305,-302*****
;******************************************************************************
;** **
;** COMPACTFLASH CARD TO PIC INTERFACE **
;** **
;** MARK A. SAMUELS **
;** **
;******************************************************************************
INCLUDE "e:\mp3playerJunk\mplab\P16F877.inc"
;*************************************************************************
;******************************************************************************
; Registers
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON & _LVP_OFF
; VARIABLE DECLARATIONS
;******************************************************************************
TEMP_W EQU 0x20
TEMP_S EQU 0x21
REGA EQU TEMP_S + 1
REGB EQU REGA + 1
REGC EQU REGB + 1
REGD EQU REGC + 1
REGE EQU REGD + 1
DATA_HI EQU REGE + 1
DATA_LO EQU DATA_HI + 1
COUNTER_LO EQU DATA_LO + 1
COUNTER_HI EQU COUNTER_LO + 1
SECTORS_LO EQU COUNTER_HI + 1
SECTORS_HI EQU SECTORS_LO + 1
BUFSIZE_LO EQU SECTORS_HI + 1
BUFSIZE_HI EQU BUFSIZE_LO + 1
regx EQU BUFSIZE_HI + 1
regy EQU regx + 1
regz EQU regy + 1
regt EQU regz + 1
regu EQU regt + 1
regv EQU regu + 1
rollerlo equ regv + 1
rollerhi equ rollerlo + 1
regnosub equ rollerhi + 1
bassboostbuffer equ regnosub + 1
volumebuffer equ bassboostbuffer + 1
bassslower equ volumebuffer + 1
; PORT DECLARATIONS
;******************************************************************************
CF_DATA EQU PORTD
CF_ADDR EQU PORTE
CF_CONTROL EQU PORTA
userport equ portb
; FLAG DECLARATIONS
;******************************************************************************
; CF CONTROL
CE1 EQU 0 ; CF CONTROL PORT, 0 (LOW = ENABLE, HI = HI-Z)
CD1 EQU 1 ; CF CONTROL PORT, 1
RESET EQU 2 ; CF CONTROL PORT, 2
OE EQU 3 ; CF CONTROL PORT, 3
WE EQU 4 ; CF CONTROL PORT, 4
RDY EQU 5 ; CF CONTROL PORT, 5
;these are port c, mostly
vscontrol equ portc
bsync equ 0
dreq equ 1
dclk equ 6
sdata equ 7
xcs equ 2
sclk equ 3
si equ 5
so equ 4
xreset equ 2 ;this is on port b!!!!
userreset equ 3
bassboost equ 4
volume equ 5
skipbutton equ 6
surround equ 7
; CF CARD REGISTER ADDRESSES
;******************************************************************************
; ADDRESS VALUES, LOW 3 BITS AS FOLLOWS:
; (X,X,X,X,X,A2,A1,A0)
DATA_REG EQU 0x00 ; ADDRESS OF DATA REGISTER
ERROR_REG EQU 0x01 ; ADDRESS OF ERROR REGISTER
FEATURES_REG EQU 0x01 ; ADDRESS OF FEATURES REGISTER
SEC_CNT_REG EQU 0x02 ; ADDRESS OF SECTOR COUNT REGISTER
SEC_NUM_REG EQU 0x03 ; ADDRESS OF SECTOR NUMBER REGISTER
CYL_LO_REG EQU 0x04 ; ADDRESS OF LOW CYLINDER REGISTER
CYL_HI_REG EQU 0x05 ; ADDRESS OF HIGH CYLINDER REGISTER
HEAD_REG EQU 0x06 ; ADDRESS OF HEAD/DRIVE REGISTER
STATUS_REG EQU 0x07 ; ADDRESS OF STATUS REGISTER
COMMAND_REG EQU 0x07 ; ADDRESS OF COMMAND REGISTER
; COMMAND ASSIGNMENTS
;******************************************************************************
; COMMAND VALUES, 8 BITS
IDENTIFY EQU 0xEC
WRITE_SEC EQU 0x30
READ_SEC EQU 0x20
PAGE
org 0
NOP
goto PRE_MAIN
org 4
goto Int
;******************************************************************************
;******************************************************************************
;** **
;** INTERRUPT SERVICE ROUTINE **
;** **
;******************************************************************************
;******************************************************************************
; (NO INTERRUPTS IN THIS CODE... ONLY HEADER AND FOOTER FOR ISR)
Int
movwf TEMP_W
swapf STATUS, w
movwf TEMP_S
; check int source here
goto End_of_Int
End_of_Int
swapf TEMP_S, w
movwf STATUS
swapf TEMP_W, f
swapf TEMP_W, w
retfie
;++++++++++++++++++++++++++++++++++++++++subroutines
;******************************************************************************
;* CHECK_READY SUBROUTINE *
;******************************************************************************
CHECK_READY
BTFSS CF_CONTROL,RDY ; CHECK IF CF READY
GOTO CHECK_READY
RETURN
;******************************************************************************
;* CF WRITE SUBROUTINE *
;******************************************************************************
CF_WRITE
; ENSURE CARD IS READY
CALL CHECK_READY
NOP
; STROBE "WE" LINE LOW
BCF CF_CONTROL, WE
NOP
NOP
NOP
BSF CF_CONTROL, WE
NOP
RETURN
;******************************************************************************
;* CF READ SUBROUTINE *
;******************************************************************************
CF_READ
; READ TWO BYTES
CALL CHECK_READY
; SET TRIS REGISTERS FOR DATA LINES TO INPUT
BSF STATUS, RP0
MOVLW 0xFF
MOVWF CF_DATA
BCF STATUS, RP0
NOP
CLRF CF_DATA
; SET OE LINE LOW
NOP
BCF CF_CONTROL, OE
NOP
NOP
NOP
; READ AND STORE BYTE #1
MOVF CF_DATA,W
MOVWF DATA_LO
NOP
; SET OE LINE HI
BSF CF_CONTROL, OE
NOP
NOP
CALL CHECK_READY
; BYTE #2
; SET OE LINE LOW
NOP
BCF CF_CONTROL, OE
NOP
NOP
NOP
;READ AND STORE BYTE #2
MOVF CF_DATA,W
MOVWF DATA_HI
NOP
; SET OE LINE HI
BSF CF_CONTROL, OE
NOP
; CHANGE CF_DATA BACK TO OUTPUT
BSF STATUS, RP0
CLRF CF_DATA
BCF STATUS, RP0
NOP
RETURN
;************************************************************************
;* ONE_SEC *
;* GENERATES ONE SECOND DELAY *
;************************************************************************
ONE_SEC
MOVLW .255
MOVWF REGD
GOTO ONE100
HALF_SEC
MOVLW .128
MOVWF REGD
ONE100
CALL DELAY
DECFSZ REGD,F
GOTO ONE100
RETURN
;******************************************************************************
;* DELAY SUBROUTINE *
;******************************************************************************
DELAY
MOVLW .2 ; # OF 1MS DELAYS
MOVWF REGB
DL100
CLRF REGC
DL200 ;------\
NOP ; \
; \
DECFSZ REGC,F ; > 1 MS (APPROX)
GOTO DL200 ; /
; /
DECFSZ REGB,F ;------/
GOTO DL100 ;
RETURN
;------------------------------------------------------------------------------
serial_delay
MOVLW .52
MOVWF REGy
Serial_byte_delay
DECFSZ REGy,F
GOTO Serial_byte_delay
RETURN
nop
;---------------------------------------------------------------------------
CFread_VSsend
; READ TWO BYTES
CALL CHECK_READY
BSF STATUS, RP0 ; SET TRIS REGISTERS FOR DATA LINES TO INPUT
MOVLW 0xFF
MOVWF CF_DATA
BCF STATUS, RP0
CLRF CF_DATA ;is this needed
BCF CF_CONTROL, OE ; SET OE LINE LOW
MOVF CF_DATA,W ; READ AND STORE BYTE #1
BSF CF_CONTROL, OE ; SET OE LINE HI
;bsf portb,4;-------------
;nop;------------------------
;nop;---------------------
;bcf portb,4;-------------
; movlw 0xf5
bsf vscontrol,bsync
movwf txreg
nop
nop
bcf vscontrol,bsync
CALL CHECK_READY
BCF CF_CONTROL, OE ; BYTE #2 ; SET OE LINE LOW
MOVF CF_DATA,W ;READ AND STORE BYTE #2
BSF CF_CONTROL, OE ; SET OE LINE HI
bsf vscontrol,bsync
movwf txreg
nop
nop
bcf vscontrol,bsync
BSF STATUS, RP0 ; CHANGE CF_DATA BACK TO OUTPUT
CLRF CF_DATA
BCF STATUS, RP0
RETURN
spiout
movwf sspbuf
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
return
;++++++++++++++++++++++++++++++++++++++++
sdi_out
bsf vscontrol,bsync
movwf txreg
nop
nop
bcf vscontrol,bsync
nop
nop
nop
nop
return
;+++++++++++++++++++++++++++++++++++++++++++
resetvs1001
;reset and mode set
bcf vscontrol,xcs
movlw 0x02
call spiout
movlw 0x00
call spiout
movlw 0x03
call spiout
movlw 0x04
call spiout
bsf vscontrol,xcs
call delay
;unreset and mode set
bcf vscontrol,xcs
movlw 0x02
call spiout
movlw 0x00
call spiout
movlw 0x03
call spiout
movlw 0x00
call spiout
bsf vscontrol,xcs
call delay
morezeroes
check_vs_a
BTFSS vscontrol,dreq ; CHECK IF vs1001 READY
GOTO CHECK_vs_a
movlw 0x00
call sdi_out
call sdi_out
call sdi_out
call sdi_out
decfsz regnosub
goto morezeroes
return
;+++++++++++++++++subroutines end
;*****************************************************************************
;*****************************************************************************
PRE_MAIN
;*****************************************************************************
;*****************************************************************************
; CLEAR MEMORY SPACE (SET ALL RAM VALUES TO 0x00)
GOTO INIT_DONE
INIT_DONE
; Setup
BSF STATUS, RP0 ; Goto Bank 1
MOVLW 0x00
MOVWF TRISA ; Set RC(7:0) as outputs
MOVWF TRISD ; Set RD(7:0) as outputs
MOVWF TRISE ; Set RE(2:0) as outputs
MOVLW 0xd2 ;1101 0010b
MOVWF TRISC ;
MOVLW 0xfb ;iiii ioii
MOVWF TRISB ; bit 2 must be output for vs reset pin
BSF CF_CONTROL,CD1 ; MAKE CD1 AN INPUT (CARD DETECT)
BSF CF_CONTROL,RDY ; MAKE RDY AN INPUT (RDY/BSY)
MOVLW 0x06 ; Set PORTA as digital I/O
MOVWF ADCON1
MOVLW 0x00 ;
MOVWF OPTION_REG
BCF STATUS, RP0 ; Go back to Bank 0
MOVLW 0x00
MOVWF ADCON0
;**********************************************************************
;**********************************************************************
MAIN
;**********************************************************************
;**********************************************************************
bcf portb,4
bsf vscontrol,xcs ;chip select off sci (active low)
bcf portb,xreset ;reset vs1001
MOVLW 0x18
MOVWF CF_CONTROL
MOVLW 0x00
MOVWF CF_ADDR
bsf portb,xreset ;activate vs1001
;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
;usart_setup ;synchronous, max speed
bsf rcsta,spen
bsf status,rp0
movlw .0
movwf spbrg
;bsf txsta,brgh
bsf txsta,sync
bcf txsta,tx9
bsf txsta,csrc
bsf txsta,txen
bcf status,rp0
call One_sec
;spi setup
bsf status,rp0
bsf sspstat,cke
bcf status,rp0
bsf sspcon,sspen ;enable port
;initialize vs1001
;set volume
bcf vscontrol,xcs
movlw 0x02
call spiout
movlw 0x0b
call spiout
movlw 0x25
call spiout
movlw 0x25
call spiout
movwf volumebuffer
bsf vscontrol,xcs
call delay
;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
CHK_CARD
BTFSC CF_CONTROL, CD1 ; CARD INSERTED?
GOTO CHK_CARD ; NO, GO BACK
; YES, GO ON
BSF CF_CONTROL, RESET ; RESET CF CARD
NOP
NOP
BCF CF_CONTROL, RESET
NOP
NOP
CALL HALF_SEC
; WRITE CF EXECUTE IDENTIFY DRIVE COMMAND (0xEC)
MOVLW COMMAND_REG ; REGISTER TO BE ADRESSED
MOVWF CF_ADDR
MOVLW IDENTIFY ; INSTRUCTION CODE
MOVWF CF_DATA
CALL CF_WRITE
; READ DATA REGISTER
MOVLW READ_SEC
MOVWF CF_ADDR
MOVLW .5 ; DROP FIRST 5 WORDS
MOVWF REGA
TRUNC1
CALL CF_READ
DECFSZ REGA,F
GOTO TRUNC1
; READ AND STORE THE NUMBER OF BYTES PER SECTOR
CALL CF_READ
MOVLW .15 ; SKIP NEXT 15 WORDS
MOVWF REGA
TRUNC2
CALL CF_READ
DECFSZ REGA,F
GOTO TRUNC2
; READ AND STORE THE BUFFER SIZE
CALL CF_READ
MOVF DATA_HI, W
MOVWF BUFSIZE_HI
MOVF DATA_LO, W
MOVWF BUFSIZE_LO
MOVLW 0x00
MOVWF regv
MOVLW 0x02
MOVWF regu
MOVLW 0x2B
MOVWF regt
call resetvs1001
;+__+_+_++_+__+_+_+_+_++_
;+_+_++__+_+_++_+____+_+
superread
btfsc userport,userreset
goto skipuserreset
call resetvs1001
skipuserreset
btfsc userport,volume
goto skipvolume
decf volumebuffer,f
bcf vscontrol,xcs
movlw 0x02
call spiout
movlw 0x0b
call spiout
movf volumebuffer,w
call spiout
movf volumebuffer,w
call spiout
bsf vscontrol,xcs
skipvolume
btfsc userport,bassboost
goto skipbassboost
bcf vscontrol,xcs
movlw 0x02
call spiout
movlw 0x00
call spiout
movlw 0x03
call spiout
movlw 0x80
call spiout
bsf vscontrol,xcs
skipbassboost
btfsc userport,surround
goto skipsurround
bcf vscontrol,xcs
movlw 0x02
call spiout
movlw 0x00
call spiout
movlw 0x03
call spiout
movlw 0x01
call spiout
bsf vscontrol,xcs
skipsurround
btfsc userport,skipbutton
goto notrackskip
movlw 0x04
addwf regt,F
BTFSC STATUS,Z
INCF regu,F
BTFSC STATUS,Z
INCF regv,F
notrackskip
MOVLW 0xE0
MOVWF CF_DATA
MOVLW HEAD_REG
MOVWF CF_ADDR
CALL CF_WRITE
movf regv ,w
MOVWF CF_DATA
MOVLW CYL_HI_REG
MOVWF CF_ADDR
CALL CF_WRITE
movf regu ,w
MOVWF CF_DATA
MOVLW CYL_LO_REG
MOVWF CF_ADDR
CALL CF_WRITE
movf regt ,w
MOVWF CF_DATA
MOVLW SEC_NUM_REG
MOVWF CF_ADDR
CALL CF_WRITE
MOVLW 0x01
MOVWF CF_DATA
MOVLW SEC_CNT_REG
MOVWF CF_ADDR
CALL CF_WRITE
MOVLW READ_SEC
MOVWF CF_DATA
MOVLW COMMAND_REG
MOVWF CF_ADDR
CALL CF_WRITE
MOVLW DATA_REG
MOVWF CF_ADDR
movlw .16
movwf regx
printout
CHECK_vs
BTFSS vscontrol,dreq ; CHECK IF vs1001 READY
GOTO CHECK_vs
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
CALL CFREAD_vssend
DECFSZ REGX, F
GOTO printout
; INCREMENT COUNTER
INCF regt,F
BTFSC STATUS,Z
INCF regu,F
BTFSC STATUS,Z
INCF regv,F
BTFSC STATUS,Z
goto end_chk
GOTO superread
; LOOP FOREVER UNTIL CARD REMOVED, THEN RESET
END_CHK
BTFSC CF_CONTROL,CD1
GOTO CHK_CARD
GOTO END_CHK
; END OF MAIN LOOP
retlw 'a'
retlw 'z'
retlw 'z'
retlw 'h'
retlw 'o'
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -