📄 usbdtask.c
字号:
/*
* Main of USB Device control task
* $Revision: 1.6 $ $Date: 2006/12/22 05:33:16 $
*/
#include <string.h>
#include "OSCall.h"
#include "SPRDEF.h"
#include "SPRSTS.h"
#include "Handler.h"
#include "USBD_ProtEnum.h"
#include "USBDTask.h"
#include "DeviceTask.h"
#include "USBD_ProtStorage.h"
#include "usbd_func.h"
#include "usbd_if.h"
#include "usb_descinfo.h"
#include "led_if.h"
#include "PM_IF.h"
/*---------------------------------------------------------------------------
* Setting
*/
#define FIFOAREA0 (0x00000040) /* Number of bytes for FIFO in EP0 */
#define FIFOAREA1 (0x00000100) /* Number of bytes for FIFO in EPa(Unused) */
#define FIFOAREA2 (0x00810700) /* Number of bytes for FIFO in EPb(Bulk In) */
#define FIFOAREA3 (0x00020700) /* Number of bytes for FIFO in EPc(Bulk Out) */
/*---------------------------------------------------------------------------
* Definition
*/
#define STATE_IDLE (0) /* Idle */
#define STATE_WAIT_CONNECT (1) /* Waiting Connect */
#define STATE_WAIT_ATTACH (2) /* Waiting Attach */
#define STATE_WAIT_DETACH (3) /* Waiting Detach */
#define STATE_NOT_CONFIG (4) /* Not Configured */
#define STATE_STRG_CONFIG (5) /* Storage Configured */
#define STATE_NC_SUSPEND (6) /* Suspend(Not Config) */
#define STATE_SC_SUSPEND (7) /* Suspend(Storage Config) */
#define STATE_STRG_NONE (0) /* No action */
#define STATE_STRG_WAIT_CMD (1) /* Waiting command */
#define STATE_STRG_WAIT_REQ (2) /* Waiting request */
#define STATE_STRG_DATAXFER (3) /* Data transfer */
#define STATE_STRG_STATUSXFER (4) /* Status's transmission */
#define MAX_STRG_CMD_LEN (12) /* Length of Storage command packet */
/*---------------------------------------------------------------------------
* Structure
*/
typedef struct tagUSBDTaskInfo {
UCHAR state; /* State of Main */
UCHAR initDescriptor:1; /* Descriptor has been set */
UCHAR reqUsbdWakeup:1; /* Request of Wakeup */
UCHAR reqUsbdRemoteWakeup:1; /* Request of Remote Wakeup */
UCHAR reserved:5; /* Reserved */
} USBD_TASK_INFO;
typedef struct tagUSBDStrgInfo {
UCHAR state; /* State of Storage */
UCHAR maxLUN; /* MaxLUN */
ULONG reqXferSize; /* Number of transfer which is requested */
ULONG remainXferSize;
UCHAR reqXferDir; /* Direction of transfer */
UCHAR initStrg:1; /* Flag for Storage initialization */
UCHAR reqStrgReset:1; /* Request of Storage Reset */
UCHAR reqGetMaxLUN:1; /* Request of processing SetMaxLUN request */
} USBD_STRG_INFO;
/*---------------------------------------------------------------------------
* Variables
*/
static USBD_TASK_INFO UsbdTaskInfo; /* internal information of Task */
static USBD_STRG_INFO UsbdStrgInfo; /* internal information of Storage */
/*---------------------------------------------------------------------------
* MACRO
*/
/*---------------------------------------------------------------------------
* Function Declaration
*/
static LONG USBDTaskInit( void );
static LONG USBDForceEvent( void );
static LONG USBDIntEvent( void );
static LONG USBDMsgEvent( PMSGUSBD );
static LONG USBDMailDataCancel( void );
static LONG StateIdleMsgProc(PMSGUSBD pMsg);
static LONG StateWaitConnectMsgProc(PMSGUSBD pMsg);
static LONG StateWaitAttachMsgProc(PMSGUSBD pMsg);
static LONG StateWaitDetachMsgProc(PMSGUSBD pMsg);
static LONG StateNotConfigMsgProc(PMSGUSBD pMsg);
static LONG StateStrgConfigMsgProc(PMSGUSBD pMsg);
static LONG StateNC_SuspendMsgProc(PMSGUSBD pMsg);
static LONG StateSC_SuspendMsgProc(PMSGUSBD pMsg);
static LONG StateStrgMainMsgProc(PMSGUSBD pMsg);
static LONG USBDStatusError( PMSGUSBD pMsg );
static LONG StateNotIdleIntProc(void);
static LONG ReqUsbdSetDesc(PMSGUSBD pMsg);
static LONG ReqUsbdDetectVbus(PMSGUSBD pMsg);
static LONG ReqUsbdVbusStatus(PMSGUSBD pMsg);
static LONG ReqUsbdPullupCtrl(PMSGUSBD pMsg);
static LONG NtfyUsbdWakeup(PMSGUSBD pMsg);
static LONG ReqUsbdRemoteWakeup(PMSGUSBD pMsg);
static LONG ReqUsbdRequestNtfyParam(PMSGUSBD pMsg);
static LONG ReqUsbdRequestXferStart(PMSGUSBD pMsg);
static LONG ReqUsbdRequestEnd(PMSGUSBD pMsg);
static LONG NtfyUsbdStrgReset(PMSGUSBD pMsg);
static LONG ReqUsbdStrgSetLUN(PMSGUSBD pMsg);
static LONG ReqUsbdStrgXferStart(PMSGUSBD pMsg);
static LONG ReqUsbdStrgXferAbort(PMSGUSBD pMsg);
static LONG ReqUsbdStrgXferFlush(PMSGUSBD pMsg);
static LONG ReqUsbdStrgCmdEnd(PMSGUSBD pMsg);
static LONG VBusChangeCallback(ULONG lParam0,ULONG lParam1,VOID *pParam);
static LONG ReqUsbdWakeupCallback(ULONG lParam0,ULONG lParam1,VOID *pParam);
static LONG NtfyUsbdRemoteWakeupCallback(ULONG lParam0,ULONG lParam1,VOID *pParam);
static LONG NtfyUsbdSuspendCallback(ULONG lParam0,ULONG lParam1,VOID *pParam);
static LONG NtfyUsbdResetCallback(ULONG lParam0,ULONG lParam1,VOID *pParam);
static LONG NtfyUsbdResumeCallback(ULONG lParam0,ULONG lParam1,VOID *pParam);
static LONG StorageEventCallback(ULONG lEvent,ULONG lParam1,VOID *pParam);
static LONG StorageXferEventCallback(ULONG lEvent,ULONG lParam1,VOID *pParam);
static LONG ReqUsbdStrgReset(void);
static LONG NtfyUsbdStrgCmd(void);
static LONG NtfyUsbdStrgCmdEnd(void);
static LONG NtfyUsbdStrgActiveChange(ULONG lActiveFlag);
#ifdef DEBUG_C
extern ULONG USBResetCount;
#endif
/*
//=============================================================================
// Function_Name: USBDTask
// description : USBD Control Task
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
// Refer to P10乽Fig.3-3 Basic Flow of Event Waiting乿, "DEVICE Software General Design Specification"
//
void USBDTask( void )
{
FLGPTN flgptn;
PMSGUSBD pk_msg;
int mpfid,ercd;
USBDTaskInit(); /* Initialize the task */
while(1)
{
/* Wait for event flag */
OS_WaiFlg( FLGID_USBD, FLG_WAIT_PTN_USBD, TWF_ORW, &flgptn );
if ( flgptn & FLG_EVENT_FORCE_USBD )
{
/*******************************/
/* Event of force process */
/*******************************/
OS_ClrFlg( FLGID_USBD, ~(FLG_EVENT_FORCE_USBD));/* Clear flag */
USBDMailDataCancel(); /* Discard message data */
USBDForceEvent(); /* Process of force event */
}
else if ( flgptn & FLG_EVENT_INT_USBD )
{
/*******************************/
/* Event of interrupt process */
/*******************************/
OS_ClrFlg( FLGID_USBD, ~(FLG_EVENT_INT_USBD)); /* Clear flag */
USBDIntEvent(); /* Process of interrupt event */
}
else if ( flgptn & FLG_EVENT_MSG_USBD )
{
/*******************************/
/* Event of message process */
/*******************************/
OS_DisDsp();
/* Receive message from mailbox */
ercd = OS_PRcvMbx( MBXID_USBD, ( T_MSG** )&pk_msg );
if ( ercd == E_OK )
{
/* There are messages */
OS_EnaDsp();
USBDMsgEvent( (PMSGUSBD)pk_msg ); /* Process of message event */
mpfid = pk_msg->msgHead.useMpfId;
OS_RelMpf( mpfid, (VP)pk_msg ); /* Release message buffer */
}
else if ( ercd == E_TMOUT )
{
/* There is no message */
OS_ClrFlg( FLGID_USBD, ~(FLG_EVENT_MSG_USBD)); /* Clear flag */
OS_EnaDsp();
}
else
{
OS_EnaDsp();
/* Error in message receiving */
}
}
else
{
OS_EnaDsp();
/* */
}
}
}
/*
//=============================================================================
// Function_Name: USBDTaskInit
// description : Initialize USBD Control Task
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
LONG USBDTaskInit( void )
{
LONG retValue;
LONG retTemp;
#ifdef AUTO_REMOTEWAKEUP
UCHAR mode;
#endif
retValue = STATUS_UNSUCCESSFUL;
while (1) {
/*------------------------------------------------------------------*/
/* Initial setting of S1R72V05 LSI & Initialization of USB parts */
/*------------------------------------------------------------------*/
USBD_ProtEnumReset(); /* USBD Common */
/*------------------------------------------------------------------*/
/* Register the callback function */
/*------------------------------------------------------------------*/
/* Request of USB Wakeup */
retTemp = USBD_FuncRegisterCBRWakeup(ReqUsbdWakeupCallback);
if (retTemp != STATUS_SUCCESS) {
break;
}
/* Callback of notification for Remote Wakeup */
retTemp = USBD_ProtRegisterCBREnumWakeupEnd(NtfyUsbdRemoteWakeupCallback);
if (retTemp != STATUS_SUCCESS) {
break;
}
/* Callback of notification for USB Reset */
retTemp = USBD_ProtRegisterCBREnumResetEvent(NtfyUsbdResetCallback);
if (retTemp != STATUS_SUCCESS) {
break;
}
/* Callback of notification for USB Suspend */
retTemp = USBD_ProtRegisterCBREnumSuspendEvent(NtfyUsbdSuspendCallback);
if (retTemp != STATUS_SUCCESS) {
break;
}
/* Callback of notification for USB Resume */
retTemp = USBD_ProtRegisterCBREnumResumeEvent(NtfyUsbdResumeCallback);
if (retTemp != STATUS_SUCCESS) {
break;
}
#ifdef AUTO_REMOTEWAKEUP
/*
* When Remote Wakeup is enabled,
* set it if sending Remote Wakeup signal automatically by occurrence of USB Suspend is expected.
* (Be used for test of Remote Wakeup)
*/
mode = USBD_PROT_ENUM_AUTO_WAKEUP;
retTemp = USBD_ProtEnumSetParameter(&mode,USBD_PROT_ENUM_REMOTEWAKEUP_MODE);
if (retTemp != STATUS_SUCCESS) {
break;
}
#endif
/*------------------------------------------------------------------*/
/* internal information of Task */
/*------------------------------------------------------------------*/
memset(&UsbdTaskInfo,0x00,sizeof (USBD_TASK_INFO));
memset(&UsbdStrgInfo,0x00,sizeof (USBD_STRG_INFO));
UsbdTaskInfo.state = STATE_IDLE; /* Idle */
UsbdStrgInfo.state = STATE_STRG_NONE; /* No action */
UsbdStrgInfo.maxLUN = 0xFF;
retValue = STATUS_SUCCESS;
break;
}
return retValue;
}
/*
//=============================================================================
// Function_Name: USBDForceEvent
// description : Process of force event
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
LONG USBDForceEvent( void )
{
PMSGUSBD msg;
OS_GetMpf( MPFID_USBD_MSG, (VP)&msg ); /* Fixed length memory pool for message transmission */
msg->msgHead.msgSndTskId = TSKID_USBD; /* ID of USBD Task */
msg->msgHead.useMpfId = MPFID_USBD_MSG; /* ID of memory pool to be used */
msg->msgHead.msgNo = MSG_NTFY_USBD_FORCE_CMP; /* Notification of completion for process of force event */
msg->msgHead.msgLength = 0;
/*----------------------------------------------------------------------*/
/* Transmission of message and notification of event */
/*----------------------------------------------------------------------*/
OS_SndMbx( MBXID_DEVICE, (T_MSG *)msg ); /* Send message */
OS_SetFlg( FLGID_DEVICE, FLG_EVENT_MSG_DEVICE ); /* Notify event to DEVICE Task */
return STATUS_SUCCESS;
}
/*
//=============================================================================
// Function_Name: USBDIntEvent
// description : Process of interrupt event
// argument :
// return :
// flag :
// global :
//=============================================================================
*/
LONG USBDIntEvent( void )
{
/* Do process which is related to message number */
switch (UsbdTaskInfo.state) {
case STATE_IDLE: /* Idle */
/* Do nothing */
break;
case STATE_WAIT_CONNECT: /* Waiting Connect */
/* No break */
case STATE_WAIT_ATTACH: /* Waiting Attach */
/* No break */
case STATE_WAIT_DETACH: /* Waiting Detach */
/* No break */
case STATE_NOT_CONFIG: /* Not Configured */
/* No break */
case STATE_STRG_CONFIG: /* Storage Configured */
/* No break */
case STATE_NC_SUSPEND: /* Suspend(Not Config) */
/* No break */
case STATE_SC_SUSPEND: /* Suspend(Storage Config) */
StateNotIdleIntProc(); /* Process of event handler */
break;
default:
/* ??? */
break;
}
return STATUS_SUCCESS;
}
/*
//=============================================================================
// Function_Name: USBDMsgEvent
// description : Process of message event
// argument :
// return :
// flag :
// global :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -