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

📄 usb.c

📁 Texas Instruments的TUSB3210和TUSB2136芯片接键盘输入的固件程序源码和驱动程序源码。
💻 C
📖 第 1 页 / 共 4 页
字号:
    	// If the packet we received include more data than we expected, we ignore
    	// the entire packet and abort the transfer.  This is accomplished by
    	// stalling OEP0 and resetting the bStatusAction condition to "Nothing."
        usbStallOEP0;
        bStatusAction = STATUS_ACTION_NOTHING;
    	}
}

/***************************************************************************
 * Function:   usbSendZeroLengthPacketOnIEP0()                             *
 * Programmer: Lobo Tai (lobotai@ti.com)                                   *
 * Description: Sends a 0-lengthg packet back to the host on IEP0. Often   *
 *    called to acknowledge a packet received from the host that requires  *
 *    no data in the reply, just an acknowledgement of receipt.            *
 ***************************************************************************/

void usbSendZeroLengthPacketOnIEP0(void)
{
    wBytesRemainingOnIEP0 = NO_MORE_DATA;
    bStatusAction = STATUS_ACTION_NOTHING;
    tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;
}

/***************************************************************************
 * Function:   usbSendDataPacketOnEPO / SendNext                           *
 * Programmer: Lobo Tai (lobotai@ti.com)                                   *
 * Description: These two functions, together, are responsible for sending *
 *    data packets back to the host on IEPO.  The transfer is initiated by *
 *    first calling usbSendDataPacketOnEP0 and indicating the address of   *
 *    the buffer to send.  This initiates the transfer and sends the first *
 *    packet of data.  If there is more data than can be sent in the first *
 *    packet, the usbSendNextPacketOnIEP0 function is called to send       *
 *    subsequent packets of data when an interrupt indicates the previous  *
 *    packet has been sent.                                                *
 ***************************************************************************/

void usbSendDataPacketOnEP0(PBYTE pbBuffer)
{
    WORD wTemp;

    pbIEP0Buffer = pbBuffer;

    wTemp = (WORD)(tSetupPacket.bLengthH << 8) | (WORD)tSetupPacket.bLengthL;

    // Limit transfer size to wLength if needed
    // this prevent USB device sending 'more than require' data back to host
    if(wBytesRemainingOnIEP0 >= wTemp)
    	{
        wBytesRemainingOnIEP0 = wTemp;
        bHostAskMoreDataThanAvailable = FALSE;
        }
	else
		{ 
		bHostAskMoreDataThanAvailable = TRUE;
		}

    usbSendNextPacketOnIEP0();
}

void usbSendNextPacketOnIEP0(void)
{
    BYTE bPacketSize,bIndex;

    // First check if there are bytes remaining to be transferred
    if(wBytesRemainingOnIEP0 != NO_MORE_DATA)
    	{
        if(wBytesRemainingOnIEP0 > EP0_MAX_PACKET_SIZE)
        	{
            // More bytes are remaining than will fit in one packet
            // there will be More IN Stage
            bPacketSize = EP0_MAX_PACKET_SIZE;
            wBytesRemainingOnIEP0 -= EP0_MAX_PACKET_SIZE;
            bStatusAction = STATUS_ACTION_DATA_IN;
        	}
        else if (wBytesRemainingOnIEP0 < EP0_MAX_PACKET_SIZE)
        	{
            // The remaining data will fit in one packet.
            // This case will properly handle wBytesRemainingOnIEP0 == 0
            bPacketSize = (BYTE)wBytesRemainingOnIEP0;
            wBytesRemainingOnIEP0 = NO_MORE_DATA;        // No more data need to be Txed
            bStatusAction = STATUS_ACTION_NOTHING;
        	}
        else
        	{
            // wBytesRemainingOnIEP0 == EP0_MAX_PACKET_SIZE
            bPacketSize = EP0_MAX_PACKET_SIZE;
            if(bHostAskMoreDataThanAvailable == TRUE)
            	{
                wBytesRemainingOnIEP0 = 0;
                bStatusAction = STATUS_ACTION_DATA_IN;
            	}
            else
            	{ 
                wBytesRemainingOnIEP0 = NO_MORE_DATA;
                bStatusAction = STATUS_ACTION_NOTHING;
            	}
        	}

        for(bIndex=0; bIndex<bPacketSize; bIndex++) 
            abIEP0Buffer[bIndex] = *pbIEP0Buffer++;

        tEndPoint0DescriptorBlock.bIEPBCNT = bPacketSize;   // & EPBCT_BYTECNT_MASK;
	  	}
    else
    	{
    	bStatusAction = STATUS_ACTION_NOTHING;
    	}
}

/***************************************************************************
 * Function:   SetupPacketInterruptHandler()                               *
 * Programmer: Lobo Tai (lobotai@ti.com)                                   *
 * Description: This function is called by the UsbInterrupt function when  *
 *    a setup packet is received.  This function immediately sets both     * 
 *    OEP0 and IEP0 to a NAK state, sets the bUSBCTL to send/receive based *
 *    on the direction of the request, then proceeds to call  the          *
 *    usbDecodeAndProcessUsbRequest() function which determines which      *
 *    function should be called to handle the given USB request.           *  
 ***************************************************************************/

void SetupPacketInterruptHandler(void)
{
    // Hardware clears STALL in both data endpoints once valid setup packet is
    // received.  NAK both data endpoints.
    tEndPoint0DescriptorBlock.bIEPBCNT  = EPBCNT_NAK;
    tEndPoint0DescriptorBlock.bOEPBCNT  = EPBCNT_NAK;
    
    bUSBSTA = USBSTA_SETUP; // from now, hardware will refer NAK bit in I/OEPBCNT

    // Copy the MSB of bmRequestType to DIR bit of USBCTL to indicate the
    // direction of the transfer.
    if((tSetupPacket.bmRequestType & USB_REQ_TYPE_INPUT) == USB_REQ_TYPE_INPUT)
        bUSBCTL |= USBCTL_DIR;
    else 
    	bUSBCTL &= ~USBCTL_DIR;

	// Clear the bStatusAction to indicate that, at this point, nothing is 
	// happening (it may be set to DATA_OUT by specific functions that
	// expect a DATA packet following the setup packet).
    bStatusAction = STATUS_ACTION_NOTHING;

	// Call the function that determines which function should be called to
	// handle the specific USB request.
    usbDecodeAndProcessUsbRequest();
}

/***************************************************************************
 * Function:   OEP0InterruptHandler()                                      *
 * Programmer: Lobo Tai (lobotai@ti.com)                                   *
 * Description: This function is called by the UsbInterrupt function when  *
 *    a USB interrupt is called by OEP0.  This will happen once a data     *
 *    transfer has been initialized by a USB function handler by calling   *
 *    usbReceiveDataPacketOnEP0.                                           *
 ***************************************************************************/

void OEP0InterruptHandler(void)
{
	// We clear the IEP0 byte count since we have nothing to send out.
    tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;

	// We now handle the interrupt based on the bStatusAction condition.
	// If we are in a DATA_OUT condition, we call the usbReceiveNextPacketOnEP0
	// function to copy the data payload to its correct buffer.  If we are
	// not expecting any data on OEP0, we set the stall flag to stall the
	// endpoint and abort any additional data that may otherwise be
	// sent.
    if(bStatusAction == STATUS_ACTION_DATA_OUT) 
    	usbReceiveNextPacketOnOEP0(); // Handle this data packet
    else 
    	tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL; // We weren't expecting data
}

/***************************************************************************
 * Function:   IEP0InterruptHandler()                                      *
 * Programmer: Lobo Tai (lobotai@ti.com)                                   *
 * Description: This function is called by the UsbInterrupt function when  *
 *    a USB interrupt is caused by IEP0.  This will happen once the data   *
 *    sent by calling usbSendNextPacketOnIEP0 and means the previous data  *
 *    packet has been sent.  At that point, there are two conditions:      *
 *    either there is more data to send or there isn't.  If there is, we   *
 *    call usbSendNextPacketOnIEP0 to send the next packet of data.  If    *
 *    there isn't anymore data, we stall.  However, if the bStatusAction   *
 *    condition indicates that we were changing the devices address, we    *
 *    do so at this point.                                                 *
 ***************************************************************************/

void IEP0InterruptHandler(void)
{
	// We clear the OEP0 byte count since we are not expecting any data.
    tEndPoint0DescriptorBlock.bOEPBCNT = 0x00;

	// We now handle the interrupt based on the bStatusAction condition.
	// If we are in a DATA_IN condition, we call the usbSendNextPacketOnIEP0  
	// function to send the next data payload packet.  If we are in a
	// Set Address mode, we modify the address.  In any other case, we've
	// sent all teh data we had to send, so we stall the endpoint to indicate
	// there is no more data to send.
    if(bStatusAction == STATUS_ACTION_DATA_IN) 
    	usbSendNextPacketOnIEP0(); // Send the next data packet
    else if(bStatusAction == STATUS_ACTION_SET_ADDRESS) 
    	bFUNADR = bUsbDeviceAddress; // Set the device's address
    else 
    	tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL; // No more data to send
}

/***************************************************************************
 * Function:   USBInterrupt                                                *
 * Programmer: Craig Steiner (csteiner@vaultbbs.com)                       *
 * Description: Handles the USB interrupts generated by the USB sectiob of *
 *    the part.  This is actually External 0 interrupt on the 8051 at      *
 *    0x0003 in memory, but is used exclusively for USB interrupts on the  *
 *    TUSB2136.                                                            * 
 *                                                                         * 
 * Note: VECINT is cleared after being handled successfully so that the    * 
 *       next USB-related interrupt is made available to the handler.      *  
 ***************************************************************************/

interrupt [0x0003] void USBInterrupt(void)
{
	// Disable all interrupts because this is critical code
	EA = DISABLE;

	// Select the appropriate interrupt handler depending on the VECINT value
    switch (bVECINT)
    	{
		case VECINT_OUTPUT_ENDPOINT0:
			bVECINT  = 0x00;
			OEP0InterruptHandler();
			break;

        case VECINT_INPUT_ENDPOINT0:
			bVECINT  = 0x00;
			IEP0InterruptHandler();
			break;

		case VECINT_INPUT_ENDPOINT1:
		case 0x12:
			bVECINT = 0x00;
			IEP1InterruptHandler();
			break;

        case VECINT_STPOW_PACKET_RECEIVED:
			bVECINT  = 0x00;
			bUSBSTA = USBSTA_STPOW;
			SetupPacketInterruptHandler();
			break;

        case VECINT_SETUP_PACKET_RECEIVED:
        // hardware will NAK data stage, no matter NAK bit in I/OEPBCNT

			bVECINT  = 0x00;
//			bUSBSTA = USBSTA_SETUP; // from now, hardware will refer NAK bit in I/OEPBCNT
			SetupPacketInterruptHandler();
			break;

        case VECINT_RSTR_INTERRUPT:
			bVECINT  = 0x00;
			bUSBSTA = USBSTA_RSTR;
			UsbReset();
			break;
		
		case VECINT_RESR_INTERRUPT:
			bVECINT = 0x00;
			bUSBSTA = USBSTA_RESR;
			bSuspended = FALSE;
			break;
		
		case VECINT_SUSR_INTERRUPT:
			bVECINT = 0x00;
			bUSBSTA = USBSTA_SUSR;
			bSuspended = TRUE;
			break;

		default:
			bVECINT  = 0x00;
			break;
		}

	// End of ciritical code section, reenable interrupts
    EA = ENABLE;
}

interrupt [0x0013] void P33Interrupt(void)
{
	// Disable all interrupts because this is critical code

	bUSBCTL |= USBCTL_RWUP;
	bSuspended = FALSE;
}

⌨️ 快捷键说明

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