📄 devicetask.c
字号:
FIFO_IFSetIntEvent( FIFO_IF_MEDIA_FULL, FIFO_IF_EVENTOFF ); // FIFO Full
FIFO_IFSetIntEvent( FIFO_IF_MEDIA_EMPTY, FIFO_IF_EVENTOFF ); // FIFO Empty
CPUDMA_IFSetIntEvent( CpuDmaIntEnb, CPUDMA_IF_EVENTOFF ); // CPU DMA Event
// H/W is initialized
FIFO_IF_FIFOClear( PLAY_READ_FIFO );
FIFO_IF_FIFOClear( PLAY_WRITE_FIFO );
FIFO_IFClearFIFO_AllJoin(); // All Join is cut
return;
}
/*
//=============================================================================
// Function_Name: MsgPlayIdeXferPreParation
// description : Completion notification of data transfer preparation
// argument : none
// return : none
//=============================================================================
*/
BOOL PlaySendCmd ( void )
{
PARAM_MSG_REQ_IDE_CMD ideCmd; // Structure of command sent to IDE
//========================================================================
// Select the IDE to DEVICE transfer type
//========================================================================
if( DEVICEInfo.playInfo.xferInfo.mode == DEVICE_TASK_XFER_MODE_DMA )
{
//------------------------------------------------------------------------
// When DMA is specified from other module, DMA is set
//------------------------------------------------------------------------
DEVICEInfo.playInfo.ideXferMode = IDE_XFER_DMA;
}
else
{ // DEVICE_TASK_XFERMODE_PIO
//------------------------------------------------------------------------
// IDE device type judgment
//------------------------------------------------------------------------
if( TaskInfo.ideTaskInfo.devType[DEVICEInfo.playInfo.lun] == IDE_CMD_ATA )
{ // ATA device
// Judge the type of command receiving
//===========================================
if( DEVICEInfo.playInfo.cmdType == DEVICE_TASK_IDECMD_TYPE_ATA )
{
// H/W PIO when ATA command is transfer to ATA device
DEVICEInfo.playInfo.ideXferMode = IDE_XFER_HPIO;
}
else
{ // DEVICE_TASK_IDECMD_TYPE_ATAPI
// Judge by the command code, if it is ATAPI command for ATA device
//---------------------------------------------------
switch( *DEVICEInfo.playInfo.ideCmd )
{
case CMD_READ10: // READ 10
case CMD_WRITE10: // WRITE 10
case CMD_READ12: // READ 12
case CMD_WRITE12: // WRITE 12
DEVICEInfo.playInfo.ideXferMode = IDE_XFER_HPIO;
break;
default:
// S/W PIO when ATAPI command is transfer to ATA device
DEVICEInfo.playInfo.ideXferMode = IDE_XFER_SPIO;
break;
}
}
}
else // ATAPI device
{
// Judge the type of command receiving
if( DEVICEInfo.playInfo.cmdType == DEVICE_TASK_IDECMD_TYPE_ATA ) // ATA device
{
// Make it to software PIO, to run while any command is received
DEVICEInfo.playInfo.ideXferMode = IDE_XFER_SPIO;
}
else
{
// The ATAPI command does H/W PIO to the ATAPI device
DEVICEInfo.playInfo.ideXferMode = IDE_XFER_HPIO;
}
}
}
//========================================================================
// The command processing requirement is transfer to the IDE task
//========================================================================
if( DEVICEInfo.playInfo.cmdType == DEVICE_TASK_IDECMD_TYPE_ATA )
{
ideCmd.cmdType = IDE_CMD_ATA; // Command type ATA
}
else // DEVICE_TASK_IDECMD_TYPE_ATAPI
{
ideCmd.cmdType = IDE_CMD_ATAPI; // Command type ATAPI
}
memcpy( &ideCmd.IDECmd, &DEVICEInfo.playInfo.ideCmd,
sizeof(ideCmd.IDECmd) ); // Copy command
ideCmd.reqDataLen = DEVICEInfo.playInfo.xferInfo.reqSize; // Number of request transfer
ideCmd.LUN = DEVICEInfo.playInfo.lun; // LUN
ideCmd.opeMode = IDE_CMD_MANUAL; // Operation mode: Manual mode
ideCmd.xferMode = DEVICEInfo.playInfo.ideXferMode; // Specify transfer mode
ideCmd.bufferPtr = DEVICEInfo.playInfo.xferInfo.buffer; // Set address
SendMessage( MBXID_IDE, MSG_REQ_IDE_CMD, sizeof(ideCmd), &ideCmd ); // Send mail
return TRUE;
}
/*
//=============================================================================
// Function_Name: PlayCmdResultWait
// description : Wait for result of command execution
// argument : none
// return : none
//=============================================================================
*/
BOOL PlayCmdResultWait( void )
{
DEVICE_MSG* pMsg;
OS_FLGPTN flgPtn;
PARAM_MSG_REQ_IDE_XFER_START xferStart;
const USHORT waitMsg[] = { // Message from IDE Task
MSG_NTFY_IDE_HRST, MSG_NTFY_IDE_CMD, MSG_NTFY_IDE_CMP_XFER_READY, MSG_NTFY_IDE_XFER_CMP,
};
//========================================================================
// Wait for request of data transfer or status receiving from the IDE task
//========================================================================
while(1)
{
flgPtn = WaitMessage( (sizeof(waitMsg)/sizeof(USHORT)), (USHORT *)waitMsg, &pMsg );
switch( flgPtn )
{
case FLG_EVENT_FORCE_DEVICE: // Force event processing
// Leave out for reception of request of forcely terminating PLAY mode
return FALSE;
case FLG_EVENT_INT_DEVICE: // Interrupt event processing
// Interrupt processing
DEVICE_IntEvent();
OS_ClrFlg( FLGID_DEVICE, ~(FLG_EVENT_INT_DEVICE) );
break;
case FLG_EVENT_DMA_START_DEVICE: // Request of DMA statrt
// DMA of DEVICE and IDE is begun
//=============================================================
StartDMA( DEVICEInfo.playInfo.xferInfo.dmaCh,
DEVICEInfo.playInfo.xferInfo.dir, DEVICEInfo.playInfo.xferInfo.size, IDE_TO_MEDIA );
// Request to start DMA for IDE task
xferStart.bufferPtr = NULL;
SendMessage( MBXID_IDE, MSG_REQ_IDE_XFER_START, sizeof(xferStart), &xferStart );
OS_ClrFlg( FLGID_DEVICE, ~(FLG_EVENT_DMA_START_DEVICE) );
break;
case FLG_EVENT_DMA_ABORT_DEVICE: // Request of DMA stop
// Request to abort DMA
//------------------------------------------------------------------------------------
//========================================================================
// To abort the data transfer of IDE, software is reset
//========================================================================
SendMessage( MBXID_IDE, MSG_REQ_IDE_HRST, 0, NULL ); // Request of IDE device reset
OS_ClrFlg( FLGID_DEVICE, ~(FLG_EVENT_DMA_ABORT_DEVICE) );
break;
case FLG_EVENT_MSG_DEVICE: // Message reception
// Each processing is performed after judging source of mail receiving
//===========================================
if( pMsg->msgHead.msgSndTskId == TSKID_IDE )
{
// IDE message reception
//-----------------------------------
switch( pMsg->msgHead.msgNo )
{
case MSG_NTFY_IDE_CMP_XFER_READY: // Completion notification of IDE data transfer preparation
MsgPlayIdeXferReady( pMsg );
break;
case MSG_NTFY_IDE_XFER_CMP: // Completion notification of data transfer
MsgPlayIdeXferCmp( pMsg );
break;
case MSG_NTFY_IDE_CMD: // Completion notification of ATAPI command
MsgPlayIdeCmdCmp( pMsg );
break;
case MSG_NTFY_IDE_HRST: // Completion notification of software reset
// Because reset of the software of IDE was completed, DMA is stopped
StopDMA( DEVICEInfo.playInfo.xferInfo.dmaCh );
DEVICEInfo.playInfo.cmdStatus = DEVICE_TASK_CMD_STATUS_FAILED;
//=============================================================
// CallBack Completion notification of DMA stop
//-------------------------------------------------------------
// Message : DEVICE_TASK_MSG_DMA_ABORTED
// Param0 : 0
// pParam : NULL
//=============================================================
SendCallback( DEVICE_TASK_MSG_DMA_ABORTED, 0, NULL );
return FALSE;
// break;
default:
break;
}
}
// Free the memory pool
OS_RelMpf( pMsg->msgHead.useMpfId, pMsg );
break;
default:
// Other flag event
OS_ClrFlg( FLGID_DEVICE, ~(flgPtn) );
break;
}
//------------------------------------------------------------------------
// Whether all processing ended is confirmed
//------------------------------------------------------------------------
if( DEVICEInfo.playInfo.bCpuXferCmp == TRUE && DEVICEInfo.playInfo.bIdeCmdCmp == TRUE )
{
PLAY_INFO* pPlayInfo;
pPlayInfo = &DEVICEInfo.playInfo;
// Because the data transfer was completed, do after process
//=============================================
CPUDMA_IFStop( pPlayInfo->xferInfo.dmaCh ); // Stop DMA
CPUDMA_IFUnlockPort( pPlayInfo->xferInfo.dmaCh ); // Free the Port Lock
// Disable interrupt
FIFO_IFSetIntEvent( FIFO_IF_MEDIA_IDE_CMP, FIFO_IF_EVENTOFF ); // IDE Comp
FIFO_IFSetIntEvent( FIFO_IF_MEDIA_FULL, FIFO_IF_EVENTOFF ); // FIFO Full
FIFO_IFSetIntEvent( FIFO_IF_MEDIA_EMPTY, FIFO_IF_EVENTOFF ); // FIFO Empty
CPUDMA_IFSetIntEvent( CpuDmaIntEnb, CPUDMA_IF_EVENTOFF ); // DMA Event
// Join is cleared
FIFO_IFClearFIFO_AllJoin();
break;
}
}
return TRUE;
}
/*
//=============================================================================
// Function_Name: MsgPlayIdeXferReady
// description : Process for completion of transfer preparation
// argument : none
// return : none
//=============================================================================
*/
void MsgPlayIdeXferReady( DEVICE_MSG* pMsg )
{
PARAM_MSG_NTFY_IDE_CMP_XFER_READY* pXferReady;
PARAM_MSG_REQ_IDE_XFER_START xferStart;
PLAY_INFO* pPlayInfo;
PLAY_XFER_INFO* pXferInfo;
pXferReady = (PARAM_MSG_NTFY_IDE_CMP_XFER_READY *)pMsg->msgData;
pPlayInfo = &DEVICEInfo.playInfo;
pXferInfo = &DEVICEInfo.playInfo.xferInfo;
//========================================================================
// Times of data transfer is confirmed
//========================================================================
if( pXferReady->xferCount == 1 )
{
//-----------------------------------------------------------------
// The first transfer
//-----------------------------------------------------------------
pXferInfo->size = pXferReady->xferDataLen; // Save transfer number
pXferInfo->totalXferSize = 0x00; // Clear number of total transfer
switch( pPlayInfo->ideXferMode )
{
case STRG_XFER_MODE_DMA: // DMA transfer
// Judge PLAY operation mode
//=========================================
if( pPlayInfo->execMode == DEVICE_TASK_PLAY_CMD_SYNC_MODE )
{
// The synchronous mode: Prepare the transfer of CPU to IDE and start it
//-------------------------------------------------------
StartDMA( pXferInfo->dmaCh, pXferInfo->dir, pXferInfo->size, IDE_TO_MEDIA );
// Request to start DMA for IDE task
xferStart.bufferPtr = NULL;
SendMessage( MBXID_IDE, MSG_REQ_IDE_XFER_START, sizeof(xferStart), &xferStart );
}
else
{
// Asynchronous mode: Notify completion of DMA transfer preparation to other module
//--------------------------------------------------------
DEVICEInfo.state = DEVICE_TASK_STATE_PLAY_DMA_READY; // Wait for a DMA transfer start
//=============================================================
// CallBack Completion notification of DMA transfer preparation
//-------------------------------------------------------------
// Message : DEVICE_TASK_MSG_PLAY_READY_DMA_CMP
// Param0 :Size of transfer requirement
// pParam : NULL
//=============================================================
SendCallback( DEVICE_TASK_MSG_PLAY_READY_DMA_CMP, pPlayInfo->xferInfo.reqSize, NULL );
}
break;
case STRG_XFER_MODE_HWPIO: // H/W PIO transfer
// Process for H/W PIO transfer
//=========================================
StartDMA( pXferInfo->dmaCh, pXferInfo->dir, pXferInfo->size, IDE_ONLY_MEDIA );
// Judge direction of transfer
if( pXferInfo->dir == DEVICE_TASK_XFER_DIR_OUT )
{
U
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -