📄 usbd_sampletask.c
字号:
// Execute ATA command
result = DEVICE_TASK_ExecIdeCmd( LUN0, DEVICE_TASK_IDECMD_TYPE_ATA, &AtaCmd, &XferInfo );
if ( result != DEVICE_TASK_STATUS_SUCCESS )
{
// Failed to execute ATA command
// Clear register of control for DMA Ch0
sfr_outl( DMA_CH0CTRL, 0 );
return STATUS_UNSUCCESSFUL;
}
// Wait until DMA transfer finished
while( !( sfr_inl( DMA_CH0CTRL ) & DMACH_TREND ) )
{
dly_tsk( 50 );
}
// Clear register of control for DMA Ch0
sfr_outl( DMA_CH0CTRL, 0 );
#endif
return STATUS_SUCCESS;
}
/*
//=============================================================================
// Function_Name: ATA_ReadCmdSync
// description : Send ATA Read command(Synchronous mode)
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
long ATA_ReadCmdSync( void )
{
long result;
#ifdef TOYA2_C
// Set register of source address for DMA Ch0
rlMX21_SAR0 = READDEVICEADR;
// Set register of destination address for DMA Ch0
rlMX21_DAR0 = (unsigned long )pRdBuff ;
// Set register of transfer count for DMA Ch0
rlMX21_CNTR0 = RDBUFF_SIZE;
rlMX21_BLR0 = 16;
/* Flush and clear data cache */
flush_Dcache((unsigned long)pWrBuff, WRBUFF_SIZE);
clean_Dcache((unsigned long)pWrBuff, WRBUFF_SIZE);
// Set register of control for DMA Ch0
rlMX21_CCR0 =
(0<<14) | /* ACRPT : 0 or 1 :Auto Clear Off */
(0<<12) | /* DMOD : 0 - 3 :Dst Linear Mem */
(2<<10) | /* SMOD : 0 - 3 :Src FIFO */
(0<< 9) | /* MDIR : 0 or 1 :Direction: Inc */
(0<< 8) | /* MSEL : 0 or 1 :N/A */
(0<< 6) | /* DSIZ : 0 - 3 :dst 32bit Port */
(2<< 4) | /* SSIZ : 0 - 3 :src 16bit Port */
(1<< 3) | /* REN : 0 or 1 :Request Enable */
(0<< 2) | /* RPT : 0 or 1 :Repeat Disable */
(0<< 1) | /* FRC : 0 or 1 :Force DMA Non */
(1<< 0) ; /* CEN : 0 or 1 :Enable DMA Ch */
#else
// Set register of source address for DMA Ch0
sfr_outl( DMA_CH0SRCADD, DEVICEADR );
// Set register of destination address for DMA Ch0
sfr_outl( DMA_CH0DSTADD, (unsigned long )pRdBuff );
// Set register of transfer count for DMA Ch0
sfr_outl( DMA_CH0TRCNT, RDBUFF_SIZE/2 );
// Set register of control for DMA Ch0
sfr_outl( DMA_CH0CTRL, (DMACH_DESTADD_INC |
DMACH_TRSIZE_16BIT | DMACH_CHANNELEN));
#endif
#ifdef BIG_DRIVE
// Create ATA command(BIG DRIVE READ[25h])
memset( &AtaCmd, 0, sizeof( DEVICE_TASK_ATA_CMD ));
AtaCmd.features = 0; // Features
AtaCmd.secCnt = 0x02;
AtaCmd.bicSecCnt = 0x00; // Bic Drive Sector count
AtaCmd.bicSecNum = 0; // Bic Drive Sector countLBA[7:0]
AtaCmd.bicCylLow = 0; // Bic Drive Sector countLBA[15:8]
AtaCmd.bicCylHigh = 0; // Bic Drive Sector countLBA[23:16]
AtaCmd.bicDevHead = 0x01; // Bic Drive Sector countDevice/Head,LBA[27:24]
AtaCmd.command = 0x25; // Command
#else
// Create ATA command(READ DMA[C8h])
memset( &AtaCmd, 0, sizeof( DEVICE_TASK_ATA_CMD ));
AtaCmd.features = 0; // Features
AtaCmd.secCnt = 0x02; // Sector count
AtaCmd.secNum = 0; // LBA[7:0]
AtaCmd.cylLow = 0; // LBA[15:8]
AtaCmd.cylHigh = 0; // LBA[23:16]
AtaCmd.devHead = 0x00; // Device/Head,LBA[27:24]
AtaCmd.command = 0xC8; // Command
#endif
// Set information for data transfer
memset( &XferInfo, 0, sizeof( DEVICE_TASK_XFER_INFO ));
XferInfo.mode = DEVICE_TASK_XFER_MODE_DMA; // DMA transfer
XferInfo.size = RDBUFF_SIZE; // Number of data transfer
XferInfo.dir = DEVICE_TASK_XFER_DIR_IN; // Direction of data transfer
XferInfo.pAddress = NULL;
XferInfo.dmaChannel = DEVICE_TASK_DMA_CH0; // DMA channel
#ifdef TOYA2_C
// Execute ATA command
result = DEVICE_TASK_ExecIdeCmd( LUN0, DEVICE_TASK_IDECMD_TYPE_ATA, &AtaCmd, &XferInfo );
if ( result != DEVICE_TASK_STATUS_SUCCESS )
{
// Failed to execute ATA command
// Clear register of control for DMA Ch0
rlMX21_CCR0 = 0;
rlMX21_DISR |= 1;
return STATUS_UNSUCCESSFUL;
}
// Wait until DMA transfer finished
while( !( rlMX21_DISR & 0x01 ) )
{
dly_tsk( 50 );
}
// Clear register of control for DMA Ch0
rlMX21_CCR0 = 0;
rlMX21_DISR |= 1;
#else
// Execute ATA command
result = DEVICE_TASK_ExecIdeCmd( LUN0, DEVICE_TASK_IDECMD_TYPE_ATA, &AtaCmd, &XferInfo );
if ( result != DEVICE_TASK_STATUS_SUCCESS )
{
// Failed to execute ATA command
// Clear register of control for DMA Ch0
sfr_outl( DMA_CH0CTRL, 0 );
return STATUS_UNSUCCESSFUL;
}
// Wait until DMA transfer finished
while( !( sfr_inl( DMA_CH0CTRL ) & DMACH_TREND ) )
{
dly_tsk( 50 );
}
// Clear register of control for DMA Ch0
sfr_outl( DMA_CH0CTRL, 0 );
#endif
return STATUS_SUCCESS;
}
/*
//=============================================================================
// Function_Name: ReadDataCheck
// description : Compare the data which has been written with the data which has been read out
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
long ReadDataCheck( void )
{
int cnt;
for( cnt=0; cnt<WRBUFF_SIZE; cnt++ )
{
if ( *( pWrBuff + cnt ) != *( pRdBuff + cnt ) )
{
return STATUS_UNSUCCESSFUL;
}
}
return STATUS_SUCCESS;
}
/*
//=============================================================================
// Function_Name: ATAPI_ReadCommand
// description : Send ATAPI Read command
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
long ATAPI_ReadCommand( void )
{
long result;
// Create ATAPI command(INQUIRY)
memset( &AtapiCmd, 0, sizeof( DEVICE_TASK_ATAPI_CMD ));
AtapiCmd.command[0] = ATAPI_INQUIRY; // Command Code
AtapiCmd.command[1] = 0;
AtapiCmd.command[2] = 0;
AtapiCmd.command[4] = INQUIRY_SIZE; // Length of allocation
AtapiCmd.command[5] = 0;
// Set information for data transfer
memset( &XferInfo, 0, sizeof( DEVICE_TASK_XFER_INFO ));
XferInfo.mode = DEVICE_TASK_XFER_MODE_PIO; // PIO transfer
XferInfo.size = INQUIRY_SIZE; // Number of data transfer
XferInfo.dir = DEVICE_TASK_XFER_DIR_IN; // Direction of data transfer
XferInfo.pAddress = pInquiry; // Address of buffer for data receiving
XferInfo.dmaChannel = 0;
// Execute ATAPI command
result = DEVICE_TASK_ExecIdeCmd( LUN0, DEVICE_TASK_IDECMD_TYPE_ATAPI, &AtapiCmd, &XferInfo );
if ( result != DEVICE_TASK_STATUS_SUCCESS )
{
// Failed to execute ATAPI command
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
/*
//=============================================================================
// Function_Name: ATAPI_TestUnitRdy
// description : Send command of TEST UNIT READY
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
long ATAPI_TestUnitRdy( void )
{
#ifdef CMD_ASYNC_MODE
TskInfo.DMAxferFlg = DMA_NOTREADY;
TskInfo.IDEcmdCmpFlg = IDE_CMDSEQ_RDY;
#endif
// Create command of TEST UNIT READY
memset( &AtapiCmd, 0, sizeof( DEVICE_TASK_ATAPI_CMD ));
AtapiCmd.command[0] = ATAPI_TEST_UNIT_READY; // Command Code
AtapiCmd.command[1] = 0;
AtapiCmd.command[2] = 0;
AtapiCmd.command[4] = 0;
AtapiCmd.command[5] = 0;
AtapiCmd.command[6] = 0;
AtapiCmd.command[7] = 0;
AtapiCmd.command[8] = 0;
AtapiCmd.command[9] = 0;
AtapiCmd.command[10] = 0;
AtapiCmd.command[11] = 0;
// Set information for data transfer
memset( &XferInfo, 0, sizeof( DEVICE_TASK_XFER_INFO ));
XferInfo.mode = 0; // Mode of data transfer
XferInfo.size = 0; // Number of data transfer
XferInfo.dir = 0; // Direction of data transfer
XferInfo.pAddress = 0; // Address of buffer for data receiving
XferInfo.dmaChannel = 0;
// Execute ATAPI command
DEVICE_TASK_ExecIdeCmd( LUN0, DEVICE_TASK_IDECMD_TYPE_ATAPI, &AtapiCmd, &XferInfo );
#ifdef CMD_ASYNC_MODE
while( TskInfo.IDEcmdCmpFlg == IDE_CMDSEQ_RDY )
{
dly_tsk( 100 );
}
#endif
return STATUS_SUCCESS;
}
#ifdef USB_PLAY_TEST
/*
//=============================================================================
// Function_Name: ATAPI_TestUnitRdy
// description : Send command of TEST UNIT READY
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
long ATAPI_Read10 ( unsigned short secSize, unsigned long LBA, unsigned char *pData )
{
long result;
//------------------------------------------------------
// ATAPI command [READ]
//------------------------------------------------------
#ifdef DMA_XFER_TEST
#ifndef TOYA2_C
// Set DMA of CPU
sfr_outl( DMA_OPERATION, 1 ); // Enable DMA transfer
// Set register of source address for DMA Ch0
sfr_outl( DMA_CH0SRCADD, DEVICEADR );
// Set register of destination address for DMA Ch0
sfr_outl( DMA_CH0DSTADD, (unsigned long)pData );
// Set register of transfer count for DMA Ch0
sfr_outl( DMA_CH0TRCNT, (secSize<<8) ); // (SEC_SIZE * 512) / 2 = secSize << 8
// Set register of control for DMA Ch0
sfr_outl( DMA_CH0CTRL, (DMACH_DESTADD_INC |
DMACH_TRSIZE_16BIT | DMACH_IRQEN | DMACH_CHANNELEN));
#endif
#endif
// Create ATAPI command(READ)
memset( &AtapiCmd, 0, sizeof( DEVICE_TASK_ATAPI_CMD ));
AtapiCmd.command[0] = ATAPI_READ10; // Command Code
AtapiCmd.command[1] = 0;
AtapiCmd.command[2] = (unsigned char)(LBA >> 27);
AtapiCmd.command[3] = (unsigned char)(LBA >> 16);
AtapiCmd.command[4] = (unsigned char)(LBA >> 8);
AtapiCmd.command[5] = (unsigned char)(LBA);
AtapiCmd.command[6] = 0;
AtapiCmd.command[7] = (unsigned char)(secSize >> 8);
AtapiCmd.command[8] = (unsigned char)(secSize);
AtapiCmd.command[9] = 0;
AtapiCmd.command[10] = 0;
AtapiCmd.command[11] = 0;
// Set information for data transfer
memset( &XferInfo, 0, sizeof( DEVICE_TASK_XFER_INFO ));
#ifdef DMA_XFER_TEST
XferInfo.mode = DEVICE_TASK_XFER_MODE_DMA; // DMA transfer
XferInfo.pAddress = NULL;
#else
XferInfo.mode = DEVICE_TASK_XFER_MODE_PIO; // PIO transfer
XferInfo.pAddress = pData;
#endif
XferInfo.size = secSize<<9; // Number of data transfer
XferInfo.dir = DEVICE_TASK_XFER_DIR_IN; // Direction of data transfer
XferInfo.dmaChannel = 0;
// Execute ATAPI command
result = DEVICE_TASK_ExecIdeCmd( LUN0, DEVICE_TASK_IDECMD_TYPE_ATAPI, &AtapiCmd, &XferInfo );
if ( result != DEVICE_TASK_STATUS_SUCCESS )
{
// Failed to execute ATAPI command
DBG_FlowStrPrint( "PlayModeTest ATAPI_Read NG\r\n",0 );
#ifdef DMA_XFER_TEST
#ifndef TOYA2_C
// Set DMA of CPU
sfr_outl( DMA_OPERATION, 0 ); // Disable DMA transfer
#endif
#endif
return STATUS_UNSUCCESSFUL;
}
#ifdef DMA_XFER_TEST
#ifndef TOYA2_C
// Set DMA of CPU
sfr_outl( DMA_OPERATION, 0 ); // Disable DMA transfer
#endif
#endif
return STATUS_SUCCESS;
}
/*
//=============================================================================
// Function_Name: ATAPI_TestUnitRdy
// description : Send command of TEST UNIT READY
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
long ATAPI_Write10 ( unsigned short secSize, unsigned long LBA, unsigned char *pData )
{
long result;
//------------------------------------------------------
// ATAPI command [WRITE]
//------------------------------------------------------
#ifdef DMA_XFER_TEST
#ifndef TOYA2_C
// Set DMA of CPU
sfr_outl( DMA_OPERATION, 1 ); // Enable DMA transfer
// Set register of source address for DMA Ch0
sfr_outl( DMA_CH0SRCADD, (unsigned long)pData );
// Set register of destination address for DMA Ch0
sfr_outl( DMA_CH0DSTADD, DEVICEADR );
// Set register of transfer count for DMA Ch0
sfr_outl( DMA_CH0TRCNT, (secSize<<8) );// (SEC_SIZE * 512) / 2 = secSize << 8
// Set register of control for DMA Ch0
sfr_outl( DMA_CH0CTRL, (DMACH_ACKMODE | DMACH_SRCADD_INC |
DMACH_TRSIZE_16BIT | DMACH_IRQEN | DMACH_CHANNELEN));
#endif
#endif
// Create ATAPI command(WRITE)
memset( &AtapiCmd, 0, sizeof( DEVICE_TASK_ATAPI_CMD ));
AtapiCmd.command[0] = ATAPI_WRITE10; // Command Code
AtapiCmd.command[1] = 0;
AtapiCmd.command[2] = (unsigned char)(LBA >> 27);
AtapiCmd.command[3] = (unsigned char)(LBA >> 16);
AtapiCmd.command[4] = (unsigned char)(LBA >> 8);
AtapiCmd.command[5] = (unsigned char)(LBA);
AtapiCmd.command[6] = 0;
AtapiCmd.command[7] = (unsigned char)(secSize >> 8);
AtapiCmd.command[8] = (unsigned char)(secSize);
AtapiCmd.command[9] = 0;
AtapiCmd.command[10] = 0;
AtapiCmd.command[11] = 0;
// Set information for data transfer
memset( &XferInfo, 0, sizeof( DEVICE_TASK_XFER_INFO ));
#ifdef DMA_XFER_TEST
XferInfo.mode = DEVICE_TASK_XFER_MODE_DMA; // DMA transfer
XferInfo.pAddress = NULL;
#else
XferInfo.mode = DEVICE_TASK_XFER_MODE_PIO; // PIO transfer
XferInfo.pAddress = pData;
#endif
XferInfo.size = secSize<<9; // Number of data transfer
XferInfo.dir = DEVICE_TASK_XFER_DIR_OUT; // Direction of data transfer
XferInfo.dmaChannel = 0;
// Execute ATAPI command
result = DEVICE_TASK_ExecIdeCmd( LUN0, DEVICE_TASK_IDECMD_TYPE_ATAPI, &AtapiCmd, &XferInfo );
if ( result != DEVICE_TASK_STATUS_SUCCESS )
{
// Failed to execute ATAPI command
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -