📄 ide.c
字号:
IDEOut(FEATURE_REG, 0); IDEOut(SECTOR_COUNT_REG, 1); IDEOut(SECTOR_REG, 0); IDEOut(CYLINDER_LOW_REG, 0); IDEOut(CYLINDER_HIGH_REG, 0);#endif ClearEvent(&hIDEEvent); // // Check if we are a PACKET device // if (IsPacketDevice() == TRUE) { nError = IDE_OK; pDrive->wFlags = IDE_SUPPORT_PACKET; } else { IDEOut(COMMAND_REG, COMMAND_DIAG); if (WaitForInterrupt(INITTIMEOUT) == IDE_OK) { bResult = IDEIn(ERROR_REG); if (bResult == 0x01) { // see ATAPI-4 r17 p72 nError = IDE_OK; } } } } return (nError);}/************************************************************//* ReadSectors *//* *//* PIO data in command protocol, see ATAPI-4 r17 p224 9.7 *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int ReadSectors(BYTE bDevice, BYTE * pData, DWORD dwStartSector, WORD wSectorCount){ WORD i, x; int nError; BYTE bValue; BYTE bErrorReg; BYTE bStatus; LPDRIVE pDrive;#if (IDE_SUPPORT_CHS == 1) WORD wCHSSector; WORD wCHSHead; WORD wCHSCylinder;#endif pDrive = &sDrive[bDevice]; nError = SelectDevice(bDevice);#if (IDE_SUPPORT_CHS == 0) // // NO CHS support // if ((pDrive->wFlags & IDE_SUPPORT_LBA) == 0) { // // If we have a CHS device, this is an ERROR // nError = IDE_ERROR; }#endif if (nError == IDE_OK) { ClearEvent(&hIDEEvent); if (pDrive->wFlags & IDE_SUPPORT_LBA) { // // LBA // bValue = (BYTE) ((bDevice << 4) | 0xE0 | (dwStartSector >> 24)); IDEOut(DISK_HEAD_REG, bValue); IDEOut(LBA_16_23, (BYTE) (dwStartSector >> 16)); IDEOut(LBA_8_15, (BYTE) (dwStartSector >> 8)); IDEOut(LBA_0_7, (BYTE) (dwStartSector)); IDEOut(SECTOR_COUNT_REG, (BYTE) (wSectorCount & 0xff)); IDEOut(COMMAND_REG, COMMAND_READ_SECTORS);#if (IDE_SUPPORT_CHS == 1) } else { // // CHS // wCHSSector = (WORD) (dwStartSector % pDrive->wSectorsPerTrack) + 1; wCHSHead = (WORD) (dwStartSector / pDrive->dwOneSide); dwStartSector = dwStartSector % pDrive->dwOneSide; wCHSCylinder = (WORD) (dwStartSector / pDrive->wSectorsPerTrack); wCHSHead |= (bDevice << 4) | 0xA0; IDEOut(DISK_HEAD_REG, (BYTE) wCHSHead); IDEOut(SECTOR_REG, (BYTE) wCHSSector); IDEOut(CYLINDER_LOW_REG, (BYTE) (wCHSCylinder & 0x00FF)); IDEOut(CYLINDER_HIGH_REG, (BYTE) (wCHSCylinder >> 8)); IDEOut(SECTOR_COUNT_REG, (BYTE) (wSectorCount & 0xff)); IDEOut(COMMAND_REG, COMMAND_READ_SECTORS);#endif } for (i = 0; i < wSectorCount; i++) { nError = WaitForInterrupt(DISKTIMEOUT); if (nError == IDE_OK) { bStatus = gbIntStatus; if (bStatus & STATUS_ERROR) { bErrorReg = IDEIn(ERROR_REG); nError = IDE_ERROR; break; } for (x = 0; x < IDE_SECTOR_SIZE; x = x + 2) { pData[x] = pIDE[DATA_READ_REG_LOW]; if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) { pData[x + 1] = pIDE[DATA_READ_REG_LOW]; } else { pData[x + 1] = pIDE[DATA_READ_REG_HIGH]; } } pData += IDE_SECTOR_SIZE; } else { bStatus = IDEIn(STATUS_REG); bErrorReg = IDEIn(ERROR_REG); } } bStatus = IDEIn(STATUS_REG); } /* SelectDevice */ return (nError);}#if (IDE_SUPPORT_WRITE == 1)/************************************************************//* WriteSectors *//* *//* PIO data out command protocol, see ATAPI-4 r17 p227 9.8 *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static BYTE WriteSectors(WORD bDevice, BYTE * pData, DWORD dwStartSector, WORD wSectorCount){ WORD i; int x; int nError; BYTE bValue; BYTE bStatus; BYTE bErrorReg; LPDRIVE pDrive;#if (IDE_SUPPORT_CHS == 1) WORD wCHSSector; WORD wCHSHead; WORD wCHSCylinder;#endif pDrive = &sDrive[bDevice]; nError = SelectDevice(bDevice);#if (IDE_SUPPORT_CHS == 0) // // NO CHS support // if ((pDrive->wFlags & IDE_SUPPORT_LBA) == 0) { // // If we found a CHS device, this is an ERROR // nError = IDE_ERROR; }#endif if (nError == IDE_OK) { if (pDrive->wFlags & IDE_SUPPORT_LBA) { // // LBA // bValue = (BYTE) ((bDevice << 4) | 0xE0 | (dwStartSector >> 24)); IDEOut(DISK_HEAD_REG, bValue); IDEOut(LBA_16_23, (BYTE) (dwStartSector >> 16)); IDEOut(LBA_8_15, (BYTE) (dwStartSector >> 8)); IDEOut(LBA_0_7, (BYTE) (dwStartSector)); IDEOut(SECTOR_COUNT_REG, (BYTE) (wSectorCount & 0xff)); IDEOut(COMMAND_REG, COMMAND_WRITE_SECTORS);#if (IDE_SUPPORT_CHS == 1) } else { // // CHS // wCHSSector = (WORD) (dwStartSector % pDrive->wSectorsPerTrack) + 1; wCHSHead = (WORD) (dwStartSector / pDrive->dwOneSide); dwStartSector = dwStartSector % pDrive->dwOneSide; wCHSCylinder = (WORD) (dwStartSector / pDrive->wSectorsPerTrack); wCHSHead |= (bDevice << 4) | 0xA0; IDEOut(DISK_HEAD_REG, (BYTE) wCHSHead); IDEOut(SECTOR_REG, (BYTE) wCHSSector); IDEOut(CYLINDER_LOW_REG, (BYTE) (wCHSCylinder & 0x00FF)); IDEOut(CYLINDER_HIGH_REG, (BYTE) (wCHSCylinder >> 8)); IDEOut(SECTOR_COUNT_REG, (BYTE) (wSectorCount & 0xff)); IDEOut(COMMAND_REG, COMMAND_WRITE_SECTORS);#endif } if (WaitDRQ(CONTROLLERTIMEOUT) == IDE_OK) { bStatus = IDEIn(STATUS_REG); for (i = 0; i < wSectorCount; i++) { for (x = 0; x < IDE_SECTOR_SIZE; x = x + 2) { if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) { IDEOut(DATA_WRITE_REG_LOW, pData[x]); IDEOut(DATA_WRITE_REG_LOW, pData[x + 1]); } else { IDEOut(DATA_WRITE_REG_HIGH, pData[x + 1]); IDEOut(DATA_WRITE_REG_LOW, pData[x]); } } pData += IDE_SECTOR_SIZE; nError = WaitForInterrupt(DISKTIMEOUT); if (nError == IDE_OK) { bStatus = gbIntStatus; if ((bStatus & STATUS_ERROR) == STATUS_ERROR) { bErrorReg = IDEIn(ERROR_REG); nError = IDE_ERROR; break; } } else { // // Error // nError = IDE_ERROR; break; } } } else { // // Device: Set error status (D) // WaitForInterrupt(DISKTIMEOUT); bErrorReg = IDEIn(ERROR_REG); } /* endif WaitDRQ */ } /* SelectDevice */ return (nError);}#endif/************************************************************//* CFChange *//************************************************************/THREAD(CFChange, arg){ BYTE bNewStatus; BYTE *pSectorBuffer; while (1) { NutEventWaitNext(&hCFChangeInt, 0); // // Wait a while, that the cf contact is stable and not to bounce. // NutSleep(2000); bNewStatus = (PINE & BV(CF_IRQ)); if (bNewStatus != gbCFMountStatus) { if (bNewStatus == CF_AVAILABLE) { gbCFMountStatus = CF_AVAILABLE; // // We must mount the new CF card. // HardwareReset(&sDrive[0]); pSectorBuffer = (BYTE *) NutHeapAlloc(IDE_SECTOR_SIZE); if (pSectorBuffer != NULL) { IDEMountDevice(IDE_DRIVE_C, pSectorBuffer); NutHeapFree(pSectorBuffer); if (pUserMountFunc != NULL) { pUserMountFunc(IDE_DRIVE_C); } } NutEnterCritical(); EICR &= ~CF_INT_SENS_MASK; EICR |= CF_INT_RISING_EDGE; NutExitCritical(); } else { gbCFMountStatus = CF_NOT_AVAILABLE; // // The user has removed the CF card, // now UnMount the device. // IDEUnMountDevice(IDE_DRIVE_C); if (pUserUnMountFunc != NULL) { pUserUnMountFunc(IDE_DRIVE_C); } NutEnterCritical(); EICR &= ~CF_INT_SENS_MASK; EICR |= CF_INT_FALLING_EDGE; NutExitCritical(); } } /* endif bValue != gbCFMountStatus */ } /* end while */}/*==========================================================*//* DEFINE: All code exported *//*==========================================================*//************************************************************//* IDEInit *//************************************************************/int IDEInit(int nBaseAddress, int nIDEMode, IDE_MOUNT_FUNC * pMountFunc, IDE_MOUNT_FUNC * pUnMountFunc){ int i; int nError; BYTE bValue; pUserMountFunc = pMountFunc; pUserUnMountFunc = pUnMountFunc; // // If nBaseAddress is 0, we use the default address // if (nBaseAddress == 0) { nBaseAddress = IDE_BASE_ADDRESS; } // // With MCUCR 0xC0 and XMCRA 0x02 we set: // // Wait two cycles during read/write and // wait one cycle before driving out new address. // This setting is for 0x1100 - 0xffff //#ifdef __AVR_ENHANCED__ XMCRA = _BV(SRW11);#endif // // Enable the IDE Reset // DDRD = 0x20; for (i = 0; i < IDE_MAX_SUPPORTED_DEVICE; i++) { memset((BYTE *) & sDrive[i], 0x00, sizeof(DRIVE)); sDrive[i].bDevice = (BYTE) i; sDrive[i].bIDEMode = (BYTE) nIDEMode; } IDESemaInit(); pIDE = (unsigned char *) nBaseAddress; ClearEvent(&hIDEEvent); NutEnterCritical(); // // Clear interrupt status // gbIntStatus = 0; // // Install IDE interrupt // nError = NutRegisterIrqHandler(&sig_INTERRUPT7, IDEInterrupt, NULL); if (nError == FALSE) { EICR |= IDE_INT_RISING_EDGE; sbi(EIMSK, IDE_IRQ); } switch (nIDEMode) { case IDE_HARDDISK:{ break; } // // If your drive does not work correct with 14.7456Mhz, // try to devide the clock by 2. // // Important: You must correct the baudrate in your app. // if you set 115200, you get only 57600. // case IDE_HARDDISK_7MHZ:{#if defined(CLKPR) /* AT90MEGA128 uses a clock prescaler register */ CLKPR = _BV(CLKPCE); // Enable clock speed change CLKPR = 2; // Run at half the clock speed#else XDIV = 0xff;#endif break; } case IDE_COMPACT_FLASH:{ break; } case MEM_8BIT_COMPACT_FLASH:{ // // Now we will support to change the CF-Card in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -