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

📄 usb.c

📁 源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
//	Copyright (c) Samsung Electronics. All rights reserved.
//	@File : USB.C
//	@Description : implementation of usb image download function

#include <windows.h>
#include <halether.h>
#include <bsp.h>
#include "loader.h"
#include "usb.h"

#define __DEBUG_MSG_	0
#define __INFO_MSG_		0

void InitDescriptorTable(void)
{	
    //Standard device descriptor
    descDev.bLength=0x12;	//EP0_DEV_DESC_SIZE=0x12 bytes    
    descDev.bDescriptorType=USB_DEVICE_TYPE;
    descDev.bcdUSBL=0x10;
    descDev.bcdUSBH=0x01; 	//Ver 1.10
    descDev.bDeviceClass=0xFF; //0x0          
    descDev.bDeviceSubClass=0x0;          
    descDev.bDeviceProtocol=0x0;          
    descDev.bMaxPacketSize0=0x8;         
    descDev.idVendorL=0x45;
    descDev.idVendorH=0x53;
    descDev.idProductL=0x34;
    descDev.idProductH=0x12;
    descDev.bcdDeviceL=0x00;
    descDev.bcdDeviceH=0x01;
    descDev.iManufacturer=0x1;  //index of string descriptor
    descDev.iProduct=0x2;	//index of string descriptor 
    descDev.iSerialNumber=0x0;
    descDev.bNumConfigurations=0x1;

    //Standard configuration descriptor
    descConf.bLength=0x9;    
    descConf.bDescriptorType=CONFIGURATION_TYPE;         
    descConf.wTotalLengthL=0x20; //<cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>
    descConf.wTotalLengthH=0;
    descConf.bNumInterfaces=1;
//dbg    descConf.bConfigurationValue=2;  //why 2? There's no reason.
    descConf.bConfigurationValue=1;  
    descConf.iConfiguration=0;
    descConf.bmAttributes=CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED;  //bus powered only.
    descConf.maxPower=25; //draws 50mA current from the USB bus.          

    //Standard interface descriptor
    descIf.bLength=0x9;    
    descIf.bDescriptorType=INTERFACE_TYPE;         
    descIf.bInterfaceNumber=0x0;
    descIf.bAlternateSetting=0x0; //?
    descIf.bNumEndpoints=2;	//# of endpoints except EP0
    descIf.bInterfaceClass=0xff; //0x0 ?
    descIf.bInterfaceSubClass=0x0;  
    descIf.bInterfaceProtocol=0x0;
    descIf.iInterface=0x0;

    //Standard endpoint0 descriptor
    descEndpt0.bLength=0x7;    
    descEndpt0.bDescriptorType=ENDPOINT_TYPE;         
    descEndpt0.bEndpointAddress=1|EP_ADDR_IN;   // 2400Xendpoint 1 is IN endpoint.
    descEndpt0.bmAttributes=EP_ATTR_BULK;
    descEndpt0.wMaxPacketSizeL=EP1_PKT_SIZE; //64
    descEndpt0.wMaxPacketSizeH=0x0;
    descEndpt0.bInterval=0x0; //not used

    //Standard endpoint1 descriptor
    descEndpt1.bLength=0x7;    
    descEndpt1.bDescriptorType=ENDPOINT_TYPE;         
    descEndpt1.bEndpointAddress=4|EP_ADDR_OUT;   // 2400X endpoint 3 is OUT endpoint.	// we'll use endpoint 4 // by J.I modified(8/22)
    descEndpt1.bmAttributes=EP_ATTR_BULK;
    descEndpt1.wMaxPacketSizeL=EP4_PKT_SIZE; //64		// we'll use endpoint 4 // by J.I modified(8/22)
    descEndpt1.wMaxPacketSizeH=0x0;
    descEndpt1.bInterval=0x0; //not used 
}

BOOL InitUSB()
{
//	BYTE index;				// Meaningless by J.I comment out(8/25)
//	UCHAR cRxChar;

//    volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
	pUSBCtrlAddr = (S3C2440A_USBD_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_USBD+0x140, FALSE);

    InitDescriptorTable();

    //
    // Initialize the USBD Controller
    //
		ReconfigUsbd();
//    index = pUSBCtrlAddr->INDEX.index;		// Meanless by J.I comment out(8/25)
/*
    // suspend mode disable
    pUSBCtrlAddr->PMR.sus_en = 0x0;
//		pUSBCtrlAddr->PMR.sus_mo = 0;					// Added
//		pUSBCtrlAddr->PMR.mcu_res = 0;				// Added
//		pUSBCtrlAddr->PMR.usb_re = 0;					// Added
//		pUSBCtrlAddr->PMR.iso_up = 0;					// Added

    // setup endpoint 0
    pUSBCtrlAddr->INDEX.index = 0;
    pUSBCtrlAddr->MAXP.maxp = 0x1;         // 8 BYTE
    pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;   // OUT_PKT_RDY
    pUSBCtrlAddr->EP0ICSR1.sse_ = 1;       // SETUP_END

    // setup endpoint 1
    pUSBCtrlAddr->INDEX.index = 1;
    pUSBCtrlAddr->MAXP.maxp = 0x8;     // 64 BYTE
	pUSBCtrlAddr->EP0ICSR1.de_ff = 1;
	pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
    pUSBCtrlAddr->ICSR2.mode_in = 1;   // IN
//		pUSBCtrlAddr->ICSR2.in_dma_int_en = 1;			// added
    pUSBCtrlAddr->ICSR2.iso = 0;       // BULK
//		pUSBCtrlAddr->OCSR1.clr_data_tog = 1;				// Added
//		pUSBCtrlAddr->OCSR2.iso = 0;								// Added
//		pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;			// Added

		/// Added by J.I(8/28)
//		pUSBCtrlAddr->INDEX.index = 2;
//		pUSBCtrlAddr->MAXP.maxp = 0x08;	//EP2 max packit size = 64 
//		pUSBCtrlAddr->EP0ICSR1.de_ff = 1;
//		pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
//		pUSBCtrlAddr->ICSR2.mode_in = 1;
//		pUSBCtrlAddr->ICSR2.in_dma_int_en = 1;
//		pUSBCtrlAddr->ICSR2.iso = 0;
//		pUSBCtrlAddr->OCSR1.clr_data_tog = 1;
//		pUSBCtrlAddr->OCSR2.iso = 0;
//		pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;		
    
		///	by J.I changed(8/22) EP3(not use)->EP4(out endpoint)
    // setup endpoint 3
//    pUSBCtrlAddr->INDEX.index = 3;
//    pUSBCtrlAddr->MAXP.maxp = 0x8;     // 64 BYTE
//		pUSBCtrlAddr->EP0ICSR1.de_ff = 1;
//		pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
//    pUSBCtrlAddr->ICSR2.mode_in = 0;   // OUT
//		pUSBCtrlAddr->ICSR2.in_dma_int_en = 1;	// dma interrupt disable by J.I modifed(8/22)	// added by J.I(8/28)
//		pUSBCtrlAddr->ICSR2.iso = 0;						// added by J.I(8/28)
//		pUSBCtrlAddr->OCSR1.clr_data_tog = 1;		// added by J.I(8/28)
		//clear OUT_PKT_RDY, data_toggle_bit.
		//The data toggle bit should be cleared when initialization.
//    pUSBCtrlAddr->OCSR2.iso = 0;       // BULK
//		pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;

		
    // setup endpoint 4
    pUSBCtrlAddr->INDEX.index = 4;
    pUSBCtrlAddr->MAXP.maxp = 0x8;     // 64 BYTE
	pUSBCtrlAddr->EP0ICSR1.de_ff = 1;
	pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
    pUSBCtrlAddr->ICSR2.mode_in = 0;   // OUT
		pUSBCtrlAddr->ICSR2.in_dma_int_en = 0;	// dma interrupt enable by J.I modifed(8/22)	// added by J.I(8/28)
		pUSBCtrlAddr->ICSR2.iso = 0;			// added by J.I(8/28)
		pUSBCtrlAddr->OCSR1.clr_data_tog = 1;
		//clear OUT_PKT_RDY, data_toggle_bit.
		//The data toggle bit should be cleared when initialization.
    pUSBCtrlAddr->OCSR2.iso = 0;       // BULK
		pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;		// added by J.I(8/28)
    

    // clear all EP interrupts
    pUSBCtrlAddr->EIR.ep0_int = 0x1;
    pUSBCtrlAddr->EIR.ep1_int = 0x1;
    pUSBCtrlAddr->EIR.ep2_int = 0x1;
    pUSBCtrlAddr->EIR.ep3_int = 0x1;
    pUSBCtrlAddr->EIR.ep4_int = 0x1;

    // clear reset int
    pUSBCtrlAddr->UIR.reset_int = 0x1;
//		pUSBCtrlAddr->UIR.sus_int = 1;					// added by J.I(8/28)
//		pUSBCtrlAddr->UIR.resume_int = 1;				// added by J.I(8/28)
		

    // EP0, 1, & 4 Enabled, EP2, 3 Disabled	// by J.I modified
    pUSBCtrlAddr->EIER.ep0_int_en = 0x1;
    pUSBCtrlAddr->EIER.ep1_int_en = 0x1;
    pUSBCtrlAddr->EIER.ep2_int_en = 0x0;
    pUSBCtrlAddr->EIER.ep3_int_en = 0x0;
    pUSBCtrlAddr->EIER.ep4_int_en = 0x1;
    
#if(__DEBUG_MSG_)
	EdbgOutputDebugString("INFO : -------------------------------------------------------- \r\n");
	EdbgOutputDebugString("INFO : pUSBCtrlAddr = 0x%x \r\n", pUSBCtrlAddr);
	EdbgOutputDebugString("INFO : &(pUSBCtrlAddr->EIER) = 0x%x \r\n", &(pUSBCtrlAddr->EIER));
	EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep0_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep0_int_en);
	EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep1_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep1_int_en);
	EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep2_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep2_int_en);
	EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep3_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep3_int_en);
	EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep4_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep4_int_en);
	EdbgOutputDebugString("INFO : -------------------------------------------------------- \r\n");
#endif

    // enable reset int 
    pUSBCtrlAddr->UIER.reset_int_en = 0x1;
//		ep0State=EP0_STATE_INIT;							// added by J.I(8/28)
		*/

	return TRUE;
}

