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