EA BaseBoard, playing wav, PC see\'s SD-card through USB port.

Dependencies:   mbed

USBMSC.cpp

Committer:
Lerche
Date:
2011-11-22
Revision:
0:fef366d2ed20

File content as of revision 0:fef366d2ed20:

// USB_MIDI.cpp
// MIDI edvice example
// Copyright (c) 2011 ARM Limited. All rights reserved.

//#define DEBUG
#include "dbg.h"
#include "stdint.h"
#include "USBMSC.h"
#include "USBBusInterface.h"
#include "USBDevice.h"
#include "USBDevice_Types.h"

void USBMSC::setTransferData (uint8_t *buf, int len) {
    CONTROL_TRANSFER *transfer = getTransferPtr();
    transfer->remaining = len;
    transfer->ptr = buf;
    transfer->direction = DEVICE_TO_HOST;
}

void USBMSC::attach(void (*fptr)(uint8_t)) {
    msc_evt = fptr;
}

USBMSC::USBMSC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
    msc_evt = NULL;
}

bool USBMSC::EPBULK_OUT_callback() {

    if (msc_evt && ! getEndpointStallState(EPBULK_OUT)) {
        msc_evt(EPBULK_OUT);
    }

    // We reactivate the endpoint to receive next characters
    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
    DBG("EPBULK_OUT_callback\r\n");
    return true;
}

bool USBMSC::EPBULK_IN_callback() {
    DBG("EPBULK_IN_callback\r\n");

    if (msc_evt && ! getEndpointStallState(EPBULK_IN)) {
        msc_evt(EPBULK_IN);
    }

    return false;
}

bool USBMSC::USBCallback_request () {
    bool success = false;
    CONTROL_TRANSFER *transfer = getTransferPtr();
    
    DBG("USBCallback_request: type %x, request %x\r\n", transfer->setup.bmRequestType.Type, transfer->setup.bRequest);
    /* Process standard requests */
    if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
    {
        switch (transfer->setup.bRequest)
        {
            default:
                break;
        }
    }

    if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
    {
        switch (transfer->setup.bRequest)
        {
            case 0xFE: // MSC get max LUN
                static uint8_t dummy[] = {0}; 
                transfer->remaining = 1;
                transfer->ptr = dummy;
                transfer->direction = DEVICE_TO_HOST;
                success = true;
                break;
            case 0xFF: // MSC reset
                if (transfer->setup.wLength == 0) {
                    if (msc_evt) {
                        msc_evt(0xFF);
                    }
                    success = true;
                }
                break;
            default:
                break;
        }
    }

    return success;
}

bool USBMSC::USBCallback_setConfiguration(uint8_t configuration) {
    DBG("USBCallback_setConfiguration: config %x\r\n", configuration);
    // Called in ISR context
    // Set configuration. Return false if the
    // configuration is not supported.
    if (configuration != DEFAULT_CONFIGURATION) {
        return false;
    }

    addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);

    // enable bulk-in interrupts on NAKs
    // these are required to get the BOT protocol going again after a STALL
    NakIntEnable(EPBULK_IN);

    // Configure endpoints > 0
    addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
    addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);

    // We activate the endpoint to be able to receive data
    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);

    return true;
}

uint8_t * USBMSC::configurationDesc() {
    static uint8_t configDescriptor[] = {
        // configuration descriptor
        0x09, 0x02, 32, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x32,

        // MSC
        // control class interface
        0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50, 0x00,
        // EP OUT
        0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,
        // EP IN
        0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00,
    };
    DBG("configurationDesc %d\r\n", sizeof(configDescriptor));
    return configDescriptor;
}

uint8_t * USBMSC::deviceDesc() {
    static uint8_t deviceDescriptor[] = {
        DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
        DEVICE_DESCRIPTOR,              /* bDescriptorType */
        LSB(USB_VERSION_2_0),           /* bcdUSB (LSB) */
        MSB(USB_VERSION_2_0),           /* bcdUSB (MSB) */
        0x00,                           /* bDeviceClass */
        0x00,                           /* bDeviceSubClass */
        0x00,                           /* bDeviceprotocol */
        MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
        LSB(VENDOR_ID),                 /* idVendor (LSB) */
        MSB(VENDOR_ID),                 /* idVendor (MSB) */
        LSB(PRODUCT_ID),                /* idProduct (LSB) */
        MSB(PRODUCT_ID),                /* idProduct (MSB) */
        LSB(PRODUCT_RELEASE),           /* bcdDevice (LSB) */
        MSB(PRODUCT_RELEASE),           /* bcdDevice (MSB) */
        STRING_OFFSET_IMANUFACTURER,    /* iManufacturer */
        STRING_OFFSET_IPRODUCT,         /* iProduct */
        STRING_OFFSET_ISERIAL,          /* iSerialNumber */
        0x01                            /* bNumConfigurations */
    };
    return deviceDescriptor;
}