📄 atasd.c
字号:
#include "atasd.h"
#include "DataType.h"
#include "vxworks.h"
#include "sysLib.h"
#include "ioLib.h"
#include "fcntl.h"
#include "math.h"
#include "stdio.h"
#include "dosFsLib.h"
#include "usrLib.h"
#include "semLib.h"
#define MAX_INITS 5
#define INICLK 400000
#define NORCLK 20000000
#define FCLK 200000000
#define HCLK (FCLK/2)
#define PCLK (HCLK/2)
#define MMC_SECTOR_SIZE 512
/*#define MMC_MAX_SECTOR 0x80000 1/2M个扇区,即容量最大为256MBytes*/
typedef struct DEV {
BLK_DEV sd_blkdev;
unsigned int startBlkNum;
unsigned int sd_blkOffset;
SEM_ID sd_semMutex;
}SD_DEV;
/*跟硬件相关的操作放在本文件中*/
volatile MMCreg *v_pSDMMCregs;/*=(MMCreg *)SD_BASE;*/
volatile EIOreg *v_pIOPregs; /*=(EIOreg *)IO_BASE;*/
BOOL g_bSDMMCIsExist;
volatile int RCA;
int Wide=0; /*0:1bit,1:4bit*/
int gMMC=0; /*0:SD,1:MMC*/
/*******************************************************************/
int Chk_CMDend(int cmd,int be_resp)
{
int status;
if(v_pSDMMCregs==NULL)
return 0;
if(!be_resp) /*No response*/
{
status=v_pSDMMCregs->rSDICMDSTA;
while((status&0x800)!=0x800) /*Check cmd end*/
status=v_pSDMMCregs->rSDICMDSTA;
v_pSDMMCregs->rSDICMDSTA=status;/*Clear cmd end state*/
return 1;
}
else /*With response*/
{
status=v_pSDMMCregs->rSDICMDSTA;
while(!(((status&0x200)==0x200)|((status&0x400)==0x400))) /*Check cmd/rsp end*/
status=v_pSDMMCregs->rSDICMDSTA;
if(cmd==1|cmd==9|cmd==41) /*CRC no check*/
{
if((status&0xf00)!=0xa00) /*Check error*/
{
v_pSDMMCregs->rSDICMDSTA=status; /*Clear error state*/
if(((status&0x400)==0x400))
return 0; /*Timeout error*/
}
v_pSDMMCregs->rSDICMDSTA=status; /*Clear cmd&rsp end state*/
}
else /*CRC check*/
{
if((status&0x1f00)!=0xa00) /*Check error*/
{
v_pSDMMCregs->rSDICMDSTA=status; /*Clear error state*/
if(((status&0x400)==0x400))
return 0; /*Timeout error*/
}
v_pSDMMCregs->rSDICMDSTA=status;
}
return 1;
}
}
int Chk_DATend(void)
{
int finish;
if(v_pSDMMCregs==NULL)
return 0;
finish=v_pSDMMCregs->rSDIDATSTA;
while(!(((finish&0x10)==0x10)|((finish&0x20)==0x20)))
{
/*Chek timeout or data end*/
finish=v_pSDMMCregs->rSDIDATSTA;
}
if((finish&0xfc)!=0x10)
{
printf("\nDATA:finish=0x%x.\n",finish);
v_pSDMMCregs->rSDIDATSTA=0xec; /*Clear error state*/
return 0;
}
return 1;
}
void Card_sel_desel(char sel_desel)
{
/*Card select or deselect*/
if(v_pSDMMCregs==NULL)
return;
if(sel_desel)
{
RECMDS7:
v_pSDMMCregs->rSDICMDARG=RCA<<16; /*CMD7(RCA,stuff bit)*/
v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x47; /*sht_resp,wait_resp,start,CMD7*/
/*Check end of CMD7*/
if(!Chk_CMDend(7,1))
goto RECMDS7;
if(v_pSDMMCregs->rSDIRSP0&0x1e00!=0x800)
goto RECMDS7;
}
else
{
RECMDD7:
v_pSDMMCregs->rSDICMDARG=0<<16; /*CMD7(RCA,stuff bit)*/
v_pSDMMCregs->rSDICMDCON=(0x1<<8)|0x47; /*no_resp,start,CMD7*/
/*Check end of CMD7*/
if(!Chk_CMDend(7,0))
goto RECMDD7;
}
}
void CMD0(void)
{
int nError;
if(v_pSDMMCregs==NULL)
return;
/*Make card idle state */
v_pSDMMCregs->rSDICMDARG=0x0; /*CMD0(stuff bit)*/
v_pSDMMCregs->rSDICMDCON=(1<<8)|0x40; /*No_resp,start,CMD0*/
/*Check end of CMD0*/
nError=Chk_CMDend(0,0);
printf("\nCMD0 Chk_CMDend:%d.\n",nError);
}
int CMD55(void)
{
if(v_pSDMMCregs==NULL)
return 0;
/*Make ACMD*/
v_pSDMMCregs->rSDICMDARG=RCA<<16; /*CMD7(RCA,stuff bit)*/
v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x77; /*sht_resp,wait_resp,start,CMD55*/
/*Check end of CMD55*/
if(!Chk_CMDend(55,1))
{
printf("CMD55 ERROR");
return 0;
}
return 1;
}
/************************************************************************/
UINT32 Get_SD_Capacity(void)
{
UINT32 c_size,c_size_mult,read_bl_len,num;
UINT32 r1,r2,r3,r4;
repx:
v_pSDMMCregs->rSDICMDARG=RCA<<16;
v_pSDMMCregs->rSDICMDCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x49;/*sht_resp, wait_resp, start, CMD9*/
if(!Chk_CMDend(9,1))
{
goto repx;
}
r1=v_pSDMMCregs->rSDIRSP0;
r2=v_pSDMMCregs->rSDIRSP1;
r3=v_pSDMMCregs->rSDIRSP2;
r4=v_pSDMMCregs->rSDIRSP3;
c_size=((r2&0x3ff)<<2)+(r3>>30);
c_size_mult=(r3>>15)&0x07;
read_bl_len=(r2>>16)&0x0f;
num=(c_size+1)*(1<<(c_size_mult+2))*(1<<read_bl_len)/512;
if((num>0x190000)&&(num<0x210000))num=0x200000;/*1G*/
if((num>0x90000)&&(num<0x110000))num=0x100000; /*512M*/
if((num>0x70000)&&(num<0x90000))num=0x80000; /*256M*/
if((num>0x30000)&&(num<0x50000))num=0x40000; /*128M*/
if((num>0x19000)&&(num<0x21000))num=0x20000; /*64M*/
if((num>0x9000)&&(num<0x11000))num=0x10000; /*32M*/
/* printf("\nDATA:disk_size=0x%x.\n,r1=0x%x.\n,r2=0x%x.\n,r3=0x%x.\n,r4=0x%x.\n",num,r1,r2,r3,r4);
printf("c_size=0x%x.\n,c_size_mult=0x%x.\n,read_bl_len=0x%x.\n",c_size,c_size_mult,read_bl_len);*/
return num;
}
/******************************************************************************/
int Chk_SD_OCR(void)
{
int i,j;
for(i=0;i<20;i++)
{
CMD55(); /*Make ACMD*/
v_pSDMMCregs->rSDICMDARG=0xff8000; /*ACMD41(OCR:2.7V~3.6V)*/
v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x69;/*sht_resp, wait_resp, start, ACMD41*/
if(Chk_CMDend(41,1)& (v_pSDMMCregs->rSDIRSP0==0x80ff8000)) /*OCR最高位为0表示正在POWER UP*/
{
return 1; /*Success*/
}
for(j=0;j<5000;j++); /*Wait Card power up status*/
}
return 0; /*Fail*/
}
int Chk_MMC_OCR(void)
{
int i;
if(v_pSDMMCregs==NULL)
return 0;
/*Negotiate operating condition for MMC,it makes card ready state*/
for(i=0;i<15;i++)
{
v_pSDMMCregs->rSDICMDARG=0xff8000; /*CMD1(OCR:2.7V~3.6V)*/
v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x41; /*sht_resp,wait_resp,start,CMD1*/
/*Check end of CMD1*/
if(Chk_CMDend(1,1)&v_pSDMMCregs->rSDIRSP0==0x80ff8000)
{
return 1; /*Success*/
}
}
return 0; /*Failed*/
}
void SetBus(void)
{
SET_BUS:
CMD55(); /*Make ACMD*/
/*CMD6 implement*/
v_pSDMMCregs->rSDICMDARG=Wide<<1; /*Wide 0: 1bit,1: 4bit*/
v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x46; /*sht_resp,wait_resp,start,CMD55*/
if(!Chk_CMDend(6,1)) /*ACMD6*/
goto SET_BUS;
}
void Set_1bit_bus(void)
{
Wide=0;
if(!gMMC)
SetBus();
}
void Set_4bit_bus(void)
{
Wide=1;
SetBus();
}
BOOL mmc_card_init(void)
{
return 1;
}
void init_reg(void)
{
v_pSDMMCregs=NULL;
v_pIOPregs=NULL;
v_pSDMMCregs=(volatile MMCreg*)malloc(sizeof(MMCreg));
if(v_pSDMMCregs==NULL) printf("MMCreg malloc fail!");
else v_pSDMMCregs=(MMCreg *)SD_BASE;
v_pIOPregs=(volatile EIOreg *)malloc(sizeof(EIOreg));
if(v_pIOPregs==NULL) printf("EIOreg malloc fail!");
else v_pIOPregs=(EIOreg *)IO_BASE;
}
UINT32 InitSDMMC(void)
{
/*成功返回1*/
int i;
UINT32 SD_Size;
g_bSDMMCIsExist=FALSE;
printf("initisizing.......");
init_reg();
if(v_pIOPregs==NULL)
return 0;
if(v_pSDMMCregs==NULL)
return 0;
for(i=0;i<0x5000;i++);/*max time for power up=250ms*/
rCLKCON=rCLKCON|(1<<9); /*open SD clock*/
v_pIOPregs->rGPEUP=0xf83f; /*The pull up*/
v_pIOPregs->rGPECON=0xaaaaaaaa;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -