Exemplo n.º 1
0
void EP2_Handler(void)
{
    /* BULK IN transfer */
    if (gu8IsBulkInReady)
    {
        if(gi32UsbdMessageLength >= EP2_MAX_PKT_SIZE)
        {
            gu8IsBulkInReady = 1;
            USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), pUsbMessageBuffer, EP2_MAX_PKT_SIZE);
            USBD_SET_PAYLOAD_LEN(EP2, EP2_MAX_PKT_SIZE);

            pUsbMessageBuffer += EP2_MAX_PKT_SIZE;
            gi32UsbdMessageLength -= EP2_MAX_PKT_SIZE;
        }
        else
        {
            USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), pUsbMessageBuffer, gi32UsbdMessageLength);
            USBD_SET_PAYLOAD_LEN(EP2, gi32UsbdMessageLength);
            gi32UsbdMessageLength = 0;
            gu8IsBulkInReady = 0;
        }
    }
    if (!gu8IsBulkOutReady)
        USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
}
Exemplo n.º 2
0
void CCID_BulkInMessage(void)
{
    gi32UsbdMessageLength = USB_MESSAGE_HEADER_SIZE + make32(&UsbMessageBuffer[OFFSET_DWLENGTH]);

    pUsbMessageBuffer = UsbMessageBuffer;

    if (gu8IsBulkInReady)
    {
        if(gi32UsbdMessageLength >= EP2_MAX_PKT_SIZE)
        {
            gu8IsBulkInReady = 1;
            USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), pUsbMessageBuffer, EP2_MAX_PKT_SIZE);
            USBD_SET_PAYLOAD_LEN(EP2, EP2_MAX_PKT_SIZE);

            pUsbMessageBuffer += EP2_MAX_PKT_SIZE;
            gi32UsbdMessageLength -= EP2_MAX_PKT_SIZE;
        }
        else
        {
            USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), pUsbMessageBuffer, gi32UsbdMessageLength);
            USBD_SET_PAYLOAD_LEN(EP2, gi32UsbdMessageLength);
            gi32UsbdMessageLength = 0;
            gu8IsBulkInReady = 0;
        }
    }
}
Exemplo n.º 3
0
void MSC_ReadTrig(void)
{
    uint32_t u32Len;

    if (g_u32Length)
    {
        if (g_u32BytesInStorageBuf)
        {
            /* Prepare next data packet */
            g_u8Size = EP2_MAX_PKT_SIZE;
            if (g_u8Size > g_u32Length)
                g_u8Size = g_u32Length;

            if (USBD_GET_EP_BUF_ADDR(EP2) == g_u32BulkBuf1)
                USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0), (uint8_t *)g_u32Address, g_u8Size);
            else
                USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_u32Address, g_u8Size);
            g_u32Address += g_u8Size;
        }
        else
        {
            u32Len = g_u32Length;
            if (u32Len > STORAGE_BUFFER_SIZE)
                u32Len = STORAGE_BUFFER_SIZE;

            MSC_ReadMedia(g_u32LbaAddress, u32Len, (uint8_t *)STORAGE_DATA_BUF);
            g_u32BytesInStorageBuf = u32Len;
            g_u32LbaAddress += u32Len;
            g_u32Address = STORAGE_DATA_BUF;

            /* Prepare next data packet */
            g_u8Size = EP2_MAX_PKT_SIZE;
            if (g_u8Size > g_u32Length)
                g_u8Size = g_u32Length;

            if (USBD_GET_EP_BUF_ADDR(EP2) == g_u32BulkBuf1)
                USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0), (uint8_t *)g_u32Address, g_u8Size);
            else
                USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_u32Address, g_u8Size);
            g_u32Address += g_u8Size;
        }

        /* DATA0/DATA1 Toggle */
        if (USBD_GET_EP_BUF_ADDR(EP2) == g_u32BulkBuf1)
            USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf0);
        else
            USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf1);

        /* Trigger to send out the data packet */
        USBD_SET_PAYLOAD_LEN(EP2, g_u8Size);

        g_u32Length -= g_u8Size;
        g_u32BytesInStorageBuf -= g_u8Size;
    }
    else
        USBD_SET_PAYLOAD_LEN(EP2, 0);
}
Exemplo n.º 4
0
void MSC_Write(void)
{
    uint32_t lba, len;

    if (g_u32Length > EP3_MAX_PKT_SIZE)
    {
        if (USBD_GET_EP_BUF_ADDR(EP3) == g_u32BulkBuf0)
        {
            USBD_SET_EP_BUF_ADDR(EP3, g_u32BulkBuf1);
            USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
            USBD_MemCopy((uint8_t *)g_u32Address, (uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0), EP3_MAX_PKT_SIZE);
        }
        else
        {
            USBD_SET_EP_BUF_ADDR(EP3, g_u32BulkBuf0);
            USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
            USBD_MemCopy((uint8_t *)g_u32Address, (uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), EP3_MAX_PKT_SIZE);
        }

        g_u32Address += EP3_MAX_PKT_SIZE;
        g_u32Length -= EP3_MAX_PKT_SIZE;

        /* Buffer full. Writer it to storage first. */
        if (g_u32Address >= (STORAGE_DATA_BUF + STORAGE_BUFFER_SIZE))
        {
            DataFlashWrite(g_u32DataFlashStartAddr, STORAGE_BUFFER_SIZE, (uint32_t)STORAGE_DATA_BUF);

            g_u32Address = STORAGE_DATA_BUF;
            g_u32DataFlashStartAddr += STORAGE_BUFFER_SIZE;
        }
    }
    else
    {
        if (USBD_GET_EP_BUF_ADDR(EP3) == g_u32BulkBuf0)
            USBD_MemCopy((uint8_t *)g_u32Address, (uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0), g_u32Length);
        else
            USBD_MemCopy((uint8_t *)g_u32Address, (uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), g_u32Length);
        g_u32Address += g_u32Length;
        g_u32Length = 0;


        if ((g_sCBW.u8OPCode == UFI_WRITE_10) || (g_sCBW.u8OPCode == UFI_WRITE_12))
        {
            lba = get_be32(&g_sCBW.au8Data[0]);
            len = g_sCBW.dCBWDataTransferLength;

            len = lba * UDC_SECTOR_SIZE + g_sCBW.dCBWDataTransferLength - g_u32DataFlashStartAddr;
            if (len)
                DataFlashWrite(g_u32DataFlashStartAddr, len, (uint32_t)STORAGE_DATA_BUF);
        }

        g_u8BulkState = BULK_IN;
        MSC_AckCmd();
    }
}
Exemplo n.º 5
0
/**
  * @brief    Repeat Control IN pipe
  *
  * @param    None
  *
  * @return   None
  *
  * @details  This function processes the remained data of Control IN transfer.
  *
  */
void USBD_CtrlIn(void)
{
    static uint8_t u8ZeroFlag = 0;
        
    if(g_usbd_CtrlInSize)
    {
        // Process remained data
        if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize)
        {
            // Data size > MXPLD
            USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize);
            USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
            g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize;
            g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
        }
        else
        {
            // Data size <= MXPLD
            USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize);
            USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize);
            if(g_usbd_CtrlInSize == g_usbd_CtrlMaxPktSize)
                u8ZeroFlag = 1;
            g_usbd_CtrlInPointer = 0;
            g_usbd_CtrlInSize = 0;
            
        }
    }
    else
    {
        // In ACK for Set address
        if((g_usbd_SetupPacket[0] == 0) && (g_usbd_SetupPacket[1] == 5))
        {
            if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0))
            {
                USBD_SET_ADDR(g_usbd_UsbAddr);
            }
        }

        // For size if n x MXPLD
        if(u8ZeroFlag)
        {
            USBD_SET_PAYLOAD_LEN(EP0, 0);
            u8ZeroFlag = 0;
        }
        
        // No more data for IN token
        USBD_PrepareCtrlOut(0, 0);
        DBG_PRINTF("Ctrl In Done.\n");
        
    }
}
Exemplo n.º 6
0
/**
  * @brief    Repeat Control IN pipe
  *
  * @param    None
  *
  * @return   None
  *
  * @details  This function processes the remained data of Control IN transfer.
  *
  */
void USBD_CtrlIn(void)
{
    static uint8_t u8ZeroFlag = 0;
    
    DBG_PRINTF("Ctrl In Ack. residue %d\n", g_usbd_CtrlInSize);
    if(g_usbd_CtrlInSize)
    {
        // Process remained data
        if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize)
        {
            // Data size > MXPLD
            USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize);
            USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
            g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize;
            g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
        }
        else
        {
            // Data size <= MXPLD
            USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize);
            USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize);
            if(g_usbd_CtrlInSize == g_usbd_CtrlMaxPktSize)
                u8ZeroFlag = 1;
            g_usbd_CtrlInPointer = 0;
            g_usbd_CtrlInSize = 0;
        }
    }
    else // No more data for IN token
    {
        // In ACK for Set address
        if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS))
        {
            if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0))
            {
                USBD_SET_ADDR(g_usbd_UsbAddr);
            }
        }

        /* For the case of data size is integral times maximum packet size */
        if(u8ZeroFlag)
        {
            USBD_SET_PAYLOAD_LEN(EP0, 0);
            u8ZeroFlag = 0;
        }
        
        DBG_PRINTF("Ctrl In done.\n");

    }
}
Exemplo n.º 7
0
//----- (000025B8) --------------------------------------------------------
__myevic__ uint32_t hidGetInfoCmd( CMD_T *pCmd )
{
	uint32_t u32StartAddr;
	uint32_t u32ParamLen;

	u32StartAddr = pCmd->u32Arg1;
	u32ParamLen = pCmd->u32Arg2;

	myprintf( "Get Info command - Start Addr: %d    Param Len: %d\n", pCmd->u32Arg1, pCmd->u32Arg2 );

	if ( u32ParamLen )
	{
		dfChecksum = Checksum( (uint8_t *)DataFlash.params, FMC_FLASH_PAGE_SIZE - 4 );

		if ( u32StartAddr + u32ParamLen > FMC_FLASH_PAGE_SIZE )
		{
			u32ParamLen = FMC_FLASH_PAGE_SIZE - u32StartAddr;
		}

		MemCpy( hidData, ((uint8_t *)&DataFlash) + u32StartAddr, u32ParamLen );

		hidDataIndex = u32ParamLen;
		pCmd->u32Signature = u32ParamLen;

		USBD_MemCopy(
			(uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)),
			hidData,
			EP2_MAX_PKT_SIZE
		);
		USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE );
		hidDataIndex -= EP2_MAX_PKT_SIZE;
	}

	return 0;
}
int32_t HID_CmdReadPages(CMD_T *pCmd)
{
    uint32_t u32StartPage;
    uint32_t u32Pages;

    u32StartPage = pCmd->u32Arg1;
    u32Pages     = pCmd->u32Arg2;

    printf("Read command - Start page: %d    Pages Numbers: %d\n", u32StartPage, u32Pages);

    if(u32Pages)
    {
        /* Update data to page buffer to upload */
        /* TODO: We need to update the page data if got a page read command. (0xFF is used in this sample code) */
        memcpy(g_u8PageBuff, g_u8TestPages, sizeof(g_u8PageBuff));
        g_u32BytesInPageBuf = PAGE_SIZE;

        /* The signature word is used as page counter */
        pCmd->u32Signature = 1;

        /* Trigger HID IN */
        USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5)), (void *)g_u8PageBuff, EP5_MAX_PKT_SIZE);
        USBD_SET_PAYLOAD_LEN(EP5, EP5_MAX_PKT_SIZE);
        g_u32BytesInPageBuf -= EP5_MAX_PKT_SIZE;
    }

    return 0;
}
void HID_UpdateKbData(void)
{
    int32_t i;
    uint8_t *buf;
    uint32_t key = 0xF;
    static uint32_t preKey;

    if(g_u8EP5Ready)
    {
        buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5));

        /* If GPB15 = 0, just report it is key 'a' */
        key = (PB->PIN & (1 << 15)) ? 0 : 1;

        if(key == 0)
        {
            for(i = 0; i < 8; i++)
            {
                buf[i] = 0;
            }

            if(key != preKey)
            {
                /* Trigger to note key release */
                USBD_SET_PAYLOAD_LEN(EP5, 8);
            }
        }
        else
        {
            preKey = key;
            buf[2] = 0x04; /* Key A */
            USBD_SET_PAYLOAD_LEN(EP5, 8);
        }
    }
}
Exemplo n.º 10
0
//-------------------------------------------------------------------------
__myevic__ void usbdEP3Handler()
{
    uint8_t *ptr;
    /* Interrupt OUT */
    ptr = (uint8_t *)( USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR( EP3 ) );
    hidGetOutReport( ptr, USBD_GET_PAYLOAD_LEN( EP3 ) );
    USBD_SET_PAYLOAD_LEN( EP3, EP3_MAX_PKT_SIZE );
}
void EP6_Handler(void)  /* Interrupt OUT handler */
{
    uint8_t *ptr;
    /* Interrupt OUT */
    ptr = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP6));
    HID_GetOutReport(ptr, USBD_GET_PAYLOAD_LEN(EP6));
    USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE);
}
/* Receive printer command and data from host */
void PTR_Data_Receive(void)
{
    uint8_t *pu8Buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP3));
    uint32_t u32Size = USBD_GET_PAYLOAD_LEN(EP3);

    /* trigger next OUT data */
    USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
}
void EP3_Handler(void)
{
    /* Bulk OUT */
    gu32RxSize = USBD_GET_PAYLOAD_LEN(EP3);
    gpu8RxBuf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP3));

    /* Set a flag to indicate bulk out ready */
    gi8BulkOutReady = 1;
}
Exemplo n.º 14
0
void CCID_ClassRequest(void)
{
    uint8_t buf[8];

    USBD_GetSetupPacket(buf);

    if (buf[0] & 0x80)   /* request data transfer direction */
    {
        // Device to host
        switch (buf[1])
        {
        case CCID_GET_CLOCK_FREQUENCIES:
        case CCID_GET_DATA_RATES:
        {
            uint8_t pData[1] = {0};
            USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)), pData, sizeof(pData));
            /* Data stage */
            USBD_SET_DATA1(EP0);
            USBD_SET_PAYLOAD_LEN(EP0, sizeof(pData));
            /* Status stage */
            USBD_PrepareCtrlOut(0,0);
            break;
        }
        default:
        {
            /* Setup error, stall the device */
            USBD_SetStall(0);
            break;
        }
        }
    }
    else
    {
        // Host to device
        switch (buf[1])
        {
        case CCID_ABORT:
        {
            /* Status stage */
            USBD_SET_DATA1(EP0);
            USBD_SET_PAYLOAD_LEN(EP0, 0);
            break;
        }
        default:
        {
            // Stall
            /* Setup error, stall the device */
            USBD_SetStall(0);
            break;
        }
        }
    }
}
Exemplo n.º 15
0
//-------------------------------------------------------------------------
__myevic__ void hidStartInReport( uint32_t u32ParamLen )
{
	hidDataIndex = u32ParamLen;
	hidCmd.u32Signature = u32ParamLen;

	USBD_MemCopy(
		(uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)),
		hidInDataPtr,
		EP2_MAX_PKT_SIZE
	);
	USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE );
	hidDataIndex -= EP2_MAX_PKT_SIZE;
}
Exemplo n.º 16
0
void EP4_Handler(void)
{
    /* INT IN transfer */
    if (gu8IsDeviceReady)
    {
        RDR_to_PC_NotifySlotChange();
        USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP4)), pu8IntInBuf, 2);
        USBD_SET_PAYLOAD_LEN(EP4, 2);
        gu8IsDeviceReady = 0;
    }
    if (!gu8IsBulkOutReady)
        USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
}
Exemplo n.º 17
0
/**
  * @brief      Prepare the first Control IN pipe
  *
  * @param[in]  pu8Buf  The pointer of data sent to USB host.
  * @param[in]  u32Size The IN transfer size.
  *
  * @return     None
  *
  * @details    Prepare data for Control IN transfer.
  *
  */
