📄 dvb_usb.c
字号:
#include <stdio.h>
#include "dvb_sys.h"
#ifdef CT216T_ELGIST_MM
#include "mem_api.h"
#else
#include "dvb_mem.h"
#endif
#include "task_cfg.h"
#include "io_config.h"
#include "ct_gpio.h"
#include "ct_sys.h"
#include "ct_os.h"
#include "ct_usb.h"
#include "dvb_usb.h"
#include "dvb_device.h"
//--------------------------------------------------------------------
#if 0
#define USB_MSG(p)
#else
#define USB_MSG(p) printf p
#endif
#if 1
#define USB_DEBUG(p)
#else
#define USB_DEBUG(p) printf p
#endif
//#define ENABLE_USB_TEST
//#define ENABLE_WASTE_TIME
//--------------------------------------------------------------------
// Message Command
// device message
#define DVB_USB_RESET 0x01
#define DVB_USB_DISCONNECT 0x02
#define DVB_USB_PLUG_INOUT 0x03
// user operation message
#define DVB_USB_READ_ENABLE 0x10
#define DVB_USB_READ_ERROR 0x11
#define DVB_USB_READ_DONE 0x12
#define DVB_USB_WRITE_ENABLE 0x20
#define DVB_USB_WRITE_ERROR 0x21
#define DVB_USB_WRITE_DONE 0x22
#define DVB_USB_CHANGE_LUN 0x30
#define DVB_USB_CHANGE_LUN_ERROR 0x31
#define DVB_USB_CHANGE_LUN_DONE 0x32
// usb software stack working mode
#define USB_HOST_MODE 0
#define USB_HOST_DEVICE_MODE 2
// usb software stack size
#define USB_HOST_STACK_SIZE 0x10000 // Now must set minimun 0x10000(host) and
#define USB_DEV_STACK_SIZE 0x30000 // 0x30000(device) bytes
#define USB_QUEUE_SIZE 1024
#define USB_CHUNK_SIZE_MIN 4 // 32 is not stable in 956, unit: sector
#define USB_CHUNK_SIZE_MAX 64 // 32 is not stable in 956, unit: sector
#define USB_SECTOR_SIZE 512 // unit: bytes each sector
#define USB_NO_MEDIA -1
#define USB_LUN_MAX 32
#define DVB_USB_DISABLE FALSE
#define DVB_USB_ENABLE TRUE
//--------------------------------------------------------------------
// usb status flag
static bool8 _b8UsbStackInitial = FALSE; // indicate usb procedure initial ok or not
static bool8 _b8UsbReady = FALSE; // indicate the appointed media ready or not
static bool8 _b8UsbStandby = FALSE; // indicate usb thread state suspending or running
// usb task
static CTOS_TASK DVB_USB_Polling_Task;
static u8 _au8USBPollingStack[DVB_USB_TASK_STACK_SIZE];
// usb software stack memory
u8 _au8USBStack[USB_HOST_STACK_SIZE];
// usb semaphore/message queue/timer
static CTOS_QUEUE DVB_USB_Request_MsgQueue;
static CTOS_QUEUE DVB_USB_Reply_MsgQueue;
static u32 u32UsbRequestQueueMsg[USB_QUEUE_SIZE];
static u32 u32UsbReplyQueueMsg[USB_QUEUE_SIZE];
static CTOS_SEMAPHORE DVB_USB_API_Semaphore;
CTOS_TIMER DVB_USB_MonitorTimer;
// usb read/write indicator
static u32 _u32UsbChunkSize = USB_CHUNK_SIZE_MAX;
static u32 _u32UsbStartSect;
static u32 _u32UsbSectNum;
static u8* _pu8UsbReadBuf;
static u8* _pu8UsbWriteBuf;
// usb LUN information
static ST_USB_LUN_INFO _stUSBLUNInfo;
static ST_USB_LUN_INFO _stPreUSBLUNInfo;
static s8 _s8UsbSetCurrentLUN = USB_NO_MEDIA;
// usb error information
static u32 _u32USBErrCntInfo, _u32USBMonitorCntInfo;
static bool8 _b8ForceFullSpeedFlag = FALSE;
//--------------------------------------------------------------------
static void dvb_usb_polling_task(void); // process event
static void dvb_usb_monitor_timer(u32 u32Argc); // monitor usb LUN status
//--------------------------------------------------------------------
//
// Local functions for usb application.
//
// dvb_usb_polling_task (usb internal task)
// dvb_usb_monitor_timer (usb internal monitor)
//
//--------------------------------------------------------------------
void dvb_usb_polling_task(void)
{
EN_CTOS_STATUS enStatus;
MSG_PARAMETER stSendMsg, stRecvMsg;
u32 u32RecvMsgLen = 0;
u8 u8CmdID = 0;
u32 u32MsgData = 0;
bool8 b8Resule = FALSE;
u32 u32Index;
u8 u8TryCnt;
// init usb software stack
if(FALSE == DVB_USB_Initial())
{
USB_DEBUG((" [ERROR]: %s -USBInitial error\n", __FUNCTION__));
return;
}
_b8UsbStackInitial = TRUE;
while(1)
{
enStatus = CT_OS_GetMsg(&DVB_USB_Request_MsgQueue, &stRecvMsg, &u32RecvMsgLen, CTOS_WAIT);
if(enStatus != EN_CTOS_SUCCESS)
{
continue;
}
u8CmdID = stRecvMsg.u8Cmd;
u32MsgData = stRecvMsg.unData.u32MsgData;
switch(u8CmdID)
{
// ::read command
case DVB_USB_READ_ENABLE:
{
CT_OS_ControlTimer(&DVB_USB_MonitorTimer, EN_CTOS_TIMER_DISABLE);
{
#define REG_IC_VERSION (*(volatile unsigned long*)(0x800028D0))
#define AB_VERSION 0x00000001
#define AC_VERSION 0x00000003
if (AB_VERSION == REG_IC_VERSION) // AB version
{
CT_OS_Delay(1);
}
}
// using CHUNK_SIZE segmentation for reading data size
while(_u32UsbSectNum >= _u32UsbChunkSize)
{
b8Resule = CT_USB_ReadData(_u32UsbStartSect, _u32UsbChunkSize, _pu8UsbReadBuf);
if(FALSE == b8Resule) goto read_result;
_u32UsbStartSect += (_u32UsbChunkSize);
_u32UsbSectNum -= (_u32UsbChunkSize);
_pu8UsbReadBuf += (_u32UsbChunkSize*USB_SECTOR_SIZE);
}
if(_u32UsbSectNum > 0)
{
b8Resule = CT_USB_ReadData(_u32UsbStartSect, _u32UsbSectNum, _pu8UsbReadBuf);
}
read_result:
if(FALSE == b8Resule)
{
USB_DEBUG((" [MESSAGE]: DVB_USB_READ_ERROR\n"));
if(FALSE == CT_USB_CheckMedia(_s8UsbSetCurrentLUN))
{
stSendMsg.u8Cmd = DVB_USB_READ_ERROR;
stSendMsg.unData.u32MsgData = 0;
CT_OS_PutMsg(&DVB_USB_Reply_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
CT_OS_ControlTimer(&DVB_USB_MonitorTimer, EN_CTOS_TIMER_ENABLE);
break;
}
CT_USB_Suspend();
//{
DVB_USB_Power(DVB_USB_DISABLE);
//CT_USB_Clock(DVB_USB_DISABLE);
CT_OS_Delay(50);
//CT_USB_Clock(DVB_USB_ENABLE);
DVB_USB_Power(DVB_USB_ENABLE);
//}
CT_USB_Resume();
USB_MSG((" [MESSAGE]: R/DVB_USB_RESET\n"));
CT_OS_Delay(100);
CT_USB_ClearActiveLun();
CT_USB_SetCurrentActiveLun(_s8UsbSetCurrentLUN);
u8TryCnt = 10;
do
{
CT_OS_Delay(30);
if(USB_STATUS_MASS_STORAGE_DEVICE != CT_USB_CheckStatus())
{
USB_DEBUG((" [MESSAGE]: R/DVB_USB YNOT[%d]\n", u8TryCnt));
continue;
}
if(TRUE == CT_USB_CheckMedia(_s8UsbSetCurrentLUN))
{
USB_DEBUG((" [MESSAGE]: R/DVB_USB READY\n"));
break;
}
} while(--u8TryCnt != 0);
stSendMsg.u8Cmd = DVB_USB_READ_ERROR;
stSendMsg.unData.u32MsgData = 0;
CT_OS_PutMsg(&DVB_USB_Reply_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
}
else
{
USB_DEBUG((" [MESSAGE]: DVB_USB_READ_DONE\n"));
stSendMsg.u8Cmd = DVB_USB_READ_DONE;
stSendMsg.unData.u32MsgData = 0;
CT_OS_PutMsg(&DVB_USB_Reply_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
}
CT_OS_ControlTimer(&DVB_USB_MonitorTimer, EN_CTOS_TIMER_ENABLE);
}
break;
// ::write command
case DVB_USB_WRITE_ENABLE:
{
CT_OS_ControlTimer(&DVB_USB_MonitorTimer, EN_CTOS_TIMER_DISABLE);
{
#define REG_IC_VERSION (*(volatile unsigned long*)(0x800028D0))
#define AB_VERSION 0x00000001
#define AC_VERSION 0x00000003
if (AB_VERSION == REG_IC_VERSION) // AB version
{
CT_OS_Delay(1);
}
}
// using CHUNK_SIZE segmentation for writing data size
while(_u32UsbSectNum >= _u32UsbChunkSize)
{
b8Resule = CT_USB_WriteData(_u32UsbStartSect, _u32UsbChunkSize, _pu8UsbWriteBuf);
if(FALSE == b8Resule) goto write_result;
_u32UsbStartSect += (_u32UsbChunkSize);
_u32UsbSectNum -= (_u32UsbChunkSize);
_pu8UsbWriteBuf += (_u32UsbChunkSize*USB_SECTOR_SIZE);
}
if(_u32UsbSectNum > 0)
{
b8Resule = CT_USB_WriteData(_u32UsbStartSect, _u32UsbSectNum, _pu8UsbWriteBuf);
}
write_result:
if(FALSE == b8Resule)
{
USB_DEBUG((" [MESSAGE]: DVB_USB_WRITE_ERROR\n"));
if(FALSE == CT_USB_CheckMedia(_s8UsbSetCurrentLUN))
{
stSendMsg.u8Cmd = DVB_USB_WRITE_ERROR;
stSendMsg.unData.u32MsgData = 0;
CT_OS_PutMsg(&DVB_USB_Reply_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
CT_OS_ControlTimer(&DVB_USB_MonitorTimer, EN_CTOS_TIMER_ENABLE);
break;
}
CT_USB_Suspend();
//{
DVB_USB_Power(DVB_USB_DISABLE);
//CT_USB_Clock(DVB_USB_DISABLE);
CT_OS_Delay(50);
//CT_USB_Clock(DVB_USB_ENABLE);
DVB_USB_Power(DVB_USB_ENABLE);
//}
CT_USB_Resume();
USB_MSG((" [MESSAGE]: W/DVB_USB_RESET\n"));
CT_OS_Delay(100);
CT_USB_ClearActiveLun();
CT_USB_SetCurrentActiveLun(_s8UsbSetCurrentLUN);
u8TryCnt = 10;
do
{
CT_OS_Delay(30);
if(USB_STATUS_MASS_STORAGE_DEVICE != CT_USB_CheckStatus())
{
USB_DEBUG((" [MESSAGE]: W/DVB_USB YNOT[%d]\n", u8TryCnt));
continue;
}
if(TRUE == CT_USB_CheckMedia(_s8UsbSetCurrentLUN))
{
USB_DEBUG((" [MESSAGE]: W/DVB_USB READY\n"));
break;
}
} while(--u8TryCnt != 0);
stSendMsg.u8Cmd = DVB_USB_WRITE_ERROR;
stSendMsg.unData.u32MsgData = 0;
CT_OS_PutMsg(&DVB_USB_Reply_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
}
else
{
USB_DEBUG((" [MESSAGE]: DVB_USB_WRITE_DONE\n"));
stSendMsg.u8Cmd = DVB_USB_WRITE_DONE;
stSendMsg.unData.u32MsgData = 0;
CT_OS_PutMsg(&DVB_USB_Reply_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
}
CT_OS_ControlTimer(&DVB_USB_MonitorTimer, EN_CTOS_TIMER_ENABLE);
}
break;
// ::user change media command
case DVB_USB_CHANGE_LUN:
{
USB_DEBUG((" [MESSAGE]: DVB_USB_CHANGE_LUN\n"));
if(TRUE == CT_USB_CheckMedia((u8)_s8UsbSetCurrentLUN))
{
CT_USB_SetCurrentActiveLun((u8)_s8UsbSetCurrentLUN);
CT_USB_CheckStatus();
USB_DEBUG((" [MESSAGE]: DVB_USB_CHANGE_LUN_DONE: Lun_%d\n", _s8UsbSetCurrentLUN));
stSendMsg.u8Cmd = DVB_USB_CHANGE_LUN_DONE;
stSendMsg.unData.u32MsgData = 0;
CT_OS_PutMsg(&DVB_USB_Reply_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
}
else
{
USB_DEBUG((" [MESSAGE]: DVB_USB_CHANGE_LUN_ERROR: Lun_%d\n", _s8UsbSetCurrentLUN));
stSendMsg.u8Cmd = DVB_USB_CHANGE_LUN_ERROR;
stSendMsg.unData.u32MsgData = 0;
CT_OS_PutMsg(&DVB_USB_Reply_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
}
}
break;
// ::process reset usb stack status
case DVB_USB_RESET:
{
USB_DEBUG((" [MESSAGE]: DVB_USB_RESET\n"));
CT_USB_Reset(USB_HOST_MODE, (u8 *)&_au8USBStack[0], USB_HOST_STACK_SIZE);
CT_USB_SetCurrentActiveLun(_s8UsbSetCurrentLUN);
}
break;
// ::disconnent command
case DVB_USB_DISCONNECT:
{
//USB_DEBUG((" [MESSAGE]: DVB_USB_DISCONNECT\n"));
//
//for(u32Index=0; u32Index<USB_LUN_MAX; u32Index++) // current usb system support 32 LUNs
//{
// if(_stPreUSBLUNInfo.u32LUNs&(1<<u32Index)) // release exist fs
// {
// // release all fs, DVB_LIST_Delete ST_PARTITION list
// DVB_DEVCTRL_UnRegisterDevice(EN_DEV_USB_LUN0+u32Index);
// USB_DEBUG((" [STATUS]: USB LUN_%d plug out\n", u32Index));
// }
//}
//
//// update LUN state
//_stPreUSBLUNInfo.u32LUNs = _stUSBLUNInfo.u32LUNs = 0;
//_stPreUSBLUNInfo.u8MaxLUN = _stUSBLUNInfo.u8MaxLUN = 0;
//_stPreUSBLUNInfo.b8Connect = _stUSBLUNInfo.b8Connect = 0;
//_stPreUSBLUNInfo.s8CurrentLUN = _stUSBLUNInfo.s8CurrentLUN = USB_NO_MEDIA;
CT_USB_Suspend();
{
DVB_USB_Power(DVB_USB_DISABLE);
//CT_USB_Clock(DVB_USB_DISABLE);
CT_OS_Delay(50);
//CT_USB_Clock(DVB_USB_ENABLE);
DVB_USB_Power(DVB_USB_ENABLE);
}
CT_USB_Resume();
}
break;
// ::process plug in/plug out status
case DVB_USB_PLUG_INOUT:
{
USB_DEBUG((" [MESSAGE]: DVB_USB_PLUG_INOUT\n"));
for(u32Index=0; u32Index<USB_LUN_MAX; u32Index++) // current usb system support 32 LUNs
{
//compare between before and after the change
if((_stPreUSBLUNInfo.u32LUNs&(1<<u32Index)) ^ (_stUSBLUNInfo.u32LUNs&(1<<u32Index)))
{
// 1->0, check LUN plugout, release fs
if(_stPreUSBLUNInfo.u32LUNs&(1<<u32Index))
{
// release fs, DVB_LIST_Delete ST_PARTITION list
DVB_DEVCTRL_UnRegisterDevice(EN_DEV_USB_LUN0+u32Index);
USB_DEBUG((" [STATUS]: USB LUN_%d plug out\n", u32Index));
}
// 0->1, check LUN plugin, initial fs
else
{
// initial fs, DVB_LIST_Add ST_PARTITION list
DVB_DEVCTRL_RegisterDevice(EN_DEV_USB_LUN0+u32Index);
USB_DEBUG((" [STATUS]: USB LUN_%d plug in\n", u32Index));
}
}
}
// update LUN state
_stPreUSBLUNInfo.u32LUNs = _stUSBLUNInfo.u32LUNs;
_stPreUSBLUNInfo.u8MaxLUN = _stUSBLUNInfo.u8MaxLUN;
_stPreUSBLUNInfo.b8Connect = _stUSBLUNInfo.b8Connect;
_stPreUSBLUNInfo.s8CurrentLUN = _stUSBLUNInfo.s8CurrentLUN;
}
break;
// ::process unknown status
default:
break;
} // switch(u32MsgData)
} // while(1)
}
//--------------------------------------------------------------------
void dvb_usb_monitor_timer(u32 u32Argc)
{
//MSG_PARAMETER stSendMsg;
u32 u32Index;
// usb is not concerned about the changes if usb standby
if(TRUE == _b8UsbStandby)
{
return;
}
_u32USBMonitorCntInfo++;
if(0 == _u32USBMonitorCntInfo%500) // check it per 5 second
{
if(_u32USBErrCntInfo > 3) // reduce chunk size when r/w was occurred error 3 times continually
{
if(_u32UsbChunkSize > USB_CHUNK_SIZE_MIN)
_u32UsbChunkSize = (_u32UsbChunkSize>>1);
}
else // increase chunk size
{
if(_u32UsbChunkSize < USB_CHUNK_SIZE_MAX)
_u32UsbChunkSize = (_u32UsbChunkSize<<1);
}
_u32USBErrCntInfo = 0;
_u32USBMonitorCntInfo = 0;
}
// check usb device & media status
DVB_USB_Status();
// status a: has USB device ...
if(TRUE == _stUSBLUNInfo.b8Connect)
{
//if(_stPreUSBLUNInfo.u32LUNs != _stUSBLUNInfo.u32LUNs)
//{
// USB_DEBUG((" [MESSAGE]: DVB_USB_PLUG_INOUT\n"));
// // send DVB_USB_PLUG_INOUT to dvb_usb_polling_task
// stSendMsg.u8Cmd = DVB_USB_PLUG_INOUT;
// stSendMsg.unData.u32MsgData = 0;
// CT_OS_PutMsg(&DVB_USB_Request_MsgQueue, &stSendMsg, CTOS_NO_WAIT);
//}
for(u32Index=0; u32Index<USB_LUN_MAX; u32Index++) // current usb system support 32 LUNs
{
//compare between before and after the change
if((_stPreUSBLUNInfo.u32LUNs&(1<<u32Index)) ^ (_stUSBLUNInfo.u32LUNs&(1<<u32Index)))
{
// 1->0, check LUN plugout, release fs
if(_stPreUSBLUNInfo.u32LUNs&(1<<u32Index))
{
// release fs, DVB_LIST_Delete ST_PARTITION list
DVB_DEVCTRL_UnRegisterDevice(EN_DEV_USB_LUN0+u32Index);
USB_DEBUG((" [STATUS]: USB LUN_%d plug out\n", u32Index));
}
// 0->1, check LUN plugin, initial fs
else
{
// initial fs, DVB_LIST_Add ST_PARTITION list
{
DVB_DEVCTRL_RegisterDevice(EN_DEV_USB_LUN0+u32Index);
USB_DEBUG((" [STATUS]: USB LUN_%d plug in\n", u32Index));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -