Compact Flash I/O test
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_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
Eli Hughes