void PrintEp0Pkt(U8 *pt)
{
    int i;
	EdbgOutputDebugString("[RCV:");
	for(i=0;i<EP0_PKT_SIZE;i++)
		EdbgOutputDebugString("%x,",pt[i]);
	EdbgOutputDebugString("]\r\n");
}

void WrPktEp0(U8 *buf,int num)
{
	int i;
    
	for(i=0;i<num;i++)
	{
		pUSBCtrlAddr->EP0F.fifo_data = buf[i];
	}
}

void WrPktEp1(U8 *buf,int num)
{
    int i;
    	
    for(i=0;i<num;i++)
    {
        pUSBCtrlAddr->EP1F.fifo_data = buf[i];
    }
}

void RdPktEp0(U8 *buf,int num)
{
    int i;
    	
    for(i=0;i<num;i++)
    {
        buf[i]=(U8)pUSBCtrlAddr->EP0F.fifo_data;	
    }
}
/*
void RdPktEp3(U8 *buf,int num)
{
	int i;

	for(i=0;i<num;i++)
	{
		buf[i]=(U8)(pUSBCtrlAddr->EP3F.fifo_data);
    }
}
*/
// by J.I inserted(8/22)
void RdPktEp4(U8 *buf, int num)
{
	int i;

	for(i=0; i<num; i++)
	{
		buf[i] = (U8)(pUSBCtrlAddr->EP4F.fifo_data);
	}
}
	
		

void PrepareEp1Fifo(void) 
{
    int i;
    pUSBCtrlAddr->INDEX.index=1;
    
    for(i=0;i<EP1_PKT_SIZE;i++)ep1Buf[i]=(U8)(transferIndex+i);
    WrPktEp1(ep1Buf,EP1_PKT_SIZE);
	pUSBCtrlAddr->EP0ICSR1.opr_ipr = 1;
	pUSBCtrlAddr->EP0ICSR1.sts_ = 0;
	pUSBCtrlAddr->EP0ICSR1.de_ff = 0;
}

void Ep1Handler(void)
{
    pUSBCtrlAddr->INDEX.index=1;
    
    if(pUSBCtrlAddr->EP0ICSR1.sds_sts)
    {   
		pUSBCtrlAddr->EP0ICSR1.opr_ipr = 0;
		pUSBCtrlAddr->EP0ICSR1.sts_ = 0;
		pUSBCtrlAddr->EP0ICSR1.de_ff = 0;
		pUSBCtrlAddr->EP0ICSR1.sds_sts = 0;
   		return;
    }	

    transferIndex++;

    PrepareEp1Fifo(); 

    return;
}

