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

📄 usb.c

📁 at91的一个bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// This is a driver for the UDP (USB Device Periphal) on the AT91SAM7{S,X}xxx
// chips. It appears as a generic HID device; this means that it will work
// without a kernel-mode driver under most operating systems.
//
// This is not very close to USB-compliant, but it is tested and working
// under Windows XP.
//
// To use this driver: from your code, call UsbStart() once at startup.
// After doing this, you can call UsbSendPacket() to transmit a packet
// from the device (this processor) to the host. Call UsbPoll()
// periodically to poll for received packets; when a packet is received
// it will be delivered to you by calling UsbPacketReceived(), a function
// that you provide. UsbPoll() also takes care of the signaling involved
// in enumeration.
//
// I assume that an appropriate clock has already been supplied to the UDP
// using the PMC. The exact register settings to do this will depend on
// your crystal frequency.
//
// Jonathan Westhues, split Aug 14 2005, public release May 26 2006
//-----------------------------------------------------------------------------
#include <bootrom.h>

#define min(a, b) (((a) > (b)) ? (b) : (a))

#define USB_REPORT_PACKET_SIZE 64

typedef struct PACKED {
    BYTE        bmRequestType;
    BYTE        bRequest;
    WORD        wValue;
    WORD        wIndex;
    WORD        wLength;
} UsbSetupData;

#define USB_REQUEST_GET_STATUS          0
#define USB_REQUEST_CLEAR_FEATURE       1
#define USB_REQUEST_SET_FEATURE         3
#define USB_REQUEST_SET_ADDRESS         5
#define USB_REQUEST_GET_DESCRIPTOR      6
#define USB_REQUEST_SET_DESCRIPTOR      7
#define USB_REQUEST_GET_CONFIGURATION   8
#define USB_REQUEST_SET_CONFIGURATION   9
#define USB_REQUEST_GET_INTERFACE       10
#define USB_REQUEST_SET_INTERFACE       11
#define USB_REQUEST_SYNC_FRAME          12

#define USB_DESCRIPTOR_TYPE_DEVICE              1
#define USB_DESCRIPTOR_TYPE_CONFIGURATION       2
#define USB_DESCRIPTOR_TYPE_STRING              3
#define USB_DESCRIPTOR_TYPE_INTERFACE           4
#define USB_DESCRIPTOR_TYPE_ENDPOINT            5
#define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER    6
#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONF    7
#define USB_DESCRIPTOR_TYPE_INTERFACE_POWER     8
#define USB_DESCRIPTOR_TYPE_HID                 0x21
#define USB_DESCRIPTOR_TYPE_HID_REPORT          0x22

#define USB_DEVICE_CLASS_HID                    0x03

// These descriptors are partially adapted from Jan Axelson's sample code,
// which appears to be itself adapted from Cypress's examples for their
// USB-enabled 8051s.

static const BYTE HidReportDescriptor[] = {
    0x06, 0xA0,0xFF,            // Usage Page (vendor defined) FFA0
    0x09, 0x01,                 // Usage (vendor defined)
    0xA1, 0x01,                 // Collection (Application)
    0x09, 0x02,                 // Usage (vendor defined)
    0xA1, 0x00,                 // Collection (Physical)
    0x06, 0xA1,0xFF,            // Usage Page (vendor defined) 

    // The input report
    0x09, 0x03,                 // usage - vendor defined
    0x09, 0x04,                 // usage - vendor defined
    0x15, 0x80,                 // Logical Minimum (-128)
    0x25, 0x7F,                 // Logical Maximum (127)
    0x35, 0x00,                 // Physical Minimum (0)
    0x45, 0xFF,                 // Physical Maximum (255)
    0x75, 0x08,                 // Report Size (8)  (bits)
    0x95, 0x40,                 // Report Count (64)  (fields)
    0x81, 0x02,                 // Input (Data,Variable,Absolute)  

    // The output report
    0x09, 0x05,                 // usage - vendor defined
    0x09, 0x06,                 // usage - vendor defined
    0x15, 0x80,                 // Logical Minimum (-128)
    0x25, 0x7F,                 // Logical Maximum (127)
    0x35, 0x00,                 // Physical Minimum (0)
    0x45, 0xFF,                 // Physical Maximum (255)
    0x75, 0x08,                 // Report Size (8)  (bits)
    0x95, 0x40,                 // Report Count (64)  (fields)
    0x91, 0x02,                 // Output (Data,Variable,Absolute)

    0xC0,                       // End Collection

    0xC0,                       // End Collection
};

static const BYTE DeviceDescriptor[] = {
    0x12,                       // Descriptor length (18 bytes)
    0x01,                       // Descriptor type (Device)
    0x10, 0x01,                 // Complies with USB Spec. Release 1.10
    0x00,                       // Class code (0)
    0x00,                       // Subclass code (0)
    0x00,                       // Protocol (No specific protocol)
    0x08,                       // Maximum packet size for Endpoint 0 (8 bytes)
    0xc5, 0x9a,                 // Vendor ID (random numbers)
    0x8f, 0x4b,                 // Product ID (random numbers)
    0x01, 0x00,                 // Device release number (0001)
    0x01,                       // Manufacturer string descriptor index
    0x02,                       // Product string descriptor index
    0x00,                       // Serial Number string descriptor index (None)
    0x01,                       // Number of possible configurations (1)
};

static const BYTE ConfigurationDescriptor[] = {
    0x09,                       // Descriptor length (9 bytes)
    0x02,                       // Descriptor type (Configuration)
    0x29, 0x00,                 // Total data length (41 bytes)
    0x01,                       // Interface supported (1)
    0x01,                       // Configuration value (1)
    0x00,                       // Index of string descriptor (None)
    0x80,                       // Configuration (Bus powered)
    250,                        // Maximum power consumption (500mA)

    // Interface
    0x09,                       // Descriptor length (9 bytes)
    0x04,                       // Descriptor type (Interface)
    0x00,                       // Number of interface (0)
    0x00,                       // Alternate setting (0)
    0x02,                       // Number of interface endpoint (2)
    0x03,                       // Class code (HID)
    0x00,                       // Subclass code ()
    0x00,                       // Protocol code ()
    0x00,                       // Index of string()

    // Class
    0x09,                       // Descriptor length (9 bytes)
    0x21,                       // Descriptor type (HID)
    0x00, 0x01,                 // HID class release number (1.00)
    0x00,                       // Localized country code (None)
    0x01,                       // # of HID class dscrptr to follow (1)
    0x22,                       // Report descriptor type (HID)
    // Total length of report descriptor
    sizeof(HidReportDescriptor), 0x00,

    // endpoint 1
    0x07,                       // Descriptor length (7 bytes)
    0x05,                       // Descriptor type (Endpoint)
    0x01,                       // Encoded address (Respond to OUT)
    0x03,                       // Endpoint attribute (Interrupt transfer)
    0x08, 0x00,                 // Maximum packet size (8 bytes)
    0x01,                       // Polling interval (1 ms)

    // endpoint 2
    0x07,                       // Descriptor length (7 bytes)
    0x05,                       // Descriptor type (Endpoint)
    0x82,                       // Encoded address (Respond to IN)
    0x03,                       // Endpoint attribute (Interrupt transfer)
    0x08, 0x00,                 // Maximum packet size (8 bytes)
    0x01,                       // Polling interval (1 ms)
};

static const BYTE StringDescriptor0[] = {
    0x04,                       // Length
    0x03,                       // Type is string
    0x09,                       // English
    0x04,                       //  US
};

// These string descriptors can be changed for the particular application.
// The string itself is Unicode, and the length is the total length of
// the descriptor, so it is the number of characters times two, plus two.

static const BYTE StringDescriptor1[] = {
    26,             // Length
    0x03,           // Type is string
    'M', 0x00,
    'a', 0x00,
    'n', 0x00,
    'u', 0x00,
    'f', 0x00,
    'a', 0x00,
    'c', 0x00,
    't', 0x00,
    'u', 0x00,
    'r', 0x00,
    'e', 0x00,
    'r', 0x00,
};

static const BYTE StringDescriptor2[] = {
    14,             // Length
    0x03,           // Type is string
    'D', 0x00,
    'e', 0x00,
    'v', 0x00,
    'i', 0x00,
    'c', 0x00,
    'e', 0x00,
};

static const BYTE * const StringDescriptors[] = {
    StringDescriptor0,
    StringDescriptor1,
    StringDescriptor2,
};

// The buffer used to store packets received over USB while we are in the
// process of receiving them.
static BYTE UsbBuffer[64];

// The number of characters received in the USB buffer so far.
static int  UsbSoFarCount;

static BYTE CurrentConfiguration;

//-----------------------------------------------------------------------------
// Send a packet over EP0. This blocks until the packet has been transmitted
// and an ACK from the host has been received.
//-----------------------------------------------------------------------------
static void UsbSendEp0(const BYTE *data, int len)
{
    int thisTime, i;

    do {
        thisTime = min(len, 8);
        len -= thisTime;

        for(i = 0; i < thisTime; i++) {
            UDP_ENDPOINT_FIFO(0) = *data;
            data++;
        }

        if(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED) {
            UDP_ENDPOINT_CSR(0) &= ~UDP_CSR_TX_PACKET_ACKED;
            while(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED)
                ;
        }

        UDP_ENDPOINT_CSR(0) |= UDP_CSR_TX_PACKET;

        do {
            if(UDP_ENDPOINT_CSR(0) & UDP_CSR_RX_PACKET_RECEIVED_BANK_0) {
                // This means that the host is trying to write to us, so
                // abandon our write to them.
                UDP_ENDPOINT_CSR(0) &= ~UDP_CSR_RX_PACKET_RECEIVED_BANK_0;
                return;
            }
        } while(!(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED));
    } while(len > 0);

    if(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED) {
        UDP_ENDPOINT_CSR(0) &= ~UDP_CSR_TX_PACKET_ACKED;
        while(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED)
            ;

⌨️ 快捷键说明

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