Embed:
(wiki syntax)
Show/hide line numbers
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
Eli Hughes