void Ep0Handler(void)
{
	static int ep0SubState;

	pUSBCtrlAddr->INDEX.index=0;

	//DATAEND interrupt(ep0_csr==0x0) will be ignored 
	//because ep0State==EP0_STATE_INIT when the DATAEND interrupt is issued.

//	EdbgOutputDebugString("INFO : Ep0Handler\r\n");

	if(pUSBCtrlAddr->EP0ICSR1.se_sds)
	{   
		// Host may end GET_DESCRIPTOR operation without completing the IN data stage.
		// If host does that, SETUP_END bit will be set.
		// OUT_PKT_RDY has to be also cleared because status stage sets OUT_PKT_RDY to 1.
		CLR_EP0_SETUP_END();
		if(pUSBCtrlAddr->EP0ICSR1.opr_ipr) 
		{
			FLUSH_EP0_FIFO(); //(???)
			//I think this isn't needed because EP0 flush is done automatically.   
			CLR_EP0_OUT_PKT_RDY();
		}

		ep0State=EP0_STATE_INIT;
		return;
	}	

	//I think that EP0_SENT_STALL will not be set to 1.
	if(pUSBCtrlAddr->EP0ICSR1.sts_)
	{   
		EdbgOutputDebugString("[STALL]\r\n");
		CLR_EP0_SENT_STALL();
		if(pUSBCtrlAddr->EP0ICSR1.opr_ipr)
		{
			CLR_EP0_OUT_PKT_RDY();
		}

		ep0State=EP0_STATE_INIT;
		return;
	}	

	if((pUSBCtrlAddr->EP0ICSR1.opr_ipr) && (ep0State==EP0_STATE_INIT))
	{
		RdPktEp0((U8 *)&descSetup,EP0_PKT_SIZE);

		switch(descSetup.bRequest)
		{
		case GET_DESCRIPTOR:
			switch(descSetup.bValueH)        
			{
            case USB_DEVICE_TYPE:
				CLR_EP0_OUT_PKT_RDY();
				ep0State=EP0_STATE_GD_DEV_0;	        
				break;	
			case CONFIGURATION_TYPE:
				CLR_EP0_OUT_PKT_RDY();
				if((descSetup.bLengthL+(descSetup.bLengthH<<8))>0x9)
					//bLengthH should be used for bLength=0x209 at WIN2K.    	
					ep0State=EP0_STATE_GD_CFG_0; //for WIN98,WIN2K
				else	    	    
					ep0State=EP0_STATE_GD_CFG_ONLY_0; //for WIN2K
				break;
			case STRING_TYPE:
				CLR_EP0_OUT_PKT_RDY();
				switch(descSetup.bValueL)
				{
				case 0:
					ep0State=EP0_STATE_GD_STR_I0;
					break;
				case 1:
					ep0State=EP0_STATE_GD_STR_I1;
					break;
				case 2:	
					ep0State=EP0_STATE_GD_STR_I2;
					break;
				default:
					EdbgOutputDebugString("[UE:STRI?]\r\n");
					break;
				}
				ep0SubState=0;
				break;
			case INTERFACE_TYPE:
				EdbgOutputDebugString("[GDI]\r\n");
				CLR_EP0_OUT_PKT_RDY();
				ep0State=EP0_STATE_GD_IF_ONLY_0; //for WIN98
				break;
			case ENDPOINT_TYPE:	    	
				EdbgOutputDebugString("[GDE]\r\n");
				CLR_EP0_OUT_PKT_RDY();
				switch(descSetup.bValueL&0xf)
				{
				case 0:
					ep0State=EP0_STATE_GD_EP0_ONLY_0;
					break;
				case 1:
					ep0State=EP0_STATE_GD_EP1_ONLY_0;
					break;
				default:
					EdbgOutputDebugString("[UE:GDE?]\r\n");
					break;
				}
				break;
			default:
				EdbgOutputDebugString("[UE:GD?]\r\n");
				break;
			}
			break;

		case SET_ADDRESS:
			pUSBCtrlAddr->udcFAR.func_addr = descSetup.bValueL;
			pUSBCtrlAddr->udcFAR.addr_up = 1;
			CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
			ep0State=EP0_STATE_INIT;
			break;
    	
		case SET_CONFIGURATION:
			ConfigSet.ConfigurationValue=descSetup.bValueL;
			CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
			ep0State=EP0_STATE_INIT;

			break;

			//////////////////////// For chapter 9 test ////////////////////

		case CLEAR_FEATURE:
			switch (descSetup.bmRequestType)
			{
			case DEVICE_RECIPIENT:
				if (descSetup.bValueL == 1)
					Rwuen = FALSE;
				break;

			case ENDPOINT_RECIPIENT:
				if (descSetup.bValueL == 0)
				{
					if((descSetup.bIndexL & 0x7f) == 0x00){
						StatusGet.Endpoint0= 0;    
					}
					if((descSetup.bIndexL & 0x8f) == 0x81){           // IN  Endpoint 1
						StatusGet.Endpoint1= 0;           

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -