steve
Dependents: USBMouseKeyboard USBMouseKeyboardlib
Revision 72:d2619b040139, committed 2020-10-05
- Comitter:
- cybersteve
- Date:
- Mon Oct 05 12:51:00 2020 +0000
- Parent:
- 8:335f2506f422
- Commit message:
- steve
Changed in this revision
diff -r 335f2506f422 -r d2619b040139 USBAudio/USBAudio.cpp --- a/USBAudio/USBAudio.cpp Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,618 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "stdint.h" -#include "USBAudio.h" -#include "USBAudio_Types.h" - - - -USBAudio::USBAudio(uint32_t frequency_in, uint8_t channel_nb_in, uint32_t frequency_out, uint8_t channel_nb_out, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) { - mute = 0; - volCur = 0x0080; - volMin = 0x0000; - volMax = 0x0100; - volRes = 0x0004; - available = false; - - FREQ_IN = frequency_in; - FREQ_OUT = frequency_out; - - this->channel_nb_in = channel_nb_in; - this->channel_nb_out = channel_nb_out; - - // stereo -> *2, mono -> *1 - PACKET_SIZE_ISO_IN = (FREQ_IN / 500) * channel_nb_in; - PACKET_SIZE_ISO_OUT = (FREQ_OUT / 500) * channel_nb_out; - - // STEREO -> left and right - channel_config_in = (channel_nb_in == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R; - channel_config_out = (channel_nb_out == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R; - - SOF_handler = false; - - buf_stream_out = NULL; - buf_stream_in = NULL; - - interruptOUT = false; - writeIN = false; - interruptIN = false; - available = false; - - volume = 0; - - // connect the device - USBDevice::connect(); -} - -bool USBAudio::read(uint8_t * buf) { - buf_stream_in = buf; - SOF_handler = false; - while (!available || !SOF_handler); - available = false; - return true; -} - -bool USBAudio::readNB(uint8_t * buf) { - buf_stream_in = buf; - SOF_handler = false; - while (!SOF_handler); - if (available) { - available = false; - buf_stream_in = NULL; - return true; - } - return false; -} - -bool USBAudio::readWrite(uint8_t * buf_read, uint8_t * buf_write) { - buf_stream_in = buf_read; - SOF_handler = false; - writeIN = false; - if (interruptIN) { - USBDevice::writeNB(EP3IN, buf_write, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT); - } else { - buf_stream_out = buf_write; - } - while (!available); - if (interruptIN) { - while (!writeIN); - } - while (!SOF_handler); - return true; -} - - -bool USBAudio::write(uint8_t * buf) { - writeIN = false; - SOF_handler = false; - if (interruptIN) { - USBDevice::writeNB(EP3IN, buf, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT); - } else { - buf_stream_out = buf; - } - while (!SOF_handler); - if (interruptIN) { - while (!writeIN); - } - return true; -} - - -float USBAudio::getVolume() { - return (mute) ? 0.0 : volume; -} - - -bool USBAudio::EP3_OUT_callback() { - uint32_t size = 0; - interruptOUT = true; - if (buf_stream_in != NULL) { - readEP(EP3OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN); - available = true; - buf_stream_in = NULL; - } - readStart(EP3OUT, PACKET_SIZE_ISO_IN); - return false; -} - - -bool USBAudio::EP3_IN_callback() { - interruptIN = true; - writeIN = true; - return true; -} - - - -// Called in ISR context on each start of frame -void USBAudio::SOF(int frameNumber) { - uint32_t size = 0; - - if (!interruptOUT) { - // read the isochronous endpoint - if (buf_stream_in != NULL) { - if (USBDevice::readEP_NB(EP3OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN)) { - if (size) { - available = true; - readStart(EP3OUT, PACKET_SIZE_ISO_IN); - buf_stream_in = NULL; - } - } - } - } - - if (!interruptIN) { - // write if needed - if (buf_stream_out != NULL) { - USBDevice::writeNB(EP3IN, (uint8_t *)buf_stream_out, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT); - buf_stream_out = NULL; - } - } - - SOF_handler = true; -} - - -// Called in ISR context -// Set configuration. Return false if the configuration is not supported. -bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) { - if (configuration != DEFAULT_CONFIGURATION) { - return false; - } - - // Configure isochronous endpoint - realiseEndpoint(EP3OUT, PACKET_SIZE_ISO_IN, ISOCHRONOUS); - realiseEndpoint(EP3IN, PACKET_SIZE_ISO_OUT, ISOCHRONOUS); - - // activate readings on this endpoint - readStart(EP3OUT, PACKET_SIZE_ISO_IN); - return true; -} - - -// Called in ISR context -// Set alternate setting. Return false if the alternate setting is not supported -bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) { - if (interface == 0 && alternate == 0) { - return true; - } - if (interface == 1 && (alternate == 0 || alternate == 1)) { - return true; - } - if (interface == 2 && (alternate == 0 || alternate == 1)) { - return true; - } - return false; -} - - - -// Called in ISR context -// Called by USBDevice on Endpoint0 request -// This is used to handle extensions to standard requests and class specific requests. -// Return true if class handles this request -bool USBAudio::USBCallback_request() { - bool success = false; - CONTROL_TRANSFER * transfer = getTransferPtr(); - - // Process class-specific requests - if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { - - // Feature Unit: Interface = 0, ID = 2 - if (transfer->setup.wIndex == 0x0200) { - - // Master Channel - if ((transfer->setup.wValue & 0xff) == 0) { - - switch (transfer->setup.wValue >> 8) { - case MUTE_CONTROL: - switch (transfer->setup.bRequest) { - case REQUEST_GET_CUR: - transfer->remaining = 1; - transfer->ptr = &mute; - transfer->direction = DEVICE_TO_HOST; - success = true; - break; - - case REQUEST_SET_CUR: - transfer->remaining = 1; - transfer->notify = true; - transfer->direction = HOST_TO_DEVICE; - success = true; - break; - default: - break; - } - break; - case VOLUME_CONTROL: - switch (transfer->setup.bRequest) { - case REQUEST_GET_CUR: - transfer->remaining = 2; - transfer->ptr = (uint8_t *)&volCur; - transfer->direction = DEVICE_TO_HOST; - success = true; - break; - case REQUEST_GET_MIN: - transfer->remaining = 2; - transfer->ptr = (uint8_t *)&volMin; - transfer->direction = DEVICE_TO_HOST; - success = true; - break; - case REQUEST_GET_MAX: - transfer->remaining = 2; - transfer->ptr = (uint8_t *)&volMax; - transfer->direction = DEVICE_TO_HOST; - success = true; - break; - case REQUEST_GET_RES: - transfer->remaining = 2; - transfer->ptr = (uint8_t *)&volRes; - transfer->direction = DEVICE_TO_HOST; - success = true; - break; - - case REQUEST_SET_CUR: - transfer->remaining = 2; - transfer->notify = true; - transfer->direction = HOST_TO_DEVICE; - success = true; - break; - case REQUEST_SET_MIN: - transfer->remaining = 2; - transfer->notify = true; - transfer->direction = HOST_TO_DEVICE; - success = true; - break; - case REQUEST_SET_MAX: - transfer->remaining = 2; - transfer->notify = true; - transfer->direction = HOST_TO_DEVICE; - success = true; - break; - case REQUEST_SET_RES: - transfer->remaining = 2; - transfer->notify = true; - transfer->direction = HOST_TO_DEVICE; - success = true; - break; - } - break; - default: - break; - } - } - } - } - return success; -} - - -// Called in ISR context when a data OUT stage has been performed -void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint32_t length) { - if ((length == 1) || (length == 2)) { - uint16_t data = (length == 1) ? *buf : *((uint16_t *)buf); - CONTROL_TRANSFER * transfer = getTransferPtr(); - switch (transfer->setup.wValue >> 8) { - case MUTE_CONTROL: - switch (transfer->setup.bRequest) { - case REQUEST_SET_CUR: - mute = data & 0xff; - updateVol.call(); - break; - default: - break; - } - break; - case VOLUME_CONTROL: - switch (transfer->setup.bRequest) { - case REQUEST_SET_CUR: - volCur = data; - volume = (float)volCur/(float)volMax; - updateVol.call(); - break; - default: - break; - } - break; - default: - break; - } - } -} - - - -#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ - + (5 * INTERFACE_DESCRIPTOR_LENGTH) \ - + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1) \ - + (2 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \ - + (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \ - + (2 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \ - + (2 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \ - + (2 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \ - + (2 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \ - + (2 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) ) - -#define TOTAL_CONTROL_INTF_LENGTH (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1 + \ - 2*INPUT_TERMINAL_DESCRIPTOR_LENGTH + \ - FEATURE_UNIT_DESCRIPTOR_LENGTH + \ - 2*OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) - -uint8_t * USBAudio::configurationDesc() { - static uint8_t configDescriptor[] = { - // Configuration 1 - CONFIGURATION_DESCRIPTOR_LENGTH, // bLength - CONFIGURATION_DESCRIPTOR, // bDescriptorType - LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) - MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) - 0x03, // bNumInterfaces - DEFAULT_CONFIGURATION, // bConfigurationValue - 0x00, // iConfiguration - 0x80, // bmAttributes - 50, // bMaxPower - - // Interface 0, Alternate Setting 0, Audio Control - INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR, // bDescriptorType - 0x00, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x00, // bNumEndpoints - AUDIO_CLASS, // bInterfaceClass - SUBCLASS_AUDIOCONTROL, // bInterfaceSubClass - 0x00, // bInterfaceProtocol - 0x00, // iInterface - - - // Audio Control Interface - CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1,// bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - CONTROL_HEADER, // bDescriptorSubtype - LSB(0x0100), // bcdADC (LSB) - MSB(0x0100), // bcdADC (MSB) - LSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength - MSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength - 0x02, // bInCollection - 0x01, // baInterfaceNr - 0x02, // baInterfaceNr - - // Audio Input Terminal (Speaker) - INPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - CONTROL_INPUT_TERMINAL, // bDescriptorSubtype - 0x01, // bTerminalID - LSB(TERMINAL_USB_STREAMING), // wTerminalType - MSB(TERMINAL_USB_STREAMING), // wTerminalType - 0x00, // bAssocTerminal - channel_nb_in, // bNrChannels - LSB(channel_config_in), // wChannelConfig - MSB(channel_config_in), // wChannelConfig - 0x00, // iChannelNames - 0x00, // iTerminal - - // Audio Feature Unit (Speaker) - FEATURE_UNIT_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - CONTROL_FEATURE_UNIT, // bDescriptorSubtype - 0x02, // bUnitID - 0x01, // bSourceID - 0x01, // bControlSize - CONTROL_MUTE | - CONTROL_VOLUME, // bmaControls(0) - 0x00, // bmaControls(1) - 0x00, // iTerminal - - // Audio Output Terminal (Speaker) - OUTPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - CONTROL_OUTPUT_TERMINAL, // bDescriptorSubtype - 0x03, // bTerminalID - LSB(TERMINAL_SPEAKER), // wTerminalType - MSB(TERMINAL_SPEAKER), // wTerminalType - 0x00, // bAssocTerminal - 0x02, // bSourceID - 0x00, // iTerminal - - - // Audio Input Terminal (Microphone) - INPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - CONTROL_INPUT_TERMINAL, // bDescriptorSubtype - 0x04, // bTerminalID - LSB(TERMINAL_MICROPHONE), // wTerminalType - MSB(TERMINAL_MICROPHONE), // wTerminalType - 0x00, // bAssocTerminal - channel_nb_out, // bNrChannels - LSB(channel_config_out), // wChannelConfig - MSB(channel_config_out), // wChannelConfig - 0x00, // iChannelNames - 0x00, // iTerminal - - // Audio Output Terminal (Microphone) - OUTPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - CONTROL_OUTPUT_TERMINAL, // bDescriptorSubtype - 0x05, // bTerminalID - LSB(TERMINAL_USB_STREAMING), // wTerminalType - MSB(TERMINAL_USB_STREAMING), // wTerminalType - 0x00, // bAssocTerminal - 0x04, // bSourceID - 0x00, // iTerminal - - - - - - - // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith - INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR, // bDescriptorType - 0x01, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x00, // bNumEndpoints - AUDIO_CLASS, // bInterfaceClass - SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass - 0x00, // bInterfaceProtocol - 0x00, // iInterface - - // Interface 1, Alternate Setting 1, Audio Streaming - Operational - INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR, // bDescriptorType - 0x01, // bInterfaceNumber - 0x01, // bAlternateSetting - 0x01, // bNumEndpoints - AUDIO_CLASS, // bInterfaceClass - SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass - 0x00, // bInterfaceProtocol - 0x00, // iInterface - - // Audio Streaming Interface - STREAMING_INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - STREAMING_GENERAL, // bDescriptorSubtype - 0x01, // bTerminalLink - 0x00, // bDelay - LSB(FORMAT_PCM), // wFormatTag - MSB(FORMAT_PCM), // wFormatTag - - // Audio Type I Format - FORMAT_TYPE_I_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - STREAMING_FORMAT_TYPE, // bDescriptorSubtype - FORMAT_TYPE_I, // bFormatType - channel_nb_in, // bNrChannels - 0x02, // bSubFrameSize - 16, // bBitResolution - 0x01, // bSamFreqType - LSB(FREQ_IN), // tSamFreq - (FREQ_IN >> 8) & 0xff, // tSamFreq - (FREQ_IN >> 16) & 0xff, // tSamFreq - - // Endpoint - Standard Descriptor - ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPISO_OUT), // bEndpointAddress - E_ISOCHRONOUS, // bmAttributes - LSB(PACKET_SIZE_ISO_IN), // wMaxPacketSize - MSB(PACKET_SIZE_ISO_IN), // wMaxPacketSize - 0x01, // bInterval - 0x00, // bRefresh - 0x00, // bSynchAddress - - // Endpoint - Audio Streaming - STREAMING_ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType - ENDPOINT_GENERAL, // bDescriptor - 0x00, // bmAttributes - 0x00, // bLockDelayUnits - LSB(0x0000), // wLockDelay - MSB(0x0000), // wLockDelay - - - - - - - - // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith - INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR, // bDescriptorType - 0x02, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x00, // bNumEndpoints - AUDIO_CLASS, // bInterfaceClass - SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass - 0x00, // bInterfaceProtocol - 0x00, // iInterface - - // Interface 1, Alternate Setting 1, Audio Streaming - Operational - INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR, // bDescriptorType - 0x02, // bInterfaceNumber - 0x01, // bAlternateSetting - 0x01, // bNumEndpoints - AUDIO_CLASS, // bInterfaceClass - SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass - 0x00, // bInterfaceProtocol - 0x00, // iInterface - - // Audio Streaming Interface - STREAMING_INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - SUBCLASS_AUDIOCONTROL, // bDescriptorSubtype - 0x05, // bTerminalLink (output terminal microphone) - 0x01, // bDelay - 0x01, // wFormatTag - 0x00, // wFormatTag - - // Audio Type I Format - FORMAT_TYPE_I_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType - SUBCLASS_AUDIOSTREAMING, // bDescriptorSubtype - FORMAT_TYPE_I, // bFormatType - channel_nb_out, // bNrChannels - 0x02, // bSubFrameSize - 0x10, // bBitResolution - 0x01, // bSamFreqType - LSB(FREQ_OUT), // tSamFreq - (FREQ_OUT >> 8) & 0xff, // tSamFreq - (FREQ_OUT >> 16) & 0xff, // tSamFreq - - // Endpoint - Standard Descriptor - ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPISO_IN), // bEndpointAddress - E_ISOCHRONOUS, // bmAttributes - LSB(PACKET_SIZE_ISO_OUT), // wMaxPacketSize - MSB(PACKET_SIZE_ISO_OUT), // wMaxPacketSize - 0x01, // bInterval - 0x00, // bRefresh - 0x00, // bSynchAddress - - // Endpoint - Audio Streaming - STREAMING_ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType - ENDPOINT_GENERAL, // bDescriptor - 0x00, // bmAttributes - 0x00, // bLockDelayUnits - LSB(0x0000), // wLockDelay - MSB(0x0000), // wLockDelay - - // Terminator - 0 // bLength - }; - return configDescriptor; -} - -uint8_t * USBAudio::stringIinterfaceDesc() { - static uint8_t stringIinterfaceDescriptor[] = { - 0x0c, //bLength - STRING_DESCRIPTOR, //bDescriptorType 0x03 - 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio - }; - return stringIinterfaceDescriptor; -} - -uint8_t * USBAudio::stringIproductDesc() { - static uint8_t stringIproductDescriptor[] = { - 0x16, //bLength - STRING_DESCRIPTOR, //bDescriptorType 0x03 - 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio - }; - return stringIproductDescriptor; -}
diff -r 335f2506f422 -r d2619b040139 USBAudio/USBAudio.h --- a/USBAudio/USBAudio.h Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,287 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef USBAudio_H -#define USBAudio_H - -/* These headers are included for child class. */ -#include "USBEndpoints.h" -#include "USBDescriptor.h" -#include "USBDevice_Types.h" - -#include "USBDevice.h" - - -/** -* USBAudio example -* -* @code -* #include "mbed.h" -* #include "USBAudio.h" -* -* Serial pc(USBTX, USBRX); -* -* // frequency: 48 kHz -* #define FREQ 48000 -* -* // 1 channel: mono -* #define NB_CHA 1 -* -* // length of an audio packet: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1 -* #define AUDIO_LENGTH_PACKET 48 * 2 * 1 -* -* // USBAudio -* USBAudio audio(FREQ, NB_CHA); -* -* int main() { -* int16_t buf[AUDIO_LENGTH_PACKET/2]; -* -* while (1) { -* // read an audio packet -* audio.read((uint8_t *)buf); -* -* -* // print packet received -* pc.printf("recv: "); -* for(int i = 0; i < AUDIO_LENGTH_PACKET/2; i++) { -* pc.printf("%d ", buf[i]); -* } -* pc.printf("\r\n"); -* } -* } -* @endcode -*/ -class USBAudio: public USBDevice { -public: - - /** - * Constructor - * - * @param frequency_in frequency in Hz (default: 48000) - * @param channel_nb_in channel number (1 or 2) (default: 1) - * @param frequency_out frequency in Hz (default: 8000) - * @param channel_nb_out_in channel number (1 or 2) (default: 1) - * @param vendor_id Your vendor_id - * @param product_id Your product_id - * @param product_release Your preoduct_release - */ - USBAudio(uint32_t frequency_in = 48000, uint8_t channel_nb_in = 1, uint32_t frequency_out = 8000, uint8_t channel_nb_out = 1, uint16_t vendor_id = 0x7bb8, uint16_t product_id = 0x1111, uint16_t product_release = 0x0100); - - /** - * Get current volume between 0.0 and 1.0 - * - * @returns volume - */ - float getVolume(); - - /** - * Read an audio packet. During a frame, only a single reading (you can't write and read an audio packet during the same frame)can be done using this method. Warning: Blocking - * - * @param buf pointer on a buffer which will be filled with an audio packet - * - * @returns true if successfull - */ - bool read(uint8_t * buf); - - /** - * Try to read an audio packet. During a frame, only a single reading (you can't write and read an audio packet during the same frame)can be done using this method. Warning: Non Blocking - * - * @param buf pointer on a buffer which will be filled if an audio packet is available - * - * @returns true if successfull - */ - bool readNB(uint8_t * buf); - - /** - * Write an audio packet. During a frame, only a single writing (you can't write and read an audio packet during the same frame)can be done using this method. - * - * @param buf pointer on the audio packet which will be sent - * @returns true if successful - */ - bool write(uint8_t * buf); - - /** - * Write and read an audio packet at the same time (on the same frame) - * - * @param buf_read pointer on a buffer which will be filled with an audio packet - * @param buf_write pointer on the audio packet which will be sent - * @returns true if successful - */ - bool readWrite(uint8_t * buf_read, uint8_t * buf_write); - - - /** attach a handler to update the volume - * - * @param function Function to attach - * - */ - void attach(void(*fptr)(void)) { - updateVol.attach(fptr); - } - - /** Attach a nonstatic void/void member function to update the volume - * - * @param tptr Object pointer - * @param mptr Member function pointer - * - */ - template<typename T> - void attach(T *tptr, void(T::*mptr)(void)) { - updateVol.attach(tptr, mptr); - } - - -protected: - - /* - * Called by USBDevice layer. Set configuration of the device. - * For instance, you can add all endpoints that you need on this function. - * - * @param configuration Number of the configuration - * @returns true if class handles this request - */ - virtual bool USBCallback_setConfiguration(uint8_t configuration); - - /* - * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context - * This is used to handle extensions to standard requests - * and class specific requests - * - * @returns true if class handles this request - */ - virtual bool USBCallback_request(); - - /* - * Get string product descriptor - * - * @returns pointer to the string product descriptor - */ - virtual uint8_t * stringIproductDesc(); - - /* - * Get string interface descriptor - * - * @returns pointer to the string interface descriptor - */ - virtual uint8_t * stringIinterfaceDesc(); - - /* - * Get configuration descriptor - * - * @returns pointer to the configuration descriptor - */ - virtual uint8_t * configurationDesc(); - - /* - * Called by USBDevice layer. Set interface/alternate of the device. - * - * @param interface Number of the interface to be configured - * @param alternate Number of the alternate to be configured - * @returns true if class handles this request - */ - virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate); - - /* - * Called by USBDevice on Endpoint0 request completion - * if the 'notify' flag has been set to true. Warning: Called in ISR context - * - * In this case it is used to indicate that a HID report has - * been received from the host on endpoint 0 - * - * @param buf buffer received on endpoint 0 - * @param length length of this buffer - */ - virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length); - - /* - * Callback called on each Start of Frame event - */ - virtual void SOF(int frameNumber); - - /* - * Callback called when a packet is received - */ - virtual bool EP3_OUT_callback(); - - /* - * Callback called when a packet has been sent - */ - virtual bool EP3_IN_callback(); - -private: - - // stream available ? - volatile bool available; - - // interrupt OUT has been received - volatile bool interruptOUT; - - // interrupt IN has been received - volatile bool interruptIN; - - // audio packet has been written - volatile bool writeIN; - - // FREQ - uint32_t FREQ_OUT; - uint32_t FREQ_IN; - - // size of the maximum packet for the isochronous endpoint - uint32_t PACKET_SIZE_ISO_IN; - uint32_t PACKET_SIZE_ISO_OUT; - - // mono, stereo,... - uint8_t channel_nb_in; - uint8_t channel_nb_out; - - // channel config: master, left, right - uint8_t channel_config_in; - uint8_t channel_config_out; - - // mute state - uint8_t mute; - - // Volume Current Value - uint16_t volCur; - - // Volume Minimum Value - uint16_t volMin; - - // Volume Maximum Value - uint16_t volMax; - - // Volume Resolution - uint16_t volRes; - - // Buffer containing one audio packet (to be read) - volatile uint8_t * buf_stream_in; - - // Buffer containing one audio packet (to be written) - volatile uint8_t * buf_stream_out; - - // callback to update volume - FunctionPointer updateVol; - - // boolean showing that the SOF handler has been called. Useful for readNB. - volatile bool SOF_handler; - - volatile float volume; - -}; - -#endif
diff -r 335f2506f422 -r d2619b040139 USBAudio/USBAudio_Types.h --- a/USBAudio/USBAudio_Types.h Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef USBAUDIO_TYPES_H -#define USBAUDIO_TYPES_H - - -#define DEFAULT_CONFIGURATION (1) - -// Audio Request Codes -#define REQUEST_SET_CUR 0x01 -#define REQUEST_GET_CUR 0x81 -#define REQUEST_SET_MIN 0x02 -#define REQUEST_GET_MIN 0x82 -#define REQUEST_SET_MAX 0x03 -#define REQUEST_GET_MAX 0x83 -#define REQUEST_SET_RES 0x04 -#define REQUEST_GET_RES 0x84 - -#define MUTE_CONTROL 0x01 -#define VOLUME_CONTROL 0x02 - - -// Audio Descriptor Sizes -#define CONTROL_INTERFACE_DESCRIPTOR_LENGTH 0x09 -#define STREAMING_INTERFACE_DESCRIPTOR_LENGTH 0x07 -#define INPUT_TERMINAL_DESCRIPTOR_LENGTH 0x0C -#define OUTPUT_TERMINAL_DESCRIPTOR_LENGTH 0x09 -#define FEATURE_UNIT_DESCRIPTOR_LENGTH 0x09 -#define STREAMING_ENDPOINT_DESCRIPTOR_LENGTH 0x07 - -// Audio Format Type Descriptor Sizes -#define FORMAT_TYPE_I_DESCRIPTOR_LENGTH 0x0b - -#define AUDIO_CLASS 0x01 -#define SUBCLASS_AUDIOCONTROL 0x01 -#define SUBCLASS_AUDIOSTREAMING 0x02 - -// Audio Descriptor Types -#define INTERFACE_DESCRIPTOR_TYPE 0x24 -#define ENDPOINT_DESCRIPTOR_TYPE 0x25 - -// Audio Control Interface Descriptor Subtypes -#define CONTROL_HEADER 0x01 -#define CONTROL_INPUT_TERMINAL 0x02 -#define CONTROL_OUTPUT_TERMINAL 0x03 -#define CONTROL_FEATURE_UNIT 0x06 - -// USB Terminal Types -#define TERMINAL_USB_STREAMING 0x0101 - -// Predefined Audio Channel Configuration Bits -// Mono -#define CHANNEL_M 0x0000 -#define CHANNEL_L 0x0001 /* Left Front */ -#define CHANNEL_R 0x0002 /* Right Front */ - -// Feature Unit Control Bits -#define CONTROL_MUTE 0x0001 -#define CONTROL_VOLUME 0x0002 - -// Input Terminal Types -#define TERMINAL_MICROPHONE 0x0201 - -// Output Terminal Types -#define TERMINAL_SPEAKER 0x0301 -#define TERMINAL_HEADPHONES 0x0302 - -// Audio Streaming Interface Descriptor Subtypes -#define STREAMING_GENERAL 0x01 -#define STREAMING_FORMAT_TYPE 0x02 - -// Audio Data Format Type I Codes -#define FORMAT_PCM 0x0001 - -// Audio Format Types -#define FORMAT_TYPE_I 0x01 - -// Audio Endpoint Descriptor Subtypes -#define ENDPOINT_GENERAL 0x01 - -#endif
diff -r 335f2506f422 -r d2619b040139 USBMIDI/MIDIMessage.h --- a/USBMIDI/MIDIMessage.h Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,250 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef MIDIMESSAGE_H -#define MIDIMESSAGE_H - -#include "mbed.h" - -// MIDI Message Format -// -// [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ] -// -// MIDI Data Messages (Channel Specific) -// -// Message msg n m -// --------------------------------------------- -// Note Off 0x8 Key Velocity -// Note On 0x9 Key Velocity -// Polyphonic Aftertouch 0xA Key Pressure -// Control Change 0xB Controller Value -// Program Change 0xC Program - -// Channel Aftertouch 0xD Pressure - -// Pitch Wheel 0xE LSB MSB - -#define CABLE_NUM (0<<4) - -/** A MIDI message container */ -class MIDIMessage { -public: - MIDIMessage() {} - - MIDIMessage(uint8_t *buf) { - *((uint32_t *)data) = *((uint32_t *)buf); - } - - // create messages - - /** Create a NoteOff message - * @param key Key ID - * @param velocity Key velocity (0-127, default = 127) - * @param channel Key channel (0-15, default 0) - * @returns A MIDIMessage - */ - static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0) { - MIDIMessage msg; - msg.data[0] = CABLE_NUM | 0x08; - msg.data[1] = 0x80 | (channel & 0x0F); - msg.data[2] = key & 0x7F; - msg.data[3] = velocity & 0x7F; - return msg; - } - - /** Create a NoteOn message - * @param key Key ID - * @param velocity Key velocity (0-127, default = 127) - * @param channel Key channel (0-15, default 0) - * @returns A MIDIMessage - */ - static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0) { - MIDIMessage msg; - msg.data[0] = CABLE_NUM | 0x09; - msg.data[1] = 0x90 | (channel & 0x0F); - msg.data[2] = key & 0x7F; - msg.data[3] = velocity & 0x7F; - return msg; - } - - /** Create a PolyPhonic Aftertouch message - * @param key Key ID - * @param pressure Aftertouch pressure (0-127) - * @param channel Key channel (0-15, default 0) - * @returns A MIDIMessage - */ - static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0) { - MIDIMessage msg; - msg.data[0] = CABLE_NUM | 0x0A; - msg.data[1] = 0xA0 | (channel & 0x0F); - msg.data[2] = key & 0x7F; - msg.data[3] = pressure & 0x7F; - return msg; - } - - /** Create a Control Change message - * @param control Controller ID - * @param value Controller value (0-127) - * @param channel Controller channel (0-15, default 0) - * @returns A MIDIMessage - */ - static MIDIMessage ControlChange(int control, int value, int channel = 0) { - MIDIMessage msg; - msg.data[0] = CABLE_NUM | 0x0B; - msg.data[1] = 0xB0 | (channel & 0x0F); - msg.data[2] = control & 0x7F; - msg.data[3] = value & 0x7F; - return msg; - } - - /** Create a Program Change message - * @param program Program ID - * @param channel Channel (0-15, default 0) - * @returns A MIDIMessage - */ - static MIDIMessage ProgramChange(int program, int channel = 0) { - MIDIMessage msg; - msg.data[0] = CABLE_NUM | 0x0C; - msg.data[1] = 0xC0 | (channel & 0x0F); - msg.data[2] = program & 0x7F; - msg.data[3] = 0x00; - return msg; - } - - /** Create a Channel Aftertouch message - * @param pressure Pressure - * @param channel Key channel (0-15, default 0) - * @returns A MIDIMessage - */ - static MIDIMessage ChannelAftertouch(int pressure, int channel = 0) { - MIDIMessage msg; - msg.data[0] = CABLE_NUM | 0x0D; - msg.data[1] = 0xD0 | (channel & 0x0F); - msg.data[2] = pressure & 0x7F; - msg.data[3] = 0x00; - return msg; - } - - /** Create a Pitch Wheel message - * @param pitch Pitch (-8192 - 8191, default = 0) - * @param channel Channel (0-15, default 0) - * @returns A MIDIMessage - */ - static MIDIMessage PitchWheel(int pitch = 0, int channel = 0) { - MIDIMessage msg; - int p = pitch + 8192; // 0 - 16383, 8192 is center - msg.data[0] = CABLE_NUM | 0x0E; - msg.data[1] = 0xE0 | (channel & 0x0F); - msg.data[2] = p & 0x7F; - msg.data[3] = (p >> 7) & 0x7F; - return msg; - } - - /** Create an All Notes Off message - * @param channel Channel (0-15, default 0) - * @returns A MIDIMessage - */ - static MIDIMessage AllNotesOff(int channel = 0) { - return ControlChange(123, 0, channel); - } - - // decode messages - - /** MIDI Message Types */ - enum MIDIMessageType { - ErrorType, - NoteOffType, - NoteOnType, - PolyphonicAftertouchType, - ControlChangeType, - ProgramChangeType, - ChannelAftertouchType, - PitchWheelType, - AllNotesOffType - }; - - /** Read the message type - * @returns MIDIMessageType - */ - MIDIMessageType type() { - switch((data[1] >> 4) & 0xF) { - case 0x8: return NoteOffType; - case 0x9: return NoteOnType; - case 0xA: return PolyphonicAftertouchType; - case 0xB: - if(controller() < 120) { // standard controllers - return ControlChangeType; - } else if(controller() == 123) { - return AllNotesOffType; - } else { - return ErrorType; // unsupported atm - } - case 0xC: return ProgramChangeType; - case 0xD: return ChannelAftertouchType; - case 0xE: return PitchWheelType; - default: return ErrorType; - } - } - - /** Read the channel number */ - int channel() { - return (data[1] & 0x0F); - } - - /** Read the key ID */ - int key() { - return (data[2] & 0x7F); - } - - /** Read the velocity */ - int velocity() { - return (data[3] & 0x7F); - } - - /** Read the controller value */ - int value() { - return (data[3] & 0x7F); - } - - /** Read the aftertouch pressure */ - int pressure() { - if(type() == PolyphonicAftertouchType) { - return (data[3] & 0x7F); - } else { - return (data[2] & 0x7F); - } - } - - /** Read the controller number */ - int controller() { - return (data[2] & 0x7F); - } - - /** Read the program number */ - int program() { - return (data[2] & 0x7F); - } - - /** Read the pitch value */ - int pitch() { - int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F); - return p - 8192; // 0 - 16383, 8192 is center - } - - uint8_t data[4]; -}; - -#endif
diff -r 335f2506f422 -r d2619b040139 USBMIDI/USBMIDI.cpp --- a/USBMIDI/USBMIDI.cpp Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "stdint.h" -#include "USBMIDI.h" - - -USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) { - midi_evt = NULL; - USBDevice::connect(); -} - -void USBMIDI::write(MIDIMessage m) { - USBDevice::write(EPBULK_IN, m.data, 4, MAX_PACKET_SIZE_EPBULK); -} - - -void USBMIDI::attach(void (*fptr)(MIDIMessage)) { - midi_evt = fptr; -} - - -bool USBMIDI::EP2_OUT_callback() { - uint8_t buf[64]; - uint32_t len; - readEP(EPBULK_OUT, buf, &len, 64); - - if (midi_evt != NULL) { - for (int i=0; i<len; i+=4) { - midi_evt(MIDIMessage(buf+i)); - } - } - - // We reactivate the endpoint to receive next characters - readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); - return true; -} - - - -// Called in ISR context -// Set configuration. Return false if the -// configuration is not supported. -bool USBMIDI::USBCallback_setConfiguration(uint8_t configuration) { - if (configuration != DEFAULT_CONFIGURATION) { - return false; - } - - // 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 * USBMIDI::stringIinterfaceDesc() { - static uint8_t stringIinterfaceDescriptor[] = { - 0x0c, //bLength - STRING_DESCRIPTOR, //bDescriptorType 0x03 - 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio - }; - return stringIinterfaceDescriptor; -} - -uint8_t * USBMIDI::stringIproductDesc() { - static uint8_t stringIproductDescriptor[] = { - 0x16, //bLength - STRING_DESCRIPTOR, //bDescriptorType 0x03 - 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio - }; - return stringIproductDescriptor; -} - - -uint8_t * USBMIDI::configurationDesc() { - static uint8_t configDescriptor[] = { - // configuration descriptor - 0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50, - - // The Audio Interface Collection - 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor - 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor - 0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors - 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor - - // MIDI IN JACKS - 0x06, 0x24, 0x02, 0x01, 0x01, 0x00, - 0x06, 0x24, 0x02, 0x02, 0x02, 0x00, - - // MIDI OUT JACKS - 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, - 0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00, - - // OUT endpoint descriptor - 0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x25, 0x01, 0x01, 0x01, - - // IN endpoint descriptor - 0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x25, 0x01, 0x01, 0x03, - }; - return configDescriptor; -}
diff -r 335f2506f422 -r d2619b040139 USBMIDI/USBMIDI.h --- a/USBMIDI/USBMIDI.h Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef USBMIDI_H -#define USBMIDI_H - -/* These headers are included for child class. */ -#include "USBEndpoints.h" -#include "USBDescriptor.h" -#include "USBDevice_Types.h" - -#include "USBDevice.h" -#include "MIDIMessage.h" - -#define DEFAULT_CONFIGURATION (1) - -/** -* USBMIDI example -* -* @code -* #include "mbed.h" -* #include "USBMIDI.h" -* -* USBMIDI midi; -* -* int main() { -* while (1) { -* for(int i=48; i<83; i++) { // send some messages! -* midi.write(MIDIMessage::NoteOn(i)); -* wait(0.25); -* midi.write(MIDIMessage::NoteOff(i)); -* wait(0.5); -* } -* } -* } -* @endcode -*/ -class USBMIDI: public USBDevice { -public: - - /** - * Constructor - * - * @param vendor_id Your vendor_id - * @param product_id Your product_id - * @param product_release Your preoduct_release - */ - USBMIDI(uint16_t vendor_id = 0x0700, uint16_t product_id = 0x0101, uint16_t product_release = 0x0001); - - /** - * Send a MIDIMessage - * - * @param m The MIDIMessage to send - */ - void write(MIDIMessage m); - - /** - * Attach a callback for when a MIDIEvent is received - * - * @param fptr function pointer - */ - void attach(void (*fptr)(MIDIMessage)); - - -protected: - virtual bool EP2_OUT_callback(); - virtual bool USBCallback_setConfiguration(uint8_t configuration); - /* - * Get string product descriptor - * - * @returns pointer to the string product descriptor - */ - virtual uint8_t * stringIproductDesc(); - - /* - * Get string interface descriptor - * - * @returns pointer to the string interface descriptor - */ - virtual uint8_t * stringIinterfaceDesc(); - - /* - * Get configuration descriptor - * - * @returns pointer to the configuration descriptor - */ - virtual uint8_t * configurationDesc(); - -private: - void (*midi_evt)(MIDIMessage); - -}; - -#endif
diff -r 335f2506f422 -r d2619b040139 USBMSD/USBMSD.cpp --- a/USBMSD/USBMSD.cpp Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,645 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "stdint.h" -#include "USBMSD.h" - -#define DISK_OK 0x00 -#define NO_INIT 0x01 -#define NO_DISK 0x02 -#define WRITE_PROTECT 0x04 - -#define CBW_Signature 0x43425355 -#define CSW_Signature 0x53425355 - -// SCSI Commands -#define TEST_UNIT_READY 0x00 -#define REQUEST_SENSE 0x03 -#define FORMAT_UNIT 0x04 -#define INQUIRY 0x12 -#define MODE_SELECT6 0x15 -#define MODE_SENSE6 0x1A -#define START_STOP_UNIT 0x1B -#define MEDIA_REMOVAL 0x1E -#define READ_FORMAT_CAPACITIES 0x23 -#define READ_CAPACITY 0x25 -#define READ10 0x28 -#define WRITE10 0x2A -#define VERIFY10 0x2F -#define READ12 0xA8 -#define WRITE12 0xAA -#define MODE_SELECT10 0x55 -#define MODE_SENSE10 0x5A - -// MSC class specific requests -#define MSC_REQUEST_RESET 0xFF -#define MSC_REQUEST_GET_MAX_LUN 0xFE - -#define DEFAULT_CONFIGURATION (1) - -// max packet size -#define MAX_PACKET MAX_PACKET_SIZE_EPBULK - -// CSW Status -enum Status { - CSW_PASSED, - CSW_FAILED, - CSW_ERROR, -}; - - -USBMSD::USBMSD(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) { - stage = READ_CBW; - memset((void *)&cbw, 0, sizeof(CBW)); - memset((void *)&csw, 0, sizeof(CSW)); -} - - - -// Called in ISR context to process a class specific request -bool USBMSD::USBCallback_request(void) { - - bool success = false; - CONTROL_TRANSFER * transfer = getTransferPtr(); - static uint8_t maxLUN[1] = {0}; - - if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { - switch (transfer->setup.bRequest) { - case MSC_REQUEST_RESET: - reset(); - success = true; - break; - case MSC_REQUEST_GET_MAX_LUN: - transfer->remaining = 1; - transfer->ptr = maxLUN; - transfer->direction = DEVICE_TO_HOST; - success = true; - break; - default: - break; - } - } - - return success; -} - - -bool USBMSD::connect() { - - //disk initialization - if (disk_status() & NO_INIT) { - if (disk_initialize()) { - return false; - } - } - - // get number of blocks - BlockCount = disk_sectors(); - - // get memory size - MemorySize = disk_size(); - - if (BlockCount > 0) { - BlockSize = MemorySize / BlockCount; - if (BlockSize != 0) { - page = (uint8_t *)malloc(BlockSize * sizeof(uint8_t)); - if (page == NULL) - return false; - } - } else { - return false; - } - - //connect the device - USBDevice::connect(); - return true; -} - - -void USBMSD::reset() { - stage = READ_CBW; -} - - -// Called in ISR context called when a data is received -bool USBMSD::EP2_OUT_callback() { - uint32_t size = 0; - uint8_t buf[MAX_PACKET_SIZE_EPBULK]; - readEP(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK); - switch (stage) { - // the device has to decode the CBW received - case READ_CBW: - CBWDecode(buf, size); - break; - - // the device has to receive data from the host - case PROCESS_CBW: - switch (cbw.CB[0]) { - case WRITE10: - case WRITE12: - memoryWrite(buf, size); - break; - case VERIFY10: - memoryVerify(buf, size); - break; - } - break; - - // an error has occured: stall endpoint and send CSW - default: - stallEndpoint(EPBULK_OUT); - csw.Status = CSW_ERROR; - sendCSW(); - break; - } - - //reactivate readings on the OUT bulk endpoint - readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); - return true; -} - -// Called in ISR context when a data has been transferred -bool USBMSD::EP2_IN_callback() { - switch (stage) { - - // the device has to send data to the host - case PROCESS_CBW: - switch (cbw.CB[0]) { - case READ10: - case READ12: - memoryRead(); - break; - } - break; - - //the device has to send a CSW - case SEND_CSW: - sendCSW(); - break; - - // an error has occured - case ERROR: - stallEndpoint(EPBULK_IN); - sendCSW(); - break; - - // the host has received the CSW -> we wait a CBW - case WAIT_CSW: - stage = READ_CBW; - break; - } - return true; -} - - -void USBMSD::memoryWrite (uint8_t * buf, uint16_t size) { - - if ((addr + size) > MemorySize) { - size = MemorySize - addr; - stage = ERROR; - stallEndpoint(EPBULK_OUT); - } - - // we fill an array in RAM of 1 block before writing it in memory - for (int i = 0; i < size; i++) - page[addr%BlockSize + i] = buf[i]; - - // if the array is filled, write it in memory - if (!((addr + size)%BlockSize)) { - if (!(disk_status() & WRITE_PROTECT)) { - disk_write(page, addr/BlockSize); - } - } - - addr += size; - length -= size; - csw.DataResidue -= size; - - if ((!length) || (stage != PROCESS_CBW)) { - csw.Status = (stage == ERROR) ? CSW_FAILED : CSW_PASSED; - sendCSW(); - } -} - -void USBMSD::memoryVerify (uint8_t * buf, uint16_t size) { - uint32_t n; - - if ((addr + size) > MemorySize) { - size = MemorySize - addr; - stage = ERROR; - stallEndpoint(EPBULK_OUT); - } - - // beginning of a new block -> load a whole block in RAM - if (!(addr%BlockSize)) - disk_read(page, addr/BlockSize); - - // info are in RAM -> no need to re-read memory - for (n = 0; n < size; n++) { - if (page[addr%BlockSize + n] != buf[n]) { - memOK = false; - break; - } - } - - addr += size; - length -= size; - csw.DataResidue -= size; - - if ( !length || (stage != PROCESS_CBW)) { - csw.Status = (memOK && (stage == PROCESS_CBW)) ? CSW_PASSED : CSW_FAILED; - sendCSW(); - } -} - - -bool USBMSD::inquiryRequest (void) { - uint8_t inquiry[] = { 0x00, 0x80, 0x00, 0x01, - 36 - 4, 0x80, 0x00, 0x00, - 'M', 'B', 'E', 'D', '.', 'O', 'R', 'G', - 'M', 'B', 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', 'K', ' ', ' ', ' ', - '1', '.', '0', ' ', - }; - if (!write(inquiry, sizeof(inquiry))) { - return false; - } - return true; -} - - -bool USBMSD::readFormatCapacity() { - uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08, - (BlockCount >> 24) & 0xff, - (BlockCount >> 16) & 0xff, - (BlockCount >> 8) & 0xff, - (BlockCount >> 0) & 0xff, - - 0x02, - (BlockSize >> 16) & 0xff, - (BlockSize >> 8) & 0xff, - (BlockSize >> 0) & 0xff, - }; - if (!write(capacity, sizeof(capacity))) { - return false; - } - return true; -} - - -bool USBMSD::readCapacity (void) { - uint8_t capacity[] = { - ((BlockCount - 1) >> 24) & 0xff, - ((BlockCount - 1) >> 16) & 0xff, - ((BlockCount - 1) >> 8) & 0xff, - ((BlockCount - 1) >> 0) & 0xff, - - (BlockSize >> 24) & 0xff, - (BlockSize >> 16) & 0xff, - (BlockSize >> 8) & 0xff, - (BlockSize >> 0) & 0xff, - }; - if (!write(capacity, sizeof(capacity))) { - return false; - } - return true; -} - -bool USBMSD::write (uint8_t * buf, uint16_t size) { - - if (size >= cbw.DataLength) { - size = cbw.DataLength; - } - stage = SEND_CSW; - - if (!writeNB(EPBULK_IN, buf, size, MAX_PACKET_SIZE_EPBULK)) { - return false; - } - - csw.DataResidue -= size; - csw.Status = CSW_PASSED; - return true; -} - - -bool USBMSD::modeSense6 (void) { - uint8_t sense6[] = { 0x03, 0x00, 0x00, 0x00 }; - if (!write(sense6, sizeof(sense6))) { - return false; - } - return true; -} - -void USBMSD::sendCSW() { - csw.Signature = CSW_Signature; - writeNB(EPBULK_IN, (uint8_t *)&csw, sizeof(CSW), MAX_PACKET_SIZE_EPBULK); - stage = WAIT_CSW; -} - -bool USBMSD::requestSense (void) { - uint8_t request_sense[] = { - 0x70, - 0x00, - 0x05, // Sense Key: illegal request - 0x00, - 0x00, - 0x00, - 0x00, - 0x0A, - 0x00, - 0x00, - 0x00, - 0x00, - 0x30, - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - }; - - if (!write(request_sense, sizeof(request_sense))) { - return false; - } - - return true; -} - -void USBMSD::fail() { - csw.Status = CSW_FAILED; - sendCSW(); -} - - -void USBMSD::CBWDecode(uint8_t * buf, uint16_t size) { - if (size == sizeof(cbw)) { - memcpy((uint8_t *)&cbw, buf, size); - if (cbw.Signature == CBW_Signature) { - csw.Tag = cbw.Tag; - csw.DataResidue = cbw.DataLength; - if ((cbw.CBLength < 1) || (cbw.CBLength > 16) ) { - fail(); - } else { - switch (cbw.CB[0]) { - case TEST_UNIT_READY: - testUnitReady(); - break; - case REQUEST_SENSE: - requestSense(); - break; - case INQUIRY: - inquiryRequest(); - break; - case MODE_SENSE6: - modeSense6(); - break; - case READ_FORMAT_CAPACITIES: - readFormatCapacity(); - break; - case READ_CAPACITY: - readCapacity(); - break; - case READ10: - case READ12: - if (infoTransfer()) { - if ((cbw.Flags & 0x80)) { - stage = PROCESS_CBW; - memoryRead(); - } else { - stallEndpoint(EPBULK_OUT); - csw.Status = CSW_ERROR; - sendCSW(); - } - } - break; - case WRITE10: - case WRITE12: - if (infoTransfer()) { - if (!(cbw.Flags & 0x80)) { - stage = PROCESS_CBW; - } else { - stallEndpoint(EPBULK_IN); - csw.Status = CSW_ERROR; - sendCSW(); - } - } - break; - case VERIFY10: - if (!(cbw.CB[1] & 0x02)) { - csw.Status = CSW_PASSED; - sendCSW(); - break; - } - if (infoTransfer()) { - if (!(cbw.Flags & 0x80)) { - stage = PROCESS_CBW; - memOK = true; - } else { - stallEndpoint(EPBULK_IN); - csw.Status = CSW_ERROR; - sendCSW(); - } - } - break; - case MEDIA_REMOVAL: - csw.Status = CSW_PASSED; - sendCSW(); - break; - default: - fail(); - break; - } - } - } - } -} - -void USBMSD::testUnitReady (void) { - - if (cbw.DataLength != 0) { - if ((cbw.Flags & 0x80) != 0) { - stallEndpoint(EPBULK_IN); - } else { - stallEndpoint(EPBULK_OUT); - } - } - - csw.Status = CSW_PASSED; - sendCSW(); -} - - -void USBMSD::memoryRead (void) { - uint32_t n; - - n = (length > MAX_PACKET) ? MAX_PACKET : length; - - if ((addr + n) > MemorySize) { - n = MemorySize - addr; - stage = ERROR; - } - - // we read an entire block - if (!(addr%BlockSize)) - disk_read(page, addr/BlockSize); - - // write data which are in RAM - writeNB(EPBULK_IN, &page[addr%BlockSize], n, MAX_PACKET_SIZE_EPBULK); - - addr += n; - length -= n; - - csw.DataResidue -= n; - - if ( !length || (stage != PROCESS_CBW)) { - csw.Status = (stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED; - stage = (stage == PROCESS_CBW) ? SEND_CSW : stage; - } -} - - -bool USBMSD::infoTransfer (void) { - uint32_t n; - - // Logical Block Address of First Block - n = (cbw.CB[2] << 24) | (cbw.CB[3] << 16) | (cbw.CB[4] << 8) | (cbw.CB[5] << 0); - - addr = n * BlockSize; - - // Number of Blocks to transfer - switch (cbw.CB[0]) { - case READ10: - case WRITE10: - case VERIFY10: - n = (cbw.CB[7] << 8) | (cbw.CB[8] << 0); - break; - - case READ12: - case WRITE12: - n = (cbw.CB[6] << 24) | (cbw.CB[7] << 16) | (cbw.CB[8] << 8) | (cbw.CB[9] << 0); - break; - } - - length = n * BlockSize; - - if (!cbw.DataLength) { // host requests no data - csw.Status = CSW_FAILED; - sendCSW(); - return false; - } - - if (cbw.DataLength != length) { - if ((cbw.Flags & 0x80) != 0) { - stallEndpoint(EPBULK_IN); - } else { - stallEndpoint(EPBULK_OUT); - } - - csw.Status = CSW_FAILED; - sendCSW(); - return false; - } - - return true; -} - - - - - -// Called in ISR context -// Set configuration. Return false if the -// configuration is not supported. -bool USBMSD::USBCallback_setConfiguration(uint8_t configuration) { - if (configuration != DEFAULT_CONFIGURATION) { - return false; - } - - // Configure endpoints > 0 - addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK); - addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); - - //activate readings - readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); - return true; -} - - -uint8_t * USBMSD::stringIinterfaceDesc() { - static uint8_t stringIinterfaceDescriptor[] = { - 0x08, //bLength - STRING_DESCRIPTOR, //bDescriptorType 0x03 - 'M',0,'S',0,'D',0 //bString iInterface - MSD - }; - return stringIinterfaceDescriptor; -} - -uint8_t * USBMSD::stringIproductDesc() { - static uint8_t stringIproductDescriptor[] = { - 0x12, //bLength - STRING_DESCRIPTOR, //bDescriptorType 0x03 - 'M',0,'b',0,'e',0,'d',0,' ',0,'M',0,'S',0,'D',0 //bString iProduct - Mbed Audio - }; - return stringIproductDescriptor; -} - - -uint8_t * USBMSD::configurationDesc() { - static uint8_t configDescriptor[] = { - - // Configuration 1 - 9, // bLength - 2, // bDescriptorType - LSB(9 + 9 + 7 + 7), // wTotalLength - MSB(9 + 9 + 7 + 7), - 0x01, // bNumInterfaces - 0x01, // bConfigurationValue: 0x01 is used to select this configuration - 0x00, // iConfiguration: no string to describe this configuration - 0xC0, // bmAttributes - 100, // bMaxPower, device power consumption is 100 mA - - // Interface 0, Alternate Setting 0, MSC Class - 9, // bLength - 4, // bDescriptorType - 0x00, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x02, // bNumEndpoints - 0x08, // bInterfaceClass - 0x06, // bInterfaceSubClass - 0x50, // bInterfaceProtocol - 0x04, // iInterface - - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - 7, // bLength - 5, // bDescriptorType - PHY_TO_DESC(EPBULK_IN), // bEndpointAddress - 0x02, // bmAttributes (0x02=bulk) - LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) - 0, // bInterval - - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - 7, // bLength - 5, // bDescriptorType - PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress - 0x02, // bmAttributes (0x02=bulk) - LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) - 0 // bInterval - }; - return configDescriptor; -}
diff -r 335f2506f422 -r d2619b040139 USBMSD/USBMSD.h --- a/USBMSD/USBMSD.h Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,239 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - - -#ifndef USBMSD_H -#define USBMSD_H - -/* These headers are included for child class. */ -#include "USBEndpoints.h" -#include "USBDescriptor.h" -#include "USBDevice_Types.h" - -#include "USBDevice.h" - -/** - * USBMSD class: generic class in order to use all kinds of blocks storage chip - * - * Introduction - * - * The USBMSD implements the MSD protocol. It permits to access a memory chip (flash, sdcard,...) - * from a computer over USB. But this class doesn't work standalone, you need to subclass this class - * and define virtual functions which are called in USBMSD. - * - * How to use this class with your chip ? - * - * You have to inherit and define some pure virtual functions (mandatory step): - * - virtual int disk_read(char * data, int block): function to read a block - * - virtual int disk_write(const char * data, int block): function to write a block - * - virtual int disk_initialize(): function to initialize the memory - * - virtual int disk_sectors(): return the number of blocks - * - virtual int disk_size(): return the memory size - * - virtual int disk_status(): return the status of the storage chip (0: OK, 1: not initialized, 2: no medium in the drive, 4: write protection) - * - * All functions names are compatible with the fat filesystem library. So you can imagine using your own class with - * USBMSD and the fat filesystem library in the same program. Just be careful because there are two different parts which - * will access the sd card. You can do a master/slave system using the disk_status method. - * - * Once these functions defined, you can call connect() (at the end of the constructor of your class for instance) - * of USBMSD to connect your mass storage device. connect() will first call disk_status() to test the status of the disk. - * If disk_status() returns 1 (disk not initialized), then disk_initialize() is called. After this step, connect() will collect information - * such as the number of blocks and the memory size. - */ -class USBMSD: public USBDevice { -public: - - /** - * Constructor - * - * @param vendor_id Your vendor_id - * @param product_id Your product_id - * @param product_release Your preoduct_release - */ - USBMSD(uint16_t vendor_id = 0x0703, uint16_t product_id = 0x0104, uint16_t product_release = 0x0001); - - /** - * Connect the USB MSD device. Establish disk initialization before really connect the device. - * - * @returns true if successful - */ - bool connect(); - - -protected: - - /* - * read a block on a storage chip - * - * @param data pointer where will be stored read data - * @param block block number - * @returns 0 if successful - */ - virtual int disk_read(uint8_t * data, uint64_t block) = 0; - - /* - * write a block on a storage chip - * - * @param data data to write - * @param block block number - * @returns 0 if successful - */ - virtual int disk_write(const uint8_t * data, uint64_t block) = 0; - - /* - * Disk initilization - */ - virtual int disk_initialize() = 0; - - /* - * Return the number of blocks - * - * @returns number of blocks - */ - virtual uint64_t disk_sectors() = 0; - - /* - * Return memory size - * - * @returns memory size - */ - virtual uint64_t disk_size() = 0; - - - /* - * To check the status of the storage chip - * - * @returns status: 0: OK, 1: disk not initialized, 2: no medium in the drive, 4: write protected - */ - virtual int disk_status() = 0; - - /* - * Get string product descriptor - * - * @returns pointer to the string product descriptor - */ - virtual uint8_t * stringIproductDesc(); - - /* - * Get string interface descriptor - * - * @returns pointer to the string interface descriptor - */ - virtual uint8_t * stringIinterfaceDesc(); - - /* - * Get configuration descriptor - * - * @returns pointer to the configuration descriptor - */ - virtual uint8_t * configurationDesc(); - - /* - * Callback called when a packet is received - */ - virtual bool EP2_OUT_callback(); - - /* - * Callback called when a packet has been sent - */ - virtual bool EP2_IN_callback(); - - /* - * Set configuration of device. Add endpoints - */ - virtual bool USBCallback_setConfiguration(uint8_t configuration); - - /* - * Callback called to process class specific requests - */ - virtual bool USBCallback_request(); - - -private: - - // MSC Bulk-only Stage - enum Stage { - READ_CBW, // wait a CBW - ERROR, // error - PROCESS_CBW, // process a CBW request - SEND_CSW, // send a CSW - WAIT_CSW, // wait that a CSW has been effectively sent - }; - - // Bulk-only CBW - typedef __packed struct { - uint32_t Signature; - uint32_t Tag; - uint32_t DataLength; - uint8_t Flags; - uint8_t LUN; - uint8_t CBLength; - uint8_t CB[16]; - } CBW; - - // Bulk-only CSW - typedef __packed struct { - uint32_t Signature; - uint32_t Tag; - uint32_t DataResidue; - uint8_t Status; - } CSW; - - //state of the bulk-only state machine - Stage stage; - - // current CBW - CBW cbw; - - // CSW which will be sent - CSW csw; - - // addr where will be read or written data - uint32_t addr; - - // length of a reading or writing - uint32_t length; - - // memory OK (after a memoryVerify) - bool memOK; - - // cache in RAM before writing in memory. Useful also to read a block. - uint8_t * page; - - int BlockSize; - uint64_t MemorySize; - uint64_t BlockCount; - - void CBWDecode(uint8_t * buf, uint16_t size); - void sendCSW (void); - bool inquiryRequest (void); - bool write (uint8_t * buf, uint16_t size); - bool readFormatCapacity(); - bool readCapacity (void); - bool infoTransfer (void); - void memoryRead (void); - bool modeSense6 (void); - void testUnitReady (void); - bool requestSense (void); - void memoryVerify (uint8_t * buf, uint16_t size); - void memoryWrite (uint8_t * buf, uint16_t size); - void reset(); - void fail(); -}; - -#endif
diff -r 335f2506f422 -r d2619b040139 USBSerial/CircBuffer.h --- a/USBSerial/CircBuffer.h Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef CIRCBUFFER_H -#define CIRCBUFFER_H - -template <class T> -class CircBuffer { -public: - CircBuffer(int length) { - write = 0; - read = 0; - size = length + 1; - buf = (T *)malloc(size * sizeof(T)); - }; - - bool isFull() { - return ((write + 1) % size == read); - }; - - bool isEmpty() { - return (read == write); - }; - - void queue(T k) { - if (isFull()) { - read++; - read %= size; - } - buf[write++] = k; - write %= size; - } - - uint16_t available() { - return (write >= read) ? write - read : size - read + write; - }; - - bool dequeue(T * c) { - bool empty = isEmpty(); - if (!empty) { - *c = buf[read++]; - read %= size; - } - return(!empty); - }; - -private: - volatile uint16_t write; - volatile uint16_t read; - uint16_t size; - T * buf; -}; - -#endif
diff -r 335f2506f422 -r d2619b040139 USBSerial/USBCDC.cpp --- a/USBSerial/USBCDC.cpp Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,253 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "stdint.h" -#include "USBCDC.h" - -static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08}; - -#define DEFAULT_CONFIGURATION (1) - -#define CDC_SET_LINE_CODING 0x20 -#define CDC_GET_LINE_CODING 0x21 -#define CDC_SET_CONTROL_LINE_STATE 0x22 - -#define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK - -USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) { - terminal_connected = false; - USBDevice::connect(); -} - -bool USBCDC::USBCallback_request(void) { - /* Called in ISR context */ - - bool success = false; - CONTROL_TRANSFER * transfer = getTransferPtr(); - - /* Process class-specific requests */ - - if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { - switch (transfer->setup.bRequest) { - case CDC_GET_LINE_CODING: - transfer->remaining = 7; - transfer->ptr = cdc_line_coding; - transfer->direction = DEVICE_TO_HOST; - success = true; - break; - case CDC_SET_LINE_CODING: - transfer->remaining = 7; - success = true; - terminal_connected = true; - break; - case CDC_SET_CONTROL_LINE_STATE: - terminal_connected = false; - success = true; - break; - default: - break; - } - } - - return success; -} - - -// Called in ISR context -// Set configuration. Return false if the -// configuration is not supported. -bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) { - if (configuration != DEFAULT_CONFIGURATION) { - return false; - } - - // Configure endpoints > 0 - addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); - addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK); - addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); - - // We activate the endpoint to be able to recceive data - readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); - return true; -} - -bool USBCDC::send(uint8_t * buffer, uint32_t size) { - return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE); -} - -bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) { - if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) - return false; - if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) - return false; - return true; -} - -bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) { - if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) - return false; - if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) - return false; - return true; -} - - -uint8_t * USBCDC::deviceDesc() { - static uint8_t deviceDescriptor[] = { - 18, // bLength - 1, // bDescriptorType - 0x10, 0x01, // bcdUSB - 2, // bDeviceClass - 0, // bDeviceSubClass - 0, // bDeviceProtocol - MAX_PACKET_SIZE_EP0, // bMaxPacketSize0 - LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor - LSB(PRODUCT_ID), MSB(PRODUCT_ID),// idProduct - 0x00, 0x01, // bcdDevice - 1, // iManufacturer - 2, // iProduct - 3, // iSerialNumber - 1 // bNumConfigurations - }; - return deviceDescriptor; -} - -uint8_t * USBCDC::stringIinterfaceDesc() { - static uint8_t stringIinterfaceDescriptor[] = { - 0x08, - STRING_DESCRIPTOR, - 'C',0,'D',0,'C',0, - }; - return stringIinterfaceDescriptor; -} - -uint8_t * USBCDC::stringIproductDesc() { - static uint8_t stringIproductDescriptor[] = { - 0x16, - STRING_DESCRIPTOR, - 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 - }; - return stringIproductDescriptor; -} - - -#define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7) - -uint8_t * USBCDC::configurationDesc() { - static uint8_t configDescriptor[] = { - // configuration descriptor - 9, // bLength - 2, // bDescriptorType - LSB(CONFIG1_DESC_SIZE), // wTotalLength - MSB(CONFIG1_DESC_SIZE), - 2, // bNumInterfaces - 1, // bConfigurationValue - 0, // iConfiguration - 0x80, // bmAttributes - 50, // bMaxPower - - // IAD to associate the two CDC interfaces - 0x08, // bLength - 0x0b, // bDescriptorType - 0x00, // bFirstInterface - 0x02, // bInterfaceCount - 0x02, // bFunctionClass - 0x02, // bFunctionSubClass - 0, // bFunctionProtocol - 0, // iFunction - - // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 - 9, // bLength - 4, // bDescriptorType - 0, // bInterfaceNumber - 0, // bAlternateSetting - 1, // bNumEndpoints - 0x02, // bInterfaceClass - 0x02, // bInterfaceSubClass - 0x01, // bInterfaceProtocol - 0, // iInterface - - // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 - 5, // bFunctionLength - 0x24, // bDescriptorType - 0x00, // bDescriptorSubtype - 0x10, 0x01, // bcdCDC - - // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 - 5, // bFunctionLength - 0x24, // bDescriptorType - 0x01, // bDescriptorSubtype - 0x03, // bmCapabilities - 1, // bDataInterface - - // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 - 4, // bFunctionLength - 0x24, // bDescriptorType - 0x02, // bDescriptorSubtype - 0x06, // bmCapabilities - - // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 - 5, // bFunctionLength - 0x24, // bDescriptorType - 0x06, // bDescriptorSubtype - 0, // bMasterInterface - 1, // bSlaveInterface0 - - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPINT_IN), // bEndpointAddress - E_INTERRUPT, // bmAttributes (0x03=intr) - LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) - 16, // bInterval - - - - - // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 - 9, // bLength - 4, // bDescriptorType - 1, // bInterfaceNumber - 0, // bAlternateSetting - 2, // bNumEndpoints - 0x0A, // bInterfaceClass - 0x00, // bInterfaceSubClass - 0x00, // bInterfaceProtocol - 0, // iInterface - - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPBULK_IN), // bEndpointAddress - E_BULK, // bmAttributes (0x02=bulk) - LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) - 0, // bInterval - - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress - E_BULK, // bmAttributes (0x02=bulk) - LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) - 0 // bInterval - }; - return configDescriptor; -}
diff -r 335f2506f422 -r d2619b040139 USBSerial/USBCDC.h --- a/USBSerial/USBCDC.h Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef USBCDC_H -#define USBCDC_H - -/* These headers are included for child class. */ -#include "USBEndpoints.h" -#include "USBDescriptor.h" -#include "USBDevice_Types.h" - -#include "USBDevice.h" - -class USBCDC: public USBDevice { -public: - - /* - * Constructor - * - * @param vendor_id Your vendor_id - * @param product_id Your product_id - * @param product_release Your preoduct_release - */ - USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release); - -protected: - - /* - * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength. - * - * @returns pointer to the device descriptor - */ - virtual uint8_t * deviceDesc(); - - /* - * Get string product descriptor - * - * @returns pointer to the string product descriptor - */ - virtual uint8_t * stringIproductDesc(); - - /* - * Get string interface descriptor - * - * @returns pointer to the string interface descriptor - */ - virtual uint8_t * stringIinterfaceDesc(); - - /* - * Get configuration descriptor - * - * @returns pointer to the configuration descriptor - */ - virtual uint8_t * configurationDesc(); - - /* - * Send a buffer - * - * @param endpoint endpoint which will be sent the buffer - * @param buffer buffer to be sent - * @param size length of the buffer - * @returns true if successful - */ - bool send(uint8_t * buffer, uint32_t size); - - /* - * Read a buffer from a certain endpoint. Warning: blocking - * - * @param endpoint endpoint to read - * @param buffer buffer where will be stored bytes - * @param size the number of bytes read will be stored in *size - * @param maxSize the maximum length that can be read - * @returns true if successful - */ - bool readEP(uint8_t * buffer, uint32_t * size); - - /* - * Read a buffer from a certain endpoint. Warning: non blocking - * - * @param endpoint endpoint to read - * @param buffer buffer where will be stored bytes - * @param size the number of bytes read will be stored in *size - * @param maxSize the maximum length that can be read - * @returns true if successful - */ - bool readEP_NB(uint8_t * buffer, uint32_t * size); - -protected: - virtual bool USBCallback_request(); - virtual bool USBCallback_setConfiguration(uint8_t configuration); - volatile bool terminal_connected; - -}; - -#endif
diff -r 335f2506f422 -r d2619b040139 USBSerial/USBSerial.cpp --- a/USBSerial/USBSerial.cpp Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "stdint.h" -#include "USBSerial.h" - -int USBSerial::_putc(int c) { - if (!terminal_connected) - return 0; - send((uint8_t *)&c, 1); - return 1; -} - -int USBSerial::_getc() { - uint8_t c; - while (buf.isEmpty()); - buf.dequeue(&c); - return c; -} - - -bool USBSerial::writeBlock(uint8_t * buf, uint16_t size) { - if(size > MAX_PACKET_SIZE_EPBULK) { - return false; - } - if(!send(buf, size)) { - return false; - } - return true; -} - - - -bool USBSerial::EP2_OUT_callback() { - uint8_t c[65]; - uint32_t size = 0; - - //we read the packet received and put it on the circular buffer - readEP(c, &size); - for (int i = 0; i < size; i++) { - buf.queue(c[i]); - } - - //call a potential handler - rx.call(); - - // We reactivate the endpoint to receive next characters - readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); - return true; -} - -uint8_t USBSerial::available() { - return buf.available(); -}
diff -r 335f2506f422 -r d2619b040139 USBSerial/USBSerial.h --- a/USBSerial/USBSerial.h Fri Mar 01 13:10:29 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -/* Copyright (c) 2010-2011 mbed.org, MIT License -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software -* and associated documentation files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or -* substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef USBSERIAL_H -#define USBSERIAL_H - -#include "USBCDC.h" -#include "Stream.h" -#include "CircBuffer.h" - - -/** -* USBSerial example -* -* @code -* #include "mbed.h" -* #include "USBSerial.h" -* -* //Virtual serial port over USB -* USBSerial serial; -* -* int main(void) { -* -* while(1) -* { -* serial.printf("I am a virtual serial port\n"); -* wait(1); -* } -* } -* @endcode -*/ -class USBSerial: public USBCDC, public Stream { -public: - - /** - * Constructor - * - * @param vendor_id Your vendor_id (default: 0x1f00) - * @param product_id Your product_id (default: 0x2012) - * @param product_release Your preoduct_release (default: 0x0001) - * - */ - USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001): USBCDC(vendor_id, product_id, product_release), buf(128){ }; - - - /** - * Send a character. You can use puts, printf. - * - * @param c character to be sent - * @returns true if there is no error, false otherwise - */ - virtual int _putc(int c); - - /** - * Read a character: blocking - * - * @returns character read - */ - virtual int _getc(); - - /** - * Check the number of bytes available. - * - * @returns the number of bytes available - */ - uint8_t available(); - - /** - * Write a block of data. - * - * For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written. - * - * @param buf pointer on data which will be written - * @param size size of the buffer. The maximum size of a block is limited by the size of the endpoint (64 bytes) - * - * @returns true if successfull - */ - bool writeBlock(uint8_t * buf, uint16_t size); - - /** - * Attach a member function to call when a packet is received. - * - * @param tptr pointer to the object to call the member function on - * @param mptr pointer to the member function to be called - */ - template<typename T> - void attach(T* tptr, void (T::*mptr)(void)) { - if((mptr != NULL) && (tptr != NULL)) { - rx.attach(tptr, mptr); - } - } - - /** - * Attach a callback called when a packet is received - * - * @param fptr function pointer - */ - void attach(void (*fn)(void)) { - if(fn != NULL) { - rx.attach(fn); - } - } - - -protected: - virtual bool EP2_OUT_callback(); - -private: - FunctionPointer rx; - CircBuffer<uint8_t> buf; -}; - -#endif