SAMV71 Xplained Ultra Software Package 1.0

diskio_samv7x.c

00001 /*-----------------------------------------------------------------------*/
00002 /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2007        */
00003 /*-----------------------------------------------------------------------*/
00004 /* This is a stub disk I/O module that acts as front end of the existing */
00005 /* disk I/O modules and attach it to FatFs module with common interface. */
00006 /*-----------------------------------------------------------------------*/
00007 
00008 #include "board.h"
00009 #include "libstoragemedia.h"
00010 
00011 #include "diskio.h"
00012 #include "integer.h"
00013 #include "..\fatfs_config.h"
00014 
00015 #include <string.h>
00016 #include <stdio.h>
00017 #include <assert.h>
00018 
00019 #define MAX_MEDS        1
00020 
00021 sMedia medias[MAX_MEDS];
00022 /** SDCard driver instance. */
00023 sSdCard sdDrv[BOARD_NUM_MCI];
00024 
00025 
00026 /*-----------------------------------------------------------------------*/
00027 /* Initialize a Drive                                                    */
00028 /*-----------------------------------------------------------------------*/
00029 
00030 
00031 DSTATUS disk_initialize (
00032     BYTE drv                /* Physical drive number (0..) */
00033 )
00034 {
00035     DSTATUS stat = STA_NOINIT;
00036 
00037     switch (drv)
00038     {
00039         case DRV_SDRAM :
00040             stat = 0;
00041             break;
00042 
00043         case DRV_MMC :
00044             stat = 0;
00045             TRACE_INFO("Init media Sdcard\n\r");
00046             if(!(MEDSdcard_Initialize(&medias[drv], &sdDrv[drv])))
00047             {
00048               TRACE_ERROR(" SD Init fail\n\r ");
00049               stat = 1;
00050             }
00051             break;
00052 
00053         case DRV_NAND:
00054             stat = 0;
00055             break;
00056     }
00057 
00058     return stat;
00059 }
00060 
00061 /*-----------------------------------------------------------------------*/
00062 /* Return Disk Status                                                    */
00063 /*-----------------------------------------------------------------------*/
00064 
00065 DSTATUS disk_status (
00066     BYTE drv        /* Physical drive number (0..) */
00067 )
00068 {
00069     DSTATUS stat=STA_NOINIT;
00070 
00071     switch (drv)
00072     {
00073         case DRV_SDRAM :
00074             stat = 0;  // ok
00075             break;
00076 
00077         case DRV_MMC :
00078             stat = 0;  // ok
00079             break;
00080         case DRV_NAND:
00081             stat = 0;
00082             break;
00083     }
00084 
00085     return stat;
00086 }
00087 
00088 /*-----------------------------------------------------------------------*/
00089 /* Read Sector(s)                                                        */
00090 /*-----------------------------------------------------------------------*/
00091 
00092 DRESULT disk_read (
00093     BYTE drv,        /* Physical drive number (0..) */
00094     BYTE *buff,        /* Data buffer to store read data */
00095     DWORD sector,    /* Sector address (LBA) */
00096     UINT count        /* Number of sectors to read (1..255) */
00097 )
00098 {
00099     unsigned char result;
00100     DRESULT res = RES_ERROR;
00101 
00102     unsigned int addr, len;
00103     if (medias[drv].blockSize < SECTOR_SIZE_DEFAULT)
00104     {
00105         addr = sector * (SECTOR_SIZE_DEFAULT / medias[drv].blockSize);
00106         len  = count * (SECTOR_SIZE_DEFAULT / medias[drv].blockSize);
00107     }
00108     else
00109     {
00110         addr = sector;
00111         len  = count;
00112     }
00113 
00114     result = MED_Read(&medias[drv], addr, (void*)buff, len, NULL, NULL);
00115 
00116     if( result == MED_STATUS_SUCCESS )
00117     {
00118         res = RES_OK;
00119     }
00120     else
00121     {
00122         TRACE_ERROR("MED_Read pb: 0x%X\n\r", result);
00123         res = RES_ERROR;
00124     }
00125    return res;
00126 }
00127 
00128 /*-----------------------------------------------------------------------*/
00129 /* Write Sector(s)                                                       */
00130 /*-----------------------------------------------------------------------*/
00131 /* The FatFs module will issue multiple sector transfer request
00132 /  (count > 1) to the disk I/O layer. The disk function should process
00133 /  the multiple sector transfer properly Do. not translate it into
00134 /  multiple single sector transfers to the media, or the data read/write
00135 /  performance may be drastically decreased. */
00136 
00137 #if _FS_READONLY == 0
00138 DRESULT disk_write (
00139     BYTE drv,            /* Physical drive number (0..) */
00140     const BYTE *buff,    /* Data to be written */
00141     DWORD sector,        /* Sector address (LBA) */
00142     UINT count            /* Number of sectors to write (1..255) */
00143 )
00144 {
00145     DRESULT res=RES_PARERR;
00146     unsigned int result;
00147     void * tmp;
00148     tmp = (void *) buff;
00149 
00150     unsigned int addr, len;
00151     if (medias[drv].blockSize < SECTOR_SIZE_DEFAULT)
00152     {
00153         addr = sector * (SECTOR_SIZE_DEFAULT / medias[drv].blockSize);
00154         len  = count * (SECTOR_SIZE_DEFAULT / medias[drv].blockSize);
00155     }
00156     else
00157     {
00158         addr = sector;
00159         len  = count;
00160     }
00161 
00162     result = MED_Write(&medias[drv], addr, (void*)tmp, len, NULL, NULL);
00163 
00164     if( result == MED_STATUS_SUCCESS )
00165     {
00166         res = RES_OK;
00167     }
00168     else
00169     {
00170         TRACE_ERROR("MED_Write pb: 0x%X\n\r", result);
00171         res = RES_ERROR;
00172     }
00173 
00174     return res;
00175 }
00176 #endif /* _FS_READONLY */
00177 
00178 /*-----------------------------------------------------------------------*/
00179 /* Miscellaneous Functions                                               */
00180 // Command    Description
00181 //
00182 //CTRL_SYNC    Make sure that the disk drive has finished pending write process.
00183 // When the disk I/O module has a write back cache, flush the dirty sector immediately.
00184 // In read-only configuration, this command is not needed.
00185 //
00186 //GET_SECTOR_COUNT    Returns total sectors on the drive into the DWORD variable pointed by Buffer.
00187 // This command is used in only f_mkfs function.
00188 //
00189 //GET_BLOCK_SIZE    Returns erase block size of the memory array in unit
00190 // of sector into the DWORD variable pointed by Buffer.
00191 // When the erase block size is unknown or magnetic disk device, return 1.
00192 // This command is used in only f_mkfs function.
00193 /*-----------------------------------------------------------------------*/
00194 
00195 DRESULT disk_ioctl (
00196     BYTE drv,        /* Physical drive number (0..) */
00197     BYTE ctrl,        /* Control code */
00198     void *buff        /* Buffer to send/receive control data */
00199 )
00200 {
00201     DRESULT res=RES_PARERR;
00202 
00203     switch (drv)
00204     {
00205         case DRV_SDRAM :
00206         switch (ctrl)
00207         {
00208             case GET_BLOCK_SIZE:
00209                 *(DWORD*)buff = 1;
00210                 res = RES_OK;
00211                 break;
00212 
00213             case GET_SECTOR_COUNT :   /* Get number of sectors on the disk (DWORD) */
00214                 if (medias[DRV_SDRAM].blockSize < SECTOR_SIZE_DEFAULT)
00215                 {
00216                     *(DWORD*)buff = (DWORD)(medias[DRV_SDRAM].size /
00217                                             (SECTOR_SIZE_DEFAULT /
00218                                             medias[DRV_SDRAM].blockSize));
00219                 }
00220                 else
00221                 {
00222                     *(DWORD*)buff = (DWORD)(medias[DRV_SDRAM].size);
00223                 }
00224                 res = RES_OK;
00225                 break;
00226 
00227             case GET_SECTOR_SIZE :   /* Get sectors on the disk (WORD) */
00228                 if (medias[DRV_SDRAM].blockSize < SECTOR_SIZE_DEFAULT)
00229                 {
00230                     *(WORD*)buff = SECTOR_SIZE_DEFAULT;
00231                 }
00232                 else
00233                 {
00234                     *(WORD*)buff = medias[DRV_SDRAM].blockSize;
00235                 }
00236                 res = RES_OK;
00237                 break;
00238 
00239             case CTRL_SYNC :   /* Make sure that data has been written */
00240                 res = RES_OK;
00241                 break;
00242 
00243             default:
00244                 res = RES_PARERR;
00245         }
00246         break;
00247 
00248         case DRV_MMC :
00249         switch (ctrl)
00250         {
00251             case GET_BLOCK_SIZE:
00252                 *(DWORD*)buff = 1;
00253                 res = RES_OK;
00254                 break;
00255 
00256             case GET_SECTOR_COUNT :   /* Get number of sectors on the disk (DWORD) */
00257                 if (medias[DRV_MMC].blockSize < SECTOR_SIZE_DEFAULT)
00258                 {
00259                     *(DWORD*)buff = (DWORD)(medias[DRV_MMC].size /
00260                                                 (SECTOR_SIZE_DEFAULT /
00261                                                 medias[DRV_MMC].blockSize));
00262                 }
00263                 else
00264                 {
00265                     *(DWORD*)buff = (DWORD)(medias[DRV_MMC].size);
00266                 }
00267                 res = RES_OK;
00268                 break;
00269 
00270             case GET_SECTOR_SIZE :   /* Get sectors on the disk (WORD) */
00271                 if (medias[DRV_MMC].blockSize < SECTOR_SIZE_DEFAULT)
00272                 {
00273                     *(WORD*)buff = SECTOR_SIZE_DEFAULT;
00274                 }
00275                 else
00276                 {
00277                     *(WORD*)buff = medias[DRV_MMC].blockSize;
00278                 }
00279                 res = RES_OK;
00280                 break;
00281 
00282             case CTRL_SYNC :   /* Make sure that data has been written */
00283                 res = RES_OK;
00284                 break;
00285 
00286             default:
00287                 res = RES_PARERR;
00288         }
00289         break;
00290 
00291         case DRV_NAND :
00292             switch (ctrl)
00293             {
00294                 case GET_BLOCK_SIZE:
00295                     *(DWORD*)buff = 1;
00296                     res = RES_OK;
00297                     break;
00298 
00299                 case GET_SECTOR_COUNT :   /* Get number of sectors on the disk (DWORD) */
00300                     if (medias[DRV_NAND].blockSize < SECTOR_SIZE_DEFAULT)
00301                     {
00302                         *(DWORD*)buff = (DWORD)(medias[DRV_NAND].size /
00303                                                 (SECTOR_SIZE_DEFAULT /
00304                                                 medias[DRV_NAND].blockSize));
00305                     }
00306                     else
00307                     {
00308                         *(DWORD*)buff = (DWORD)(medias[DRV_NAND].size);
00309                     }
00310                     res = RES_OK;
00311                     break;
00312 
00313                 case GET_SECTOR_SIZE :     /* Get sectors on the disk (WORD) */
00314                     if (medias[DRV_NAND].blockSize < SECTOR_SIZE_DEFAULT)
00315                     {
00316                         *(WORD*)buff = SECTOR_SIZE_DEFAULT;
00317                     }
00318                     else
00319                     {
00320                         *(WORD*)buff = medias[DRV_NAND].blockSize;
00321                     }
00322                     res = RES_OK;
00323                     break;
00324 
00325                 case CTRL_SYNC :   /* Make sure that data has been written */
00326                     MED_Flush(&medias[DRV_NAND]);
00327                     res = RES_OK;
00328                     break;
00329 
00330                 default:
00331                     res = RES_PARERR;
00332         }
00333     }
00334    return res;
00335 }
00336 
00337 //------------------------------------------------------------------------------
00338 /// Current time is returned with packed into a DWORD value.
00339 /// The bit field is as follows:
00340 ///   bit31:25  Year from 1980 (0..127)
00341 ///   bit24:21  Month (1..12)
00342 ///   bit20:16  Day in month(1..31)
00343 ///   bit15:11  Hour (0..23)
00344 ///   bit10:5   Minute (0..59)
00345 ///   bit4:0    Second / 2 (0..29)
00346 //------------------------------------------------------------------------------
00347 DWORD get_fattime (void)
00348 {
00349     unsigned int time;
00350 
00351     time =  ((2010-1980)<<25)
00352           | ( 9<<21)
00353           | (15<<16)
00354           | (17<<11)
00355           | (45<<5)
00356           | ((59/2)<<0);
00357 
00358     return time;
00359 }
00360 
00361 
00362 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines