Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
diskio.c
00001 #include "mbed.h" 00002 #include "LPC17xx.h" 00003 #include "integer.h" 00004 #include "diskio.h" 00005 #include "stdarg.h" 00006 #include "USBHost.h" 00007 #include "Terminal.h" 00008 00009 /*-------------------------------------------------------------------------- 00010 00011 Module Private Functions 00012 00013 ---------------------------------------------------------------------------*/ 00014 00015 static volatile DSTATUS Stat[3] = {STA_NOINIT | STA_NODISK}; /* Disk status */ 00016 static volatile BYTE DiskProcTimer[3]={0}; /* 100Hz decrement timer */ 00017 00018 00019 00020 00021 00022 BYTE RAM_DISK[512]; 00023 00024 DWORD BlockSize; 00025 DWORD BlockCount; 00026 00027 //#define _CF_DEBUG_MESSAGES 00028 //#define _CF_DEBUG_READ_ATA 00029 00030 #ifdef _CF_DEBUG_MESSAGES 00031 #define CF_DEBUG(...) printf(__VA_ARGS__) 00032 #else 00033 #define CF_DEBUG do{}while(0); 00034 #endif 00035 00036 void disk_timerproc (void); 00037 00038 #define LED1_MASK (uint32_t )(1<<18) 00039 #define LED2_MASK (uint32_t )(1<<20) 00040 #define LED3_MASK (uint32_t )(1<<21) 00041 #define LED4_MASK (uint32_t )(1<<23) 00042 00043 00044 #define LED1_ON LPC_GPIO1->FIOSET=LED1_MASK 00045 #define LED1_OFF LPC_GPIO1->FIOCLR=LED1_MASK 00046 #define LED1_TOGGLE LPC_GPIO1->FIOPIN^=LED1_MASK 00047 00048 #define LED2_ON LPC_GPIO1->FIOSET=LED2_MASK 00049 #define LED2_OFF LPC_GPIO1->FIOCLR=LED2_MASK 00050 #define LED2_TOGGLE LPC_GPIO1->FIOPIN^=LED2_MASK 00051 00052 #define LED3_ON LPC_GPIO1->FIOSET=LED3_MASK 00053 #define LED3_OFF LPC_GPIO1->FIOCLR=LED3_MASK 00054 #define LED3_TOGGLE LPC_GPIO1->FIOPIN^=LED3_MASK 00055 00056 #define LED4_ON LPC_GPIO1->FIOSET=LED4_MASK 00057 #define LED4_OFF LPC_GPIO1->FIOCLR=LED4_MASK 00058 #define LED4_TOGGLE LPC_GPIO1->FIOPIN^=LED4_MASK 00059 00060 00061 00062 //8-bit Data Bus is on Pins P0.4 - P0.11 00063 #define DATA_BUS_MASK (uint32_t )((0xFF)<<4) 00064 00065 //3 bit address is on Port 2.0 - 2.2 00066 #define ADDRESS_BUS_MASK (uint32_t )(0x7) 00067 00068 //ChipSelects are on port 2 00069 #define CS0_MASK (uint32_t )(1<<3) 00070 #define CS1_MASK (uint32_t )(1<<4) 00071 00072 //IORD and IOWR are on port 0 00073 #define IORD_MASK (uint32_t )(1<<24) 00074 #define IOWR_MASK (uint32_t )(1<<23) 00075 00076 00077 //Reset and power enable are on port 1 00078 #define COMPACT_FLASH_RESET_MASK (uint32_t )(1<<30) 00079 #define COMPACT_FLASH_POWER_ENABLE_MASK (uint32_t )(0x80000000) 00080 //Card Detect is on Port 2 00081 #define COMPACT_FLASH_CARD_DETECT_MASK (uint32_t )(1<<5) 00082 00083 //Low Level Bus Operation Macros 00084 //Note: LPC 176x have dedicate set and clear registers 00085 00086 #define SET_DATA_BUS_TO_INPUTS LPC_GPIO0->FIODIR &= ~(DATA_BUS_MASK); 00087 #define SET_DATA_BUS_TO_OUTPUT LPC_GPIO0->FIODIR |= (DATA_BUS_MASK); 00088 00089 #define CS0_ACTIVE LPC_GPIO2->FIOCLR = CS0_MASK 00090 #define CS0_INACTIVE LPC_GPIO2->FIOSET = CS0_MASK 00091 #define CS1_ACTIVE LPC_GPIO2->FIOCLR = CS1_MASK 00092 #define CS1_INACTIVE LPC_GPIO2->FIOSET = CS1_MASK 00093 00094 #define IORD_ACTIVE LPC_GPIO0->FIOCLR = IORD_MASK 00095 #define IORD_INACTIVE LPC_GPIO0->FIOSET = IORD_MASK 00096 00097 #define IOWR_ACTIVE LPC_GPIO0->FIOCLR = IOWR_MASK 00098 #define IOWR_INACTIVE LPC_GPIO0->FIOSET = IOWR_MASK 00099 00100 #define COMPACT_FLASH_RESET_ACTIVE LPC_GPIO1->FIOCLR = COMPACT_FLASH_RESET_MASK 00101 #define COMPACT_FLASH_RESET_INACTIVE LPC_GPIO1->FIOSET = COMPACT_FLASH_RESET_MASK 00102 00103 #define COMPACT_FLASH_POWER_ENABLE LPC_GPIO1->FIOCLR = COMPACT_FLASH_POWER_ENABLE_MASK 00104 #define COMPACT_FLASH_POWER_DISABLE LPC_GPIO1->FIOSET = COMPACT_FLASH_POWER_ENABLE_MASK 00105 00106 #define COMPACT_FLASH_CARD_DETECTED (!((LPC_GPIO2->FIOPIN)&COMPACT_FLASH_CARD_DETECT_MASK)) 00107 00108 //To set the Address and Data Bus Lines we will use the convient Mask register in the Port I/O modules 00109 //The Hardware will mask out pins that are set to 1 in the MASK register 00110 00111 #define SET_CF_ADDRESS(ADDRESS) LPC_GPIO2->FIOMASK=~(ADDRESS_BUS_MASK); \ 00112 LPC_GPIO2->FIOPIN=ADDRESS; \ 00113 LPC_GPIO2->FIOMASK=0 //Always remember to reset the mask for other operations to complete correctly 00114 00115 00116 #define SET_CF_DATA(DATA) LPC_GPIO0->FIOMASK=~(DATA_BUS_MASK); \ 00117 LPC_GPIO0->FIOPIN=(((uint32_t)DATA)<<4); \ 00118 LPC_GPIO0->FIOMASK=0 //Always remember to reset the mask for other operations to complete correctly 00119 00120 #define GET_CF_DATA(DATA) LPC_GPIO0->FIOMASK=~(DATA_BUS_MASK); \ 00121 (DATA) = (LPC_GPIO0->FIOPIN)>>4; \ 00122 LPC_GPIO0->FIOMASK=0 //Always remember to reset the mask for other operations to complete correctly 00123 00124 #define SET_DATA_BUS_AS_OUTPUTS LPC_GPIO0->FIODIR|=DATA_BUS_MASK 00125 #define SET_DATA_BUS_AS_INPUTS LPC_GPIO0->FIODIR&=~DATA_BUS_MASK 00126 00127 /* ATA command */ 00128 #define CMD_RESET 0x08 /* DEVICE RESET */ 00129 #define CMD_READ 0x20 /* READ SECTOR(S) */ 00130 #define CMD_WRITE 0x30 /* WRITE SECTOR(S) */ 00131 #define CMD_IDENTIFY 0xEC /* DEVICE IDENTIFY */ 00132 #define CMD_SETFEATURES 0xEF /* SET FEATURES */ 00133 00134 /* ATA register bit definitions */ 00135 #define LBA 0xE0 00136 #define BUSY 0x80 00137 #define DRDY 0x40 00138 #define DF 0x20 00139 #define DRQ 0x08 00140 #define ERR 0x01 00141 #define SRST 0x40 00142 #define nIEN 0x20 00143 00144 /* Bit definitions for Control Port */ 00145 #define CTL_READ 0x20 00146 #define CTL_WRITE 0x40 00147 #define CTL_RESET 0x80 00148 #define REG_DATA 0x0 00149 #define REG_ERROR 0x1 00150 #define REG_FEATURES 0x1 00151 #define REG_COUNT 0x2 00152 #define REG_SECTOR 0x3 00153 #define REG_CYLL 0x4 00154 #define REG_CYLH 0x5 00155 #define REG_DEV 0x6 00156 #define REG_COMMAND 0x7 00157 #define REG_STATUS 0x7 00158 #define REG_DEVCTRL 0xE 00159 #define REG_ALTSTAT 0xE 00160 00161 void InitCompactFlashInterface() 00162 { 00163 SET_DATA_BUS_AS_INPUTS; 00164 00165 LPC_GPIO2->FIODIR |= ADDRESS_BUS_MASK | CS0_MASK | CS1_MASK; 00166 LPC_GPIO2->FIODIR &=~(COMPACT_FLASH_CARD_DETECT_MASK); 00167 LPC_GPIO1->FIODIR |= COMPACT_FLASH_RESET_MASK | COMPACT_FLASH_POWER_ENABLE_MASK | LED1_MASK | LED2_MASK | LED3_MASK | LED4_MASK; 00168 LPC_GPIO0->FIODIR |= IORD_MASK | IOWR_MASK ; 00169 00170 COMPACT_FLASH_RESET_ACTIVE; 00171 COMPACT_FLASH_POWER_DISABLE; 00172 CS0_INACTIVE; 00173 CS1_INACTIVE; 00174 00175 SysTick_Config(SystemCoreClock/100); 00176 NVIC_SetVector(SysTick_IRQn, (uint32_t)(&disk_timerproc)); 00177 } 00178 00179 /*-----------------------------------------------------------------------*/ 00180 /* Read an ATA register */ 00181 /*-----------------------------------------------------------------------*/ 00182 00183 static 00184 BYTE read_ata ( 00185 BYTE reg /* Register to be read */ 00186 ) 00187 { 00188 BYTE rd; 00189 00190 CS0_ACTIVE; 00191 SET_DATA_BUS_AS_INPUTS; 00192 SET_CF_ADDRESS(reg); 00193 IORD_ACTIVE; 00194 __nop(); 00195 __nop(); 00196 __nop(); 00197 __nop(); 00198 00199 GET_CF_DATA(rd); 00200 __nop(); 00201 __nop(); 00202 __nop(); 00203 __nop(); 00204 IORD_INACTIVE; 00205 CS0_INACTIVE; 00206 #ifdef _CF_DEBUG_READ_ATA 00207 CF_DEBUG("rd 0x%2x\r\n",rd); 00208 #endif 00209 return rd; 00210 } 00211 00212 00213 00214 /*-----------------------------------------------------------------------*/ 00215 /* Write a byte to an ATA register */ 00216 /*-----------------------------------------------------------------------*/ 00217 00218 static 00219 void write_ata ( 00220 BYTE reg, /* Register to be written */ 00221 BYTE dat /* Data to be written */ 00222 ) 00223 { 00224 00225 __nop(); 00226 CS0_ACTIVE; 00227 SET_DATA_BUS_AS_OUTPUTS; 00228 SET_CF_ADDRESS(reg); 00229 SET_CF_DATA(dat); 00230 IOWR_ACTIVE; 00231 __nop(); 00232 __nop(); 00233 __nop(); 00234 __nop(); 00235 IOWR_INACTIVE; 00236 __nop(); 00237 __nop(); 00238 __nop(); 00239 __nop(); 00240 CS0_INACTIVE; 00241 SET_DATA_BUS_AS_INPUTS; 00242 } 00243 00244 00245 00246 /*-----------------------------------------------------------------------*/ 00247 /* Read a part of data block */ 00248 /*-----------------------------------------------------------------------*/ 00249 00250 static 00251 void read_part ( 00252 BYTE *buff, /* Data buffer to store read data */ 00253 BYTE ofs, /* Offset of the part of data in unit of word */ 00254 BYTE count /* Number of word to pick up */ 00255 ) 00256 { 00257 BYTE c = 0, dl, dh; 00258 00259 SET_CF_ADDRESS(REG_DATA); /* Select Data register */ 00260 __nop(); 00261 __nop(); 00262 00263 SET_DATA_BUS_AS_INPUTS; 00264 CS0_ACTIVE; 00265 __nop(); 00266 __nop(); 00267 do { 00268 IORD_ACTIVE; /* IORD = L */ 00269 __nop(); 00270 __nop(); 00271 __nop(); 00272 __nop(); 00273 GET_CF_DATA(dl); /* Read Even data */ 00274 IORD_INACTIVE; /* IORD = H */ 00275 __nop(); 00276 __nop(); 00277 __nop(); 00278 __nop(); 00279 IORD_ACTIVE; /* IORD = L */ 00280 __nop(); 00281 __nop(); 00282 __nop(); 00283 __nop(); 00284 GET_CF_DATA(dh); /* Read Odd data */ 00285 IORD_INACTIVE; /* IORD = H */ 00286 __nop(); 00287 __nop(); 00288 __nop(); 00289 __nop(); 00290 if (count && (c >= ofs)) { /* Pick up a part of block */ 00291 *buff++ = dl; 00292 *buff++ = dh; 00293 count--; 00294 } 00295 } while (++c); 00296 CS0_INACTIVE; 00297 00298 read_ata(REG_ALTSTAT); 00299 read_ata(REG_STATUS); 00300 } 00301 00302 00303 /*-----------------------------------------------------------------------*/ 00304 /* Wait for Data Ready */ 00305 /*-----------------------------------------------------------------------*/ 00306 00307 static 00308 int wait_data (void) 00309 { 00310 BYTE s; 00311 00312 DiskProcTimer[CF] = 100; /* Time out = 1 sec */ 00313 do { 00314 if (!DiskProcTimer[CF]) return 0; /* Abort when timeout occured */ 00315 s = read_ata(REG_STATUS); /* Get status */ 00316 } while ((s & (BUSY|DRQ)) != DRQ); /* Wait for BUSY goes low and DRQ goes high */ 00317 00318 read_ata(REG_ALTSTAT); 00319 return 1; 00320 } 00321 00322 00323 00324 00325 /*-----------------------------------------------------------------------*/ 00326 /* Initialize Disk Drive */ 00327 /*-----------------------------------------------------------------------*/ 00328 00329 DSTATUS disk_initialize ( 00330 BYTE drv /* Physical drive number (0) */ 00331 ) 00332 { 00333 DSTATUS RetVal; 00334 00335 switch(drv) 00336 { 00337 case COMPACT_FLASH: 00338 00339 Stat[CF] |= STA_NOINIT; 00340 for (DiskProcTimer[CF] = 10; DiskProcTimer[CF]; ); /* 100ms */ 00341 if (Stat[CF] & STA_NODISK) return Stat[CF]; /* Exit when socket is empty */ 00342 COMPACT_FLASH_POWER_ENABLE; /* Initialize CFC control port */ 00343 for (DiskProcTimer[CF] = 1;DiskProcTimer[CF]; ); /* 10ms */ 00344 00345 SET_DATA_BUS_AS_INPUTS; 00346 for (DiskProcTimer[CF] = 5; DiskProcTimer[CF]; ); /* 50ms */ 00347 COMPACT_FLASH_RESET_INACTIVE; 00348 for (DiskProcTimer[CF] = 5; DiskProcTimer[CF]; ); /* 50ms */ 00349 write_ata(REG_DEV, LBA); /* Select Device 0 */ 00350 DiskProcTimer[CF] = 200; 00351 00352 do { /* Wait for card goes ready */ 00353 if (!DiskProcTimer[CF]) 00354 { 00355 CF_DEBUG("Timeout waiting for card BUSY to go inactive\r\n"); 00356 return Stat[CF]; 00357 } 00358 } while (read_ata(REG_STATUS) & BUSY); 00359 00360 00361 write_ata(REG_DEVCTRL, SRST | nIEN); /* Software reset */ 00362 for (DiskProcTimer[CF] = 2; DiskProcTimer[CF]; ); /* 20ms */ 00363 00364 write_ata(REG_DEVCTRL, nIEN); /* Release software reset */ 00365 00366 for (DiskProcTimer[CF] = 2; DiskProcTimer[CF]; ); /* 20ms */ 00367 00368 DiskProcTimer[CF] = 200; 00369 do { /* Wait for card goes ready */ 00370 if (!DiskProcTimer[CF]) 00371 { 00372 CF_DEBUG("Timeout waiting for card DRDY\r\n"); 00373 return Stat[CF]; 00374 } 00375 } while ((read_ata(REG_STATUS) & (DRDY|BUSY)) != DRDY); 00376 00377 CF_DEBUG("Setting to 8-bit PIO MOD\r\n"); 00378 write_ata(REG_FEATURES, 0x01); /* Select 8-bit PIO transfer mode */ 00379 write_ata(REG_COMMAND, CMD_SETFEATURES); 00380 DiskProcTimer[CF] = 200; 00381 do { 00382 if (!DiskProcTimer[CF]) 00383 { 00384 CF_DEBUG("Timeout waiting after trying to call the SETFEATURES command\r\n"); 00385 return Stat[CF]; 00386 } 00387 00388 } while (read_ata(REG_STATUS) & (BUSY | ERR)); 00389 00390 Stat[CF] &= ~STA_NOINIT; /* When device goes ready, clear STA_NOINIT */ 00391 00392 RetVal = Stat[CF]; 00393 00394 break; 00395 00396 case USB: 00397 00398 if(USB_Disk_Detected) 00399 { 00400 TERMINAL_PRINTF("USB Disk Detected.\r\n"); 00401 Stat[USB] &= ~(STA_NOINIT | STA_NODISK); 00402 } 00403 else 00404 { 00405 TERMINAL_PRINTF("USB Disk not attached.\r\n"); 00406 Stat[USB] |= STA_NOINIT | STA_NODISK; 00407 } 00408 00409 RetVal = Stat[USB]; 00410 break; 00411 00412 00413 case RAM: 00414 Stat[RAM] &= ~STA_NOINIT; 00415 RetVal = Stat[RAM]; 00416 break; 00417 00418 default: 00419 RetVal = STA_NOINIT; 00420 break; 00421 } 00422 00423 return RetVal; 00424 } 00425 00426 00427 00428 /*-----------------------------------------------------------------------*/ 00429 /* Return Disk Status */ 00430 /*-----------------------------------------------------------------------*/ 00431 00432 DSTATUS disk_status ( 00433 BYTE drv 00434 ) 00435 { 00436 DSTATUS RetVal; 00437 00438 switch(drv) 00439 { 00440 case CF: 00441 RetVal = Stat[CF]; 00442 break; 00443 00444 00445 case USB: 00446 RetVal = Stat[USB]; 00447 break; 00448 00449 case RAM: 00450 RetVal = Stat[RAM]; 00451 break; 00452 00453 default: 00454 RetVal = STA_NOINIT; 00455 break; 00456 } 00457 00458 return RetVal; 00459 } 00460 00461 00462 00463 /*-----------------------------------------------------------------------*/ 00464 /* Read Sector(s) */ 00465 /*-----------------------------------------------------------------------*/ 00466 00467 DRESULT disk_read ( 00468 BYTE drv, /* Physical drive nmuber (0) */ 00469 BYTE *buff, /* Data buffer to store read data */ 00470 DWORD sector, /* Sector number (LBA) */ 00471 BYTE count /* Sector count (1..255) */ 00472 ) 00473 { 00474 BYTE c; 00475 DWORD i; 00476 00477 switch(drv) 00478 { 00479 case CF: 00480 if (Stat[CF] & STA_NOINIT) return RES_NOTRDY; 00481 00482 /* Issue Read Setor(s) command */ 00483 write_ata(REG_COUNT, count); 00484 write_ata(REG_SECTOR, (BYTE)sector); 00485 write_ata(REG_CYLL, (BYTE)(sector >> 8)); 00486 write_ata(REG_CYLH, (BYTE)(sector >> 16)); 00487 write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA); 00488 write_ata(REG_COMMAND, CMD_READ); 00489 00490 do { 00491 if (!wait_data()) return RES_ERROR; /* Wait data ready */ 00492 00493 SET_CF_ADDRESS(REG_DATA); 00494 __nop(); 00495 __nop(); 00496 __nop(); 00497 __nop(); 00498 CS0_ACTIVE; 00499 c = 0; 00500 00501 __nop(); 00502 __nop(); 00503 __nop(); 00504 00505 SET_DATA_BUS_AS_INPUTS; 00506 do { 00507 IORD_ACTIVE; /* IORD = L */ 00508 __nop(); 00509 __nop(); 00510 __nop(); 00511 GET_CF_DATA(*buff++); /* Get even data */ 00512 __nop(); 00513 __nop(); 00514 __nop(); 00515 00516 __nop(); 00517 __nop(); 00518 __nop(); 00519 00520 IORD_INACTIVE; /* IORD = H */ 00521 __nop(); 00522 __nop(); 00523 __nop(); 00524 00525 IORD_ACTIVE; /* IORD = L */ 00526 __nop(); 00527 __nop(); 00528 __nop(); 00529 00530 GET_CF_DATA(*buff++); /* Get Odd data */ 00531 __nop(); 00532 __nop(); 00533 __nop(); 00534 00535 __nop(); 00536 IORD_INACTIVE; /* IORD = H */ 00537 __nop(); 00538 __nop(); 00539 __nop(); 00540 00541 00542 } while (--c); 00543 } while (--count); 00544 00545 CS0_INACTIVE; 00546 read_ata(REG_ALTSTAT); 00547 read_ata(REG_STATUS); 00548 00549 return RES_OK; 00550 break; 00551 00552 00553 case USB: 00554 00555 if(MassStorage_Read(sector, 1,(u8 *) buff, 512) == 0) 00556 return RES_OK; 00557 else 00558 return RES_NOTRDY; 00559 00560 break; 00561 00562 case RAM: 00563 for(i=0;i<512;i++) 00564 { 00565 buff[i] = RAM_DISK[i]; 00566 } 00567 return RES_OK; 00568 break; 00569 00570 default: 00571 return RES_PARERR; 00572 break; 00573 } 00574 } 00575 00576 00577 /*-----------------------------------------------------------------------*/ 00578 /* Write Sector(s) */ 00579 /*-----------------------------------------------------------------------*/ 00580 00581 DRESULT disk_write ( 00582 BYTE drv, /* Physical drive number (0) */ 00583 const BYTE *buff, /* Data to be written */ 00584 DWORD sector, /* Sector number (LBA) */ 00585 BYTE count /* Sector count (1..255) */ 00586 ) 00587 { 00588 BYTE s, c; 00589 DWORD i; 00590 DRESULT RetVal; 00591 00592 switch(drv) 00593 { 00594 case CF: 00595 /* Issue Write Setor(s) command */ 00596 write_ata(REG_COUNT, count); 00597 write_ata(REG_SECTOR, (BYTE)sector); 00598 write_ata(REG_CYLL, (BYTE)(sector >> 8)); 00599 write_ata(REG_CYLH, (BYTE)(sector >> 16)); 00600 write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA); 00601 write_ata(REG_COMMAND, CMD_WRITE); 00602 00603 do { 00604 if (!wait_data()) return RES_ERROR; 00605 00606 SET_CF_ADDRESS(REG_DATA); 00607 __nop(); 00608 __nop(); 00609 __nop(); 00610 CS0_ACTIVE; 00611 __nop(); 00612 __nop(); 00613 __nop(); 00614 00615 SET_DATA_BUS_AS_OUTPUTS; 00616 c = 0; 00617 do { 00618 SET_CF_DATA(*buff++); /* Set even data */ 00619 __nop(); 00620 __nop(); 00621 __nop(); 00622 00623 IOWR_ACTIVE; /* IOWR = L */ 00624 __nop(); 00625 __nop(); 00626 __nop(); 00627 00628 IOWR_INACTIVE; /* IOWR = H */ 00629 __nop(); 00630 __nop(); 00631 __nop(); 00632 00633 SET_CF_DATA(*buff++); /* Set odd data */ 00634 __nop(); 00635 __nop(); 00636 __nop(); 00637 00638 IOWR_ACTIVE; /* IOWR = L */ 00639 __nop(); 00640 __nop(); 00641 __nop(); 00642 00643 IOWR_INACTIVE; /* IOWR = H */ 00644 __nop(); 00645 __nop(); 00646 __nop(); 00647 } while (--c); 00648 00649 } while (--count); 00650 00651 SET_DATA_BUS_AS_INPUTS; 00652 CS0_INACTIVE; 00653 00654 DiskProcTimer[CF] = 100; 00655 do { 00656 if (!DiskProcTimer[CF]) return RES_ERROR; 00657 s = read_ata(REG_STATUS); 00658 } while (s & BUSY); 00659 if (s & ERR) return RES_ERROR; 00660 00661 read_ata(REG_ALTSTAT); 00662 read_ata(REG_STATUS); 00663 00664 RetVal = RES_OK; 00665 break; 00666 00667 00668 case USB: 00669 00670 if( MassStorage_Write(sector, 1, (u8 *)buff, 512) == 0) 00671 RetVal = RES_OK; 00672 else 00673 RetVal = RES_NOTRDY; 00674 00675 break; 00676 00677 case RAM: 00678 00679 for(i=0;i<512;i++) 00680 { 00681 RAM_DISK[i] = buff[i]; 00682 } 00683 RetVal = RES_OK; 00684 00685 break; 00686 00687 default: 00688 RetVal = RES_PARERR; 00689 break; 00690 00691 } 00692 return RetVal; 00693 } 00694 00695 00696 00697 /*-----------------------------------------------------------------------*/ 00698 /* Miscellaneous Functions */ 00699 /*-----------------------------------------------------------------------*/ 00700 00701 DRESULT disk_ioctl ( 00702 BYTE drv, /* Physical drive nmuber (0) */ 00703 BYTE ctrl, /* Control code */ 00704 void *buff /* Buffer to send/receive data block */ 00705 ) 00706 { 00707 BYTE n, w, ofs, dl, dh, *ptr = (BYTE *)buff; 00708 00709 switch(drv) 00710 { 00711 case CF: 00712 switch (ctrl) 00713 { 00714 case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ 00715 ofs = 60; w = 2; n = 0; 00716 break; 00717 00718 case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */ 00719 *(DWORD*)buff = 32; 00720 return RES_OK; 00721 break; 00722 case CTRL_SYNC : /* Nothing to do */ 00723 return RES_OK; 00724 break; 00725 case ATA_GET_REV : /* Get firmware revision (8 chars) */ 00726 ofs = 23; w = 4; n = 4; 00727 break; 00728 00729 case ATA_GET_MODEL : /* Get model name (40 chars) */ 00730 ofs = 27; w = 20; n = 20; 00731 break; 00732 00733 case ATA_GET_SN : /* Get serial number (20 chars) */ 00734 ofs = 10; w = 10; n = 10; 00735 break; 00736 00737 default: 00738 return RES_PARERR; 00739 } 00740 00741 write_ata(REG_COMMAND, CMD_IDENTIFY); 00742 00743 if (!wait_data()) return RES_ERROR; 00744 00745 read_part(ptr, ofs, w); 00746 00747 while (n--) 00748 { 00749 dl = *ptr; dh = *(ptr+1); 00750 *ptr++ = dh; *ptr++ = dl; 00751 } 00752 00753 return RES_OK; 00754 break; 00755 00756 00757 case USB: 00758 if (USB_Disk_Detected == 0) 00759 { 00760 // TERMINAL_PRINTF("USB Disk not attached\r\n"); 00761 return RES_ERROR; 00762 } 00763 else 00764 { 00765 Stat[USB] &= ~STA_NOINIT; 00766 switch (ctrl) 00767 { 00768 00769 case GET_SECTOR_COUNT: 00770 /* if(MassStorage_ReadCapacity(USB_Disk_Device, &BlockCount, &BlockSize) == 0) 00771 { 00772 00773 *(DWORD *)(buff) = BlockCount; 00774 00775 00776 } 00777 else 00778 { 00779 return RES_ERROR; 00780 }*/ 00781 return RES_OK; 00782 break; 00783 00784 case GET_BLOCK_SIZE : 00785 00786 /* if(MassStorage_ReadCapacity(USB_Disk_Device, &BlockCount, &BlockSize) == 0) 00787 { 00788 *(DWORD *)(buff) = BlockSize; 00789 return RES_OK; 00790 } 00791 else 00792 { 00793 return RES_ERROR; 00794 }*/ 00795 return RES_OK; 00796 00797 break; 00798 00799 case CTRL_SYNC : 00800 return RES_OK; 00801 break; 00802 00803 case ATA_GET_REV : 00804 strcpy ((CHAR *)buff,"00000"); 00805 return RES_OK; 00806 break; 00807 00808 case ATA_GET_MODEL : 00809 strcpy ((CHAR *)buff, "000000"); 00810 return RES_OK; 00811 break; 00812 00813 case ATA_GET_SN : 00814 strcpy ((CHAR *)buff,"00000000"); 00815 return RES_OK; 00816 break; 00817 00818 default: 00819 return RES_PARERR; 00820 } 00821 } 00822 00823 break; 00824 00825 case RAM: 00826 switch (ctrl) 00827 00828 { 00829 case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ 00830 *(DWORD *)(buff) = 1; 00831 break; 00832 00833 case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */ 00834 *(DWORD *)(buff) = 1; 00835 return RES_OK; 00836 break; 00837 case CTRL_SYNC : /* Nothing to do */ 00838 return RES_OK; 00839 break; 00840 00841 case ATA_GET_REV : /* Get firmware revision (8 chars) */ 00842 strcpy ((CHAR *)buff,"Rev 0.01"); 00843 break; 00844 00845 case ATA_GET_MODEL : /* Get model name (40 chars) */ 00846 strcpy ((CHAR *)buff,"Wavenumber RAM Drive"); 00847 break; 00848 00849 case ATA_GET_SN : /* Get serial number (20 chars) */ 00850 strcpy ((CHAR *)buff,"12345"); 00851 break; 00852 default: 00853 return RES_PARERR; 00854 } 00855 return RES_OK; 00856 break; 00857 00858 default: 00859 return RES_PARERR; 00860 break; 00861 } 00862 00863 return RES_OK; 00864 } 00865 00866 00867 /*-----------------------------------------------------------------------*/ 00868 /* Device timer interrupt procedure */ 00869 /*-----------------------------------------------------------------------*/ 00870 /* This function must be called in period of 10ms */ 00871 00872 void disk_timerproc (void) 00873 { 00874 static BYTE pv; 00875 BYTE n; 00876 00877 n = DiskProcTimer[CF]; /* 100Hz decrement timer */ 00878 if (n) DiskProcTimer[CF] = --n; 00879 00880 n = DiskProcTimer[USB]; /* 100Hz decrement timer */ 00881 if (n) DiskProcTimer[USB] = --n; 00882 00883 n = DiskProcTimer[RAM]; /* 100Hz decrement timer */ 00884 if (n) DiskProcTimer[RAM] = --n; 00885 00886 n = pv; 00887 pv = COMPACT_FLASH_CARD_DETECTED ; /* Sapmle socket switch */ 00888 00889 00890 //Check Compact Flash Card Detect 00891 if (n == pv) { /* Have contacts stabled? */ 00892 if (!COMPACT_FLASH_CARD_DETECTED ) 00893 { /* CD1 or CD2 is high (Socket empty) */ 00894 Stat[CF] |= (STA_NODISK | STA_NOINIT); 00895 SET_DATA_BUS_TO_INPUTS; /* Float D0-D7 */ 00896 COMPACT_FLASH_RESET_ACTIVE; /* Assert RESET# */ 00897 COMPACT_FLASH_POWER_DISABLE; /* Power OFF */ 00898 LED1_OFF; 00899 } 00900 else 00901 { /* CD1 and CD2 are low (Card inserted) */ 00902 Stat[CF] &= ~STA_NODISK; 00903 LED1_ON; 00904 } 00905 } 00906 00907 //Check to see if a USB drive is connected 00908 if(USB_Disk_Detected>0) 00909 LED2_ON; 00910 else 00911 LED2_OFF; 00912 00913 } 00914 00915 00916 DWORD get_fattime(void) 00917 { 00918 time_t CurrentTimeStamp; 00919 tm *CurrentLocalTime; 00920 DWORD FATFSTimeCode; 00921 00922 CurrentTimeStamp = time(NULL); 00923 CurrentLocalTime = localtime(&CurrentTimeStamp); 00924 00925 //Map the tm struct time into the FatFs time code 00926 FATFSTimeCode = ((CurrentLocalTime->tm_year-80)<<25) | 00927 ((CurrentLocalTime->tm_mon+1)<<21) | 00928 ((CurrentLocalTime->tm_mday)<<16) | 00929 ((CurrentLocalTime->tm_hour)<<11) | 00930 ((CurrentLocalTime->tm_min)<<5) | 00931 ((CurrentLocalTime->tm_sec)); 00932 00933 return FATFSTimeCode; 00934 }
Generated on Sat Jul 16 2022 22:22:09 by
1.7.2