BeRTOS
|
00001 00038 /*-----------------------------------------------------------------------*/ 00039 /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ 00040 /*-----------------------------------------------------------------------*/ 00041 00042 #include <fs/fatfs/diskio.h> 00043 #include <stdio.h> 00044 #include <errno.h> 00045 #include <time.h> 00046 00047 #define SECTOR_SIZE 512 00048 00049 static volatile DSTATUS Stat = STA_NOINIT; 00050 00057 /*-----------------------------------------------------------------------*/ 00058 /* Inidialize a Drive */ 00059 00060 static FILE *fake_disk = 0; 00061 00062 DSTATUS disk_initialize ( 00063 BYTE drv /* Physical drive nmuber (0..) */ 00064 ) 00065 { 00066 if (drv) 00067 return STA_NOINIT; /* Support only drive 0 */ 00068 // XXX: pay attention here: some functions call disk_initialize *after* it has 00069 // been initialized for the first time. 00070 // Here we just return the status (that should always be ~STA_NOINIT after the first 00071 // call) 00072 if (fake_disk) 00073 return Stat; 00074 00075 const char *path = "emuldisk.dsk"; 00076 fake_disk = fopen(path, "w+"); 00077 int err = errno; 00078 if (!fake_disk) 00079 { 00080 switch (err) 00081 { 00082 case EINVAL: 00083 fprintf(stderr, "invalid mode\n"); 00084 default: 00085 return STA_NOINIT; 00086 } 00087 } 00088 Stat &= ~STA_NOINIT; 00089 return Stat; 00090 } 00091 00092 00093 00094 /*-----------------------------------------------------------------------*/ 00095 /* Return Disk Status */ 00096 00097 DSTATUS disk_status ( 00098 BYTE drv /* Physical drive nmuber (0..) */ 00099 ) 00100 { 00101 if (drv) 00102 return STA_NOINIT; /* Support only drive 0 */ 00103 return Stat; 00104 } 00105 00106 00107 00108 /*-----------------------------------------------------------------------*/ 00109 /* Read Sector(s) */ 00110 00111 DRESULT disk_read ( 00112 BYTE drv, /* Physical drive nmuber (0..) */ 00113 BYTE *buff, /* Data buffer to store read data */ 00114 DWORD sector, /* Sector address (LBA) */ 00115 BYTE count /* Number of sectors to read (1..255) */ 00116 ) 00117 { 00118 if (drv || !count) return RES_PARERR; 00119 if (Stat & STA_NOINIT) return RES_NOTRDY; 00120 00121 fseek(fake_disk, sector * SECTOR_SIZE, SEEK_SET); 00122 size_t read_items = fread(buff, SECTOR_SIZE, count, fake_disk); 00123 if (read_items == count) 00124 return RES_OK; 00125 else 00126 { 00127 if (feof(fake_disk)) 00128 fprintf(stderr, "end-of-file\n"); 00129 if (ferror(fake_disk)) 00130 fprintf(stderr, "error\n"); 00131 return RES_ERROR; 00132 } 00133 } 00134 00135 00136 /*-----------------------------------------------------------------------*/ 00137 /* Write Sector(s) */ 00138 00139 #if _READONLY == 0 00140 DRESULT disk_write ( 00141 BYTE drv, /* Physical drive nmuber (0..) */ 00142 const BYTE *buff, /* Data to be written */ 00143 DWORD sector, /* Sector address (LBA) */ 00144 BYTE count /* Number of sectors to write (1..255) */ 00145 ) 00146 { 00147 if (drv || !count) return RES_PARERR; 00148 if (Stat & STA_NOINIT) return RES_NOTRDY; 00149 if (Stat & STA_PROTECT) return RES_WRPRT; 00150 00151 fseek(fake_disk, sector * SECTOR_SIZE, SEEK_SET); 00152 size_t write_items = fwrite(buff, SECTOR_SIZE, count, fake_disk); 00153 if (write_items == count) 00154 return RES_OK; 00155 else 00156 { 00157 if (feof(fake_disk)) 00158 fprintf(stderr, "end-of-file\n"); 00159 if (ferror(fake_disk)) 00160 fprintf(stderr, "error\n"); 00161 return RES_ERROR; 00162 } 00163 } 00164 #endif /* _READONLY */ 00165 00166 00167 00168 /*-----------------------------------------------------------------------*/ 00169 /* Miscellaneous Functions */ 00170 00171 DRESULT disk_ioctl ( 00172 BYTE drv, /* Physical drive nmuber (0..) */ 00173 BYTE ctrl, /* Control code */ 00174 void *buff /* Buffer to send/receive control data */ 00175 ) 00176 { 00177 if (drv) return RES_PARERR; 00178 if (Stat & STA_NOINIT) return RES_NOTRDY; 00179 00180 switch (ctrl) 00181 { 00182 case GET_SECTOR_SIZE: 00183 *(WORD*)buff = SECTOR_SIZE; 00184 break; 00185 case GET_SECTOR_COUNT: 00186 *(DWORD*)buff = 65536; 00187 break; 00188 case GET_BLOCK_SIZE: 00189 *(DWORD*)buff = 1; 00190 break; 00191 case CTRL_SYNC: 00192 fflush(fake_disk); 00193 break; 00194 default: 00195 return RES_PARERR; 00196 } 00197 return RES_OK; 00198 } 00199 00200 DWORD get_fattime(void) 00201 { 00202 time_t tmp = time(0); 00203 struct tm *t = localtime(&tmp); 00204 DWORD tim = 0; 00205 // seconds 00206 tim |= (t->tm_sec / 2); 00207 // min 00208 tim |= (t->tm_min << 5); 00209 // hour 00210 tim |= (t->tm_hour << 11); 00211 // month day (1..31) 00212 tim |= (t->tm_mday << 16); 00213 // month (1..12) 00214 tim |= ((t->tm_mon + 1) << 21); 00215 // year (0..127) 00216 tim |= ((t->tm_year - 80) << 25); 00217 return tim; 00218 } 00219