⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvb_usb.c

📁 DVB软件,基于CT216软件的开发源程序.
💻 C
📖 第 1 页 / 共 4 页
字号:
#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 + -