void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size)
{
    DBG_PRINTF("Prepare Ctrl In %d\n", u32Size);
    if(u32Size > g_usbd_CtrlMaxPktSize)
    {
        // Data size > MXPLD
        g_usbd_CtrlInPointer = pu8Buf + g_usbd_CtrlMaxPktSize;
        g_usbd_CtrlInSize = u32Size - g_usbd_CtrlMaxPktSize;
        USBD_SET_DATA1(EP0);
        USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, g_usbd_CtrlMaxPktSize);
        USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
    }
    else
    {
        // Data size <= MXPLD
        g_usbd_CtrlInPointer = 0;
        g_usbd_CtrlInSize = 0;
        USBD_SET_DATA1(EP0);
        USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, u32Size);
        USBD_SET_PAYLOAD_LEN(EP0, u32Size);
    }
}
Exemplo n.º 18
0
void WEAK HID_SendReport(uint8_t id, const void* data, uint32_t len)
{
	uint8_t *p = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2));
	const uint8_t *d = reinterpret_cast<const uint8_t *>(data);

	p[0] = id;
	for (uint32_t i=0; i<len; i++)
		p[i+1] = d[i];
    g_u8EP2Ready = 0;
    /* Set transfer length and trigger IN transfer */
    USBD_SET_PAYLOAD_LEN(EP2, len+1);

	while(!g_u8EP2Ready);
}
Exemplo n.º 19
0
//----- (000025B8) --------------------------------------------------------
__myevic__ uint32_t hidFMCReadCmd( CMD_T *pCmd )
{
	uint32_t u32StartAddr;
	uint32_t u32ParamLen;

	u32StartAddr = pCmd->u32Arg1;
	u32ParamLen  = pCmd->u32Arg2;

	myprintf( "FMC Read command - Start Addr: %d    Param Len: %d\n", pCmd->u32Arg1, pCmd->u32Arg2 );
	
	if ( ! u32ParamLen % EP2_MAX_PKT_SIZE )
	{
		return -1;
	}
	
	if ( u32ParamLen )
	{
		if ( u32ParamLen > FMC_FLASH_PAGE_SIZE )
		{
			u32ParamLen = FMC_FLASH_PAGE_SIZE;
		}

		SYS_UnlockReg();
		FMC_ENABLE_ISP();

		for ( uint32_t i = 0 ; i < u32ParamLen ; i += 4 )
		{
			uint32_t data;
			data = FMC_Read( u32StartAddr + i );
			MemCpy( &hidData[i], &data, 4 );
		}

		FMC_DISABLE_ISP();
		SYS_LockReg();

		hidDataIndex = u32ParamLen;
		pCmd->u32Signature = u32ParamLen;

		USBD_MemCopy(
			(uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)),
			hidData,
			EP2_MAX_PKT_SIZE
		);
		USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE );
		hidDataIndex -= EP2_MAX_PKT_SIZE;
	}

	return 0;
}
void HID_SetInReport(void)
{
    uint32_t u32StartPage;
    uint32_t u32TotalPages;
    uint32_t u32PageCnt;
    uint8_t *ptr;
    uint8_t u8Cmd;

    u8Cmd        = gCmd.u8Cmd;
    u32StartPage = gCmd.u32Arg1;
    u32TotalPages= gCmd.u32Arg2;
    u32PageCnt   = gCmd.u32Signature;

    /* Check if it is in data phase of read command */
    if(u8Cmd == HID_CMD_READ)
    {
        /* Process the data phase of read command */
        if((u32PageCnt >= u32TotalPages) && (g_u32BytesInPageBuf == 0))
        {
            /* The data transfer is complete. */
            u8Cmd = HID_CMD_NONE;
            printf("Read command complete!\n");
        }
        else
        {
            if(g_u32BytesInPageBuf == 0)
            {
                /* The previous page has sent out. Read new page to page buffer */
                /* TODO: We should update new page data here. (0xFF is used in this sample code) */
                printf("Reading page %d\n", u32StartPage + u32PageCnt);
                memcpy(g_u8PageBuff, g_u8TestPages + u32PageCnt * PAGE_SIZE, sizeof(g_u8PageBuff));

                g_u32BytesInPageBuf = PAGE_SIZE;

                /* Update the page counter */
                u32PageCnt++;
            }

            /* Prepare the data for next HID IN transfer */
            ptr = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5));
            USBD_MemCopy(ptr, (void *)&g_u8PageBuff[PAGE_SIZE - g_u32BytesInPageBuf], EP5_MAX_PKT_SIZE);
            USBD_SET_PAYLOAD_LEN(EP5, EP5_MAX_PKT_SIZE);
            g_u32BytesInPageBuf -= EP5_MAX_PKT_SIZE;
        }
    }

    gCmd.u8Cmd        = u8Cmd;
    gCmd.u32Signature = u32PageCnt;
}
Exemplo n.º 21
0
/**
  * @brief    Repeat Control OUT pipe
  *
  * @param    None
  *
  * @return   None
  *
  * @details  This function processes the successive Control OUT transfer.
  *
  */
void USBD_CtrlOut(void)
{
    uint32_t u32Size;

    DBG_PRINTF("Ctrl Out Ack %d\n", g_usbd_CtrlOutSize);
    if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit)
    {
        u32Size = USBD_GET_PAYLOAD_LEN(EP1);
        USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size);
        g_usbd_CtrlOutPointer += u32Size;
        g_usbd_CtrlOutSize += u32Size;

        if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit)
            USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize);

    }
}
Exemplo n.º 22
0
void EP3_Handler(void)
{
    /* BULK OUT */
    static int offset = 0;
    uint32_t len;

    len = USBD_GET_PAYLOAD_LEN(EP3);

    USBD_MemCopy(&UsbMessageBuffer[offset], (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP3)), len);

    if((len >= 0x0A && len != 0xFF) || offset != 0)
    {
        if(offset == 0)
        {
            /* Calculate number of byte to receive to finish the message  */
            gi32UsbdMessageLength = USB_MESSAGE_HEADER_SIZE + make32(&UsbMessageBuffer[OFFSET_DWLENGTH]);
        }

        gi32UsbdMessageLength -= (int) len;
        /* Prepare next reception if whole message not received */
        if(gi32UsbdMessageLength > 0)
        {
            pUsbMessageBuffer = UsbMessageBuffer + len;
            offset += len;
        }

        if(gi32UsbdMessageLength == 0)
        {
            gu8IsBulkOutReady = 1;
            offset = 0;
        }
        if(gi32UsbdMessageLength < 0)
        {
            UsbMessageBuffer[OFFSET_DWLENGTH] = 0xFF;
            UsbMessageBuffer[OFFSET_DWLENGTH+1] = 0xFF;
            UsbMessageBuffer[OFFSET_DWLENGTH+2] = 0xFF;
            UsbMessageBuffer[OFFSET_DWLENGTH+3] = 0xFF;
            gu8IsBulkOutReady = 1;
        }
    }
    CCID_DispatchMessage();

    /* trigger next out packet */
    if (gi32UsbdMessageLength > 0)
        USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
}
Exemplo n.º 23
0
/**
  * @brief  USBD Endpoint Config.
  * @param  None.
  * @retval None.
  */
void CCID_Init(void)
{
    /* Init setup packet buffer */
    /* Buffer for setup packet -> [0 ~ 0x7] */
    USBD->BUFSEG = SETUP_BUF_BASE;

    /*****************************************************/
    /* EP0 ==> control IN endpoint, address 0 */
    USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0);
    /* Buffer range for EP0 */
    USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE);

    /* EP1 ==> control OUT endpoint, address 0 */
    USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0);
    /* Buffer range for EP1 */
    USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE);

    /*****************************************************/
    /* EP2 ==> Bulk IN endpoint, address 2 */
    USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | BULK_IN_EP_NUM);
    /* Buffer offset for EP2 */
    USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE);

    /* EP3 ==> Bulk Out endpoint, address 2 */
    USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | BULK_OUT_EP_NUM);
    /* Buffer offset for EP3 */
    USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE);
    /* trigger receive OUT data */
    USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);

    /* EP4 ==> Interrupt IN endpoint, address 3 */
    USBD_CONFIG_EP(EP4, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM);
    /* Buffer offset for EP4 ->  */
    USBD_SET_EP_BUF_ADDR(EP4, EP4_BUF_BASE);

    /* check card state */
    gu8IsDeviceReady = 1;
    pu8IntInBuf = &UsbIntMessageBuffer[0];
    pUsbMessageBuffer = &UsbMessageBuffer[0];
    RDR_to_PC_NotifySlotChange();
    USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP4)), pu8IntInBuf, 2);
    USBD_SET_PAYLOAD_LEN(EP4, 2);
}
Exemplo n.º 24
0
void USB_Write(const uint8_t *buf,int len)
{
	barrier();
	gi8BulkInReady = 0;
	barrier();
	USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), (uint8_t *)buf, len);
	barrier();
	USBD_SET_PAYLOAD_LEN(EP2, len);
	barrier();
	while(gi8BulkInReady == 0) barrier();;
	gi8BulkInReady = 0;
	barrier();
	/*
	if(len <8)
		delay(4);
	else
		delay(len/4);
	
	*/
}
Exemplo n.º 25
0
void MSC_RequestSense(void)
{
    uint8_t tmp[20];

    memset(tmp, 0, 18);
    if (g_u8Prevent)
    {
        g_u8Prevent = 0;
        tmp[0]= 0x70;
    }
    else
        tmp[0] = 0xf0;

    tmp[2] = g_au8SenseKey[0];
    tmp[7] = 0x0a;
    tmp[12] = g_au8SenseKey[1];
    tmp[13] = g_au8SenseKey[2];
    USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), tmp, 20);

    g_au8SenseKey[0] = 0;
    g_au8SenseKey[1] = 0;
    g_au8SenseKey[2] = 0;
}
Exemplo n.º 26
0
void MSC_ClassRequest(void)
{
    uint8_t buf[8];

    USBD_GetSetupPacket(buf);

    if (buf[0] & 0x80)   /* request data transfer direction */
    {
        // Device to host
        switch (buf[1])
        {
        case GET_MAX_LUN:
        {
            /* Check interface number with cfg descriptor and check wValue = 0, wLength = 1 */
            if ((((buf[3]<<8)+buf[2]) == 0) && (((buf[5]<<8)+buf[4]) == 0) && (((buf[7]<<8)+buf[6]) == 1))
            {
                M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0;
                /* Data stage */
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 1);
                /* Status stage */
                USBD_PrepareCtrlOut(0,0);
            }
            else     /* Invalid Get MaxLun command */
            {
                USBD_SetStall(0);
            }
            break;
        }
        default:
        {
            /* Setup error, stall the device */
            USBD_SetStall(0);
            break;
        }
        }
    }
    else
    {
        // Host to device
        switch (buf[1])
        {
        case BULK_ONLY_MASS_STORAGE_RESET:
        {
            /* Check interface number with cfg descriptor and check wValue = 0, wLength = 0 */
            if ((((buf[3]<<8)+buf[2]) == 0) && (((buf[5]<<8)+buf[4]) == 0) && (((buf[7]<<8)+buf[6]) == 0))
            {
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 0);

                USBD_LockEpStall(0);

                /* Clear ready */
                USBD->EP[EP2].CFG |= USBD_CFG_CLRRDY_Msk;
                USBD->EP[EP3].CFG |= USBD_CFG_CLRRDY_Msk;

                /* Prepare to receive the CBW */
                g_u8EP3Ready = 0;
                g_u8BulkState = BULK_CBW;

                USBD_SET_DATA1(EP3);
                USBD_SET_EP_BUF_ADDR(EP3, g_u32BulkBuf0);
                USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
            }
            else     /* Invalid Reset command */
            {
                USBD_SetStall(0);
            }
            break;
        }
        default:
        {
            // Stall
            /* Setup error, stall the device */
            USBD_SetStall(0);
            break;
        }
        }
    }
}
Exemplo n.º 27
0
//----- (00002C60) --------------------------------------------------------
__myevic__ void hidSetInReport()
{
	uint8_t cmd = hidCmd.u8Cmd;

	switch ( cmd )
	{
		case HID_CMD_GETINFO:
		case HID_CMD_SCREENSHOT:
		{
			if ( hidDataIndex )
			{
				USBD_MemCopy(
					(uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)),
					&hidInDataPtr[hidCmd.u32Signature - hidDataIndex],
					EP2_MAX_PKT_SIZE
				);
				USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE );
				hidDataIndex -= EP2_MAX_PKT_SIZE;
			}
			else
			{
				cmd = HID_CMD_NONE;
			}
			break;
		}

		case HID_CMD_FMCREAD:
		{
			if ( !hidDataIndex )
			{
				uint32_t u32Addr = hidCmd.u32Arg1 + hidCmd.u32Signature;
				int32_t  u32Size = hidCmd.u32Arg2 - hidCmd.u32Signature;
				if ( u32Size > 0 )
				{
					if ( u32Size > FMC_FLASH_PAGE_SIZE ) u32Size = FMC_FLASH_PAGE_SIZE;

					SYS_UnlockReg();
					FMC_ENABLE_ISP();

					for ( int i = 0 ; i < u32Size ; i += 4 )
					{
						uint32_t data = FMC_Read( u32Addr + i );
						MemCpy( &hidData[ FMC_FLASH_PAGE_SIZE - u32Size + i ], &data, 4 );
					}

					FMC_DISABLE_ISP();
					SYS_LockReg();

					hidDataIndex = u32Size;
					hidCmd.u32Signature += u32Size;
				}
			}
			if ( hidDataIndex )
			{
				USBD_MemCopy(
					(uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)),
					&hidData[ FMC_FLASH_PAGE_SIZE - hidDataIndex ],
					EP2_MAX_PKT_SIZE
				);
				USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE );
				hidDataIndex -= EP2_MAX_PKT_SIZE;
			}
			else
			{
				cmd = HID_CMD_NONE;
			}
			break;
		}

		default:
			cmd = HID_CMD_NONE;
			break;
	}

	hidCmd.u8Cmd = cmd;
}
void HID_ClassRequest(void)
{
    uint8_t buf[8];

    USBD_GetSetupPacket(buf);

    if (buf[0] & 0x80)   /* request data transfer direction */
    {
        // Device to host
        switch (buf[1])
        {
        case GET_LINE_CODE:
        {
            if (buf[4] == 0)   /* VCOM-1 */
            {
                USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)), (uint8_t *)&gLineCoding, 7);
            }
            /* Data stage */
            USBD_SET_DATA1(EP0);
            USBD_SET_PAYLOAD_LEN(EP0, 7);
            /* Status stage */
            USBD_PrepareCtrlOut(0,0);
            break;
        }
        case GET_REPORT:
        case GET_IDLE:
        case GET_PROTOCOL:
        default:
        {
            /* Setup error, stall the device */
            USBD_SetStall(0);
            break;
        }
        }
    }
    else
    {
        // Host to device
        switch (buf[1])
        {
        case SET_CONTROL_LINE_STATE:
        {
            if (buf[4] == 0)   /* VCOM-1 */
            {
                gCtrlSignal = buf[3];
                gCtrlSignal = (gCtrlSignal << 8) | buf[2];
                //printf("RTS=%d  DTR=%d\n", (gCtrlSignal0 >> 1) & 1, gCtrlSignal0 & 1);
            }

            /* Status stage */
            USBD_SET_DATA1(EP0);
            USBD_SET_PAYLOAD_LEN(EP0, 0);
            break;
        }
        case SET_LINE_CODE:
        {
            //g_usbd_UsbConfig = 0100;
            if (buf[4] == 0) /* VCOM-1 */
                USBD_PrepareCtrlOut((uint8_t *)&gLineCoding, 7);

            /* Status stage */
            USBD_SET_DATA1(EP0);
            USBD_SET_PAYLOAD_LEN(EP0, 0);

//                 /* UART setting */
//                 if (buf[4] == 0) /* VCOM-1 */
//                     VCOM_LineCoding(0);
            break;
        }
        case SET_REPORT:
        {
            if(buf[3] == 2)
            {
                /* Request Type = Output */
                USBD_SET_DATA1(EP1);
                USBD_SET_PAYLOAD_LEN(EP1, buf[6]);

                /* Trigger for HID Int in */
                USBD_SET_PAYLOAD_LEN(EP5, 0);

                /* Status stage */
                USBD_PrepareCtrlIn(0, 0);
            }
            break;
        }
        case SET_IDLE:
        {
            /* Status stage */
            USBD_SET_DATA1(EP0);
            USBD_SET_PAYLOAD_LEN(EP0, 0);
            break;
        }
        case SET_PROTOCOL:
        default:
        {
            // Stall
            /* Setup error, stall the device */
            USBD_SetStall(0);
            break;
        }
        }
    }
}
Exemplo n.º 29
0
void VCOM_TransferData(void)
{
    int32_t i, i32Len;

    /* Check wether USB is ready for next packet or not*/
    if(gu32TxSize == 0)
    {
        /* Check wether we have new COM Rx data to send to USB or not */
        if(comRbytes)
        {
            i32Len = comRbytes;
            if(i32Len > EP2_MAX_PKT_SIZE)
                i32Len = EP2_MAX_PKT_SIZE;

            for(i = 0; i < i32Len; i++)
            {
                gRxBuf[i] = comRbuf[comRhead++];
                if(comRhead >= RXBUFSIZE)
                    comRhead = 0;
            }

            __set_PRIMASK(1);
            comRbytes -= i32Len;
            __set_PRIMASK(0);

            gu32TxSize = i32Len;
            USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), (uint8_t *)gRxBuf, i32Len);
            USBD_SET_PAYLOAD_LEN(EP2, i32Len);
        }
        else
        {
            /* Prepare a zero packet if previous packet size is EP2_MAX_PKT_SIZE and
               no more data to send at this moment to note Host the transfer has been done */
            i32Len = USBD_GET_PAYLOAD_LEN(EP2);
            if(i32Len == EP2_MAX_PKT_SIZE)
                USBD_SET_PAYLOAD_LEN(EP2, 0);
        }
    }

    /* Process the Bulk out data when bulk out data is ready. */
    if(gi8BulkOutReady && (gu32RxSize <= TXBUFSIZE - comTbytes))
    {
        for(i = 0; i < gu32RxSize; i++)
        {
            comTbuf[comTtail++] = gpu8RxBuf[i];
            if(comTtail >= TXBUFSIZE)
                comTtail = 0;
        }

        __set_PRIMASK(1);
        comTbytes += gu32RxSize;
        __set_PRIMASK(0);

        gu32RxSize = 0;
        gi8BulkOutReady = 0; /* Clear bulk out ready flag */

        /* Ready to get next BULK out */
        USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
    }

    /* Process the software Tx FIFO */
    if(comTbytes)
    {
        /* Check if Tx is working */
        if((UART0->IER & UART_IER_THRE_IE_Msk) == 0)
        {
            /* Send one bytes out */
            UART0->THR = comTbuf[comThead++];
            if(comThead >= TXBUFSIZE)
                comThead = 0;

            __set_PRIMASK(1);
            comTbytes--;
            __set_PRIMASK(0);

            /* Enable Tx Empty Interrupt. (Trigger first one) */
            UART0->IER |= UART_IER_THRE_IE_Msk;
        }
    }
}
Exemplo n.º 30
0
/**
  * @brief    Process standard request
  *
  * @param    None
  *
  * @return   None
  *
  * @details  Parse standard request and perform the corresponding action.
  *
  */
void USBD_StandardRequest(void)
{
    /* clear global variables for new request */
    g_usbd_CtrlInPointer = 0;
    g_usbd_CtrlInSize = 0;

    if(g_usbd_SetupPacket[0] & 0x80)    /* request data transfer direction */
    {
        // Device to host
        switch(g_usbd_SetupPacket[1])
        {
            case GET_CONFIGURATION:
            {
                // Return current configuration setting
                /* Data stage */
                M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig;
                USBD_SET_DATA1(EP1);
                USBD_SET_PAYLOAD_LEN(EP1, 0);
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 1);
                /* Status stage */
                USBD_PrepareCtrlOut(0, 0);
                DBG_PRINTF("Get configuration\n");
                break;
            }
            case GET_DESCRIPTOR:
            {
                USBD_GetDescriptor();
                break;
            }
            case GET_INTERFACE:
            {
                // Return current interface setting
                /* Data stage */
                M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbAltInterface;
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 1);
                /* Status stage */
                USBD_PrepareCtrlOut(0, 0);
                DBG_PRINTF("Get interface\n");
                break;
            }
            case GET_STATUS:
            {
                // Device
                if(g_usbd_SetupPacket[0] == 0x80)
                {
                    uint8_t u8Tmp;

                    u8Tmp = 0;
                    if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x40) u8Tmp |= 1; // Self-Powered/Bus-Powered.
                    if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x20) u8Tmp |= (g_usbd_RemoteWakeupEn << 1); // Remote wake up

                    M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp;

                }
                // Interface
                else if(g_usbd_SetupPacket[0] == 0x81)
                    M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0;
                // Endpoint
                else if(g_usbd_SetupPacket[0] == 0x82)
                {
                    uint8_t ep = g_usbd_SetupPacket[4] & 0xF;
                    M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = USBD_GetStall(ep) ? 1 : 0;
                }

                M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = 0;
                /* Data stage */
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 2);
                /* Status stage */
                USBD_PrepareCtrlOut(0, 0);
                DBG_PRINTF("Get status\n");
                break;
            }
            default:
            {
                /* Setup error, stall the device */
                USBD_SET_EP_STALL(EP0);
                USBD_SET_EP_STALL(EP1);
                DBG_PRINTF("Unknown request. stall ctrl pipe.\n");
                break;
            }
        }
    }
    else
    {
        // Host to device
        switch(g_usbd_SetupPacket[1])
        {
            case CLEAR_FEATURE:
            {
                if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT)
                {
                    int32_t epNum, i;

                    /* EP number stall is not allow to be clear in MSC class "Error Recovery Test".
                       a flag: g_u32EpStallLock is added to support it */
                    epNum = g_usbd_SetupPacket[4] & 0xF;
                    for(i = 0; i < USBD_MAX_EP; i++)
                    {
                        if(((USBD->EP[i].CFG & 0xF) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0))
                        {
                            USBD->EP[i].CFGP &= ~USBD_CFGP_SSTALL_Msk;
                            DBG_PRINTF("Clr stall ep%d %x\n",i, USBD->EP[i].CFGP);
                        }
                    }
                }
                else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
                    g_usbd_RemoteWakeupEn = 0;

                /* Status stage */
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 0);
                DBG_PRINTF("Clear feature op %d\n", g_usbd_SetupPacket[2]);
                break;
            }
            case SET_ADDRESS:
            {
                g_usbd_UsbAddr = g_usbd_SetupPacket[2];
                DBG_PRINTF("Set addr to %d\n", g_usbd_UsbAddr);

                // DATA IN for end of setup
                /* Status Stage */
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 0);
                break;
            }
            case SET_CONFIGURATION:
            {
                g_usbd_UsbConfig = g_usbd_SetupPacket[2];

                if(g_usbd_pfnSetConfigCallback)
                    g_usbd_pfnSetConfigCallback();
                // DATA IN for end of setup
                /* Status stage */
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 0);
                DBG_PRINTF("Set config to %d\n", g_usbd_UsbConfig);
                break;
            }
            case SET_FEATURE:
            {
                if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT)
                {
                    USBD_SetStall(g_usbd_SetupPacket[4] & 0xF);
                    DBG_PRINTF("Set feature. stall ep %d\n", g_usbd_SetupPacket[4] & 0xF);                    
                }
                else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
                {
                    g_usbd_RemoteWakeupEn = 1;
                    DBG_PRINTF("Set feature. enable remote wakeup\n");
                }

                /* Status stage */
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 0);
                break;
            }
            case SET_INTERFACE:
            {
                g_usbd_UsbAltInterface = g_usbd_SetupPacket[2];
                if(g_usbd_pfnSetInterface != NULL)
                    g_usbd_pfnSetInterface();
                /* Status stage */
                USBD_SET_DATA1(EP0);
                USBD_SET_PAYLOAD_LEN(EP0, 0);
                DBG_PRINTF("Set interface to %d\n", g_usbd_UsbAltInterface);
                break;
            }
            default:
            {
                /* Setup error, stall the device */
                USBD_SET_EP_STALL(EP0);
                USBD_SET_EP_STALL(EP1);
                DBG_PRINTF("Unsupported request. stall ctrl pipe.\n");
                break;
            }
        }
    }
}