📄 rio.cpp
字号:
COMMANDOUT( B_01110000, B_00000000, B_00000100 );
COMMANDOUT( B_10100000, B_00001100, B_00000100 );
OUTPORT( m_iPortControl, B_00000000 );
IODELAY( m_lTimeIODelayTx );
OUTPORT( m_iPortControl, B_00000100 );
IODELAY( m_lTimeIODelayTx );
}
// send 32K in 512 byte chunks
UCHAR* pauc = (UCHAR*)pv;
for( iA=0; iA<(32768/512); ++iA, pauc+=512 )
{
ulPos512ByteBlock = ((ULONG)uiPos32KBlock * 32768 + (ULONG)iA * 512) / 512;
ulPosLo = ulPos512ByteBlock & 0xff;
if ( m_bUseExternalFlash )
{
ulPosHi = POS_BANK_EXTERNALFLASH;
ulPosMid = (ulPos512ByteBlock & 0xff00) >> 8;
}
else if ( m_bSpecialEdition )
{
ulPosHi = ulPos512ByteBlock / 32768;
ulPosMid = (ulPos512ByteBlock & 0x7f00) >> 8;
}
else
{
ulPosHi = ulPos512ByteBlock / 16384;
ulPosMid = (ulPos512ByteBlock & 0x3f00) >> 8;
}
// issue upload 512 byte block command
COMMANDOUT( B_10101011, B_00001100, B_00000100 );
COMMANDOUT( ulPosHi, B_00000000, B_00000100 );
COMMANDOUT( B_10100001, B_00001100, B_00000100 );
COMMANDOUT( B_10000000, B_00000000, B_00000100 );
COMMANDOUT( B_10100010, B_00001100, B_00000100 );
COMMANDOUT( B_00000000, B_00000000, B_00000100 );
COMMANDOUT( ulPosLo, B_00000000, B_00000100 );
COMMANDOUT( ulPosMid, B_00000000, B_00000100 );
COMMANDOUT( B_10100011, B_00001100, B_00000100 );
// create checksum of 512 byte block
USHORT usChecksum = 0;
USHORT* paus = (USHORT*)pauc;
for( iB=0; iB<(512/sizeof(short)); ++iB, ++paus )
usChecksum -= *paus;
// clock out data
#if defined(_WINNT)
{
DWORD dwSizeReturn;
DeviceIoControl( m_hDriver, RIOIO_IOCTL_WRITEBLOCK, pauc, 512,
NULL, 0, &dwSizeReturn, NULL );
}
#else
UCHAR* pauc2 = pauc;
for( iB=0; iB<512; ++iB, ++pauc2 )
{
OUTPORT( m_iPortData, (*pauc2) );
if ( !(iB & 1) )
OUTPORT( m_iPortControl, B_00000000 );
else
OUTPORT( m_iPortControl, B_00000100 );
IODELAY( 1 );
}
#endif
// prepare end of block
CEnd512ByteBlock cEnd512ByteBlock;
memset( &cEnd512ByteBlock, 0, sizeof(CEnd512ByteBlock) );
cEnd512ByteBlock.m_usChecksum = usChecksum;
if ( uiPos32KBlockNext == 0xffff )
{
cEnd512ByteBlock.m_ulPos512ByteBlockNextMult256 = 0xffffffff;
cEnd512ByteBlock.m_ucPos8192KBlockNext1 = 0xff;
cEnd512ByteBlock.m_ucPos8192KBlockNext2 = 0xff;
}
else
{
cEnd512ByteBlock.m_ulPos512ByteBlockNextMult256 = ((ULONG)uiPos32KBlockNext * 64) * 256;
if ( !m_bSpecialEdition )
{
cEnd512ByteBlock.m_ucPos8192KBlockNext1 = uiPos32KBlockNext / 256;
cEnd512ByteBlock.m_ucPos8192KBlockNext2 = uiPos32KBlockNext / 256;
}
else
{
cEnd512ByteBlock.m_ucPos8192KBlockNext1 = uiPos32KBlockNext / 512;
cEnd512ByteBlock.m_ucPos8192KBlockNext2 = uiPos32KBlockNext / 512;
}
if ( m_bUseExternalFlash )
{
cEnd512ByteBlock.m_ulPos512ByteBlockNextMult256 += 0x01000000;
cEnd512ByteBlock.m_ucPos8192KBlockNext1 = 0;
cEnd512ByteBlock.m_ucPos8192KBlockNext2 = 0;
}
}
if ( uiPos32KBlockPrev == 0xffff )
{
cEnd512ByteBlock.m_ulPos512ByteBlockPrevMult256 = 0xffffffff;
cEnd512ByteBlock.m_ucPos8192KBlockPrev1 = 0xff;
cEnd512ByteBlock.m_ucPos8192KBlockPrev2 = 0xff;
cEnd512ByteBlock.m_usPos32KBlockPrevMult256 = 0xffff;
}
else
{
cEnd512ByteBlock.m_ulPos512ByteBlockPrevMult256 = ((ULONG)uiPos32KBlockPrev * 64) * 256;
if ( !m_bSpecialEdition )
{
cEnd512ByteBlock.m_ucPos8192KBlockPrev1 = uiPos32KBlockPrev / 256;
cEnd512ByteBlock.m_ucPos8192KBlockPrev2 = uiPos32KBlockPrev / 256;
}
else
{
cEnd512ByteBlock.m_ucPos8192KBlockPrev1 = uiPos32KBlockPrev / 512;
cEnd512ByteBlock.m_ucPos8192KBlockPrev2 = uiPos32KBlockPrev / 512;
}
if ( m_bUseExternalFlash )
{
cEnd512ByteBlock.m_ulPos512ByteBlockPrevMult256 += 0x01000000;
cEnd512ByteBlock.m_ucPos8192KBlockPrev1 = 0;
cEnd512ByteBlock.m_ucPos8192KBlockPrev2 = 0;
}
cEnd512ByteBlock.m_usPos32KBlockPrevMult256 = uiPos32KBlockPrev * 256;
}
// output end of block
#if defined(_WINNT)
{
DWORD dwSizeReturn;
DeviceIoControl( m_hDriver, RIOIO_IOCTL_WRITEBLOCK, &cEnd512ByteBlock,
sizeof(CEnd512ByteBlock), NULL, 0, &dwSizeReturn, NULL );
}
#else
pauc2 = (UCHAR*)&cEnd512ByteBlock;
for( iB=0; iB<sizeof(CEnd512ByteBlock); ++iB, ++pauc2 )
{
OUTPORT( m_iPortData, (*pauc2) );
if ( !(iB & 1) )
OUTPORT( m_iPortControl, B_00000000 );
else
OUTPORT( m_iPortControl, B_00000100 );
IODELAY( 1 );
}
#endif
// end of tx
COMMANDOUT( B_10100001, B_00001100, B_00000100 );
COMMANDOUT( B_00010000, B_00000000, B_00000100 );
WAITACK();
COMMANDOUT( B_10100001, B_00001100, B_00000100 );
COMMANDOUT( B_01110000, B_00000000, B_00000100 );
COMMANDOUT( B_10100000, B_00001100, B_00000100 );
OUTPORT( m_iPortControl, B_00000000 );
IODELAY( m_lTimeIODelayTx );
OUTPORT( m_iPortControl, B_00000100 );
IODELAY( m_lTimeIODelayTx );
}
return TRUE;
}
// tx 32K block
BOOL CRio::Tx32KBlock( void* pv, UINT uiPos32KBlock, UINT uiPos32KBlockPrev,
UINT uiPos32KBlockNext )
{
int iRetry = 0;
while( iRetry < MAX_RETRY )
{
if ( Tx32KBlockRetry(pv, uiPos32KBlock, uiPos32KBlockPrev, uiPos32KBlockNext) )
return TRUE;
DELAY( CLOCK_SECOND );
++iRetry;
}
LogError( CRIO_ERROR_TXBLOCKRETRY, "too many retries for tx block" );
return FALSE;
}
// rx 32K block retry
BOOL CRio::Rx32KBlockRetry( void* pv, UINT uiPos32KBlock )
{
ULONG ulPos512ByteBlock;
ULONG ulPosHi;
ULONG ulPosMid;
ULONG ulPosLo;
int iA, iB;
// io intro
if ( !IOIntro() )
return FALSE;
// get 32K in 512 byte chunks
UCHAR* pauc = (UCHAR*)pv;
for( iA=0; iA<(32768/512); ++iA, pauc+=512 )
{
ulPos512ByteBlock = ((ULONG)uiPos32KBlock * 32768 + (ULONG)iA * 512) / 512;
ulPosLo = ulPos512ByteBlock & 0xff;
if ( m_bUseExternalFlash )
{
ulPosHi = POS_BANK_EXTERNALFLASH;
ulPosMid = (ulPos512ByteBlock & 0xff00) >> 8;
}
else if ( m_bSpecialEdition )
{
ulPosHi = ulPos512ByteBlock / 32768;
ulPosMid = (ulPos512ByteBlock & 0x7f00) >> 8;
}
else
{
ulPosHi = ulPos512ByteBlock / 16384;
ulPosMid = (ulPos512ByteBlock & 0x3f00) >> 8;
}
// issue download 512 byte block command
COMMANDOUT( B_10101011, B_00001100, B_00000100 );
COMMANDOUT( ulPosHi, B_00000000, B_00000100 );
COMMANDOUT( B_10100001, B_00001100, B_00000100 );
COMMANDOUT( B_00000000, B_00000000, B_00000100 );
COMMANDOUT( B_10100010, B_00001100, B_00000100 );
COMMANDOUT( B_00000000, B_00000000, B_00000100 );
COMMANDOUT( ulPosLo, B_00000000, B_00000100 );
COMMANDOUT( ulPosMid, B_00000000, B_00000100 );
WAITACK();
COMMANDOUT( B_10100000, B_00001100, B_00000100 );
// clock in data
#if defined(_WINNT)
{
DWORD dwSizeReturn;
DeviceIoControl( m_hDriver, RIOIO_IOCTL_READBLOCK, pauc, 512,
pauc, 512, &dwSizeReturn, NULL );
}
#else
for( iB=0; iB<512; ++iB )
*(pauc+iB) = GetDataByte();
#endif
// clock in 16 bytes which are ignored
for( iB=0; iB<16; ++iB )
GetDataByte();
// delay
WAITACK();
}
return TRUE;
}
// rx 32K block
BOOL CRio::Rx32KBlock( void* pv, UINT uiPos32KBlock )
{
int iRetry = 0;
while( iRetry < MAX_RETRY )
{
if ( Rx32KBlockRetry(pv, uiPos32KBlock) )
return TRUE;
DELAY( CLOCK_SECOND );
++iRetry;
}
LogError( CRIO_ERROR_RXBLOCKRETRY, "too many retries for rx block" );
return FALSE;
}
// mark bad blocks
BOOL CRio::MarkBadBlocks( BOOL (*pfProgress)(int iPos, int iCount, void* cookie), void* cookie)
{
// create temp block
UCHAR* paucBlock;
NEWBLOCK( paucBlock );
// block count
USHORT usPos32KBlockEnd;
if ( m_bUseExternalFlash )
usPos32KBlockEnd = m_uiCount32KBlockAvailableExternal;
else
usPos32KBlockEnd = m_bSpecialEdition ? CRIO_COUNT_32KBLOCKIN64M : CRIO_COUNT_32KBLOCKIN32M;
// assume directory block is ok
m_cDirBlock.m_auc32KBlockUsed[ 0 ] = CRIO_ID_32KBLOCK_FREE;
// process all blocks (except directory block)
int iCount32KBlockBad = 0;
USHORT usPos32KBlock;
for( usPos32KBlock=1; usPos32KBlock<usPos32KBlockEnd; ++usPos32KBlock )
{
UINT uiB;
// progress callback
if ( pfProgress )
{
if ( !pfProgress(usPos32KBlock, usPos32KBlockEnd, cookie) )
{
LogError( CRIO_ERROR_INTERRUPTED, "operation interrupted" );
break;
}
}
// default to bad block
UCHAR ucState = CRIO_ID_32KBLOCK_BAD;
// create and send test block 1
memset( paucBlock, B_10101010, CRIO_SIZE_32KBLOCK );
if ( !Tx32KBlock(paucBlock, usPos32KBlock, 0, 0) )
break;
// get test block 1
if ( !Rx32KBlock(paucBlock, usPos32KBlock) )
break;
// check test block 1
for( uiB=0; uiB<CRIO_SIZE_32KBLOCK; ++uiB )
{
if ( *(paucBlock+uiB) != B_10101010 )
break;
}
// if ok
if ( uiB == CRIO_SIZE_32KBLOCK )
{
// create and send test block 2
memset( paucBlock, B_01010101, CRIO_SIZE_32KBLOCK);
if ( !Tx32KBlock(paucBlock, usPos32KBlock, 0, 0) )
break;
// get test block 2
if ( !Rx32KBlock(paucBlock, usPos32KBlock) )
break;
// check test block 2
for( uiB=0; uiB<CRIO_SIZE_32KBLOCK; ++uiB )
{
if ( *(paucBlock+uiB) != B_01010101 )
break;
}
// if ok, block ok
if ( uiB == CRIO_SIZE_32KBLOCK )
ucState = CRIO_ID_32KBLOCK_FREE;
}
// store block state
m_cDirBlock.m_auc32KBlockUsed[ usPos32KBlock ] = ucState;
// adjust bad block count
if ( ucState == CRIO_ID_32KBLOCK_BAD )
++iCount32KBlockBad;
}
// if tx,rx block error or interrupted
if ( usPos32KBlock < usPos32KBlockEnd )
return FALSE;
// store blocks used and bad block count
m_cDirBlock.m_cDirHeader.m_usCount32KBlockUsed = iCount32KBlockBad;
m_cDirBlock.m_cDirHeader.m_usCount32KBlockBad = iCount32KBlockBad;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// operations
void CRio::UseExternalFlash( BOOL bUseExternalFlash )
{
m_bUseExternalFlash = bUseExternalFlash;
}
BOOL CRio::CheckPresent( void )
{
// io intro
if ( !IOIntro() )
return FALSE;
// bank to check (bank 0-3 are internal, bank 4 external)
int iPos = m_bUseExternalFlash ? POS_BANK_EXTERNALFLASH : 0;
// issue read id command
COMMANDOUT( 0xab, B_00001100, B_00000100 );
COMMANDOUT( iPos, B_00000000, B_00000100 );
COMMANDOUT( 0xa1, B_00001100, B_00000100 );
COMMANDOUT( 0x90, B_00000000, B_00000100 );
COMMANDOUT( 0xa2, B_00001100, B_00000100 );
COMMANDOUT( 0x00, B_00000000, B_00000100 );
COMMANDOUT( 0xa0, B_00001100, B_00000100 );
UCHAR ucManufacturer = GetDataByte();
UCHAR ucDevice = GetDataByte();
// check manufacturer code
switch( ucManufacturer )
{
case 0xa0:
case 0xaa:
case 0xff:
case 0xdd:
case 0x00:
LogError( CRIO_ERROR_DEVICENOTFOUND, "device not found" );
return FALSE;
}
// determine bank size in 512 byte blocks
ULONG ulCount512ByteBlock;
switch( ucDevice )
{
case 0xea:
case 0x64: ulCount512ByteBlock = 4096; break;
case 0xe3:
case 0xe5: ulCount512ByteBlock = 8192; break;
case 0xe6: ulCount512ByteBlock = 16384; break;
case 0x73: ulCount512ByteBlock = 32768; break;
case 0x75: ulCount512ByteBlock = 65536; break;
default:
LogError( CRIO_ERROR_DEVICENOTFOUND, "device not found" );
return FALSE;
};
// if internal
if ( !m_bUseExternalFlash )
{
// if special edition found (each bank of 4 is 512 * 32768)
if ( ulCount512ByteBlock == 32768 )
m_bSpecialEdition = TRUE;
}
// else external
else
{
// convert page count to 32K block count
m_uiCount32KBlockAvailableExternal = (ulCount512ByteBlock * 512) / CRIO_SIZE_32KBLOCK;
}
return TRUE;
}
CDirEntry* CRio::FindFile( const char* pszFile, CFindFile* pFindFile)
{
// search directory entries for matching filename
int iCountEntry = m_cDirBlock.m_cDirHeader.m_usCountEntry;
CDirEntry* pDirEntry = m_cDirBlock.m_acDirEntry;
int iA = 0;
if(pFindFile)
{
if(pFindFile->m_iCount < iCountEntry)
{
iA = ++pFindFile->m_iCount;
pDirEntry = ++pFindFile->m_iEntry;
}
}
for(; iA<iCountEntry; ++iA, ++pDirEntry )
{
if ( !strcmp(pszFile, pDirEntry->m_szName) )
{
if(pFindFile)
{
pFindFile->m_iCount = iA;
pFindFile->m_iEntry = pDirEntry;
}
return pDirEntry;
}
}
return NULL;
}
BOOL CRio::Initialize( BOOL bMarkBadBlock, BOOL (*pfProgress)(int iPos, int iCount, void* cookie), void* cookie)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -