📄 ata.c
字号:
SET_HY_PRG_READY();
}
/*===========================================================================*/
/* SendStatus */
/*===========================================================================*/
void SendStatus(unsigned int status)
{
while((READ_CMD_LSB())&1); //wait for the syncronisation bit
outpw2r(STATUS_ADDR, status)
}
/*===========================================================================*/
/* GetSectorNumber */
/*===========================================================================*/
unsigned int GetSectorNumber()
{
return READ_ADDRESS() >> 9;
}
/*===========================================================================*/
/* GetSectorCount */
/*===========================================================================*/
unsigned int GetSectorCount()
{
return READ_SECOND_ARGUMENT() >> 14;
}
/*===========================================================================*/
/* SetErrorCode */
/*===========================================================================*/
void SetErrorCode(unsigned int ErrorCode)
{
static const ErrorCodeTable[]={0, 1, 4, 4, 4, 16, 8, 32};
// NO_ERROR = 0
// NOT_FOUND = 1 (OUT_OF_RANGE)
// ERASE, WRITE and READ ERRORS = 4 (CARD_ECC_ERROR)
// MISALIGNED_ERROR = 16
// WRITEPROTECT_ERROR = 8
// ERASE_SKIP = 32
SendStatus(ErrorCodeTable[ErrorCode]);
#if RTK
printf("Error %d \n", ErrorCode);
#endif
}
#endif
void SetRedLed()
{
unsigned int dummy;
asm volatile ("LDW.IOA 0, %0, ($000013B8 | (4 << 13))": "=l" (dummy));
asm volatile ("ORI %0, 1<<2": "=l" (dummy));
asm volatile ("STW.IOA 0, %0, ($000013B8 | (4 << 13))": "=l" (dummy));
}
void SetGreenLed()
{
unsigned int dummy;
asm volatile ("LDW.IOA 0, %0, ($000013B8 | (4 << 13))": "=l" (dummy));
asm volatile ("ORI %0, 1<<3": "=l" (dummy));
asm volatile ("STW.IOA 0, %0, ($000013B8 | (4 << 13))": "=l" (dummy));
}
void ClearRedLed()
{
unsigned int dummy;
asm volatile ("LDW.IOA 0, %0, ($000013B8 | (4 << 13))": "=l" (dummy));
asm volatile ("ANDNI %0, 1<<2": "=l" (dummy));
asm volatile ("STW.IOA 0, %0, ($000013B8 | (4 << 13))": "=l" (dummy));
}
void ClearGreenLed()
{
unsigned int dummy;
asm volatile ("LDW.IOA 0, %0, ($000013B8 | (4 << 13))": "=l" (dummy));
asm volatile ("ANDNI %0, 1<<3": "=l" (dummy));
asm volatile ("STW.IOA 0, %0, ($000013B8 | (4 << 13))": "=l" (dummy));
}
/*===========================================================================*/
/* BackGroundEraseAndSleep */
/*===========================================================================*/
void BackGroundEraseAndSleep(unsigned int Event)
{
if (!EVENT(Event))
{
WaitUntilAllChipsIdle();
*(unsigned char *)FLASH_IDLE=0;
#if RTK
SET_WRITEPROT();
WaitGuard(Event|SOFTRESETOFF_EVENT);
CLEAR_WRITEPROT();
#else
EnterSleepMode(Event|SOFTRESETOFF_EVENT);
#endif
}
}
/*===========================================================================*/
/* FillHyperstoneBuffer */
/*===========================================================================*/
unsigned int FillSectorBuffer()
{
WaitGuard(PC_EVENT);
if (EVENT(AGAIN_EVENT))
{
RESET_EVENT(AGAIN_EVENT);
EXCHANGE_BUFFERS();
SET_HY_READY();
}
else
{
RESET_EVENT(STOP_EVENT);
return FALSE;
}
return TRUE;
}
/*===========================================================================*/
/* CheckSector */
/*===========================================================================*/
unsigned int CheckSector(unsigned int *S1, unsigned int *S2)
{
unsigned int i;
for(i=0; i<128; i++)
if (*(S1+i) != *(S2+i))
return ERROR;
return NO_ERROR;
}
/*===========================================================================*/
/* WriteLoop */
/*===========================================================================*/
static unsigned int WriteLoop(unsigned int LogSectorNumber,
unsigned int MinorCommandCode)
{
unsigned int Overhead;
Overhead = 0;
WRITE_BACK_PTR(Overhead, 0);
switch (MinorCommandCode)
{
case USER_AREA_WRITE:
EXCHANGE_BUFFERS();
SET_HY_READY();
WriteSectorToFlash(LogSectorNumber, SECTOR_BUFFER,Overhead);
if (EVENT(REPEAT_BIT))
while(1)
{
LogSectorNumber++;
if(FillSectorBuffer())
WriteSectorToFlash(LogSectorNumber, SECTOR_BUFFER,Overhead);
else
break;
}
break;
case COMMAND_56_WRITE:
EXCHANGE_BUFFERS();
SET_HY_READY();
CycleTest();
break;
case WRITE_CSD:
case SET_PRE_ERASE:
case SET_WRITE_PROTECT:
case CLEAR_WRITE_PROTECT:
case SET_CER_RANDOM_1:
case SET_CER_RESPONSE_2:
case SECURE_WRITE:
case CHANGE_SECURE_AREA:
case WRITE_MKB:
default:
return FALSE;
}
TerminateWriteCommand();
return TRUE;
} // end of WriteLoop
/*===========================================================================*/
/* ReadLoop */
/*===========================================================================*/
static unsigned int ReadLoop(unsigned int LogSectorNumber,
unsigned int MinorCommandCode,
unsigned int SectorOffset,
unsigned int SectorLength)
{
switch (MinorCommandCode)
{
case USER_AREA_READ:
// Read Function with error correction
ReadSectorFromFlash(LogSectorNumber, SECTOR_BUFFER);
// Read Function without error correction
//ReadSectorFromFlashNoECC(LogSectorNumber, SECTOR_BUFFER);
EXCHANGE_BUFFERS();
SET_HY_READY();
if (EVENT(REPEAT_BIT))
while(1)
{
LogSectorNumber++;
ReadSectorFromFlash(LogSectorNumber, SECTOR_BUFFER);
if(WaitDRQ(INDEFINITE))
{
EXCHANGE_BUFFERS();
SET_HY_READY();
}
else
break;
}
break;
case COMMAND_56_WRITE:
SetBuffer(SECTOR_BUFFER, 0, SECTOR_SIZE);
CycleTestRead();
EXCHANGE_BUFFERS();
SET_HY_READY();
break;
case NUMBER_WRITTEN_SECTORS:
case SDSTATUS:
case SD_CONF_REGISTER:
case READ_WRITE_PROTECT:
case SECURE_READ:
case MID_READ:
case MKB_READ:
case GET_CER_RANDOM_2:
case GET_CER_RESPONSE_1:
default:
return FALSE;
}
return TRUE;
} // end of ReadLoop
/*===========================================================================*/
/* MainLoop */
/*===========================================================================*/
void MainLoop()
{
unsigned int LogSectorNumber;
unsigned int EraseSectorStart, EraseSectorEnd;
unsigned int i;
for ( ;; )
{
RESET_EVENT(REPEAT_BIT);
BackGroundEraseAndSleep(PC_EVENT|DEBUG_EVENT);
if ( EVENT(COMMAND_EVENT) )
{
RESET_EVENT(COMMAND_EVENT);
LogSectorNumber = GetSectorNumber() + LOG_TO_PHYS;
switch ( GET_COMMAND_CODE() )
{
case READ_STATUS_OPC:
if ( READ_INTREG() & HY_NON_STOP )
SET_EVENT(REPEAT_BIT);
ReadLoop(LogSectorNumber, GET_MINOR_COMMANDCODE(),
GetSectorOffset(), GetSectorLength());
RESET_EVENT(REPEAT_BIT);
break;
case SPECIALWRITE_OPC:
if ( READ_INTREG() & HY_NON_STOP )
SET_EVENT(REPEAT_BIT);
WriteLoop(LogSectorNumber, GET_MINOR_COMMANDCODE());
RESET_EVENT(REPEAT_BIT);
break;
case ERASE_OPC:
EraseSectorStart = (READ_ADDRESS() >> 9) + LOG_TO_PHYS;
EraseSectorEnd = (READ_ERASE_END() >> 9) + LOG_TO_PHYS;
EraseSectorStart &= 0x1f;
EraseSectorEnd &= 0x1f;
EraseSectorEnd ++;
for ( i=EraseSectorStart; i< EraseSectorEnd; i+=32 )
EraseBlock(i);
TerminateWriteCommand();
break;
case READ_OPC:
break;
case WRITE_OPC:
break;
case VENDOR_OPC:
//VendorCommands(LogSectorNumber, GET_MINOR_COMMANDCODE());
break;
}
}
if ( EVENT(STOP_EVENT) )
{
RESET_EVENT(STOP_EVENT);
}
if ( EVENT(AGAIN_EVENT) )
{
RESET_EVENT(AGAIN_EVENT);
}
if ( EVENT(DEBUG_EVENT) )
{
RESET_EVENT(DEBUG_EVENT);
}
}
} // end of MainLoop
/*===========================================================================*/
/* Main */
/*===========================================================================*/
void main()
{
static unsigned int CID[4];
static unsigned int CSD[4];
CID[0] = 0x55AA55AA;
CID[1] = 0x55AA55AA;
CID[2] = 0x55AA55AA;
CID[3] = 0x55AA55AA;
CSD[0] = 0x01234567;
CSD[1] = 0x76543210;
CSD[2] = 0x89ABCDEF;
CSD[3] = 0xFEDCBA98;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -