⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atasd.c

📁 vxworks下SD卡及DOS文件系统驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -