📄 usb.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <halether.h>
#include <bsp.h>
#include "loader.h"
volatile S3C2440A_USBD_REG * pUSBCtrlAddr;
int g_DMAbufIndex = 0;
int debugM = 0;
volatile int DMADone = 0;
#define REAL_PHYSICAL_ADDR_EP3_FIFO (0x520001CC) //Endpoint 3 FIFO
ULONG realPhysicalAddr_UsbdRxBuf=0;
//OUT_CSR2
#define EPO_OUT_DMA_INT_MASK (1<<5)
#define EPO_ISO (1<<6)
#define EPO_BULK (0<<6)
#define EPO_AUTO_CLR (1<<7)
//USB DMA control register
#define UDMA_IN_RUN_OB (1<<7)
#define UDMA_IGNORE_TTC (1<<7)
#define UDMA_DEMAND_MODE (1<<3)
#define UDMA_OUT_RUN_OB (1<<2)
#define UDMA_OUT_DMA_RUN (1<<2)
#define UDMA_IN_DMA_RUN (1<<1)
#define UDMA_DMA_MODE_EN (1<<0)
#define pISR (*(unsigned *)(0x30000000+0x18)) // Virtual Address 0x0 is mapped to 0x30000000, ISR Address is VA 0x18
#define U8 unsigned char
#define U32 unsigned int
#define BUFARRAYSIZE 64
volatile unsigned char downArr[BUFARRAYSIZE];
volatile unsigned char *downPt;
#define DMABUFFER 0x32000000
volatile unsigned int downPtIndex = DMABUFFER;
volatile unsigned int readPtIndex = DMABUFFER;
volatile unsigned int loopcnt = 0;
volatile DWORD DownloadAddress, TotalSize;
#define BULK_PKT_SIZE 64
#define EP0_PKT_SIZE 8
#define EP1_PKT_SIZE BULK_PKT_SIZE
#define EP3_PKT_SIZE BULK_PKT_SIZE
U8 ep1Buf[EP1_PKT_SIZE];
int transferIndex=0;
void Isr_Init(void);
void IsrUsbd(unsigned int val);
void IsrHandler(void);
void Ep3Handler(void);
void ConfigEp3DmaMode(U32 bufAddr,U32 count);
void DMA2Handler(void);
#define rEP3_DMA_TTC_L (*(volatile unsigned char *)0x5200024c) //EP3 DMA total Tx counter
#define rEP3_DMA_TTC_M (*(volatile unsigned char *)0x52000250)
#define rEP3_DMA_TTC_H (*(volatile unsigned char *)0x52000254)
#define rEP3_DMA_TTC (pUSBCtrlAddr->EP3DTL.ep3_ttl_l+(pUSBCtrlAddr->EP3DTM.ep3_ttl_m<<8)+(pUSBCtrlAddr->EP3DTH.ep3_ttl_h<<16))
#define SKIP 1
#define DOIT 0
// Standard bmRequestType (Recipient)
#define DEVICE_RECIPIENT (0)
#define INTERFACE_RECIPIENT (1)
#define ENDPOINT_RECIPIENT (2)
#define OTHER_RECIPIENT (3)
#define EP0_STATE_INIT (0)
#define EP0_STATE_GD_DEV_0 (10) //10-10=0
#define EP0_STATE_GD_DEV_1 (11) //11-10=1
#define EP0_STATE_GD_DEV_2 (12) //12-10=2
#define EP0_STATE_GD_CFG_0 (20)
#define EP0_STATE_GD_CFG_1 (21)
#define EP0_STATE_GD_CFG_2 (22)
#define EP0_STATE_GD_CFG_3 (23)
#define EP0_STATE_GD_CFG_4 (24)
#define EP0_STATE_GD_CFG_ONLY_0 (40)
#define EP0_STATE_GD_CFG_ONLY_1 (41)
#define EP0_STATE_GD_IF_ONLY_0 (42)
#define EP0_STATE_GD_IF_ONLY_1 (43)
#define EP0_STATE_GD_EP0_ONLY_0 (44)
#define EP0_STATE_GD_EP1_ONLY_0 (45)
#define EP0_INTERFACE_GET (46)
#define EP0_STATE_GD_STR_I0 (30)
#define EP0_STATE_GD_STR_I1 (31)
#define EP0_STATE_GD_STR_I2 (32)
#define EP0_CONFIG_SET (33)
#define EP0_GET_STATUS0 (35)
#define EP0_GET_STATUS1 (36)
#define EP0_GET_STATUS2 (37)
#define EP0_GET_STATUS3 (38)
#define EP0_GET_STATUS4 (39)
#define CLR_EP0_OUT_PKT_RDY() pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1; pUSBCtrlAddr->EP0ICSR1.sse_ = 0;
#define CLR_EP0_OUTPKTRDY_DATAEND() pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1; pUSBCtrlAddr->EP0ICSR1.de_ff = 1;; pUSBCtrlAddr->EP0ICSR1.sse_ = 0;
#define SET_EP0_IN_PKT_RDY() pUSBCtrlAddr->EP0ICSR1.ipr_ = 1; pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 0; pUSBCtrlAddr->EP0ICSR1.sse_ = 0;
#define SET_EP0_INPKTRDY_DATAEND() pUSBCtrlAddr->EP0ICSR1.ipr_ = 1; pUSBCtrlAddr->EP0ICSR1.de_ff = 1; pUSBCtrlAddr->EP0ICSR1.sse_ = 0; pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 0;
#define CLR_EP0_SETUP_END() pUSBCtrlAddr->EP0ICSR1.sse_ = 1; pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 0;
#define CLR_EP0_SENT_STALL() pUSBCtrlAddr->EP0ICSR1.sts_ = 0; pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 0; pUSBCtrlAddr->EP0ICSR1.sse_ = 0;
#define FLUSH_EP0_FIFO() {while(pUSBCtrlAddr->OFCR1.out_cnt_low) pUSBCtrlAddr->EP0F.fifo_data;}
#define CLR_EP3_OUT_PKT_READY() pUSBCtrlAddr->OCSR1.fifo_flush = 0; pUSBCtrlAddr->OCSR1.send_stall = 0; pUSBCtrlAddr->OCSR1.clr_data_tog = 0; pUSBCtrlAddr->OCSR1.out_pkt_rdy = 0;
#define CLR_EP3_SENT_STALL() pUSBCtrlAddr->OCSR1.fifo_flush = 0; pUSBCtrlAddr->OCSR1.send_stall = 0; pUSBCtrlAddr->OCSR1.clr_data_tog = 0; pUSBCtrlAddr->OCSR1.sent_stall = 0;
volatile U8 Rwuen;
volatile U8 Selfpwr=TRUE;
U32 ep0State;
struct USB_SETUP_DATA{
U8 bmRequestType;
U8 bRequest;
U8 bValueL;
U8 bValueH;
U8 bIndexL;
U8 bIndexH;
U8 bLengthL;
U8 bLengthH;
};
struct USB_DEVICE_DESCRIPTOR{
U8 bLength;
U8 bDescriptorType;
U8 bcdUSBL;
U8 bcdUSBH;
U8 bDeviceClass;
U8 bDeviceSubClass;
U8 bDeviceProtocol;
U8 bMaxPacketSize0;
U8 idVendorL;
U8 idVendorH;
U8 idProductL;
U8 idProductH;
U8 bcdDeviceL;
U8 bcdDeviceH;
U8 iManufacturer;
U8 iProduct;
U8 iSerialNumber;
U8 bNumConfigurations;
};
struct USB_CONFIGURATION_DESCRIPTOR{
U8 bLength;
U8 bDescriptorType;
U8 wTotalLengthL;
U8 wTotalLengthH;
U8 bNumInterfaces;
U8 bConfigurationValue;
U8 iConfiguration;
U8 bmAttributes;
U8 maxPower;
};
struct USB_INTERFACE_DESCRIPTOR{
U8 bLength;
U8 bDescriptorType;
U8 bInterfaceNumber;
U8 bAlternateSetting;
U8 bNumEndpoints;
U8 bInterfaceClass;
U8 bInterfaceSubClass;
U8 bInterfaceProtocol;
U8 iInterface;
};
struct USB_ENDPOINT_DESCRIPTOR{
U8 bLength;
U8 bDescriptorType;
U8 bEndpointAddress;
U8 bmAttributes;
U8 wMaxPacketSizeL;
U8 wMaxPacketSizeH;
U8 bInterval;
};
struct USB_CONFIGURATION_SET{
U8 ConfigurationValue;
};
struct USB_GET_STATUS{
U8 Device;
U8 Interface;
U8 Endpoint0;
U8 Endpoint1;
U8 Endpoint3;
};
struct USB_INTERFACE_GET{
U8 AlternateSetting;
};
struct USB_SETUP_DATA descSetup;
struct USB_DEVICE_DESCRIPTOR descDev;
struct USB_CONFIGURATION_DESCRIPTOR descConf;
struct USB_INTERFACE_DESCRIPTOR descIf;
struct USB_ENDPOINT_DESCRIPTOR descEndpt0;
struct USB_ENDPOINT_DESCRIPTOR descEndpt1;
struct USB_CONFIGURATION_SET ConfigSet;
struct USB_INTERFACE_GET InterfaceGet;
struct USB_GET_STATUS StatusGet; //={0,0,0,0,0};
// Descriptor Types
#define USB_DEVICE_TYPE (1)
#define CONFIGURATION_TYPE (2)
#define STRING_TYPE (3)
#define INTERFACE_TYPE (4)
#define ENDPOINT_TYPE (5)
//string descriptor
#define LANGID_US_L (0x09)
#define LANGID_US_H (0x04)
// Standard Request Codes
#define GET_STATUS (0)
#define CLEAR_FEATURE (1)
#define SET_FEATURE (3)
#define SET_ADDRESS (5)
#define GET_DESCRIPTOR (6)
#define SET_DESCRIPTOR (7)
#define GET_CONFIGURATION (8)
#define SET_CONFIGURATION (9)
#define GET_INTERFACE (10)
#define SET_INTERFACE (11)
#define SYNCH_FRAME (12)
//configuration descriptor: bmAttributes
#define CONF_ATTR_DEFAULT (0x80) //Spec 1.0 it was BUSPOWERED bit.
#define CONF_ATTR_REMOTE_WAKEUP (0x20)
#define CONF_ATTR_SELFPOWERED (0x40)
//endpoint descriptor
#define EP_ADDR_IN (0x80)
#define EP_ADDR_OUT (0x00)
#define EP_ATTR_CONTROL (0x0)
#define EP_ATTR_ISOCHRONOUS (0x1)
#define EP_ATTR_BULK (0x2)
#define EP_ATTR_INTERRUPT (0x3)
static const U8 descStr0[]={
4,STRING_TYPE,LANGID_US_L,LANGID_US_H, //codes representing languages
};
static const U8 descStr1[]={ //Manufacturer
(0x14+2),STRING_TYPE,
'S',0x0,'y',0x0,'s',0x0,'t',0x0,'e',0x0,'m',0x0,' ',0x0,'M',0x0,
'C',0x0,'U',0x0,
};
static const U8 descStr2[]={ //Product
(0x2a+2),STRING_TYPE,
'S',0x0,'E',0x0,'C',0x0,' ',0x0,'S',0x0,'3',0x0,'C',0x0,'2',0x0,
'4',0x0,'1',0x0,'0',0x0,'X',0x0,' ',0x0,'T',0x0,'e',0x0,'s',0x0,
't',0x0,' ',0x0,'B',0x0,'/',0x0,'D',0x0
};
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=3|EP_ADDR_OUT; // 2400X endpoint 3 is OUT endpoint.
descEndpt1.bmAttributes=EP_ATTR_BULK;
descEndpt1.wMaxPacketSizeL=EP3_PKT_SIZE; //64
descEndpt1.wMaxPacketSizeH=0x0;
descEndpt1.bInterval=0x0; //not used
}
BOOL InitUSB()
{
BYTE index;
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
//
index = pUSBCtrlAddr->INDEX.index;
// suspend mode disable
pUSBCtrlAddr->PMR.sus_en = 0x0;
// 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.iso = 0; // BULK
// 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->OCSR2.iso = 0; // BULK
// 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;
// EP0, 1, & 3 Enabled, EP2, 4 Disabled
pUSBCtrlAddr->EIER.ep0_int_en = 0x1;
pUSBCtrlAddr->EIER.ep1_int_en = 0x1;
pUSBCtrlAddr->EIER.ep2_int_en = 0x0;
pUSBCtrlAddr->EIER.ep3_int_en = 0x1;
pUSBCtrlAddr->EIER.ep4_int_en = 0x0;
/*
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");
*/
// enable reset int
pUSBCtrlAddr->UIER.reset_int_en = 0x1;
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -