
/***********************************************************************
*                          Micrium, Inc.
*                      949 Crestview Circle
*                     Weston,  FL 33327-1848
*
*                            uC/FS
*
*             (c) Copyright 2001 - 2007, Micrium, Inc.
*                      All rights reserved.
*
***********************************************************************

----------------------------------------------------------------------
File        : generic_drv.c
Purpose     : DE2 SD CARD DEIVE driver
----------------------------------------------------------------------

This is an example driver that should help implementing any kind of
data storage devices into the filesystem. The device you may use does
not need to provide any special functions other than reading data from
a given sector address.

---------------------------END-OF-HEADER------------------------------
*/
//由于ucfs 没有 mmc和 sd的驱动文件.这个是本人结合SD协议写的基于SD模式的SD卡读写，只供参考
/*
********************************************************************
*
*       #include Section
*
**********************************************************************
*/
#include "SD_Card.h"
#include "fs_dev.h"
#include "fs_lbl.h"
#include "fs_port.h"
#include "include.h"
#include <includes.h>

/*********************************************************************
*  Wether this driver is being compiled into the FS or not can be
*  switched on/off in the global configuration file "fs_conf.h".
*  Refer the corresponding #define in the section "Device Driver Support"
*/

//#if FS_USE_GENDEV_DRIVER /* only compiled if needed */
#if  FS_USE_MMC_DRIVER      //because no mmc driver ,so modify it

#include "fs_api.h"   /* Standard includes that always must be included. */
#include "fs_clib.h"
#include "includes.h"
//#include "mmc.h"        //包含读写mmc_sdc的基本函数库


BYTE Firstsector_buff[512] ;


/*********************************************************************
*
*       #defines configurable
*
**********************************************************************/

static FS_u32   _FS_mmc_logicalstart[FS_MMC_MAXUNIT];     /* start of partition */
/*********************************************************************
*
*  Sets the maximum number of devices that this driver can address.
*/
#define FS_GENDEV_MAX_DEVICE 1

/*********************************************************************
*  If the media size always remains the same, you can define a
*  constant size here.
*/
#define FS_GENDEV_NUMSEC            250000  //

/*********************************************************************
*
*  If the bytes per sector size does not change, you can define a
*  constant size here.
*/
#define FS_GENDEV_BYTESPERSECTOR     512

BYTE read_status;
BYTE write_status;   //写u25805 作u30340 状u24577 
BYTE response_buffer[20];
//BYTE csdbuf[17];
BYTE RCA[2];
BYTE cmd_buffer[5];
const BYTE cmd0[5]   = {0x40,0x00,0x00,0x00,0x00};//Resetting a card
const BYTE cmd55[5]  = {0x77,0x00,0x00,0x00,0x00};
const BYTE cmd2[5]   = {0x42,0x00,0x00,0x00,0x00};//get its unique card identification (CID) number.
const BYTE cmd3[5]   = {0x43,0x00,0x00,0x00,0x00};//asking the card to publish a new relative card address (RCA)
const BYTE cmd7[5]   = {0x47,0x00,0x00,0x00,0x00};//CMD7 is used to select one SD Card and place it in the Transfer State
const BYTE cmd9[5]   = {0x49,0x00,0x00,0x00,0x00};//Addressed card sends its card-specific data (CSD)on the CMD line.
const BYTE cmd12[5]  = {0x4C,0x00,0x00,0x00,0x00};//stop command
const BYTE cmd13[5]  = {0x4D,0x00,0x00,0x00,0x00};//Addressed card sends its status register.
const BYTE cmd16[5]  = {0x50,0x00,0x00,0x02,0x00};//set block length
const BYTE cmd17[5]  = {0x51,0x00,0x00,0x00,0x00};
const BYTE cmd18[5]  = {0x52,0x00,0x00,0x00,0x00};
const BYTE cmd30[5]  = {0x5E,0x00,0x00,0x00,0x00};
const BYTE cmd32[5]  = {0x60,0x00,0x00,0x00,0x00};//erase block start
const BYTE cmd33[5]  = {0x61,0x00,0x00,0x00,0x00};//erase block end
const BYTE cmd38[5]  = {0x66,0x00,0x00,0x00,0x00};
const BYTE cmd24[5]  = {0x58,0x00,0x00,0x00,0x00}; 
const BYTE cmd25[5]  = {0x59,0x00,0x00,0x00,0x00};
const BYTE cmd27[5]  = {0x5B,0x00,0x00,0x00,0x00}; //write CSD
const BYTE cmd56[5]  = {0x78,0x00,0x00,0x00,0x00}; //generalcommand in write mode 
const BYTE cmd42[5]  = {0x6A,0x00,0x00,0x00,0x00}; //lock/unlock command  
const BYTE acmd6[5]  = {0x46,0x00,0x00,0x00,0x02};
const BYTE acmd41[5] = {0x69,0x0f,0xf0,0x00,0x00};
const BYTE acmd51[5] = {0x73,0x00,0x00,0x00,0x00};
const BYTE cmd29[5] =  {0x5d,0x00,0x00,0x00,0x00};
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
void N_busy(void)
{
  int i;
  SD_CMD_IN;
  for(i=0;i<6;i++)
  {
    SD_CLK_LOW;
    SD_CLK_HIGH;
  }
 
} 

//-------------------------------------------------------------------------
void Ncr(void)
{
  SD_CMD_IN;
  SD_CLK_LOW;
  SD_CLK_HIGH;
  SD_CLK_LOW;
  SD_CLK_HIGH;
} 
//-------------------------------------------------------------------------
void Ncc(void)
{
  int i;
  for(i=0;i<8;i++)
  {
    SD_CLK_LOW;
    SD_CLK_HIGH;
  }
}
//-------------------------------------------------------------------------
BYTE SD_card_init(void)
{
    BYTE x,y;
    SD_CMD_OUT;
    SD_DAT_IN;
    SD_CLK_HIGH;
    SD_CMD_HIGH;
    SD_DAT_LOW;
    read_status=0;
    for(x=0;x<40;x++)
    Ncr();
    for(x=0;x<5;x++)
    cmd_buffer[x]=cmd0[x];
    y = send_cmd(cmd_buffer);
    do
    {
      for(x=0;x<40;x++);
      Ncc();
      for(x=0;x<5;x++)
      cmd_buffer[x]=cmd55[x];
      y = send_cmd(cmd_buffer);
      Ncr();
      if(response_R(1)>1) //response too long or crc error
      return 1;
      Ncc();
      for(x=0;x<5;x++)
      cmd_buffer[x]=acmd41[x];
      y = send_cmd(cmd_buffer);
      Ncr();      
    } while(response_R(3)==1);
    Ncc();
    for(x=0;x<5;x++)
    cmd_buffer[x]=cmd2[x];
    y = send_cmd(cmd_buffer);
    Ncr();
    if(response_R(2)>1)
    return 1;
    Ncc();
    for(x=0;x<5;x++)
    cmd_buffer[x]=cmd3[x];
    y = send_cmd(cmd_buffer);
    Ncr();
    if(response_R(6)>1)
    return 1;         
    RCA[0]=response_buffer[1];
    RCA[1]=response_buffer[2];
    Ncc();
    for(x=0;x<5;x++)
    cmd_buffer[x]=cmd9[x];
    cmd_buffer[1] = RCA[0];
    cmd_buffer[2] = RCA[1];  
    y = send_cmd(cmd_buffer);
    Ncr();
    if(response_R(2)>1)
    return 1; 
    Ncc();
    for(x=0;x<5;x++)
    cmd_buffer[x]=cmd7[x];
    cmd_buffer[1] = RCA[0];
    cmd_buffer[2] = RCA[1];
    y = send_cmd(cmd_buffer);
    Ncr();
    if(response_R(1)>1)
    return 1; 
    Ncc();
    for(x=0;x<5;x++)
    cmd_buffer[x]=cmd16[x];
    y = send_cmd(cmd_buffer);  
    Ncr();
    if(response_R(1)>1)
    return 1;
    read_status =1; //sd card ready
    return 0;
  }

BYTE SD_EraseBlock(UINT32 startaddr, UINT32 num)
{   
    BYTE i;
    Ncc();
    for(i=0;i<5;i++)
    cmd_buffer[0]=  cmd32[0];
    cmd_buffer[1] = (startaddr>>15)&0xff; 
    cmd_buffer[2] = (startaddr>>7)&0xff;
    cmd_buffer[3] = (startaddr<<1)&0xff;
    cmd_buffer[4] = 0;
    send_cmd(cmd_buffer);  
    Ncr();
    if(response_R(1)>1)
    return 1;
    Ncc();
    for(i=0;i<5;i++)
    cmd_buffer[0]=  cmd33[0];
    cmd_buffer[1] = ((startaddr+num-1)>>15)&0xff; 
    cmd_buffer[2] = ((startaddr+num-1)>>7)&0xff;
    cmd_buffer[3] = ((startaddr+num-1)<<1)&0xff;
    cmd_buffer[4] = 0;
    send_cmd(cmd_buffer);  
    Ncr();
    if(response_R(1)>1)
    return 1;
    Ncc();
    for(i=0;i<5;i++)
    cmd_buffer[i]=cmd38[i];
    send_cmd(cmd_buffer);  
    Ncr();
    if(response_R(1)>1)
    return 1;
    while(1)
    {
      SD_CLK_LOW;
      SD_CLK_HIGH;      
      if(SD_TEST_DAT)
      break;
    }     
 }

//-------------------------------------------------------------------------
BYTE  exam_crc (void)
{
  BYTE c = 0,i;
  SD_DAT_IN;  
   while(1)
    {
      SD_CLK_LOW;
      SD_CLK_HIGH;      
      if(!(SD_TEST_DAT))
      break;
    }
    for(i=0;i<4;i++)    
      {
           SD_CLK_LOW;
           SD_CLK_HIGH;      
           c <<= 1;            
           if(SD_TEST_DAT)     c |= 0x01;            
         
       }         
    
    if(c==9)
    {
     printf("transmisson error\n");
     return 1;
    }
    else if(c==5)
    {
     printf("transmisson success\n");
    } 
    else if(c==0xf)
    {
     printf("Card is busy \n");
    } 
    
  while(1)
    {
      SD_CLK_LOW;
      SD_CLK_HIGH;      
      if(SD_TEST_DAT)
      break;
    }  
    
   return 0 ;        
}
//-------------------------------------------------------------------------
UINT16 GetCRC16(BYTE  *pSource,   UINT16  len)
{
UINT16 const CRCTable[256]={0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
              0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
              0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
              0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
              0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
              0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
              0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
              0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
              0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
              0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
              0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
              0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
              0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
              0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
              0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
              0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
              0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
              0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
              0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
              0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
              0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
              0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
              0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
              0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
              0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
              0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
              0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
              0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
              0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
              0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
              0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
              0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 };
  
  UINT32  crc = 0;
  BYTE da;
  while(len--!=0) {
  da=(BYTE) (crc/256); 
  crc<<=8; 
  crc^=(UINT16)CRCTable[da^*pSource]; 
  pSource++;
 }
return(crc);
}

//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
BYTE SD_read_lba(FS_u32 Unit,UINT32 Sector, BYTE  *pBuffer)
{
  
  BYTE c=0;
  UINT32  i;
  SD_CMD_OUT;  
  SD_DAT_IN; 
               
      Ncc();         
      cmd_buffer[0] = cmd17[0];
      cmd_buffer[1] = (Sector>>15)&0xff; 
      cmd_buffer[2] = (Sector>>7)&0xff;
      cmd_buffer[3] = (Sector<<1)&0xff;
      cmd_buffer[4] = 0;
      Sector++;
      send_cmd(cmd_buffer); 
      Ncr();
     
  while(1)
    {
      SD_CLK_LOW;
      SD_CLK_HIGH;
      if(!(SD_TEST_DAT))
      break;
    }
    
    for(i=0;i<512;i++)
    {
      BYTE j;
      for(j=0;j<8;j++)
      {
        SD_CLK_LOW;
        SD_CLK_HIGH;
        c <<= 1; 
        if(SD_TEST_DAT)
        c |= 0x01;
      } 
      *pBuffer=c;
      pBuffer++;
    } 
    for(i=0; i<16; i++)
    {
        SD_CLK_LOW;
        SD_CLK_HIGH;
    }
  read_status = 1;  //SD data next in
  return 0;
}
//-------------------------------------------------------------------------
BYTE response_R(BYTE s)
{
  BYTE a=0,b=0,c=0,r=0,crc=0;
  BYTE i,j=6,k;
  while(1)
  {
    SD_CLK_LOW;
    SD_CLK_HIGH;
    if(!(SD_TEST_CMD))
    break;
    if(crc++ >100)
    return 2;
  } 
  crc =0;
  if(s == 2)
  j = 17;

  for(k=0; k<j; k++)
  {
    c = 0;
    if(k > 0)                      //for crc culcar
    b = response_buffer[k-1];    
    for(i=0; i<8; i++)
    {
      SD_CLK_LOW;
      if(a > 0)
      c <<= 1; 
      else
      i++; 
      a++; 
      SD_CLK_HIGH;
      if(SD_TEST_CMD)
      c |= 0x01;
      
      if(k > 0)
      {
        crc <<= 1;
        if((crc ^ b) & 0x80)
        crc ^= 0x09;
        b <<= 1;
        crc &= 0x7f;
      }
    }
    if(s==3)
    { 
      if( k==1 &&(!(c&0x80)))
      r=1;
    }
    response_buffer[k] = c;
  }
  if(s==1 || s==6)
  {
    if(c != ((crc<<1)+1))
    r=2;
  } 
  return r; 
}
//-------------------------SD_write_lba----------------------------------------
BYTE SD_write_lba(FS_u32 Unit,UINT32 Sector, BYTE  *pBuffer)  
{       
  SD_DAT_OUT ;
  BYTE b;
  UINT32 crc=0;
  UINT16 cr=0;
  UINT32  i,k;
      Ncc();
      cmd_buffer[0] = cmd24[0];
      cmd_buffer[1] = (Sector>>15)&0xff; 
      cmd_buffer[2] = (Sector>>7)&0xff;
      cmd_buffer[3] = (Sector<<1)&0xff;
      cmd_buffer[4] = 0;
      send_cmd(cmd_buffer); 
      Ncr();
      if(response_R(1)>1) 
      return 1;
     
   Ncr();
   SD_CLK_LOW;
   SD_DAT_LOW; 
   SD_CLK_HIGH;    
    for(i=0; i < 512; i++)  
   {
    b = pBuffer[ i ];
    for(k=0; k<8; k++)  
    {
      SD_CLK_LOW;   
      if(b&0x80)        
      SD_DAT_HIGH; 
      else 
      SD_DAT_LOW;     
      SD_CLK_HIGH;       
      b<<=1;   
    }   
   }  
   
  cr = GetCRC16(pBuffer, 512);                
  crc = cr & 0xffff ;  
  crc =((crc<<1)|0x01);
 
  for(k=0; k<17; k++)  
  {
    SD_CLK_LOW;
    if(crc&0x10000)
    SD_DAT_HIGH;
    else
    SD_DAT_LOW; 
    SD_CLK_HIGH;
    crc<<=1;
  }       
  exam_crc ();
  N_busy(); 
  return 0;
}
//-------------------------------------------------------------------------
BYTE send_cmd(BYTE *in)
{
  int i,j;
  BYTE b,crc=0;
  SD_CMD_OUT;
  for(i=0; i < 5; i++)
  {
    b = in[i];
    for(j=0; j<8; j++)
    {
      SD_CLK_LOW;
      if(b&0x80)
      SD_CMD_HIGH;
      else
      SD_CMD_LOW; 
      crc <<= 1;
      SD_CLK_HIGH;
      if((crc ^ b) & 0x80)
      crc ^= 0x09;
      b<<=1;
    } 
    crc &= 0x7f; 
  }  
  crc =((crc<<1)|0x01);
  b = crc; 
  for(j=0; j<8; j++)
  {
    SD_CLK_LOW;
    if(crc&0x80)
    SD_CMD_HIGH;
    else
    SD_CMD_LOW; 
    SD_CLK_HIGH;
    crc<<=1;
  }    
  return b;   
}


/*********************************************************************
*
*       Static data
*
**********************************************************************
*/

/*********************************************************************
*  To make sure you initialize the device only once, use a static
*  variable for that purpose.
*/
static int _GenDev_Status[FS_GENDEV_MAX_DEVICE];

/*********************************************************************
*
*       Static code
*
**********************************************************************
*/

/*********************************************************************
*
*       _GENDEV_DevStatus
*
*  Description:
*    FS driver function. Gets status of the device. This function is also
*    used to initialize the device and to detect a media change.
*
*  Parameters:
*    Unit                  - Device number.
*
*  Return value:
*    ==1 (FS_LBL_MEDIA_CHANGED) - The media of the device has changed.
*    ==0                       - Device okay and ready for operation.
*  <0                          - An error has occured.
*/

static int _GENDEV_DevStatus(FS_u32 Unit)
{
  static int init;
  int x;
  char a;

  if (!init) {
    /*
       The function is called the first time. For each unit,
       the flag for 'diskchange' is set. That makes sure, that
       FS_LBL_MEDIACHANGED is returned, if there is already a
       media in the reader.
    */
    for (init = 0; init <FS_GENDEV_MAX_DEVICE; init++) {
      _GenDev_Status[init] = 1;
    }
    init = 1;
   }
  if (Unit >= FS_GENDEV_MAX_DEVICE)
   {
    return -1;  /* No valid unit number */
   }
  a = SD_card_init();  //初始化一张卡 ，
  if (a!=0x0)            //如果不能初始化一张卡
   {
    return -1;            /* No card in reader */
   }
  /* When you get here, then there is a card in the reader */
  a = _GenDev_Status[Unit];  /* Check if the media has changed */
  if (a){
    /*
       A diskchange took place. The following code reads the MBR of the
       card to get its partition information.
    */
    _GenDev_Status[Unit] = 0;  /* Reset 'diskchange' flag */
    SD_card_init();         //由于工作再单卡状态，其实不用选择
    
    x = SD_read_lba(Unit, 0, Firstsector_buff);

    //SD_read_multilba(mmc_buff,0,1 ); 

    //x = disk_read
      // (
	//mmc_buff,		/* Data buffer to store read data */
	//0,		        /* Sector number (LBA) */
	//1			/* Sector count (1..255) */
      // )   ;
    if (x != 0)
     {
      return -1;
     }
    _FS_mmc_logicalstart[Unit]=0;
    return FS_LBL_MEDIACHANGED;
  }
  return 0;
}

/*********************************************************************
*
*       _GENDEV_DevRead
*
*  Description:
*    FS driver function. Read a sector from the medium.
*
*  Parameters:
*    Unit            - Device number.
*    Sector          - Sector to be read from the device.
*    pBuffer         - Pointer to buffer for storing the data.
*
*    Return value:
*    ==0             - Sector has been read and copied to pBuffer.
*    <0              - An error has occured.
*/
//here ,i see the parameter that unit as number of the read sectors

static int _GENDEV_DevRead(FS_u32 Unit, FS_u32 Sector, BYTE *pBuffer)
 {
    int x;
    printf("hello _FS_GENDEV_DevRead\n");
    if (Sector >= FS_GENDEV_NUMSEC)
     {
      return -1;  /* Out of sector range */
     }
   x = SD_read_lba(Unit, Sector, pBuffer);
   
    if (x != 0) {
       x = -1;
     }
  return x;
}

/*********************************************************************
*
*       _GENDEV_DevWrite
*
*  Description:
*  FS driver function. Write sector to the RAM disk.
*
*  Parameters:
*    Unit        - Device number.
*    Sector          - Sector to be written to the device.
*    pBuffer         - Pointer to data to be stored.
*
*  Return value:
*    ==0             - Sector has been written to the device.
*    <0              - An error has occured.
*/
static int _GENDEV_DevWrite(FS_u32 Unit, FS_u32 Sector, BYTE *pBuffer) {
  int x;
  
  if (Sector >= FS_GENDEV_NUMSEC) {
    return -1;  /* Out of sector range */
  }
  
  x =SD_write_lba( Unit,Sector, pBuffer); 
  if (x != 0) {
    x = -1;
  }
  return x;
 }



/*********************************************************************
*
*             _GENDEV_DevIoCtl
*
*  Description:
*    FS driver function. Execute device command.
*
*  Parameters:
*    Unit    - Device number.
*    Cmd         - Command to be executed.
*    Aux         - Parameter depending on command.
*    pBuffer     - Pointer to a buffer used for the command.
*
*  Return value:
*    This function is used to execute device specific commands.
*    In the file fs_api.h you can find I/O commands that are currently
*    implemented. If the higher layers don't know the command, they
*    send it to the next lower. Your driver does not have to
*    implement one of these commands. Only if automatic formatting
*    is used or user routines need to get the size of the medium,
*    FS_CMD_GET_DEVINFO must be implemented.
*/
static int _GENDEV_DevIoCtl(FS_u32 Unit, FS_i32 Cmd, FS_i32 Aux, void *pBuffer) {
  return 0;  
}


/*********************************************************************
*
*       _GENDEV_InitDevice
*
*  Description:
*  Initializes the device drivers internal variables and hardware.
*
*  Parameters:
*    Unit        - Device number.
*
*  Return value:
*    ==0             - Sector has been written to the device.
*    <0              - An error has occured.
*/
static int _GENDEV_InitDevice(FS_u32 Unit) {
  int x;
    x = SD_card_init();
   if (x != 0) {
    x = -1;
  }
  return x;
}

/*********************************************************************
*
*       Public data
*
**********************************************************************
*/

/* This structure contains pointers to the functions that all drivers
   of the file system must provide. */
const FS__device_type FS__mmcdevice_driver=
 {
  "mmc",
  _GENDEV_DevStatus,
  _GENDEV_DevRead,
  _GENDEV_DevWrite,
  _GENDEV_DevIoCtl,
};



#endif /* FS_USE_MMC_DRIVER */

/*************************** End of file ****************************/
