📄 sdmmc.s
字号:
.module sdmmc.c
.area data(ram, con, rel)
_readPos::
.blkb 2
.area idata
.word 0
.area data(ram, con, rel)
.dbfile D:\桌面\mp3\sdmmc\sdmmc.c
.dbsym e readPos _readPos i
_sectorPos::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile D:\桌面\mp3\sdmmc\sdmmc.c
.dbsym e sectorPos _sectorPos c
_LBA_Opened::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile D:\桌面\mp3\sdmmc\sdmmc.c
.dbsym e LBA_Opened _LBA_Opened c
.area text(rom, con, rel)
.dbfile D:\桌面\mp3\sdmmc\sdmmc.c
.dbfunc e MMC_Port_Init _MMC_Port_Init fV
.even
_MMC_Port_Init::
.dbline -1
.dbline 75
; /**************************************************************************************
; //------------------ MMC/SD-Card Reading and Writing implementation -------------------
; //FileName : mmc.c
; //Function : Connect AVR to MMC/SD
; //Created by : ZhengYanbo
; //Created date : 15/08/2005
; //Version : V1.2
; //Last Modified: 19/08/2005
; //Filesystem : Read or Write MMC without any filesystem
;
; //CopyRight (c) 2005 ZhengYanbo
; //Email: Datazyb_007@163.com
; ****************************************************************************************/
; /*
; 读扇区方法:
;
; 1. Set_block_length(default is 512 bytes).Use set_block_length command.如果你的缓冲区是512字节,那么这个区一般不用设置.
;
; 2. Send block read command.我用的是cmd16
; //Command 16 is for reading Blocks from MMC/SD-Card
; unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
;
; 3. Wait for block start token(is 0xFE)
; //Read Start Byte form MMC/SD-Card (FEh/Start Byte)
; while (Read_Byte_MMC() != 0xfe){};
;
; 4. Read 512 bytes out from your Card.
;
; 5. Read CRC bytes(2 bytes) 这里对我没有用处,空读就行了.
; //CRC-Byte
; Read_Byte_MMC();//CRC - Byte
; Read_Byte_MMC();//CRC - Byte
;
; 6. Disable SD Card and return TRUE
;
; 另外请大家使用时候注意下面函数:
; unsigned char MMC_Start_Read_Sector(unsigned long sector);
; void MMC_get_data(unsigned int Bytes,unsigned char *buffer);
; void MMC_get_data_LBA(unsigned long lba, unsigned int Bytes,unsigned char *buffer);
; void MMC_GotoSectorOffset(unsigned long LBA,unsigned int offset);
; void MMC_LBA_Close(void);
; 如果你的RAM足够大,那么你可以一次缓冲完一个sector,这些函数可以删除(因为我写这些函数时候,使用的CPU是8515) 如果使用例如MEGA8515这样的CPU,RAM不足1KB,你只能定义例如sectBuf[64]这样小的DATA BUFFER. 那么这些函数就可以保留,先使用MMC_Start_Read_Sector(unsigned long sector)打开一个LBA,时候再去读数据到你的循环缓冲区sectBuf[64],分8次完成一个LBA数据.
;
; */
;
;
; #include "config.h"
; #if USE_MMC
; //BUFFER_TYPE sectorBuffer; //512 bytes for sector buffer
;
; //--------------------------------------------------------------
; uint16 readPos=0;
; uint8 sectorPos=0;
; uint8 LBA_Opened=0; //Set to 1 when a sector is opened.
; uint8 Init_Flag; //Set it to 1 when Init is processing.
; //---------------------------------------------------------------
; // Prototypes
; //---------------------------------------------------------------
; void MMC_Port_Init(void);
;
; uint8 Read_Byte_MMC(void);
; //uint8 Read_Byte_MMC_Long(void);
; void Write_Byte_MMC(uint8 value);
; uint8 MMC_Read_Block(uint8 *CMD,uint8 *Buffer,uint16 Bytes);
; uint8 Write_Command_MMC(uint8 *CMD);
; uint8 Read_CSD_MMC(uint8 *Buffer);
; uint8 Read_CID_MMC(uint8 *Buffer);
; void delay_us(uint8 us);
;
;
; //****************************************************************************
; // Port Init
; void MMC_Port_Init(void)
; //****************************************************************************
; {
.dbline 77
; //Config ports
; MMC_DDR&=~(1<<SPI_MISO); //Set Pin MMC_DI as Input
cbi 0x17,6
.dbline 78
; MMC_DDR|=(1<<SPI_CLK); //Set Pin MMC_Clock as Output
sbi 0x17,7
.dbline 79
; MMC_DDR|=(1<<SPI_MOSI); //Set Pin MMC_DO as Output
sbi 0x17,5
.dbline 80
; MMC_DDR|=(1<<MMC_Chip_Select); //Set Pin MMC_Chip_Select as Output
sbi 0x17,4
.dbline 82
; //busy led port init
; MMC_DDR|=(1<<SPI_Busy); //Set spi busy led port output
sbi 0x17,0
.dbline 83
; MMC_PORT|=(1<<SPI_Busy); //busy led off
sbi 0x18,0
.dbline 85
;
; MMC_Disable(); //Set MMC_Chip_Select to High,MMC/SD Invalid.
sbi 0x18,4
.dbline 85
.dbline -2
L7:
.dbline 0 ; func end
ret
.dbend
.area lit(rom, con, rel)
L9:
.byte 64,0
.byte 0,0
.byte 0,149
.area text(rom, con, rel)
.dbfile D:\桌面\mp3\sdmmc\sdmmc.c
.dbfunc e MMC_Init _MMC_Init fc
; spispeeddub -> R20
; spimode -> R22
; CMD -> y+0
; temp -> R10
; i -> R12
; retry -> R14
.even
_MMC_Init::
xcall push_gset5
sbiw R28,6
.dbline -1
.dbline 92
; }
;
; //****************************************************************************
; //Routine for Init MMC/SD card(SPI-MODE)
; uint8 MMC_Init(void)
; //****************************************************************************
; {
.dbline 95
; uint8 retry,temp,spimode,spispeeddub;
; uint8 i;
; uint8 CMD[] = {MMC_RESET,0x00,0x00,0x00,0x00,0x95};
ldi R24,<L9
ldi R25,>L9
movw R30,R28
ldi R16,6
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
xcall asgncblk
.dbline 99
;
; //MMC_Port_Init(); //Init SPI port
;
; spimode=SPCR;
in R22,0xd
.dbline 100
; spispeeddub=SPSR;
in R20,0xe
.dbline 101
; SPSR=0;
clr R2
out 0xe,R2
.dbline 102
; SPCR=0;
out 0xd,R2
.dbline 104
;
; for(i=0;i<200;i++) //Wait MMC/SD ready...
clr R12
xjmp L13
L10:
.dbline 105
.dbline 106
nop
.dbline 107
ldi R16,255
xcall _delay_us
.dbline 108
L11:
.dbline 104
inc R12
L13:
.dbline 104
mov R24,R12
cpi R24,200
brlo L10
.dbline 110
; {
; NOP();
; delay_us(255);
; }
;
; Init_Flag=1; //Set the init flag
ldi R24,1
sts _Init_Flag,R24
.dbline 112
;
; MMC_Disable();
sbi 0x18,4
.dbline 112
.dbline 114
;
; for (i=0;i<0x0f;i++)
clr R12
xjmp L17
L14:
.dbline 115
.dbline 116
ldi R16,255
xcall _Write_Byte_MMC
.dbline 117
L15:
.dbline 114
inc R12
L17:
.dbline 114
mov R24,R12
cpi R24,15
brlo L14
.dbline 120
; {
; Write_Byte_MMC(0xff); //send 74 clock at least!!!
; }
;
; //Send Command CMD0 to MMC/SD Card
; retry=0;
clr R14
L18:
.dbline 123
;
; do
; { //retry 200 times to send CMD0 command
.dbline 124
; temp=Write_Command_MMC(CMD);
movw R16,R28
xcall _Write_Command_MMC
mov R10,R16
.dbline 125
; retry++;
inc R14
.dbline 126
; if(retry==200)
mov R24,R14
cpi R24,200
brne L21
.dbline 127
; { //time out
.dbline 128
; return(INIT_CMD0_ERROR);//CMD0 Error!
ldi R16,1
xjmp L8
L21:
.dbline 130
; }
; }
L19:
.dbline 131
; while(temp!=1);
mov R24,R10
cpi R24,1
brne L18
.dbline 134
;
; //Send Command CMD1 to MMC/SD-Card
; CMD[0] = MMC_INIT; //Command 1
ldi R24,65
std y+0,R24
.dbline 135
; CMD[5] = 0xFF;
ldi R24,255
std y+5,R24
.dbline 136
; retry=0;
clr R14
L24:
.dbline 138
; do
; { //retry 100 times to send CMD1 command
.dbline 139
; temp=Write_Command_MMC(CMD);
movw R16,R28
xcall _Write_Command_MMC
mov R10,R16
.dbline 140
; retry++;
inc R14
.dbline 141
; if(retry==100)
mov R24,R14
cpi R24,100
brne L27
.dbline 142
; { //time out
.dbline 143
; return(INIT_CMD1_ERROR);//CMD1 Error!
ldi R16,2
xjmp L8
L27:
.dbline 145
; }
; }
L25:
.dbline 146
; while(temp!=0);
tst R10
brne L24
.dbline 148
;
; Init_Flag=0; //Init is completed,clear the flag
clr R2
sts _Init_Flag,R2
.dbline 150
;
; MMC_Disable(); //set MMC_Chip_Select to high
sbi 0x18,4
.dbline 150
.dbline 151
; SPCR=spimode;
out 0xd,R22
.dbline 152
; SPSR=spispeeddub;
out 0xe,R20
.dbline 153
; return(0); //All commands have been taken.
clr R16
.dbline -2
L8:
adiw R28,6
xcall pop_gset5
.dbline 0 ; func end
ret
.dbsym r spispeeddub 20 c
.dbsym r spimode 22 c
.dbsym l CMD 0 A[6:6]c
.dbsym r temp 10 c
.dbsym r i 12 c
.dbsym r retry 14 c
.dbend
.dbfunc e MMC_get_volume_info _MMC_get_volume_info fV
.dbstruct 0 11 MMC_VOLUME_INFO
.dbfield 0 size_MB i
.dbfield 2 sector_multiply c
.dbfield 3 sector_count i
.dbfield 5 name A[6:6]c
.dbend
; tmp -> y+16
; spispeeddub -> R20
; spimode -> R22
; buffer -> y+0
; vinf -> R10,R11
.even
_MMC_get_volume_info::
xcall push_gset3
movw R10,R16
sbiw R28,20
.dbline -1
.dbline 163
; }
;
; //****************************************************************************
; //returns the :
; // size of the card in MB ( ret * 1024^2) == bytes
; // sector count and multiplier MB are in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
; // name of the media
; void MMC_get_volume_info(VOLUME_INFO_TYPE *vinf)
; //****************************************************************************
; {
.dbline 168
;
; uint8 tmp[4],buffer[16];
; #if !(HW_SPI_Mode)
; uint8 spimode,spispeeddub;
; spimode=SPCR;
in R22,0xd
.dbline 169
; spispeeddub=SPSR;
in R20,0xe
.dbline 170
; SPCR&=~(1<<SPIE);
cbi 0xd,7
.dbline 174
; #endif
;
; // read the CSD register
; Read_CSD_MMC(buffer);
movw R16,R28
xcall _Read_CSD_MMC
.dbline 179
; // get the C_SIZE value. bits [73:62] of data
; // [73:72] == buffer[6] && 0x03
; // [71:64] == buffer[7]
; // [63:62] == buffer[8] && 0xc0
; vinf->sector_count = buffer[6] & 0x03;
ldd R24,y+6
clr R25
andi R24,3
andi R25,0
movw R30,R10
std z+4,R25
std z+3,R24
.dbline 180
; vinf->sector_count <<= 8;
movw R24,R10
adiw R24,3
movw R30,R24
ldd R4,z+0
ldd R5,z+1
mov R5,R4
clr R4
std z+1,R5
std z+0,R4
.dbline 181
; vinf->sector_count += buffer[7];
movw R24,R10
adiw R24,3
ldd R4,y+7
clr R5
movw R30,R24
ldd R6,z+0
ldd R7,z+1
add R6,R4
adc R7,R5
std z+1,R7
std z+0,R6
.dbline 182
; vinf->sector_count <<= 2;
movw R24,R10
adiw R24,3
movw R30,R24
ldd R4,z+0
ldd R5,z+1
lsl R4
rol R5
lsl R4
rol R5
std z+1,R5
std z+0,R4
.dbline 183
; vinf->sector_count += (buffer[8] & 0xc0) >> 6;
movw R24,R10
adiw R24,3
movw R2,R24
ldi R18,6
ldi R19,0
ldd R16,y+8
clr R17
andi R16,192
andi R17,0
xcall asr16
movw R30,R2
ldd R4,z+0
ldd R5,z+1
add R4,R16
adc R5,R17
std z+1,R5
std z+0,R4
.dbline 188
;
; // get the val for C_SIZE_MULT. bits [49:47] of sectorBuffer.data
; // [49:48] == buffer[5] && 0x03
; // [47] == buffer[4] && 0x80
; vinf->sector_multiply = buffer[9] & 0x03;
ldd R24,y+9
andi R24,3
movw R30,R10
std z+2,R24
.dbline 189
; vinf->sector_multiply <<= 1;
movw R24,R10
adiw R24,2
movw R30,R24
ldd R4,z+0
lsl R4
std z+0,R4
.dbline 190
; vinf->sector_multiply += (buffer[10] & 0x80) >> 7;
movw R24,R10
adiw R24,2
movw R2,R24
ldd R24,y+10
andi R24,128
lsr R24
lsr R24
lsr R24
lsr R24
lsr R24
lsr R24
lsr R24
movw R30,R2
ldd R4,z+0
add R4,R24
std z+0,R4
.dbline 194
;
; // work out the MBs
; // mega bytes in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
; vinf->size_MB = vinf->sector_count >> (9-vinf->sector_multiply);
movw R30,R10
ldd R2,z+2
clr R3
ldi R18,9
ldi R19,0
sub R18,R2
sbc R19,R3
movw R30,R10
ldd R16,z+3
ldd R17,z+4
xcall lsr16
movw R30,R10
std z+1,R17
std z+0,R16
.dbline 196
; // get the name of the card
; Read_CID_MMC(buffer);
movw R16,R28
xcall _Read_CID_MMC
.dbline 197
; vinf->name[0] = buffer[3];
ldd R2,y+3
movw R30,R10
std z+5,R2
.dbline 198
; vinf->name[1] = buffer[4];
ldd R2,y+4
movw R30,R10
std z+6,R2
.dbline 199
; vinf->name[2] = buffer[5];
ldd R2,y+5
movw R30,R10
std z+7,R2
.dbline 200
; vinf->name[3] = buffer[6];
ldd R2,y+6
movw R30,R10
std z+8,R2
.dbline 201
; vinf->name[4] = buffer[7];
ldd R2,y+7
movw R30,R10
std z+9,R2
.dbline 202
; vinf->name[5] = 0x00; //end flag
clr R2
movw R30,R10
std z+10,R2
.dbline 232
; /* //----------------------------------------------------------
; // LCDclrscr();
; //Print Product name on lcd
; Com_putstring("Product:\r\n",10,&RTbuf_UART0);
; Com_putstring(vinf->name,6,&RTbuf_UART0);
; Com_putstring("\r\n",2,&RTbuf_UART0);
; //Print Card Size(eg:128MB)
; Com_putstring("Tot:",4,&RTbuf_UART0);
; tmp[0]=((vinf->size_MB>>12)&0x0f)+0x30;
; tmp[1]=(vinf->size_MB>>8)&0x0f+0x30;
; tmp[2]=(vinf->size_MB>>4)&0x0f+0x30;
; tmp[3]=vinf->size_MB&0x0f+0x30;
; Com_putstring(tmp,4,&RTbuf_UART0);
; Com_putstring("MB\r\n",4,&RTbuf_UART0);
; Com_putstring("sector_mult:",12,&RTbuf_UART0);
; // tmp[0]=((vinf->sector_multiply>>12)&0x0f)+0x30;
; // tmp[1]=(vinf->sector_multiply>>8)&0x0f+0x30;
; tmp[0]=(vinf->sector_multiply>>4)&0x0f+0x30;
; tmp[1]=vinf->sector_multiply&0x0f+0x30;
; Com_putstring(tmp,2,&RTbuf_UART0);
; Com_putstring("\r\n",2,&RTbuf_UART0);
; Com_putstring("sect_cnt:",9,&RTbuf_UART0);
; tmp[0]=((vinf->sector_count>>12)&0x0f)+0x30;
; tmp[1]=(vinf->sector_count>>8)&0x0f+0x30;
; tmp[2]=(vinf->sector_count>>4)&0x0f+0x30;
; tmp[3]=vinf->sector_count&0x0f+0x30;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -