SAMV71 Xplained Ultra Software Package 1.0

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