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

📄 usb.c

📁 Sirf/Centrality公司GPS平台AtlasIII芯片AT640的Nboot源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>
#include "def.h"
#include "at4x0f.h"
#include "debug.h"
#include "usbotg.h"
#include "nand.h"
#include "loader.h"
#include "vendormsg.h"

//#include "bspname.h"
#define BSP_NAME "AT4X0BD"

#define CONFIG_DESC_LENGTH      0x3c

extern TOC* g_pTOC;

static unsigned char DESCRIPTOR_TABLE[78] = {0x12,0x01,0x10,0x01,0xff,0xff,0xff,0x08,
                                    0x52,0x32,0x04,0x00,0x01,0x01,0x00,0x00,
                                    0x00,0x01,
                                    0x09,0x02,0x3c,0x00,0x01,0x01,0x00,0xc0,0x00,//Config Descriptor
                                    0x09,0x04,0x00,0x00,0x06,0xff,0xff,0xff,0x00,//Interface Descriptor - Alternate setting 0
                                    0x07,0x05,0x81,0x02,0x10,0x00,0x00,
                                    0x07,0x05,0x01,0x02,0x10,0x00,0x00,
                                    0x07,0x05,0x82,0x02,0x40,0x00,0x00,
                                    0x07,0x05,0x02,0x02,0x40,0x00,0x00,
                                    0x07,0x05,0x83,0x02,0x40,0x00,0x00,
                                    0x07,0x05,0x03,0x02,0x40,0x00,0x00};

//                                        MPS   FORMAT      XBSA    YBSA    BS
static USB_ENDPOINT ep_table[NUM_EPS*2] = {{8,  CTL_TYPE,   0,      0,      0x07},		//EP0 out
                                        {8,     CTL_TYPE,   0,      0,      0x07},		//EP0 in
                                        {16,    BLK_TYPE,   0x08,   0x18,   0x0f},		//EP1 out
                                        {16,    BLK_TYPE,   0x28,   0x38,   0x0f},		//EP1 in
                                        {64,    BLK_TYPE,   0x48,   0x88,   0x3f},		//EP2 out
                                        {64,    BLK_TYPE,   0xc8,   0x108,  0x3f},		//EP2 in
                                        {64,    BLK_TYPE,   0x00,   0x40,   0x3f},		//EP3 out
                                        {64,    BLK_TYPE,   0x00,   0x40,   0x3f}};		//EP3 in

USB_INTERRUPT   usb_int;
TASK_CTRL       usb_task;
USB_PARAMETER   usb_para;


void USB_Reset(void);
void USB_Run(void);
void USB_ConfigEps(void);
void USB_ResetState(void);

void vendor_command(void);

void bulk_in_ep1(void);
void bulk_out_ep1(void);
void bulk_in_ep2(void);

#ifndef USING_USB_DMA_MODE
void bulk_out_ep2(void);
#endif // USING_USB_DMA_MODE

unsigned char SetupPacket[8];

#define BMREQUEST_TYPE_V    SetupPacket[0]
#define BREQUEST_V          SetupPacket[1]
#define WVALUE_LO_V         SetupPacket[2]
#define WVALUE_HI_V         SetupPacket[3]
#define WINDEX_LO_V         SetupPacket[4]
#define WINDEX_HI_V         SetupPacket[5]
#define WLENGTH_LO_V        SetupPacket[6]
#define WLENGTH_HI_V        SetupPacket[7]

unsigned char iDevAddr;
unsigned char g_bEp0End;

unsigned int  bDeviceConfigured;
unsigned int  bAddrAssigned;
unsigned int  bSetAddress;
unsigned int  bTransferOver;
unsigned int  bWaitForXmit;
int bStatusStage;

unsigned short iNeededLen;
unsigned char iXferedLen;
unsigned char * pEp0Data;

uchar *		pCurImgCache = (uchar *)SDRAM_IMG_CACHE_START;
ulong		g_iCurImgLength = 16384;
ulong		iCurImgTransfered = 0;

uchar *		pDbgMsg = NULL;


int bWriteImage = 0;
int bWriteToc = 0;
int bChangeCS = 0;
int iValue;

extern int g_iDevStatus;
extern char	g_dbgMsg[64];
int bNeedZeroPkt = 0;
int bInstRcvd = 0;

extern DWORD g_nCurImg;
extern DWORD g_nNandCS;

extern int g_bTransportChange;

#ifdef USING_USB_DMA_MODE
void OTG_FuncDmaCfg(int epnum, DWORD dwSMSA)
{
	if (USBOTG_FUNC_IS_EP_READY(USB_EP_ADDR(epnum, EP_OUT_DIR)))
	{
		USBOTG_FUNC_CLR_EP_READY(USB_EP_ADDR(epnum, EP_OUT_DIR));
	}

	USBOTG_FUNC_SET_EP_XFER_LEN(epnum, EP_OUT_DIR, 64);
	USBOTG_FUNC_SET_EP_SMSA(USB_EP_ADDR(epnum, EP_OUT_DIR), dwSMSA);
	USBOTG_FUNC_EP_EN_DMA (USB_EP_ADDR(epnum, EP_OUT_DIR));
	USBOTG_FUNC_SET_EP_READY(USB_EP_ADDR(epnum, EP_OUT_DIR));
}
#endif //USING_USB_DMA_MODE

void OTG_FuncCommonInit()
{
    USBOTG_TOP_SET_FUNC_MODE();                 // OTG port forced as function

    USBOTG_MNP_PULSE_ADDR = TL_NONE_SET;

    USBOTG_TOP_INT_EN(TL_FUNCTION_INT);// Enable Function Interrupts

    // Bit2=FunctionEnable
    USBOTG_TL_CLK_CTRL_ADDR |= TL_FUNC_CLOCK_ON;

    USBOTG_FC_SYS_INT_EN_ADDR = (FC_RESET_DETECT_INT | FC_DONE_REG_INT);

    USBOTG_FC_DONE_REG_EN_ADDR = (1 << (NUM_EPS*2)) -1;  // enable all Done Interrupts

    // program the device model for short frame also
    USBOTG_MNP_CTRL_ADDR |= 0x800;
}

void USB_Init(void)
{
    volatile unsigned int io_i;
    unsigned int uiReg;

    PWR_CLOCK_ENABLE(PWRCLK_USB_EN | PWRCLK_PCI_EN);

    INT_RISC_MASK |= INT_MASK_USB;

	{
		PWR_PLL2_CONFIG = 0x00004220; // pll2 192MHz
		for(io_i=1;io_i<=1000;io_i++);

		// set usb clock ratio to pll2:usb_clk=4:1
		uiReg = PWR_CLK_RATIO;
		uiReg &= ~0xf0000;
		uiReg |=  0x40000;
		PWR_CLK_RATIO = uiReg;

		// set usb clock source to pll2
		uiReg = PWR_CLK_SWITCH;
		uiReg &= ~0x0c;
		uiReg |=  0x08;
		PWR_CLK_SWITCH = uiReg;

		for(io_i=1;io_i<=10000;io_i++);
	}

	USB_Reset();
}

void USB_Reset(void)
{
    RESET_DECLARE(RESET_SR_USB_RST);
    RESET_CLEAR(RESET_SR_USB_RST);

    OTG_FuncCommonInit();
    USB_ConfigEps();

    USBOTG_FC_IMM_INT_ADDR = 0xffffffff;

    USB_ResetState();

#ifdef USING_USB_DMA_MODE
	OTG_FuncDmaCfg(2, (DWORD)SDRAM_IMG_CACHE_START);
#endif // USING_USB_DMA_MODE

	g_iDevStatus = ATLAS_DEV_STATUS_UNINITED_NBOOT;
}

void USB_ConfigEps(void)
{
    int i;

    for (i = 0; i < NUM_EPS * 2; ++i) {
        USBOTG_FUNC_INIT_EP (i >> 1,
                            (i & 1) ? EP_IN_DIR : EP_OUT_DIR,
                            ep_table[i].mps,
                            ep_table[i].format,
                            ep_table[i].xbsa,
                            ep_table[i].ybsa,
                            ep_table[i].bs);
    }
    USBOTG_FUNC_SET_EP_XFER_LEN(1, EP_IN_DIR, 16);
    USBOTG_FUNC_SET_EP_XFER_LEN(1, EP_OUT_DIR, 16);
    USBOTG_FUNC_SET_EP_XFER_LEN(2, EP_IN_DIR, 64);
    USBOTG_FUNC_SET_EP_XFER_LEN(2, EP_OUT_DIR, 64);
}

void USB_ResetState(void)
{
    bDeviceConfigured = 0;
    bAddrAssigned = 0;
    bSetAddress = 0;
    bTransferOver = 1;
    bWaitForXmit = 0;

    memset(&usb_int, 0, sizeof(USB_INTERRUPT));
}

void USB_Process(void)
{
	while(1)
    {
		if (usb_int.intr)
		{
			INT_RISC_MASK &= ~INT_MASK_USB;
	        USB_Run();
			usb_int.intr = 0;
			INT_RISC_MASK |= INT_MASK_USB;
		}

		if(	g_iDevStatus != ATLAS_DEV_STATUS_INITING_NBOOT && 
			g_iDevStatus != ATLAS_DEV_STATUS_SENDING_MSG_NBOOT	)
			return;
    }
}


void Set_Configuration(void)
{
    // Check whether bmrequest type is for device.
    if( (BMREQUEST_TYPE_V != 0) || (WLENGTH_LO_V != 0) ||
        (WLENGTH_HI_V != 0) || (WINDEX_LO_V != 0) || (WINDEX_HI_V != 0))
    {
        USBOTG_FUNC_STALL_EP(USB_EP_ADDR(0, EP_OUT_DIR));
        return;
    }

    // Check whether the device in configured state.
    if((bDeviceConfigured != 0) && (bAddrAssigned == 0))
    {
        USBOTG_FUNC_STALL_EP(USB_EP_ADDR(0, EP_OUT_DIR));
        return;
    }

    switch(WVALUE_LO_V)
    {
        case 0x01:
            bDeviceConfigured = 1;
			g_iDevStatus = ATLAS_DEV_STATUS_IDLE_NBOOT;
            break;
        case 0x00:
            bDeviceConfigured = 0;
            break;
        default:
            USBOTG_FUNC_STALL_EP(USB_EP_ADDR(0, EP_OUT_DIR));
            break;
    }
}

void Set_Address(void)
{
    // Check whether the device is in configured state. If yes, the device behavior
    // for this request is unspecified.
    if(bDeviceConfigured != 0)
        goto set_addr_stall;

    // Check whether bmrequest type is for device.
    if((BMREQUEST_TYPE_V != 0) || (WLENGTH_LO_V != 0) || (WLENGTH_HI_V != 0) || (WINDEX_LO_V != 0) || (WINDEX_HI_V != 0))
        goto set_addr_stall;

    // Get the wValue low byte for processing. The device address should not exceed 127 .
    // Because only 7-bits are provided for address field for USB device address.
    // if address value exceeds 127 then we should consider as unsupported request.
    if(WVALUE_LO_V == 0 && WVALUE_HI_V == 0)
        goto set_addr_stall;

    //  Currently store the address assigned by the host in a variable and only
    //  after the status stage write the address in the Register.
    iDevAddr = WVALUE_LO_V;
//  USBOTG_FC_DEV_ADDRESS_ADDR = WVALUE_LO_V;
    bAddrAssigned = 1;
    bSetAddress = 1;

	g_iDevStatus = ATLAS_DEV_STATUS_INITING_NBOOT;

	return;

set_addr_stall:
    USBOTG_FUNC_STALL_EP(USB_EP_ADDR(0, EP_OUT_DIR));
    return;

}

void send_ep0_data()
{
    unsigned short curLength;
    WORD *pwBuf = (WORD *)&pEp0Data[iXferedLen];

    curLength = iNeededLen - iXferedLen;
    if(curLength > 8)
        curLength = 8;

    USBOTG_FUNC_PREPARE_EP(0, EP_IN_DIR);

    USBOTG_FUNC_SET_EP_XFER_LEN(0, EP_IN_DIR, curLength);

    *(volatile DWORD *)(USBOTG_DATA_BASE + 0) = (pwBuf [1] << 16) | pwBuf [0];
    *(volatile DWORD *)(USBOTG_DATA_BASE + 4) = (pwBuf [3] << 16) | pwBuf [2];

    USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(0, EP_IN_DIR));
    USBOTG_FUNC_SET_EP_READY(USB_EP_ADDR(0, EP_IN_DIR));

    iXferedLen += curLength;

    if ((iXferedLen == iNeededLen) && (iNeededLen % 8) || (curLength == 0))
    {
        bTransferOver = 1;
    }
    //Set a flag here, the next EP0 recieve will not be handled until the current xmit is finished.
    bWaitForXmit = 1;
    bStatusStage = 1;
}

void Get_Descriptor(void)
{
    unsigned short length;

    length = WLENGTH_HI_V << 8;
    length = length | WLENGTH_LO_V;

    // compare wlength value with the actual device
    // descriptor length.If greater,then initialise
    // Total numer of bytes with actual descriptor
    // length otherwise with wlength value and
    // for remaining bytes respond with stall on EP0.
    switch(WVALUE_HI_V)
    {
        case 0x01:
                if(length <= 0x12)
                    iNeededLen = length;
                else
                    iNeededLen = 0x12;
                pEp0Data = (unsigned char*)DESCRIPTOR_TABLE;
                break;

        case 0x02:
                if(length <= CONFIG_DESC_LENGTH)
                    iNeededLen = length;
                else
                    iNeededLen = CONFIG_DESC_LENGTH;
                pEp0Data = (unsigned char*)DESCRIPTOR_TABLE + 0x12;
                break;
        default:
            USBOTG_FUNC_STALL_EP(USB_EP_ADDR(0, EP_OUT_DIR));
            return;
    }

    iXferedLen = 0;
    bTransferOver = 0;
    send_ep0_data();
    return;
}

void device_command(void)
{
    switch (BREQUEST_V)
    {
        case USB_SET_ADDR:
            Set_Address();
            break;
        case USB_GET_DESCRIPTOR:
            Get_Descriptor();
            break;
        case USB_SET_CONFIG:
            Set_Configuration();
            break;
        case USB_GET_STATUS:
            break;
        default:
            USBOTG_FUNC_STALL_EP(USB_EP_ADDR(0, EP_OUT_DIR));
            break;
    }
}

void process_setup_packet(void)
{
    // upon setup, the host will always expect a DATA1 packet
    USBOTG_FUNC_SET_EP_PID1(0, EP_IN_DIR);
    if ((WLENGTH_LO_V == 0) && (WLENGTH_HI_V == 0))
    {
        //clear last config.
        USBOTG_FUNC_PREPARE_EP(0, EP_IN_DIR);

        USBOTG_FUNC_SET_EP_XFER_LEN(0, EP_IN_DIR, 0);
        USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(0, EP_IN_DIR));
        USBOTG_FUNC_SET_EP_READY(USB_EP_ADDR(0, EP_IN_DIR));

        bStatusStage = 1;
    }

    if((BMREQUEST_TYPE_V & 0x60) == 0)
    {
        switch(BMREQUEST_TYPE_V & 0x03)
        {
        case 0x00:
            device_command();
            break;
        default:
            USBOTG_FUNC_STALL_EP(USB_EP_ADDR(0, EP_OUT_DIR));
            break;
        }
    }
    else
    {
        if((BMREQUEST_TYPE_V & 0x60) == 0x40)
        {
            vendor_command();
        }

⌨️ 快捷键说明

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