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

📄 upsd_usb.c

📁 upsd 3200序列的usb驱动
💻 C
字号:
/////////////////////////////////////////////////////////////////////////////
// upsd_usb.c
//
// USB driver module for uPSD3000 chip.
//
// Author: Jon Moore
//
// Revision History:
//
// 07/22/02 (JAM) Initial coding.
// 01/21/03 (JAM) V1.0.7 - Fixed '0 length packet' bug.

/*---------------------------------------------------------------------------
Copyright (c) 2002 ST Microelectronics
This example demo code is provided as is and has no warranty,
implied or otherwise.  You are free to use/modify any of the provided
code at your own risk in your applications with the expressed limitation
of liability (see below) so long as your product using the code contains
at least one uPSD products (device).

LIMITATION OF LIABILITY:   NEITHER STMicroelectronics NOR ITS VENDORS OR 
AGENTS SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
--------------------------------------------------------------------------*/

#include "general.h"
#include "upsd3200.h"
#include "upsd_xreg.h"
#include "upsd_usb.h"

//-- Variables ---------------------------------------------------------------

#define HID_DEVICE 1

// Constant Variables for USB configuration
extern const uchar code cUSCL_value;

// Constant Variables for USB Descriptors
extern const device_descriptor code deviceDesc;
extern const configuration_descriptor code configDesc;
extern const uchar code string0Desc[];
extern const uchar code string1Desc[];
extern const uchar code string2Desc[];
extern const uchar * const code stringDescTable[];

#if HID_DEVICE
extern const uchar code hidClassDesc[];
extern const uchar code hidClassDescSize;
extern const uchar code reportDesc[];
extern const uchar code reportDescSize;
#endif

volatile uchar idata usbState;

volatile uchar idata SuspendCounter;

setup_buffer setupPacket;

static uchar* pTransmitBufferEP0;
static int    bytesToTransmitEP0;
static BOOL   shortTransfer;

extern void OnDeviceConfigured();

/////////////////// UsbInitialize()
//
// USB driver module initialization routine.

void UsbInitialize() 
{
	pTransmitBufferEP0 = NULL;
	bytesToTransmitEP0 = 0;

    // Set USB clock prescaler
	USCL = cUSCL_value;

	// Reset EP0 and arm it for receiving only
	UCON0 = uTX0E | uRX0E | 8;
	UCON0 = uRX0E | 8;

    // Enable ep1
    UCON2 = uEP1E | uEP2E;
	UCON1 = uTX1E | 8;
	UDT1 = 0xBA;
	UDT1 = 0xBE;
	UCON1 = uTX1E | 2;

	// Enable all USB interrupts except uMCUR (MCU reset on USB reset)
	UIEN = ~uMCUR;

    // Enable USB with default address 0
    UADR = uUSBEN + 0;

    // Enable USB interrupts
    UISTA = 0;
    IEA |= bEUSB;
}

/////////////////// OnClearFeature()
//
// Handler for CLEAR_FEATURE control requests.

static void OnClearFeature()
{
    // No features currently implemented, so stall EP0
    // UCON0 |= uSTALL0; problems, so try 0 length packet instead
    UCON0 = uTSEQ0 | uRX0E | uTX0E;
}

/////////////////// OnSetAddress()
//
// Handler for SET_ADDRESS SETUP packets.

static void OnSetAddress()
{
	// Send back 0 length DATA1 packet
	UCON0 = uTSEQ0 | uRX0E | uTX0E;
}

/////////////////// OnSetConfiguration()
//
// Handler for SET_CONFIGURATION SETUP requests.

static void OnSetConfiguration()
{
    if (setupPacket.wValue.lo > 0)
    {
        usbState = US_CONFIGURED;
		OnDeviceConfigured();
    }
    else
    {
        usbState = US_ADDRESSED;
    }

	// Send back 0 length DATA1 packet
	UCON0 = uTSEQ0 | uRX0E | uTX0E;
}

/////////////////// TransmitBufferEP0()
//
// Transmits next segment of descriptor buffer (pTransmitBufferEP0).

static BOOL TransmitBufferEP0()
{
    int i;
    int nBytes;

    // If there is data going out...
    if (pTransmitBufferEP0)
    {
        // If data has already been sent...
        if (!bytesToTransmitEP0)
        {
            // Transmit 0 length packet
            UCON0 = ((UCON0 ^ uTSEQ0) & uTSEQ0) | uRX0E | uTX0E;
            pTransmitBufferEP0 = NULL;
        }
        else
        {
            // Transmit next chunk of data
            nBytes = bytesToTransmitEP0;
            if (nBytes > 8)
                nBytes = 8;
    
            UCON0 = ((UCON0 ^ uTSEQ0) & uTSEQ0) | uRX0E | uTX0E | nBytes;
            for (i = 0; i < nBytes; i++)
            {
                UDT0 = *pTransmitBufferEP0++;
            }
    
            if ((bytesToTransmitEP0 -= nBytes) == 0)
            {
                // For short transfers, we need a 0 length terminator 
                if (!shortTransfer || (nBytes < 8))
                {
                    pTransmitBufferEP0 = NULL;
                }
            }
        }
        return TRUE;
    }

    // No descriptor data going out
    UCON0 = uTSEQ0 | uRX0E;
    return FALSE;
}

/////////////////// TransmitDataEP0()
//
// Load and arm EP0 to transmit data.

void TransmitDataEP0(uchar* pData, int nBytes)
{
    if (nBytes > EP0_SIZE)
        nBytes = EP0_SIZE;

    UCON0 = ((UCON0 ^ uTSEQ0) & uTSEQ0) | uRX0E | uTX0E | nBytes;
    while (nBytes--)
    {
        UDT0 = *pData++;
    }
}

/////////////////// TransmitDataEPx()
//
// Loads and arms EP1 or EP2 transmit FIFO.

void TransmitDataEPx(int x, uchar* pData, int nBytes)
{
    int i;

    // Reset FIFO
    UCON1 |= (uTX1E | 8);

    if ((x == 1) && (nBytes > 8))
    {
        nBytes = 8;
    }
    else if ((x == 2) && (nBytes > 8))
    {
        nBytes = 8;
    }    

    // Load data
    for (i = 0; i < nBytes; i++)
    {
    	UDT1 = *pData++;
    }

    // Arm endpoint
    UCON1 = ((UCON1 ^ uTSEQ1) & uTSEQ1) 
        | uTX1E | ((x == 2) ? uEP12SEL : 0) | nBytes;
}

/////////////////// OnGetDescriptor()

static void OnGetDescriptor()
{
    int bytesRequested;

    switch (setupPacket.wValue.hi)
    {
    case DT_DEVICE:
	    pTransmitBufferEP0 = (uchar*) &deviceDesc;
	    bytesToTransmitEP0 = sizeof(deviceDesc);
        break;
    case DT_CONFIGURATION:
	    pTransmitBufferEP0 = (uchar*) &configDesc;
	    bytesToTransmitEP0 = configDesc.wTotalLength.lo;
        break;
    case DT_STRING:
	    pTransmitBufferEP0 = (uchar*) stringDescTable[setupPacket.wValue.lo];
	    bytesToTransmitEP0 = *pTransmitBufferEP0;
        break;
#if HID_DEVICE
    case DT_HID_CLASS:
	    pTransmitBufferEP0 = (uchar*) &hidClassDesc;
	    bytesToTransmitEP0 = hidClassDescSize;
		break;
	case DT_HID_REPORT:
	    pTransmitBufferEP0 = (uchar*) &reportDesc;
	    bytesToTransmitEP0 = reportDescSize;
		break;
#endif
    default:
        // Unrecognized descriptor, so stall EP0
        // UCON0 |= uSTALL0; - problems, so try 0 length packet instead
        UCON0 = uTSEQ0 | uRX0E | uTX0E;
        return;
    }

    bytesRequested = (setupPacket.wLength.hi << 8) | setupPacket.wLength.lo;
    shortTransfer = (bytesToTransmitEP0 < bytesRequested);
    if (bytesToTransmitEP0 > bytesRequested)
	{
		bytesToTransmitEP0 = bytesRequested;
	}

    // TransmitDataEP0 will toggle sequence bit to DATA1
    UCON0 &= ~uTSEQ0;
    TransmitBufferEP0();
}

/////////////////// ReadSetupPacket()
//
// Reads a setup packet from EP0.
//
// Returns TRUE if successful; stalls the endpoint and returns
// FALSE on an invalid packet size.

BOOL ReadSetupPacket()
{
    int i;
    uchar* p = (uchar*) &setupPacket;

    // Make sure the SETUP packet is the correct size
    if ((USTA & 0x0F) != 8)
    {
        UCON0 |= uSTALL0;
        return FALSE;
    }

    // Read the setup packet
    for (i = 0; i < sizeof(setup_buffer); i++)
    {
        *p++ = UDR0;
    }

    // Set data toggle bit (expecting DATA1)
    USTA |= uRSEQ;

    return TRUE;
}

/////////////////// OnSetupPacket()
//
// Basic handler for SETUP packets received on EP0.

void OnSetupPacket()
{
    pTransmitBufferEP0 = NULL;
    bytesToTransmitEP0 = 0;

    // If it's a standard request...
    if ((setupPacket.bmRequestType & 0x60) == 0)
    {
        // Handle the request
        switch (setupPacket.bRequest)
        {
        case CLEAR_FEATURE:
            OnClearFeature();
            return;
        case SET_ADDRESS:
            OnSetAddress();
            return;
        case GET_DESCRIPTOR:
            OnGetDescriptor();
            return;
        case SET_CONFIGURATION:
            OnSetConfiguration();
            return;
        default:
            break;
        }
    }

    // It's not a request we handle so stall endpoint
    // UCON0 |= uSTALL0; - problems, so try zero length packet instead
    UCON0 = uTSEQ0 | uRX0E | uTX0E;
}

/////////////////// BaseEp0TxHandler()
//
// Handler for successful data transmission on control endpoint (EP0).

void BaseEp0TxHandler()
{
	// Send next chunk of data in transaction
	if (!TransmitBufferEP0())
	{
		// The current request has finished
		if (setupPacket.bRequest == SET_ADDRESS)
		{
			UADR = setupPacket.wValue.lo | uUSBEN;
			if (setupPacket.wValue.lo != 0)
				usbState = US_ADDRESSED;
			else 
				usbState = US_DEFAULT;
		}

		setupPacket.bRequest = REQUEST_COMPLETE;
	}
}

⌨️ 快捷键说明

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