Added general purpus HID report
Fork of USBDevice by
Revision 28:6cc8a2d36729, committed 2014-08-15
- Comitter:
- betaEncoder
- Date:
- Fri Aug 15 14:14:38 2014 +0000
- Parent:
- 27:0c6524151939
- Commit message:
- First commit
Changed in this revision
diff -r 0c6524151939 -r 6cc8a2d36729 USBAudio/USBAudio.cpp --- a/USBAudio/USBAudio.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /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 - (uint8_t)(LSB(channel_config_in)), // wChannelConfig - (uint8_t)(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 - (uint8_t)(LSB(channel_config_out)), // wChannelConfig - (uint8_t)(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 - (uint8_t)(LSB(FREQ_IN)), // tSamFreq - (uint8_t)((FREQ_IN >> 8) & 0xff), // tSamFreq - (uint8_t)((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 - (uint8_t)(LSB(PACKET_SIZE_ISO_IN)), // wMaxPacketSize - (uint8_t)(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 - (uint8_t)(LSB(FREQ_OUT)), // tSamFreq - (uint8_t)((FREQ_OUT >> 8) & 0xff), // tSamFreq - (uint8_t)((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 - (uint8_t)(LSB(PACKET_SIZE_ISO_OUT)), // wMaxPacketSize - (uint8_t)(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 0c6524151939 -r 6cc8a2d36729 USBAudio/USBAudio.h --- a/USBAudio/USBAudio.h Wed Jun 18 09:00:48 2014 +0100 +++ /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 0c6524151939 -r 6cc8a2d36729 USBAudio/USBAudio_Types.h --- a/USBAudio/USBAudio_Types.h Wed Jun 18 09:00:48 2014 +0100 +++ /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 0c6524151939 -r 6cc8a2d36729 USBDevice/USBEndpoints_KL25Z.h --- a/USBDevice/USBEndpoints_KL25Z.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +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. -*/ - -#define NUMBER_OF_LOGICAL_ENDPOINTS (16) -#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2) - -/* Define physical endpoint numbers */ - -/* Endpoint No. */ -/* ---------------- */ -#define EP0OUT (0) -#define EP0IN (1) -#define EP1OUT (2) -#define EP1IN (3) -#define EP2OUT (4) -#define EP2IN (5) -#define EP3OUT (6) -#define EP3IN (7) -#define EP4OUT (8) -#define EP4IN (9) -#define EP5OUT (10) -#define EP5IN (11) -#define EP6OUT (12) -#define EP6IN (13) -#define EP7OUT (14) -#define EP7IN (15) -#define EP8OUT (16) -#define EP8IN (17) -#define EP9OUT (18) -#define EP9IN (19) -#define EP10OUT (20) -#define EP10IN (21) -#define EP11OUT (22) -#define EP11IN (23) -#define EP12OUT (24) -#define EP12IN (25) -#define EP13OUT (26) -#define EP13IN (27) -#define EP14OUT (28) -#define EP14IN (29) -#define EP15OUT (30) -#define EP15IN (31) - -/* Maximum Packet sizes */ - -#define MAX_PACKET_SIZE_EP0 (64) -#define MAX_PACKET_SIZE_EP1 (64) -#define MAX_PACKET_SIZE_EP2 (64) -#define MAX_PACKET_SIZE_EP3 (1023) -#define MAX_PACKET_SIZE_EP4 (64) -#define MAX_PACKET_SIZE_EP5 (64) -#define MAX_PACKET_SIZE_EP6 (64) -#define MAX_PACKET_SIZE_EP7 (64) -#define MAX_PACKET_SIZE_EP8 (64) -#define MAX_PACKET_SIZE_EP9 (64) -#define MAX_PACKET_SIZE_EP10 (64) -#define MAX_PACKET_SIZE_EP11 (64) -#define MAX_PACKET_SIZE_EP12 (64) -#define MAX_PACKET_SIZE_EP13 (64) -#define MAX_PACKET_SIZE_EP14 (64) -#define MAX_PACKET_SIZE_EP15 (64) - -/* Generic endpoints - intended to be portable accross devices */ -/* and be suitable for simple USB devices. */ - -/* Bulk endpoints */ -#define EPBULK_OUT (EP2OUT) -#define EPBULK_IN (EP2IN) -/* Interrupt endpoints */ -#define EPINT_OUT (EP1OUT) -#define EPINT_IN (EP1IN) -/* Isochronous endpoints */ -#define EPISO_OUT (EP3OUT) -#define EPISO_IN (EP3IN) - -#define MAX_PACKET_SIZE_EPBULK (MAX_PACKET_SIZE_EP2) -#define MAX_PACKET_SIZE_EPINT (MAX_PACKET_SIZE_EP1) -#define MAX_PACKET_SIZE_EPISO (MAX_PACKET_SIZE_EP3)
diff -r 0c6524151939 -r 6cc8a2d36729 USBDevice/USBEndpoints_LPC17_LPC23.h --- a/USBDevice/USBEndpoints_LPC17_LPC23.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +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. -*/ - -#define NUMBER_OF_LOGICAL_ENDPOINTS (16) -#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2) - -/* Define physical endpoint numbers */ - -/* Endpoint No. Type(s) MaxPacket DoubleBuffer */ -/* ---------------- ------------ ---------- --- */ -#define EP0OUT (0) /* Control 64 No */ -#define EP0IN (1) /* Control 64 No */ -#define EP1OUT (2) /* Interrupt 64 No */ -#define EP1IN (3) /* Interrupt 64 No */ -#define EP2OUT (4) /* Bulk 64 Yes */ -#define EP2IN (5) /* Bulk 64 Yes */ -#define EP3OUT (6) /* Isochronous 1023 Yes */ -#define EP3IN (7) /* Isochronous 1023 Yes */ -#define EP4OUT (8) /* Interrupt 64 No */ -#define EP4IN (9) /* Interrupt 64 No */ -#define EP5OUT (10) /* Bulk 64 Yes */ -#define EP5IN (11) /* Bulk 64 Yes */ -#define EP6OUT (12) /* Isochronous 1023 Yes */ -#define EP6IN (13) /* Isochronous 1023 Yes */ -#define EP7OUT (14) /* Interrupt 64 No */ -#define EP7IN (15) /* Interrupt 64 No */ -#define EP8OUT (16) /* Bulk 64 Yes */ -#define EP8IN (17) /* Bulk 64 Yes */ -#define EP9OUT (18) /* Isochronous 1023 Yes */ -#define EP9IN (19) /* Isochronous 1023 Yes */ -#define EP10OUT (20) /* Interrupt 64 No */ -#define EP10IN (21) /* Interrupt 64 No */ -#define EP11OUT (22) /* Bulk 64 Yes */ -#define EP11IN (23) /* Bulk 64 Yes */ -#define EP12OUT (24) /* Isochronous 1023 Yes */ -#define EP12IN (25) /* Isochronous 1023 Yes */ -#define EP13OUT (26) /* Interrupt 64 No */ -#define EP13IN (27) /* Interrupt 64 No */ -#define EP14OUT (28) /* Bulk 64 Yes */ -#define EP14IN (29) /* Bulk 64 Yes */ -#define EP15OUT (30) /* Bulk 64 Yes */ -#define EP15IN (31) /* Bulk 64 Yes */ - -/* Maximum Packet sizes */ - -#define MAX_PACKET_SIZE_EP0 (64) -#define MAX_PACKET_SIZE_EP1 (64) -#define MAX_PACKET_SIZE_EP2 (64) -#define MAX_PACKET_SIZE_EP3 (1023) -#define MAX_PACKET_SIZE_EP4 (64) -#define MAX_PACKET_SIZE_EP5 (64) -#define MAX_PACKET_SIZE_EP6 (1023) -#define MAX_PACKET_SIZE_EP7 (64) -#define MAX_PACKET_SIZE_EP8 (64) -#define MAX_PACKET_SIZE_EP9 (1023) -#define MAX_PACKET_SIZE_EP10 (64) -#define MAX_PACKET_SIZE_EP11 (64) -#define MAX_PACKET_SIZE_EP12 (1023) -#define MAX_PACKET_SIZE_EP13 (64) -#define MAX_PACKET_SIZE_EP14 (64) -#define MAX_PACKET_SIZE_EP15 (64) - -/* Generic endpoints - intended to be portable accross devices */ -/* and be suitable for simple USB devices. */ - -/* Bulk endpoints */ -#define EPBULK_OUT (EP2OUT) -#define EPBULK_IN (EP2IN) -/* Interrupt endpoints */ -#define EPINT_OUT (EP1OUT) -#define EPINT_IN (EP1IN) -/* Isochronous endpoints */ -#define EPISO_OUT (EP3OUT) -#define EPISO_IN (EP3IN) - -#define MAX_PACKET_SIZE_EPBULK (MAX_PACKET_SIZE_EP2) -#define MAX_PACKET_SIZE_EPINT (MAX_PACKET_SIZE_EP1) -#define MAX_PACKET_SIZE_EPISO (MAX_PACKET_SIZE_EP3)
diff -r 0c6524151939 -r 6cc8a2d36729 USBDevice/USBEndpoints_STM32F4.h --- a/USBDevice/USBEndpoints_STM32F4.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +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. -*/ - -#define NUMBER_OF_LOGICAL_ENDPOINTS (4) -#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2) - -/* Define physical endpoint numbers */ - -/* Endpoint No. Type(s) MaxPacket DoubleBuffer */ -/* ---------------- ------------ ---------- --- */ -#define EP0OUT (0) /* Control 64 No */ -#define EP0IN (1) /* Control 64 No */ -#define EP1OUT (2) /* Int/Bulk/Iso 64/64/1023 Yes */ -#define EP1IN (3) /* Int/Bulk/Iso 64/64/1023 Yes */ -#define EP2OUT (4) /* Int/Bulk/Iso 64/64/1023 Yes */ -#define EP2IN (5) /* Int/Bulk/Iso 64/64/1023 Yes */ -#define EP3OUT (6) /* Int/Bulk/Iso 64/64/1023 Yes */ -#define EP3IN (7) /* Int/Bulk/Iso 64/64/1023 Yes */ - -/* Maximum Packet sizes */ - -#define MAX_PACKET_SIZE_EP0 (64) -#define MAX_PACKET_SIZE_EP1 (64) /* Int/Bulk */ -#define MAX_PACKET_SIZE_EP2 (64) /* Int/Bulk */ -#define MAX_PACKET_SIZE_EP3 (64) /* Int/Bulk */ - -#define MAX_PACKET_SIZE_EP1_ISO (1023) /* Isochronous */ -#define MAX_PACKET_SIZE_EP2_ISO (1023) /* Isochronous */ -#define MAX_PACKET_SIZE_EP3_ISO (1023) /* Isochronous */ - -/* Generic endpoints - intended to be portable accross devices */ -/* and be suitable for simple USB devices. */ - -/* Bulk endpoint */ -#define EPBULK_OUT (EP2OUT) -#define EPBULK_IN (EP2IN) -/* Interrupt endpoint */ -#define EPINT_OUT (EP1OUT) -#define EPINT_IN (EP1IN) -/* Isochronous endpoint */ -#define EPISO_OUT (EP3OUT) -#define EPISO_IN (EP3IN) - -#define MAX_PACKET_SIZE_EPBULK (MAX_PACKET_SIZE_EP2) -#define MAX_PACKET_SIZE_EPINT (MAX_PACKET_SIZE_EP1) -#define MAX_PACKET_SIZE_EPISO (MAX_PACKET_SIZE_EP3_ISO)
diff -r 0c6524151939 -r 6cc8a2d36729 USBDevice/USBHAL.h --- a/USBDevice/USBHAL.h Wed Jun 18 09:00:48 2014 +0100 +++ b/USBDevice/USBHAL.h Fri Aug 15 14:14:38 2014 +0000 @@ -58,6 +58,8 @@ bool realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options); bool getEndpointStallState(unsigned char endpoint); uint32_t endpointReadcore(uint8_t endpoint, uint8_t *buffer); + +// static void _usbisr(void); protected: virtual void busReset(void){};
diff -r 0c6524151939 -r 6cc8a2d36729 USBDevice/USBHAL_KL25Z.cpp --- a/USBDevice/USBHAL_KL25Z.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,537 +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. -*/ - -#if defined(TARGET_KL25Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F) - -#include "USBHAL.h" - -USBHAL * USBHAL::instance; - -static volatile int epComplete = 0; - -// Convert physical endpoint number to register bit -#define EP(endpoint) (1<<(endpoint)) - -// Convert physical to logical -#define PHY_TO_LOG(endpoint) ((endpoint)>>1) - -// Get endpoint direction -#define IN_EP(endpoint) ((endpoint) & 1U ? true : false) -#define OUT_EP(endpoint) ((endpoint) & 1U ? false : true) - -#define BD_OWN_MASK (1<<7) -#define BD_DATA01_MASK (1<<6) -#define BD_KEEP_MASK (1<<5) -#define BD_NINC_MASK (1<<4) -#define BD_DTS_MASK (1<<3) -#define BD_STALL_MASK (1<<2) - -#define TX 1 -#define RX 0 -#define ODD 0 -#define EVEN 1 -// this macro waits a physical endpoint number -#define EP_BDT_IDX(ep, dir, odd) (((ep * 4) + (2 * dir) + (1 * odd))) - -#define SETUP_TOKEN 0x0D -#define IN_TOKEN 0x09 -#define OUT_TOKEN 0x01 -#define TOK_PID(idx) ((bdt[idx].info >> 2) & 0x0F) - -// for each endpt: 8 bytes -typedef struct BDT { - uint8_t info; // BD[0:7] - uint8_t dummy; // RSVD: BD[8:15] - uint16_t byte_count; // BD[16:32] - uint32_t address; // Addr -} BDT; - - -// there are: -// * 16 bidirectionnal endpt -> 32 physical endpt -// * as there are ODD and EVEN buffer -> 32*2 bdt -__attribute__((__aligned__(512))) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2]; -uint8_t * endpoint_buffer[(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2]; -uint8_t * endpoint_buffer_iso[2*2]; - -static uint8_t set_addr = 0; -static uint8_t addr = 0; - -static uint32_t Data1 = 0x55555555; - -static uint32_t frameNumber() { - return((USB0->FRMNUML | (USB0->FRMNUMH << 8)) & 0x07FF); -} - -uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { - return 0; -} - -USBHAL::USBHAL(void) { - // Disable IRQ - NVIC_DisableIRQ(USB0_IRQn); - -#if defined(TARGET_K64F) - MPU->CESR=0; -#endif - // fill in callback array - epCallback[0] = &USBHAL::EP1_OUT_callback; - epCallback[1] = &USBHAL::EP1_IN_callback; - epCallback[2] = &USBHAL::EP2_OUT_callback; - epCallback[3] = &USBHAL::EP2_IN_callback; - epCallback[4] = &USBHAL::EP3_OUT_callback; - epCallback[5] = &USBHAL::EP3_IN_callback; - epCallback[6] = &USBHAL::EP4_OUT_callback; - epCallback[7] = &USBHAL::EP4_IN_callback; - epCallback[8] = &USBHAL::EP5_OUT_callback; - epCallback[9] = &USBHAL::EP5_IN_callback; - epCallback[10] = &USBHAL::EP6_OUT_callback; - epCallback[11] = &USBHAL::EP6_IN_callback; - epCallback[12] = &USBHAL::EP7_OUT_callback; - epCallback[13] = &USBHAL::EP7_IN_callback; - epCallback[14] = &USBHAL::EP8_OUT_callback; - epCallback[15] = &USBHAL::EP8_IN_callback; - epCallback[16] = &USBHAL::EP9_OUT_callback; - epCallback[17] = &USBHAL::EP9_IN_callback; - epCallback[18] = &USBHAL::EP10_OUT_callback; - epCallback[19] = &USBHAL::EP10_IN_callback; - epCallback[20] = &USBHAL::EP11_OUT_callback; - epCallback[21] = &USBHAL::EP11_IN_callback; - epCallback[22] = &USBHAL::EP12_OUT_callback; - epCallback[23] = &USBHAL::EP12_IN_callback; - epCallback[24] = &USBHAL::EP13_OUT_callback; - epCallback[25] = &USBHAL::EP13_IN_callback; - epCallback[26] = &USBHAL::EP14_OUT_callback; - epCallback[27] = &USBHAL::EP14_IN_callback; - epCallback[28] = &USBHAL::EP15_OUT_callback; - epCallback[29] = &USBHAL::EP15_IN_callback; - - - // choose usb src as PLL - SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK); - - // enable OTG clock - SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK; - - // Attach IRQ - instance = this; - NVIC_SetVector(USB0_IRQn, (uint32_t)&_usbisr); - NVIC_EnableIRQ(USB0_IRQn); - - // USB Module Configuration - // Reset USB Module - USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; - while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK); - - // Set BDT Base Register - USB0->BDTPAGE1 = (uint8_t)((uint32_t)bdt>>8); - USB0->BDTPAGE2 = (uint8_t)((uint32_t)bdt>>16); - USB0->BDTPAGE3 = (uint8_t)((uint32_t)bdt>>24); - - // Clear interrupt flag - USB0->ISTAT = 0xff; - - // USB Interrupt Enablers - USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK | - USB_INTEN_SOFTOKEN_MASK | - USB_INTEN_ERROREN_MASK | - USB_INTEN_USBRSTEN_MASK; - - // Disable weak pull downs - USB0->USBCTRL &= ~(USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK); - - USB0->USBTRC0 |= 0x40; -} - -USBHAL::~USBHAL(void) { } - -void USBHAL::connect(void) { - // enable USB - USB0->CTL |= USB_CTL_USBENSOFEN_MASK; - // Pull up enable - USB0->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; -} - -void USBHAL::disconnect(void) { - // disable USB - USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK; - // Pull up disable - USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; - - //Free buffers if required: - for (int i = 0; i<(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2; i++) { - free(endpoint_buffer[i]); - endpoint_buffer[i] = NULL; - } - free(endpoint_buffer_iso[2]); - endpoint_buffer_iso[2] = NULL; - free(endpoint_buffer_iso[0]); - endpoint_buffer_iso[0] = NULL; -} - -void USBHAL::configureDevice(void) { - // not needed -} - -void USBHAL::unconfigureDevice(void) { - // not needed -} - -void USBHAL::setAddress(uint8_t address) { - // we don't set the address now otherwise the usb controller does not ack - // we set a flag instead - // see usbisr when an IN token is received - set_addr = 1; - addr = address; -} - -bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { - uint32_t handshake_flag = 0; - uint8_t * buf; - - if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { - return false; - } - - uint32_t log_endpoint = PHY_TO_LOG(endpoint); - - if ((flags & ISOCHRONOUS) == 0) { - handshake_flag = USB_ENDPT_EPHSHK_MASK; - if (IN_EP(endpoint)) { - if (endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] == NULL) - endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] = (uint8_t *) malloc (64*2); - buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)][0]; - } else { - if (endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] == NULL) - endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] = (uint8_t *) malloc (64*2); - buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)][0]; - } - } else { - if (IN_EP(endpoint)) { - if (endpoint_buffer_iso[2] == NULL) - endpoint_buffer_iso[2] = (uint8_t *) malloc (1023*2); - buf = &endpoint_buffer_iso[2][0]; - } else { - if (endpoint_buffer_iso[0] == NULL) - endpoint_buffer_iso[0] = (uint8_t *) malloc (1023*2); - buf = &endpoint_buffer_iso[0][0]; - } - } - - // IN endpt -> device to host (TX) - if (IN_EP(endpoint)) { - USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint) - USB_ENDPT_EPTXEN_MASK; // en TX (IN) tran - bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = (uint32_t) buf; - bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = 0; - } - // OUT endpt -> host to device (RX) - else { - USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint) - USB_ENDPT_EPRXEN_MASK; // en RX (OUT) tran. - bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].byte_count = maxPacket; - bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address = (uint32_t) buf; - bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info = BD_OWN_MASK | BD_DTS_MASK; - bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info = 0; - } - - Data1 |= (1 << endpoint); - - return true; -} - -// read setup packet -void USBHAL::EP0setup(uint8_t *buffer) { - uint32_t sz; - endpointReadResult(EP0OUT, buffer, &sz); -} - -void USBHAL::EP0readStage(void) { - Data1 &= ~1UL; // set DATA0 - bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK); -} - -void USBHAL::EP0read(void) { - uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(EP0OUT), RX, 0); - bdt[idx].byte_count = MAX_PACKET_SIZE_EP0; -} - -uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { - uint32_t sz; - endpointReadResult(EP0OUT, buffer, &sz); - return sz; -} - -void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { - endpointWrite(EP0IN, buffer, size); -} - -void USBHAL::EP0getWriteResult(void) { -} - -void USBHAL::EP0stall(void) { - stallEndpoint(EP0OUT); -} - -EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { - endpoint = PHY_TO_LOG(endpoint); - uint32_t idx = EP_BDT_IDX(endpoint, RX, 0); - bdt[idx].byte_count = maximumSize; - return EP_PENDING; -} - -EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { - uint32_t n, sz, idx, setup = 0; - uint8_t not_iso; - uint8_t * ep_buf; - - uint32_t log_endpoint = PHY_TO_LOG(endpoint); - - if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { - return EP_INVALID; - } - - // if read on a IN endpoint -> error - if (IN_EP(endpoint)) { - return EP_INVALID; - } - - idx = EP_BDT_IDX(log_endpoint, RX, 0); - sz = bdt[idx].byte_count; - not_iso = USB0->ENDPOINT[log_endpoint].ENDPT & USB_ENDPT_EPHSHK_MASK; - - //for isochronous endpoint, we don't wait an interrupt - if ((log_endpoint != 0) && not_iso && !(epComplete & EP(endpoint))) { - return EP_PENDING; - } - - if ((log_endpoint == 0) && (TOK_PID(idx) == SETUP_TOKEN)) { - setup = 1; - } - - // non iso endpoint - if (not_iso) { - ep_buf = endpoint_buffer[idx]; - } else { - ep_buf = endpoint_buffer_iso[0]; - } - - for (n = 0; n < sz; n++) { - buffer[n] = ep_buf[n]; - } - - if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1)) { - if (setup && (buffer[6] == 0)) // if no setup data stage, - Data1 &= ~1UL; // set DATA0 - else - Data1 ^= (1 << endpoint); - } - - if (((Data1 >> endpoint) & 1)) { - bdt[idx].info = BD_DTS_MASK | BD_DATA01_MASK | BD_OWN_MASK; - } - else { - bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK; - } - - USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; - *bytesRead = sz; - - epComplete &= ~EP(endpoint); - return EP_COMPLETED; -} - -EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { - uint32_t idx, n; - uint8_t * ep_buf; - - if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { - return EP_INVALID; - } - - // if write on a OUT endpoint -> error - if (OUT_EP(endpoint)) { - return EP_INVALID; - } - - idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0); - bdt[idx].byte_count = size; - - - // non iso endpoint - if (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPHSHK_MASK) { - ep_buf = endpoint_buffer[idx]; - } else { - ep_buf = endpoint_buffer_iso[2]; - } - - for (n = 0; n < size; n++) { - ep_buf[n] = data[n]; - } - - if ((Data1 >> endpoint) & 1) { - bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK; - } else { - bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK; - } - - Data1 ^= (1 << endpoint); - - return EP_PENDING; -} - -EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { - if (epComplete & EP(endpoint)) { - epComplete &= ~EP(endpoint); - return EP_COMPLETED; - } - - return EP_PENDING; -} - -void USBHAL::stallEndpoint(uint8_t endpoint) { - USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK; -} - -void USBHAL::unstallEndpoint(uint8_t endpoint) { - USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; -} - -bool USBHAL::getEndpointStallState(uint8_t endpoint) { - uint8_t stall = (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPSTALL_MASK); - return (stall) ? true : false; -} - -void USBHAL::remoteWakeup(void) { - // [TODO] -} - - -void USBHAL::_usbisr(void) { - instance->usbisr(); -} - - -void USBHAL::usbisr(void) { - uint8_t i; - uint8_t istat = USB0->ISTAT; - - // reset interrupt - if (istat & USB_ISTAT_USBRST_MASK) { - // disable all endpt - for(i = 0; i < 16; i++) { - USB0->ENDPOINT[i].ENDPT = 0x00; - } - - // enable control endpoint - realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); - realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); - - Data1 = 0x55555555; - USB0->CTL |= USB_CTL_ODDRST_MASK; - - USB0->ISTAT = 0xFF; // clear all interrupt status flags - USB0->ERRSTAT = 0xFF; // clear all error flags - USB0->ERREN = 0xFF; // enable error interrupt sources - USB0->ADDR = 0x00; // set default address - - return; - } - - // resume interrupt - if (istat & USB_ISTAT_RESUME_MASK) { - USB0->ISTAT = USB_ISTAT_RESUME_MASK; - } - - // SOF interrupt - if (istat & USB_ISTAT_SOFTOK_MASK) { - USB0->ISTAT = USB_ISTAT_SOFTOK_MASK; - // SOF event, read frame number - SOF(frameNumber()); - } - - // stall interrupt - if (istat & 1<<7) { - if (USB0->ENDPOINT[0].ENDPT & USB_ENDPT_EPSTALL_MASK) - USB0->ENDPOINT[0].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; - USB0->ISTAT |= USB_ISTAT_STALL_MASK; - } - - // token interrupt - if (istat & 1<<3) { - uint32_t num = (USB0->STAT >> 4) & 0x0F; - uint32_t dir = (USB0->STAT >> 3) & 0x01; - uint32_t ev_odd = (USB0->STAT >> 2) & 0x01; - - // setup packet - if ((num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) { - Data1 &= ~0x02; - bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK; - bdt[EP_BDT_IDX(0, TX, ODD)].info &= ~BD_OWN_MASK; - - // EP0 SETUP event (SETUP data received) - EP0setupCallback(); - - } else { - // OUT packet - if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN) { - if (num == 0) - EP0out(); - else { - epComplete |= (1 << EP(num)); - if ((instance->*(epCallback[EP(num) - 2]))()) { - epComplete &= ~(1 << EP(num)); - } - } - } - - // IN packet - if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == IN_TOKEN) { - if (num == 0) { - EP0in(); - if (set_addr == 1) { - USB0->ADDR = addr & 0x7F; - set_addr = 0; - } - } - else { - epComplete |= (1 << (EP(num) + 1)); - if ((instance->*(epCallback[EP(num) + 1 - 2]))()) { - epComplete &= ~(1 << (EP(num) + 1)); - } - } - } - } - - USB0->ISTAT = USB_ISTAT_TOKDNE_MASK; - } - - // sleep interrupt - if (istat & 1<<4) { - USB0->ISTAT |= USB_ISTAT_SLEEP_MASK; - } - - // error interrupt - if (istat & USB_ISTAT_ERROR_MASK) { - USB0->ERRSTAT = 0xFF; - USB0->ISTAT |= USB_ISTAT_ERROR_MASK; - } -} - - -#endif
diff -r 0c6524151939 -r 6cc8a2d36729 USBDevice/USBHAL_LPC17.cpp --- a/USBDevice/USBHAL_LPC17.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,623 +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. -*/ - -#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) - -#include "USBHAL.h" - - -// Get endpoint direction -#define IN_EP(endpoint) ((endpoint) & 1U ? true : false) -#define OUT_EP(endpoint) ((endpoint) & 1U ? false : true) - -// Convert physical endpoint number to register bit -#define EP(endpoint) (1UL<<endpoint) - -// Power Control for Peripherals register -#define PCUSB (1UL<<31) - -// USB Clock Control register -#define DEV_CLK_EN (1UL<<1) -#define AHB_CLK_EN (1UL<<4) - -// USB Clock Status register -#define DEV_CLK_ON (1UL<<1) -#define AHB_CLK_ON (1UL<<4) - -// USB Device Interupt registers -#define FRAME (1UL<<0) -#define EP_FAST (1UL<<1) -#define EP_SLOW (1UL<<2) -#define DEV_STAT (1UL<<3) -#define CCEMPTY (1UL<<4) -#define CDFULL (1UL<<5) -#define RxENDPKT (1UL<<6) -#define TxENDPKT (1UL<<7) -#define EP_RLZED (1UL<<8) -#define ERR_INT (1UL<<9) - -// USB Control register -#define RD_EN (1<<0) -#define WR_EN (1<<1) -#define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2) - -// USB Receive Packet Length register -#define DV (1UL<<10) -#define PKT_RDY (1UL<<11) -#define PKT_LNGTH_MASK (0x3ff) - -// Serial Interface Engine (SIE) -#define SIE_WRITE (0x01) -#define SIE_READ (0x02) -#define SIE_COMMAND (0x05) -#define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16)) - -// SIE Command codes -#define SIE_CMD_SET_ADDRESS (0xD0) -#define SIE_CMD_CONFIGURE_DEVICE (0xD8) -#define SIE_CMD_SET_MODE (0xF3) -#define SIE_CMD_READ_FRAME_NUMBER (0xF5) -#define SIE_CMD_READ_TEST_REGISTER (0xFD) -#define SIE_CMD_SET_DEVICE_STATUS (0xFE) -#define SIE_CMD_GET_DEVICE_STATUS (0xFE) -#define SIE_CMD_GET_ERROR_CODE (0xFF) -#define SIE_CMD_READ_ERROR_STATUS (0xFB) - -#define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint) -#define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint) -#define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint) - -#define SIE_CMD_CLEAR_BUFFER (0xF2) -#define SIE_CMD_VALIDATE_BUFFER (0xFA) - -// SIE Device Status register -#define SIE_DS_CON (1<<0) -#define SIE_DS_CON_CH (1<<1) -#define SIE_DS_SUS (1<<2) -#define SIE_DS_SUS_CH (1<<3) -#define SIE_DS_RST (1<<4) - -// SIE Device Set Address register -#define SIE_DSA_DEV_EN (1<<7) - -// SIE Configue Device register -#define SIE_CONF_DEVICE (1<<0) - -// Select Endpoint register -#define SIE_SE_FE (1<<0) -#define SIE_SE_ST (1<<1) -#define SIE_SE_STP (1<<2) -#define SIE_SE_PO (1<<3) -#define SIE_SE_EPN (1<<4) -#define SIE_SE_B_1_FULL (1<<5) -#define SIE_SE_B_2_FULL (1<<6) - -// Set Endpoint Status command -#define SIE_SES_ST (1<<0) -#define SIE_SES_DA (1<<5) -#define SIE_SES_RF_MO (1<<6) -#define SIE_SES_CND_ST (1<<7) - - -USBHAL * USBHAL::instance; - -static volatile int epComplete; -static uint32_t endpointStallState; - -static void SIECommand(uint32_t command) { - // The command phase of a SIE transaction - LPC_USB->USBDevIntClr = CCEMPTY; - LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command); - while (!(LPC_USB->USBDevIntSt & CCEMPTY)); -} - -static void SIEWriteData(uint8_t data) { - // The data write phase of a SIE transaction - LPC_USB->USBDevIntClr = CCEMPTY; - LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data); - while (!(LPC_USB->USBDevIntSt & CCEMPTY)); -} - -static uint8_t SIEReadData(uint32_t command) { - // The data read phase of a SIE transaction - LPC_USB->USBDevIntClr = CDFULL; - LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command); - while (!(LPC_USB->USBDevIntSt & CDFULL)); - return (uint8_t)LPC_USB->USBCmdData; -} - -static void SIEsetDeviceStatus(uint8_t status) { - // Write SIE device status register - SIECommand(SIE_CMD_SET_DEVICE_STATUS); - SIEWriteData(status); -} - -static uint8_t SIEgetDeviceStatus(void) { - // Read SIE device status register - SIECommand(SIE_CMD_GET_DEVICE_STATUS); - return SIEReadData(SIE_CMD_GET_DEVICE_STATUS); -} - -void SIEsetAddress(uint8_t address) { - // Write SIE device address register - SIECommand(SIE_CMD_SET_ADDRESS); - SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN); -} - -static uint8_t SIEselectEndpoint(uint8_t endpoint) { - // SIE select endpoint command - SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint)); - return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint)); -} - -static uint8_t SIEclearBuffer(void) { - // SIE clear buffer command - SIECommand(SIE_CMD_CLEAR_BUFFER); - return SIEReadData(SIE_CMD_CLEAR_BUFFER); -} - -static void SIEvalidateBuffer(void) { - // SIE validate buffer command - SIECommand(SIE_CMD_VALIDATE_BUFFER); -} - -static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status) { - // SIE set endpoint status command - SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint)); - SIEWriteData(status); -} - -static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused)); -static uint16_t SIEgetFrameNumber(void) { - // Read current frame number - uint16_t lowByte; - uint16_t highByte; - - SIECommand(SIE_CMD_READ_FRAME_NUMBER); - lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); - highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); - - return (highByte << 8) | lowByte; -} - -static void SIEconfigureDevice(void) { - // SIE Configure device command - SIECommand(SIE_CMD_CONFIGURE_DEVICE); - SIEWriteData(SIE_CONF_DEVICE); -} - -static void SIEunconfigureDevice(void) { - // SIE Configure device command - SIECommand(SIE_CMD_CONFIGURE_DEVICE); - SIEWriteData(0); -} - -static void SIEconnect(void) { - // Connect USB device - uint8_t status = SIEgetDeviceStatus(); - SIEsetDeviceStatus(status | SIE_DS_CON); -} - - -static void SIEdisconnect(void) { - // Disconnect USB device - uint8_t status = SIEgetDeviceStatus(); - SIEsetDeviceStatus(status & ~SIE_DS_CON); -} - - -static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) { - // Implemented using using EP_INT_CLR. - LPC_USB->USBEpIntClr = EP(endpoint); - while (!(LPC_USB->USBDevIntSt & CDFULL)); - return (uint8_t)LPC_USB->USBCmdData; -} - - -static void enableEndpointEvent(uint8_t endpoint) { - // Enable an endpoint interrupt - LPC_USB->USBEpIntEn |= EP(endpoint); -} - -static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused)); -static void disableEndpointEvent(uint8_t endpoint) { - // Disable an endpoint interrupt - LPC_USB->USBEpIntEn &= ~EP(endpoint); -} - -static volatile uint32_t __attribute__((used)) dummyRead; -uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { - // Read from an OUT endpoint - uint32_t size; - uint32_t i; - uint32_t data = 0; - uint8_t offset; - - LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN; - while (!(LPC_USB->USBRxPLen & PKT_RDY)); - - size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK; - - offset = 0; - - if (size > 0) { - for (i=0; i<size; i++) { - if (offset==0) { - // Fetch up to four bytes of data as a word - data = LPC_USB->USBRxData; - } - - // extract a byte - *buffer = (data>>offset) & 0xff; - buffer++; - - // move on to the next byte - offset = (offset + 8) % 32; - } - } else { - dummyRead = LPC_USB->USBRxData; - } - - LPC_USB->USBCtrl = 0; - - if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) { - SIEselectEndpoint(endpoint); - SIEclearBuffer(); - } - - return size; -} - -static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size) { - // Write to an IN endpoint - uint32_t temp, data; - uint8_t offset; - - LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN; - - LPC_USB->USBTxPLen = size; - offset = 0; - data = 0; - - if (size>0) { - do { - // Fetch next data byte into a word-sized temporary variable - temp = *buffer++; - - // Add to current data word - temp = temp << offset; - data = data | temp; - - // move on to the next byte - offset = (offset + 8) % 32; - size--; - - if ((offset==0) || (size==0)) { - // Write the word to the endpoint - LPC_USB->USBTxData = data; - data = 0; - } - } while (size>0); - } else { - LPC_USB->USBTxData = 0; - } - - // Clear WR_EN to cover zero length packet case - LPC_USB->USBCtrl=0; - - SIEselectEndpoint(endpoint); - SIEvalidateBuffer(); -} - -USBHAL::USBHAL(void) { - // Disable IRQ - NVIC_DisableIRQ(USB_IRQn); - - // fill in callback array - epCallback[0] = &USBHAL::EP1_OUT_callback; - epCallback[1] = &USBHAL::EP1_IN_callback; - epCallback[2] = &USBHAL::EP2_OUT_callback; - epCallback[3] = &USBHAL::EP2_IN_callback; - epCallback[4] = &USBHAL::EP3_OUT_callback; - epCallback[5] = &USBHAL::EP3_IN_callback; - epCallback[6] = &USBHAL::EP4_OUT_callback; - epCallback[7] = &USBHAL::EP4_IN_callback; - epCallback[8] = &USBHAL::EP5_OUT_callback; - epCallback[9] = &USBHAL::EP5_IN_callback; - epCallback[10] = &USBHAL::EP6_OUT_callback; - epCallback[11] = &USBHAL::EP6_IN_callback; - epCallback[12] = &USBHAL::EP7_OUT_callback; - epCallback[13] = &USBHAL::EP7_IN_callback; - epCallback[14] = &USBHAL::EP8_OUT_callback; - epCallback[15] = &USBHAL::EP8_IN_callback; - epCallback[16] = &USBHAL::EP9_OUT_callback; - epCallback[17] = &USBHAL::EP9_IN_callback; - epCallback[18] = &USBHAL::EP10_OUT_callback; - epCallback[19] = &USBHAL::EP10_IN_callback; - epCallback[20] = &USBHAL::EP11_OUT_callback; - epCallback[21] = &USBHAL::EP11_IN_callback; - epCallback[22] = &USBHAL::EP12_OUT_callback; - epCallback[23] = &USBHAL::EP12_IN_callback; - epCallback[24] = &USBHAL::EP13_OUT_callback; - epCallback[25] = &USBHAL::EP13_IN_callback; - epCallback[26] = &USBHAL::EP14_OUT_callback; - epCallback[27] = &USBHAL::EP14_IN_callback; - epCallback[28] = &USBHAL::EP15_OUT_callback; - epCallback[29] = &USBHAL::EP15_IN_callback; - - // Enable power to USB device controller - LPC_SC->PCONP |= PCUSB; - - // Enable USB clocks - LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; - while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON)); - - // Configure pins P0.29 and P0.30 to be USB D+ and USB D- - LPC_PINCON->PINSEL1 &= 0xc3ffffff; - LPC_PINCON->PINSEL1 |= 0x14000000; - - // Disconnect USB device - SIEdisconnect(); - - // Configure pin P2.9 to be Connect - LPC_PINCON->PINSEL4 &= 0xfffcffff; - LPC_PINCON->PINSEL4 |= 0x00040000; - - // Connect must be low for at least 2.5uS - wait(0.3); - - // Set the maximum packet size for the control endpoints - realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); - realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); - - // Attach IRQ - instance = this; - NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr); - - // Enable interrupts for device events and EP0 - LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME; - enableEndpointEvent(EP0IN); - enableEndpointEvent(EP0OUT); -} - -USBHAL::~USBHAL(void) { - // Ensure device disconnected - SIEdisconnect(); - // Disable USB interrupts - NVIC_DisableIRQ(USB_IRQn); -} - -void USBHAL::connect(void) { - NVIC_EnableIRQ(USB_IRQn); - // Connect USB device - SIEconnect(); -} - -void USBHAL::disconnect(void) { - NVIC_DisableIRQ(USB_IRQn); - // Disconnect USB device - SIEdisconnect(); -} - -void USBHAL::configureDevice(void) { - SIEconfigureDevice(); -} - -void USBHAL::unconfigureDevice(void) { - SIEunconfigureDevice(); -} - -void USBHAL::setAddress(uint8_t address) { - SIEsetAddress(address); -} - -void USBHAL::EP0setup(uint8_t *buffer) { - endpointReadcore(EP0OUT, buffer); -} - -void USBHAL::EP0read(void) { - // Not required -} - -void USBHAL::EP0readStage(void) { - // Not required -} - -uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { - return endpointReadcore(EP0OUT, buffer); -} - -void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { - endpointWritecore(EP0IN, buffer, size); -} - -void USBHAL::EP0getWriteResult(void) { - // Not required -} - -void USBHAL::EP0stall(void) { - // This will stall both control endpoints - stallEndpoint(EP0OUT); -} - -EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { - return EP_PENDING; -} - -EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { - - //for isochronous endpoint, we don't wait an interrupt - if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) { - if (!(epComplete & EP(endpoint))) - return EP_PENDING; - } - - *bytesRead = endpointReadcore(endpoint, buffer); - epComplete &= ~EP(endpoint); - return EP_COMPLETED; -} - -EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { - if (getEndpointStallState(endpoint)) { - return EP_STALLED; - } - - epComplete &= ~EP(endpoint); - - endpointWritecore(endpoint, data, size); - return EP_PENDING; -} - -EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { - if (epComplete & EP(endpoint)) { - epComplete &= ~EP(endpoint); - return EP_COMPLETED; - } - - return EP_PENDING; -} - -bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { - // Realise an endpoint - LPC_USB->USBDevIntClr = EP_RLZED; - LPC_USB->USBReEp |= EP(endpoint); - LPC_USB->USBEpInd = endpoint; - LPC_USB->USBMaxPSize = maxPacket; - - while (!(LPC_USB->USBDevIntSt & EP_RLZED)); - LPC_USB->USBDevIntClr = EP_RLZED; - - // Clear stall state - endpointStallState &= ~EP(endpoint); - - enableEndpointEvent(endpoint); - return true; -} - -void USBHAL::stallEndpoint(uint8_t endpoint) { - // Stall an endpoint - if ( (endpoint==EP0IN) || (endpoint==EP0OUT) ) { - // Conditionally stall both control endpoints - SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST); - } else { - SIEsetEndpointStatus(endpoint, SIE_SES_ST); - - // Update stall state - endpointStallState |= EP(endpoint); - } -} - -void USBHAL::unstallEndpoint(uint8_t endpoint) { - // Unstall an endpoint. The endpoint will also be reinitialised - SIEsetEndpointStatus(endpoint, 0); - - // Update stall state - endpointStallState &= ~EP(endpoint); -} - -bool USBHAL::getEndpointStallState(uint8_t endpoint) { - // Returns true if endpoint stalled - return endpointStallState & EP(endpoint); -} - -void USBHAL::remoteWakeup(void) { - // Remote wakeup - uint8_t status; - - // Enable USB clocks - LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; - while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON)); - - status = SIEgetDeviceStatus(); - SIEsetDeviceStatus(status & ~SIE_DS_SUS); -} - -void USBHAL::_usbisr(void) { - instance->usbisr(); -} - - -void USBHAL::usbisr(void) { - uint8_t devStat; - - if (LPC_USB->USBDevIntSt & FRAME) { - // Start of frame event - SOF(SIEgetFrameNumber()); - // Clear interrupt status flag - LPC_USB->USBDevIntClr = FRAME; - } - - if (LPC_USB->USBDevIntSt & DEV_STAT) { - // Device Status interrupt - // Must clear the interrupt status flag before reading the device status from the SIE - LPC_USB->USBDevIntClr = DEV_STAT; - - // Read device status from SIE - devStat = SIEgetDeviceStatus(); - //printf("devStat: %d\r\n", devStat); - - if (devStat & SIE_DS_SUS_CH) { - // Suspend status changed - if((devStat & SIE_DS_SUS) != 0) { - suspendStateChanged(0); - } - } - - if (devStat & SIE_DS_RST) { - // Bus reset - if((devStat & SIE_DS_SUS) == 0) { - suspendStateChanged(1); - } - busReset(); - } - } - - if (LPC_USB->USBDevIntSt & EP_SLOW) { - // (Slow) Endpoint Interrupt - - // Process each endpoint interrupt - if (LPC_USB->USBEpIntSt & EP(EP0OUT)) { - if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) { - // this is a setup packet - EP0setupCallback(); - } else { - EP0out(); - } - LPC_USB->USBDevIntClr = EP_SLOW; - } - - if (LPC_USB->USBEpIntSt & EP(EP0IN)) { - selectEndpointClearInterrupt(EP0IN); - LPC_USB->USBDevIntClr = EP_SLOW; - EP0in(); - } - - for (uint8_t num = 2; num < 16*2; num++) { - if (LPC_USB->USBEpIntSt & EP(num)) { - selectEndpointClearInterrupt(num); - epComplete |= EP(num); - LPC_USB->USBDevIntClr = EP_SLOW; - if ((instance->*(epCallback[num - 2]))()) { - epComplete &= ~EP(num); - } - } - } - } -} - -#endif
diff -r 0c6524151939 -r 6cc8a2d36729 USBDevice/USBHAL_LPC40.cpp --- a/USBDevice/USBHAL_LPC40.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,628 +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. -*/ - -#if defined(TARGET_LPC4088) - -#include "USBHAL.h" - - -// Get endpoint direction -#define IN_EP(endpoint) ((endpoint) & 1U ? true : false) -#define OUT_EP(endpoint) ((endpoint) & 1U ? false : true) - -// Convert physical endpoint number to register bit -#define EP(endpoint) (1UL<<endpoint) - -// Power Control for Peripherals register -#define PCUSB (1UL<<31) - -// USB Clock Control register -#define DEV_CLK_EN (1UL<<1) -#define PORT_CLK_EN (1UL<<3) -#define AHB_CLK_EN (1UL<<4) - -// USB Clock Status register -#define DEV_CLK_ON (1UL<<1) -#define AHB_CLK_ON (1UL<<4) - -// USB Device Interupt registers -#define FRAME (1UL<<0) -#define EP_FAST (1UL<<1) -#define EP_SLOW (1UL<<2) -#define DEV_STAT (1UL<<3) -#define CCEMPTY (1UL<<4) -#define CDFULL (1UL<<5) -#define RxENDPKT (1UL<<6) -#define TxENDPKT (1UL<<7) -#define EP_RLZED (1UL<<8) -#define ERR_INT (1UL<<9) - -// USB Control register -#define RD_EN (1<<0) -#define WR_EN (1<<1) -#define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2) - -// USB Receive Packet Length register -#define DV (1UL<<10) -#define PKT_RDY (1UL<<11) -#define PKT_LNGTH_MASK (0x3ff) - -// Serial Interface Engine (SIE) -#define SIE_WRITE (0x01) -#define SIE_READ (0x02) -#define SIE_COMMAND (0x05) -#define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16)) - -// SIE Command codes -#define SIE_CMD_SET_ADDRESS (0xD0) -#define SIE_CMD_CONFIGURE_DEVICE (0xD8) -#define SIE_CMD_SET_MODE (0xF3) -#define SIE_CMD_READ_FRAME_NUMBER (0xF5) -#define SIE_CMD_READ_TEST_REGISTER (0xFD) -#define SIE_CMD_SET_DEVICE_STATUS (0xFE) -#define SIE_CMD_GET_DEVICE_STATUS (0xFE) -#define SIE_CMD_GET_ERROR_CODE (0xFF) -#define SIE_CMD_READ_ERROR_STATUS (0xFB) - -#define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint) -#define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint) -#define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint) - -#define SIE_CMD_CLEAR_BUFFER (0xF2) -#define SIE_CMD_VALIDATE_BUFFER (0xFA) - -// SIE Device Status register -#define SIE_DS_CON (1<<0) -#define SIE_DS_CON_CH (1<<1) -#define SIE_DS_SUS (1<<2) -#define SIE_DS_SUS_CH (1<<3) -#define SIE_DS_RST (1<<4) - -// SIE Device Set Address register -#define SIE_DSA_DEV_EN (1<<7) - -// SIE Configue Device register -#define SIE_CONF_DEVICE (1<<0) - -// Select Endpoint register -#define SIE_SE_FE (1<<0) -#define SIE_SE_ST (1<<1) -#define SIE_SE_STP (1<<2) -#define SIE_SE_PO (1<<3) -#define SIE_SE_EPN (1<<4) -#define SIE_SE_B_1_FULL (1<<5) -#define SIE_SE_B_2_FULL (1<<6) - -// Set Endpoint Status command -#define SIE_SES_ST (1<<0) -#define SIE_SES_DA (1<<5) -#define SIE_SES_RF_MO (1<<6) -#define SIE_SES_CND_ST (1<<7) - - -USBHAL * USBHAL::instance; - -static volatile int epComplete; -static uint32_t endpointStallState; - -static void SIECommand(uint32_t command) { - // The command phase of a SIE transaction - LPC_USB->DevIntClr = CCEMPTY; - LPC_USB->CmdCode = SIE_CMD_CODE(SIE_COMMAND, command); - while (!(LPC_USB->DevIntSt & CCEMPTY)); -} - -static void SIEWriteData(uint8_t data) { - // The data write phase of a SIE transaction - LPC_USB->DevIntClr = CCEMPTY; - LPC_USB->CmdCode = SIE_CMD_CODE(SIE_WRITE, data); - while (!(LPC_USB->DevIntSt & CCEMPTY)); -} - -static uint8_t SIEReadData(uint32_t command) { - // The data read phase of a SIE transaction - LPC_USB->DevIntClr = CDFULL; - LPC_USB->CmdCode = SIE_CMD_CODE(SIE_READ, command); - while (!(LPC_USB->DevIntSt & CDFULL)); - return (uint8_t)LPC_USB->CmdData; -} - -static void SIEsetDeviceStatus(uint8_t status) { - // Write SIE device status register - SIECommand(SIE_CMD_SET_DEVICE_STATUS); - SIEWriteData(status); -} - -static uint8_t SIEgetDeviceStatus(void) { - // Read SIE device status register - SIECommand(SIE_CMD_GET_DEVICE_STATUS); - return SIEReadData(SIE_CMD_GET_DEVICE_STATUS); -} - -void SIEsetAddress(uint8_t address) { - // Write SIE device address register - SIECommand(SIE_CMD_SET_ADDRESS); - SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN); -} - -static uint8_t SIEselectEndpoint(uint8_t endpoint) { - // SIE select endpoint command - SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint)); - return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint)); -} - -static uint8_t SIEclearBuffer(void) { - // SIE clear buffer command - SIECommand(SIE_CMD_CLEAR_BUFFER); - return SIEReadData(SIE_CMD_CLEAR_BUFFER); -} - -static void SIEvalidateBuffer(void) { - // SIE validate buffer command - SIECommand(SIE_CMD_VALIDATE_BUFFER); -} - -static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status) { - // SIE set endpoint status command - SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint)); - SIEWriteData(status); -} - -static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused)); -static uint16_t SIEgetFrameNumber(void) { - // Read current frame number - uint16_t lowByte; - uint16_t highByte; - - SIECommand(SIE_CMD_READ_FRAME_NUMBER); - lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); - highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); - - return (highByte << 8) | lowByte; -} - -static void SIEconfigureDevice(void) { - // SIE Configure device command - SIECommand(SIE_CMD_CONFIGURE_DEVICE); - SIEWriteData(SIE_CONF_DEVICE); -} - -static void SIEunconfigureDevice(void) { - // SIE Configure device command - SIECommand(SIE_CMD_CONFIGURE_DEVICE); - SIEWriteData(0); -} - -static void SIEconnect(void) { - // Connect USB device - uint8_t status = SIEgetDeviceStatus(); - SIEsetDeviceStatus(status | SIE_DS_CON); -} - - -static void SIEdisconnect(void) { - // Disconnect USB device - uint8_t status = SIEgetDeviceStatus(); - SIEsetDeviceStatus(status & ~SIE_DS_CON); -} - - -static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) { - // Implemented using using EP_INT_CLR. - LPC_USB->EpIntClr = EP(endpoint); - while (!(LPC_USB->DevIntSt & CDFULL)); - return (uint8_t)LPC_USB->CmdData; -} - - -static void enableEndpointEvent(uint8_t endpoint) { - // Enable an endpoint interrupt - LPC_USB->EpIntEn |= EP(endpoint); -} - -static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused)); -static void disableEndpointEvent(uint8_t endpoint) { - // Disable an endpoint interrupt - LPC_USB->EpIntEn &= ~EP(endpoint); -} - -static volatile uint32_t __attribute__((used)) dummyRead; -uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { - // Read from an OUT endpoint - uint32_t size; - uint32_t i; - uint32_t data = 0; - uint8_t offset; - - LPC_USB->Ctrl = LOG_ENDPOINT(endpoint) | RD_EN; - while (!(LPC_USB->RxPLen & PKT_RDY)); - - size = LPC_USB->RxPLen & PKT_LNGTH_MASK; - - offset = 0; - - if (size > 0) { - for (i=0; i<size; i++) { - if (offset==0) { - // Fetch up to four bytes of data as a word - data = LPC_USB->RxData; - } - - // extract a byte - *buffer = (data>>offset) & 0xff; - buffer++; - - // move on to the next byte - offset = (offset + 8) % 32; - } - } else { - dummyRead = LPC_USB->RxData; - } - - LPC_USB->Ctrl = 0; - - if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) { - SIEselectEndpoint(endpoint); - SIEclearBuffer(); - } - - return size; -} - -static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size) { - // Write to an IN endpoint - uint32_t temp, data; - uint8_t offset; - - LPC_USB->Ctrl = LOG_ENDPOINT(endpoint) | WR_EN; - - LPC_USB->TxPLen = size; - offset = 0; - data = 0; - - if (size>0) { - do { - // Fetch next data byte into a word-sized temporary variable - temp = *buffer++; - - // Add to current data word - temp = temp << offset; - data = data | temp; - - // move on to the next byte - offset = (offset + 8) % 32; - size--; - - if ((offset==0) || (size==0)) { - // Write the word to the endpoint - LPC_USB->TxData = data; - data = 0; - } - } while (size>0); - } else { - LPC_USB->TxData = 0; - } - - // Clear WR_EN to cover zero length packet case - LPC_USB->Ctrl=0; - - SIEselectEndpoint(endpoint); - SIEvalidateBuffer(); -} - -USBHAL::USBHAL(void) { - // Disable IRQ - NVIC_DisableIRQ(USB_IRQn); - - // fill in callback array - epCallback[0] = &USBHAL::EP1_OUT_callback; - epCallback[1] = &USBHAL::EP1_IN_callback; - epCallback[2] = &USBHAL::EP2_OUT_callback; - epCallback[3] = &USBHAL::EP2_IN_callback; - epCallback[4] = &USBHAL::EP3_OUT_callback; - epCallback[5] = &USBHAL::EP3_IN_callback; - epCallback[6] = &USBHAL::EP4_OUT_callback; - epCallback[7] = &USBHAL::EP4_IN_callback; - epCallback[8] = &USBHAL::EP5_OUT_callback; - epCallback[9] = &USBHAL::EP5_IN_callback; - epCallback[10] = &USBHAL::EP6_OUT_callback; - epCallback[11] = &USBHAL::EP6_IN_callback; - epCallback[12] = &USBHAL::EP7_OUT_callback; - epCallback[13] = &USBHAL::EP7_IN_callback; - epCallback[14] = &USBHAL::EP8_OUT_callback; - epCallback[15] = &USBHAL::EP8_IN_callback; - epCallback[16] = &USBHAL::EP9_OUT_callback; - epCallback[17] = &USBHAL::EP9_IN_callback; - epCallback[18] = &USBHAL::EP10_OUT_callback; - epCallback[19] = &USBHAL::EP10_IN_callback; - epCallback[20] = &USBHAL::EP11_OUT_callback; - epCallback[21] = &USBHAL::EP11_IN_callback; - epCallback[22] = &USBHAL::EP12_OUT_callback; - epCallback[23] = &USBHAL::EP12_IN_callback; - epCallback[24] = &USBHAL::EP13_OUT_callback; - epCallback[25] = &USBHAL::EP13_IN_callback; - epCallback[26] = &USBHAL::EP14_OUT_callback; - epCallback[27] = &USBHAL::EP14_IN_callback; - epCallback[28] = &USBHAL::EP15_OUT_callback; - epCallback[29] = &USBHAL::EP15_IN_callback; - - // Enable power to USB device controller - LPC_SC->PCONP |= PCUSB; - - // Enable USB clocks - LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN; - while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON | PORT_CLK_EN)); - - // Select port USB2 - LPC_USB->StCtrl |= 3; - - - // Configure pin P0.31 to be USB2 - LPC_IOCON->P0_31 &= ~0x07; - LPC_IOCON->P0_31 |= 0x01; - - // Disconnect USB device - SIEdisconnect(); - - // Configure pin P0.14 to be Connect - LPC_IOCON->P0_14 &= ~0x07; - LPC_IOCON->P0_14 |= 0x03; - - // Connect must be low for at least 2.5uS - wait(0.3); - - // Set the maximum packet size for the control endpoints - realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); - realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); - - // Attach IRQ - instance = this; - NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr); - - // Enable interrupts for device events and EP0 - LPC_USB->DevIntEn = EP_SLOW | DEV_STAT | FRAME; - enableEndpointEvent(EP0IN); - enableEndpointEvent(EP0OUT); -} - -USBHAL::~USBHAL(void) { - // Ensure device disconnected - SIEdisconnect(); - // Disable USB interrupts - NVIC_DisableIRQ(USB_IRQn); -} - -void USBHAL::connect(void) { - NVIC_EnableIRQ(USB_IRQn); - // Connect USB device - SIEconnect(); -} - -void USBHAL::disconnect(void) { - NVIC_DisableIRQ(USB_IRQn); - // Disconnect USB device - SIEdisconnect(); -} - -void USBHAL::configureDevice(void) { - SIEconfigureDevice(); -} - -void USBHAL::unconfigureDevice(void) { - SIEunconfigureDevice(); -} - -void USBHAL::setAddress(uint8_t address) { - SIEsetAddress(address); -} - -void USBHAL::EP0setup(uint8_t *buffer) { - endpointReadcore(EP0OUT, buffer); -} - -void USBHAL::EP0read(void) { - // Not required -} - -void USBHAL::EP0readStage(void) { - // Not required -} - -uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { - return endpointReadcore(EP0OUT, buffer); -} - -void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { - endpointWritecore(EP0IN, buffer, size); -} - -void USBHAL::EP0getWriteResult(void) { - // Not required -} - -void USBHAL::EP0stall(void) { - // This will stall both control endpoints - stallEndpoint(EP0OUT); -} - -EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { - return EP_PENDING; -} - -EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { - - //for isochronous endpoint, we don't wait an interrupt - if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) { - if (!(epComplete & EP(endpoint))) - return EP_PENDING; - } - - *bytesRead = endpointReadcore(endpoint, buffer); - epComplete &= ~EP(endpoint); - return EP_COMPLETED; -} - -EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { - if (getEndpointStallState(endpoint)) { - return EP_STALLED; - } - - epComplete &= ~EP(endpoint); - - endpointWritecore(endpoint, data, size); - return EP_PENDING; -} - -EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { - if (epComplete & EP(endpoint)) { - epComplete &= ~EP(endpoint); - return EP_COMPLETED; - } - - return EP_PENDING; -} - -bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { - // Realise an endpoint - LPC_USB->DevIntClr = EP_RLZED; - LPC_USB->ReEp |= EP(endpoint); - LPC_USB->EpInd = endpoint; - LPC_USB->MaxPSize = maxPacket; - - while (!(LPC_USB->DevIntSt & EP_RLZED)); - LPC_USB->DevIntClr = EP_RLZED; - - // Clear stall state - endpointStallState &= ~EP(endpoint); - - enableEndpointEvent(endpoint); - return true; -} - -void USBHAL::stallEndpoint(uint8_t endpoint) { - // Stall an endpoint - if ( (endpoint==EP0IN) || (endpoint==EP0OUT) ) { - // Conditionally stall both control endpoints - SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST); - } else { - SIEsetEndpointStatus(endpoint, SIE_SES_ST); - - // Update stall state - endpointStallState |= EP(endpoint); - } -} - -void USBHAL::unstallEndpoint(uint8_t endpoint) { - // Unstall an endpoint. The endpoint will also be reinitialised - SIEsetEndpointStatus(endpoint, 0); - - // Update stall state - endpointStallState &= ~EP(endpoint); -} - -bool USBHAL::getEndpointStallState(uint8_t endpoint) { - // Returns true if endpoint stalled - return endpointStallState & EP(endpoint); -} - -void USBHAL::remoteWakeup(void) { - // Remote wakeup - uint8_t status; - - // Enable USB clocks - LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; - while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON)); - - status = SIEgetDeviceStatus(); - SIEsetDeviceStatus(status & ~SIE_DS_SUS); -} - -void USBHAL::_usbisr(void) { - instance->usbisr(); -} - - -void USBHAL::usbisr(void) { - uint8_t devStat; - - if (LPC_USB->DevIntSt & FRAME) { - // Start of frame event - SOF(SIEgetFrameNumber()); - // Clear interrupt status flag - LPC_USB->DevIntClr = FRAME; - } - - if (LPC_USB->DevIntSt & DEV_STAT) { - // Device Status interrupt - // Must clear the interrupt status flag before reading the device status from the SIE - LPC_USB->DevIntClr = DEV_STAT; - - // Read device status from SIE - devStat = SIEgetDeviceStatus(); - //printf("devStat: %d\r\n", devStat); - - if (devStat & SIE_DS_SUS_CH) { - // Suspend status changed - if((devStat & SIE_DS_SUS) != 0) { - suspendStateChanged(0); - } - } - - if (devStat & SIE_DS_RST) { - // Bus reset - if((devStat & SIE_DS_SUS) == 0) { - suspendStateChanged(1); - } - busReset(); - } - } - - if (LPC_USB->DevIntSt & EP_SLOW) { - // (Slow) Endpoint Interrupt - - // Process each endpoint interrupt - if (LPC_USB->EpIntSt & EP(EP0OUT)) { - if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) { - // this is a setup packet - EP0setupCallback(); - } else { - EP0out(); - } - LPC_USB->DevIntClr = EP_SLOW; - } - - if (LPC_USB->EpIntSt & EP(EP0IN)) { - selectEndpointClearInterrupt(EP0IN); - LPC_USB->DevIntClr = EP_SLOW; - EP0in(); - } - - for (uint8_t num = 2; num < 16*2; num++) { - if (LPC_USB->EpIntSt & EP(num)) { - selectEndpointClearInterrupt(num); - epComplete |= EP(num); - LPC_USB->DevIntClr = EP_SLOW; - if ((instance->*(epCallback[num - 2]))()) { - epComplete &= ~EP(num); - } - } - } - } -} - -#endif
diff -r 0c6524151939 -r 6cc8a2d36729 USBDevice/USBHAL_STM32F4.cpp --- a/USBDevice/USBHAL_STM32F4.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,402 +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. -*/ - -#if defined(TARGET_STM32F4XX) - -#include "USBHAL.h" -#include "USBRegs_STM32.h" -#include "pinmap.h" - -USBHAL * USBHAL::instance; - -static volatile int epComplete = 0; - -static uint32_t bufferEnd = 0; -static const uint32_t rxFifoSize = 512; -static uint32_t rxFifoCount = 0; - -static uint32_t setupBuffer[MAX_PACKET_SIZE_EP0 >> 2]; - -uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { - return 0; -} - -USBHAL::USBHAL(void) { - NVIC_DisableIRQ(OTG_FS_IRQn); - epCallback[0] = &USBHAL::EP1_OUT_callback; - epCallback[1] = &USBHAL::EP1_IN_callback; - epCallback[2] = &USBHAL::EP2_OUT_callback; - epCallback[3] = &USBHAL::EP2_IN_callback; - epCallback[4] = &USBHAL::EP3_OUT_callback; - epCallback[5] = &USBHAL::EP3_IN_callback; - - // Enable power and clocking - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; - - pin_function(PA_8, STM_PIN_DATA(2, 10)); - pin_function(PA_9, STM_PIN_DATA(0, 0)); - pin_function(PA_10, STM_PIN_DATA(2, 10)); - pin_function(PA_11, STM_PIN_DATA(2, 10)); - pin_function(PA_12, STM_PIN_DATA(2, 10)); - - // Set ID pin to open drain with pull-up resistor - pin_mode(PA_10, OpenDrain); - GPIOA->PUPDR &= ~(0x3 << 20); - GPIOA->PUPDR |= 1 << 20; - - // Set VBUS pin to open drain - pin_mode(PA_9, OpenDrain); - - RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; - - // Enable interrupts - OTG_FS->GREGS.GAHBCFG |= (1 << 0); - - // Turnaround time to maximum value - too small causes packet loss - OTG_FS->GREGS.GUSBCFG |= (0xF << 10); - - // Unmask global interrupts - OTG_FS->GREGS.GINTMSK |= (1 << 3) | // SOF - (1 << 4) | // RX FIFO not empty - (1 << 12); // USB reset - - OTG_FS->DREGS.DCFG |= (0x3 << 0) | // Full speed - (1 << 2); // Non-zero-length status OUT handshake - - OTG_FS->GREGS.GCCFG |= (1 << 19) | // Enable VBUS sensing - (1 << 16); // Power Up - - instance = this; - NVIC_SetVector(OTG_FS_IRQn, (uint32_t)&_usbisr); - NVIC_SetPriority(OTG_FS_IRQn, 1); -} - -USBHAL::~USBHAL(void) { -} - -void USBHAL::connect(void) { - NVIC_EnableIRQ(OTG_FS_IRQn); -} - -void USBHAL::disconnect(void) { - NVIC_DisableIRQ(OTG_FS_IRQn); -} - -void USBHAL::configureDevice(void) { - // Not needed -} - -void USBHAL::unconfigureDevice(void) { - // Not needed -} - -void USBHAL::setAddress(uint8_t address) { - OTG_FS->DREGS.DCFG |= (address << 4); - EP0write(0, 0); -} - -bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, - uint32_t flags) { - uint32_t epIndex = endpoint >> 1; - - uint32_t type; - switch (endpoint) { - case EP0IN: - case EP0OUT: - type = 0; - break; - case EPISO_IN: - case EPISO_OUT: - type = 1; - case EPBULK_IN: - case EPBULK_OUT: - type = 2; - break; - case EPINT_IN: - case EPINT_OUT: - type = 3; - break; - } - - // Generic in or out EP controls - uint32_t control = (maxPacket << 0) | // Packet size - (1 << 15) | // Active endpoint - (type << 18); // Endpoint type - - if (endpoint & 0x1) { // In Endpoint - // Set up the Tx FIFO - if (endpoint == EP0IN) { - OTG_FS->GREGS.DIEPTXF0_HNPTXFSIZ = ((maxPacket >> 2) << 16) | - (bufferEnd << 0); - } - else { - OTG_FS->GREGS.DIEPTXF[epIndex - 1] = ((maxPacket >> 2) << 16) | - (bufferEnd << 0); - } - bufferEnd += maxPacket >> 2; - - // Set the In EP specific control settings - if (endpoint != EP0IN) { - control |= (1 << 28); // SD0PID - } - - control |= (epIndex << 22) | // TxFIFO index - (1 << 27); // SNAK - OTG_FS->INEP_REGS[epIndex].DIEPCTL = control; - - // Unmask the interrupt - OTG_FS->DREGS.DAINTMSK |= (1 << epIndex); - } - else { // Out endpoint - // Set the out EP specific control settings - control |= (1 << 26); // CNAK - OTG_FS->OUTEP_REGS[epIndex].DOEPCTL = control; - - // Unmask the interrupt - OTG_FS->DREGS.DAINTMSK |= (1 << (epIndex + 16)); - } - return true; -} - -// read setup packet -void USBHAL::EP0setup(uint8_t *buffer) { - memcpy(buffer, setupBuffer, MAX_PACKET_SIZE_EP0); -} - -void USBHAL::EP0readStage(void) { -} - -void USBHAL::EP0read(void) { -} - -uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { - uint32_t* buffer32 = (uint32_t *) buffer; - uint32_t length = rxFifoCount; - for (uint32_t i = 0; i < length; i += 4) { - buffer32[i >> 2] = OTG_FS->FIFO[0][0]; - } - - rxFifoCount = 0; - return length; -} - -void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { - endpointWrite(0, buffer, size); -} - -void USBHAL::EP0getWriteResult(void) { -} - -void USBHAL::EP0stall(void) { - // If we stall the out endpoint here then we have problems transferring - // and setup requests after the (stalled) get device qualifier requests. - // TODO: Find out if this is correct behavior, or whether we are doing - // something else wrong - stallEndpoint(EP0IN); -// stallEndpoint(EP0OUT); -} - -EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { - uint32_t epIndex = endpoint >> 1; - uint32_t size = (1 << 19) | // 1 packet - (maximumSize << 0); // Packet size -// if (endpoint == EP0OUT) { - size |= (1 << 29); // 1 setup packet -// } - OTG_FS->OUTEP_REGS[epIndex].DOEPTSIZ = size; - OTG_FS->OUTEP_REGS[epIndex].DOEPCTL |= (1 << 31) | // Enable endpoint - (1 << 26); // Clear NAK - - epComplete &= ~(1 << endpoint); - return EP_PENDING; -} - -EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { - if (!(epComplete & (1 << endpoint))) { - return EP_PENDING; - } - - uint32_t* buffer32 = (uint32_t *) buffer; - uint32_t length = rxFifoCount; - for (uint32_t i = 0; i < length; i += 4) { - buffer32[i >> 2] = OTG_FS->FIFO[endpoint >> 1][0]; - } - rxFifoCount = 0; - *bytesRead = length; - return EP_COMPLETED; -} - -EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { - uint32_t epIndex = endpoint >> 1; - OTG_FS->INEP_REGS[epIndex].DIEPTSIZ = (1 << 19) | // 1 packet - (size << 0); // Size of packet - OTG_FS->INEP_REGS[epIndex].DIEPCTL |= (1 << 31) | // Enable endpoint - (1 << 26); // CNAK - OTG_FS->DREGS.DIEPEMPMSK = (1 << epIndex); - - while ((OTG_FS->INEP_REGS[epIndex].DTXFSTS & 0XFFFF) < ((size + 3) >> 2)); - - for (uint32_t i=0; i<(size + 3) >> 2; i++, data+=4) { - OTG_FS->FIFO[epIndex][0] = *(uint32_t *)data; - } - - epComplete &= ~(1 << endpoint); - - return EP_PENDING; -} - -EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { - if (epComplete & (1 << endpoint)) { - epComplete &= ~(1 << endpoint); - return EP_COMPLETED; - } - - return EP_PENDING; -} - -void USBHAL::stallEndpoint(uint8_t endpoint) { - if (endpoint & 0x1) { // In EP - OTG_FS->INEP_REGS[endpoint >> 1].DIEPCTL |= (1 << 30) | // Disable - (1 << 21); // Stall - } - else { // Out EP - OTG_FS->DREGS.DCTL |= (1 << 9); // Set global out NAK - OTG_FS->OUTEP_REGS[endpoint >> 1].DOEPCTL |= (1 << 30) | // Disable - (1 << 21); // Stall - } -} - -void USBHAL::unstallEndpoint(uint8_t endpoint) { - -} - -bool USBHAL::getEndpointStallState(uint8_t endpoint) { - return false; -} - -void USBHAL::remoteWakeup(void) { -} - - -void USBHAL::_usbisr(void) { - instance->usbisr(); -} - - -void USBHAL::usbisr(void) { - if (OTG_FS->GREGS.GINTSTS & (1 << 12)) { // USB Reset - // Set SNAK bits - OTG_FS->OUTEP_REGS[0].DOEPCTL |= (1 << 27); - OTG_FS->OUTEP_REGS[1].DOEPCTL |= (1 << 27); - OTG_FS->OUTEP_REGS[2].DOEPCTL |= (1 << 27); - OTG_FS->OUTEP_REGS[3].DOEPCTL |= (1 << 27); - - OTG_FS->DREGS.DIEPMSK = (1 << 0); - - bufferEnd = 0; - - // Set the receive FIFO size - OTG_FS->GREGS.GRXFSIZ = rxFifoSize >> 2; - bufferEnd += rxFifoSize >> 2; - - // Create the endpoints, and wait for setup packets on out EP0 - realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); - realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); - endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0); - - OTG_FS->GREGS.GINTSTS = (1 << 12); - } - - if (OTG_FS->GREGS.GINTSTS & (1 << 4)) { // RX FIFO not empty - uint32_t status = OTG_FS->GREGS.GRXSTSP; - - uint32_t endpoint = (status & 0xF) << 1; - uint32_t length = (status >> 4) & 0x7FF; - uint32_t type = (status >> 17) & 0xF; - - rxFifoCount = length; - - if (type == 0x6) { - // Setup packet - for (uint32_t i=0; i<length; i+=4) { - setupBuffer[i >> 2] = OTG_FS->FIFO[0][i >> 2]; - } - rxFifoCount = 0; - } - - if (type == 0x4) { - // Setup complete - EP0setupCallback(); - endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0); - } - - if (type == 0x2) { - // Out packet - if (endpoint == EP0OUT) { - EP0out(); - } - else { - epComplete |= (1 << endpoint); - if ((instance->*(epCallback[endpoint - 2]))()) { - epComplete &= (1 << endpoint); - } - } - } - - for (uint32_t i=0; i<rxFifoCount; i+=4) { - (void) OTG_FS->FIFO[0][0]; - } - OTG_FS->GREGS.GINTSTS = (1 << 4); - } - - if (OTG_FS->GREGS.GINTSTS & (1 << 18)) { // In endpoint interrupt - // Loop through the in endpoints - for (uint32_t i=0; i<4; i++) { - if (OTG_FS->DREGS.DAINT & (1 << i)) { // Interrupt is on endpoint - - if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 7)) {// Tx FIFO empty - // If the Tx FIFO is empty on EP0 we need to send a further - // packet, so call EP0in() - if (i == 0) { - EP0in(); - } - // Clear the interrupt - OTG_FS->INEP_REGS[i].DIEPINT = (1 << 7); - // Stop firing Tx empty interrupts - // Will get turned on again if another write is called - OTG_FS->DREGS.DIEPEMPMSK &= ~(1 << i); - } - - // If the transfer is complete - if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 0)) { // Tx Complete - epComplete |= (1 << (1 + (i << 1))); - OTG_FS->INEP_REGS[i].DIEPINT = (1 << 0); - } - } - } - OTG_FS->GREGS.GINTSTS = (1 << 18); - } - - if (OTG_FS->GREGS.GINTSTS & (1 << 3)) { // Start of frame - SOF((OTG_FS->GREGS.GRXSTSR >> 17) & 0xF); - OTG_FS->GREGS.GINTSTS = (1 << 3); - } -} - - -#endif
diff -r 0c6524151939 -r 6cc8a2d36729 USBDevice/USBRegs_STM32.h --- a/USBDevice/USBRegs_STM32.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/** - ****************************************************************************** - * @file usb_regs.h - * @author MCD Application Team - * @version V2.1.0 - * @date 19-March-2012 - * @brief hardware registers - ****************************************************************************** - * @attention - * - * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -#ifndef __USB_OTG_REGS_H__ -#define __USB_OTG_REGS_H__ - -typedef struct //000h -{ - __IO uint32_t GOTGCTL; /* USB_OTG Control and Status Register 000h*/ - __IO uint32_t GOTGINT; /* USB_OTG Interrupt Register 004h*/ - __IO uint32_t GAHBCFG; /* Core AHB Configuration Register 008h*/ - __IO uint32_t GUSBCFG; /* Core USB Configuration Register 00Ch*/ - __IO uint32_t GRSTCTL; /* Core Reset Register 010h*/ - __IO uint32_t GINTSTS; /* Core Interrupt Register 014h*/ - __IO uint32_t GINTMSK; /* Core Interrupt Mask Register 018h*/ - __IO uint32_t GRXSTSR; /* Receive Sts Q Read Register 01Ch*/ - __IO uint32_t GRXSTSP; /* Receive Sts Q Read & POP Register 020h*/ - __IO uint32_t GRXFSIZ; /* Receive FIFO Size Register 024h*/ - __IO uint32_t DIEPTXF0_HNPTXFSIZ; /* EP0 / Non Periodic Tx FIFO Size Register 028h*/ - __IO uint32_t HNPTXSTS; /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/ - uint32_t Reserved30[2]; /* Reserved 030h*/ - __IO uint32_t GCCFG; /* General Purpose IO Register 038h*/ - __IO uint32_t CID; /* User ID Register 03Ch*/ - uint32_t Reserved40[48]; /* Reserved 040h-0FFh*/ - __IO uint32_t HPTXFSIZ; /* Host Periodic Tx FIFO Size Reg 100h*/ - __IO uint32_t DIEPTXF[3];/* dev Periodic Transmit FIFO */ -} -USB_OTG_GREGS; - -typedef struct // 800h -{ - __IO uint32_t DCFG; /* dev Configuration Register 800h*/ - __IO uint32_t DCTL; /* dev Control Register 804h*/ - __IO uint32_t DSTS; /* dev Status Register (RO) 808h*/ - uint32_t Reserved0C; /* Reserved 80Ch*/ - __IO uint32_t DIEPMSK; /* dev IN Endpoint Mask 810h*/ - __IO uint32_t DOEPMSK; /* dev OUT Endpoint Mask 814h*/ - __IO uint32_t DAINT; /* dev All Endpoints Itr Reg 818h*/ - __IO uint32_t DAINTMSK; /* dev All Endpoints Itr Mask 81Ch*/ - uint32_t Reserved20; /* Reserved 820h*/ - uint32_t Reserved9; /* Reserved 824h*/ - __IO uint32_t DVBUSDIS; /* dev VBUS discharge Register 828h*/ - __IO uint32_t DVBUSPULSE; /* dev VBUS Pulse Register 82Ch*/ - __IO uint32_t DTHRCTL; /* dev thr 830h*/ - __IO uint32_t DIEPEMPMSK; /* dev empty msk 834h*/ -} -USB_OTG_DREGS; - -typedef struct -{ - __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/ - uint32_t Reserved04; /* Reserved 900h + (ep_num * 20h) + 04h*/ - __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /* Reserved 900h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/ - uint32_t Reserved14; - __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/ - uint32_t Reserved1C; /* Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/ -} -USB_OTG_INEPREGS; - -typedef struct -{ - __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ - uint32_t Reserved04; /* Reserved B00h + (ep_num * 20h) + 04h*/ - __IO uint32_t DOEPINT; /* dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /* Reserved B00h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ - uint32_t Reserved14[3]; -} -USB_OTG_OUTEPREGS; - -typedef struct -{ - __IO uint32_t HCFG; /* Host Configuration Register 400h*/ - __IO uint32_t HFIR; /* Host Frame Interval Register 404h*/ - __IO uint32_t HFNUM; /* Host Frame Nbr/Frame Remaining 408h*/ - uint32_t Reserved40C; /* Reserved 40Ch*/ - __IO uint32_t HPTXSTS; /* Host Periodic Tx FIFO/ Queue Status 410h*/ - __IO uint32_t HAINT; /* Host All Channels Interrupt Register 414h*/ - __IO uint32_t HAINTMSK; /* Host All Channels Interrupt Mask 418h*/ -} -USB_OTG_HREGS; - -typedef struct -{ - __IO uint32_t HCCHAR; - __IO uint32_t HCSPLT; - __IO uint32_t HCINT; - __IO uint32_t HCINTMSK; - __IO uint32_t HCTSIZ; - uint32_t Reserved[3]; -} -USB_OTG_HC_REGS; - -typedef struct -{ - USB_OTG_GREGS GREGS; - uint32_t RESERVED0[188]; - USB_OTG_HREGS HREGS; - uint32_t RESERVED1[9]; - __IO uint32_t HPRT; - uint32_t RESERVED2[47]; - USB_OTG_HC_REGS HC_REGS[8]; - uint32_t RESERVED3[128]; - USB_OTG_DREGS DREGS; - uint32_t RESERVED4[50]; - USB_OTG_INEPREGS INEP_REGS[4]; - uint32_t RESERVED5[96]; - USB_OTG_OUTEPREGS OUTEP_REGS[4]; - uint32_t RESERVED6[160]; - __IO uint32_t PCGCCTL; - uint32_t RESERVED7[127]; - __IO uint32_t FIFO[4][1024]; -} -USB_OTG_CORE_REGS; - - -#define OTG_FS_BASE (AHB2PERIPH_BASE + 0x0000) -#define OTG_FS ((USB_OTG_CORE_REGS *) OTG_FS_BASE) - -#endif //__USB_OTG_REGS_H__ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -
diff -r 0c6524151939 -r 6cc8a2d36729 USBHID/USBHID.cpp --- a/USBHID/USBHID.cpp Wed Jun 18 09:00:48 2014 +0100 +++ b/USBHID/USBHID.cpp Fri Aug 15 14:14:38 2014 +0000 @@ -188,9 +188,9 @@ uint8_t * USBHID::stringIproductDesc() { static uint8_t stringIproductDescriptor[] = { - 0x16, //bLength + 0x14, //bLength STRING_DESCRIPTOR, //bDescriptorType 0x03 - 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device + 'f',0,'a',0,'v',0,'B',0,'u',0,'t',0,'t',0,'o',0,'n',0, //bString iProduct - HID device }; return stringIproductDescriptor; }
diff -r 0c6524151939 -r 6cc8a2d36729 USBHID/USBMouseKeyboard.cpp --- a/USBHID/USBMouseKeyboard.cpp Wed Jun 18 09:00:48 2014 +0100 +++ b/USBHID/USBMouseKeyboard.cpp Fri Aug 15 14:14:38 2014 +0000 @@ -438,6 +438,22 @@ REPORT_COUNT(1), 0x01, INPUT(1), 0x01, END_COLLECTION(0), + + + // Generic device + 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop) + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0xa1, 0x01, // COLLECTION (Application) + REPORT_ID(1),REPORT_ID_UTILITY, + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, REPORT_PAYLOAD_SIZE, // REPORT_COUNT + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0xc0 // END_COLLECTION }; reportLength = sizeof(reportDescriptor); return reportDescriptor; @@ -554,14 +570,17 @@ USBDevice::readEP(EPINT_OUT, led, &bytesRead, MAX_HID_REPORT_SIZE); // we take led[1] because led[0] is the report ID - lock_status = led[1] & 0x07; - + if(led[0]==REPORT_ID_UTILITY) + { + genericHidCallback(bytesRead-1, &led[1]); + } // We activate the endpoint to be able to recceive data if (!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE)) return false; return true; } + uint8_t USBMouseKeyboard::lockStatus() { return lock_status; }
diff -r 0c6524151939 -r 6cc8a2d36729 USBHID/USBMouseKeyboard.h --- a/USBHID/USBMouseKeyboard.h Wed Jun 18 09:00:48 2014 +0100 +++ b/USBHID/USBMouseKeyboard.h Fri Aug 15 14:14:38 2014 +0000 @@ -23,6 +23,9 @@ #define REPORT_ID_MOUSE 2 #define REPORT_ID_VOLUME 3 +#define REPORT_ID_UTILITY (4) +#define REPORT_PAYLOAD_SIZE (63) + #include "USBMouse.h" #include "USBKeyboard.h" #include "Stream.h" @@ -67,6 +70,9 @@ * } * @endcode */ + + + class USBMouseKeyboard: public USBHID, public Stream { public: @@ -203,8 +209,10 @@ * @returns if handle by subclass, return true */ virtual bool EP1_OUT_callback(); - - + + + virtual void genericHidCallback(uint32_t length, uint8_t *buff); + private: bool mouseWrite(int8_t x, int8_t y, uint8_t buttons, int8_t z); MOUSE_TYPE mouse_type;
diff -r 0c6524151939 -r 6cc8a2d36729 USBMIDI/MIDIMessage.h --- a/USBMIDI/MIDIMessage.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,251 +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) { - for (int i = 0; i < 4; i++) - data[i] = buf[i]; - } - - // 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 0c6524151939 -r 6cc8a2d36729 USBMIDI/USBMIDI.cpp --- a/USBMIDI/USBMIDI.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /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 (uint32_t 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 0c6524151939 -r 6cc8a2d36729 USBMIDI/USBMIDI.h --- a/USBMIDI/USBMIDI.h Wed Jun 18 09:00:48 2014 +0100 +++ /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 0c6524151939 -r 6cc8a2d36729 USBMSD/USBMSD.cpp --- a/USBMSD/USBMSD.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,655 +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)); - page = NULL; -} - -USBMSD::~USBMSD() { - disconnect(); -} - - -// 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(bool blocking) { - //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) { - free(page); - page = (uint8_t *)malloc(BlockSize * sizeof(uint8_t)); - if (page == NULL) - return false; - } - } else { - return false; - } - - //connect the device - USBDevice::connect(blocking); - return true; -} - -void USBMSD::disconnect() { - //De-allocate MSD page size: - free(page); - page = NULL; - USBDevice::disconnect(); -} - -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; - - // the host has received the CSW -> we wait a CBW - case WAIT_CSW: - stage = READ_CBW; - break; - - // an error has occured - default: - stallEndpoint(EPBULK_IN); - sendCSW(); - 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, - (uint8_t)((BlockCount >> 24) & 0xff), - (uint8_t)((BlockCount >> 16) & 0xff), - (uint8_t)((BlockCount >> 8) & 0xff), - (uint8_t)((BlockCount >> 0) & 0xff), - - 0x02, - (uint8_t)((BlockSize >> 16) & 0xff), - (uint8_t)((BlockSize >> 8) & 0xff), - (uint8_t)((BlockSize >> 0) & 0xff), - }; - if (!write(capacity, sizeof(capacity))) { - return false; - } - return true; -} - - -bool USBMSD::readCapacity (void) { - uint8_t capacity[] = { - (uint8_t)(((BlockCount - 1) >> 24) & 0xff), - (uint8_t)(((BlockCount - 1) >> 16) & 0xff), - (uint8_t)(((BlockCount - 1) >> 8) & 0xff), - (uint8_t)(((BlockCount - 1) >> 0) & 0xff), - - (uint8_t)((BlockSize >> 24) & 0xff), - (uint8_t)((BlockSize >> 16) & 0xff), - (uint8_t)((BlockSize >> 8) & 0xff), - (uint8_t)((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 0c6524151939 -r 6cc8a2d36729 USBMSD/USBMSD.h --- a/USBMSD/USBMSD.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,249 +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. - * - * @param blocking if not configured - * @returns true if successful - */ - bool connect(bool blocking = true); - - /** - * Disconnect the USB MSD device. - */ - void disconnect(); - - /** - * Destructor - */ - ~USBMSD(); - -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 struct { - uint32_t Signature; - uint32_t Tag; - uint32_t DataLength; - uint8_t Flags; - uint8_t LUN; - uint8_t CBLength; - uint8_t CB[16]; - } PACKED CBW; - - // Bulk-only CSW - typedef struct { - uint32_t Signature; - uint32_t Tag; - uint32_t DataResidue; - uint8_t Status; - } PACKED 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 0c6524151939 -r 6cc8a2d36729 USBSerial/CircBuffer.h --- a/USBSerial/CircBuffer.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +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)); - }; - - ~CircBuffer() { - free(buf); - } - - 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 0c6524151939 -r 6cc8a2d36729 USBSerial/USBCDC.cpp --- a/USBSerial/USBCDC.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,279 +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, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) { - terminal_connected = false; - USBDevice::connect(connect_blocking); -} - -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; - transfer->notify = true; - success = true; - terminal_connected = true; - break; - case CDC_SET_CONTROL_LINE_STATE: - terminal_connected = false; - success = true; - break; - default: - break; - } - } - - return success; -} - -void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) { - // Request of setting line coding has 7 bytes - if (length != 7) { - return; - } - - CONTROL_TRANSFER * transfer = getTransferPtr(); - - /* Process class-specific requests */ - if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { - if (transfer->setup.bRequest == CDC_SET_LINE_CODING) { - if (memcmp(cdc_line_coding, buf, 7)) { - memcpy(cdc_line_coding, buf, 7); - - int baud = buf[0] + (buf[1] << 8) - + (buf[2] << 16) + (buf[3] << 24); - int stop = buf[4]; - int bits = buf[6]; - int parity = buf[5]; - - lineCodingChanged(baud, bits, parity, stop); - } - } - } -} - -// 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 - (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)), // idVendor - (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(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 0c6524151939 -r 6cc8a2d36729 USBSerial/USBCDC.h --- a/USBSerial/USBCDC.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +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 - * @param connect_blocking define if the connection must be blocked if USB not plugged in - */ - USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking); - -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); - - /* - * Called by USBCallback_requestCompleted when CDC line coding is changed - * Warning: Called in ISR - * - * @param baud The baud rate - * @param bits The number of bits in a word (5-8) - * @param parity The parity - * @param stop The number of stop bits (1 or 2) - */ - virtual void lineCodingChanged(int baud, int bits, int parity, int stop) {}; - -protected: - virtual bool USBCallback_request(); - virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length); - virtual bool USBCallback_setConfiguration(uint8_t configuration); - volatile bool terminal_connected; - -}; - -#endif
diff -r 0c6524151939 -r 6cc8a2d36729 USBSerial/USBSerial.cpp --- a/USBSerial/USBSerial.cpp Wed Jun 18 09:00:48 2014 +0100 +++ /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 = 0; - 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 (uint32_t 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 0c6524151939 -r 6cc8a2d36729 USBSerial/USBSerial.h --- a/USBSerial/USBSerial.h Wed Jun 18 09:00:48 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +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) - * @param connect_blocking define if the connection must be blocked if USB not plugged in - * - */ - USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001, bool connect_blocking = true): USBCDC(vendor_id, product_id, product_release, connect_blocking), buf(128){ - settingsChangedCallback = 0; - }; - - - /** - * 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(); - - /** Determine if there is a character available to read - * - * @returns - * 1 if there is a character available to read, - * 0 otherwise - */ - int readable() { return available() ? 1 : 0; } - - /** Determine if there is space available to write a character - * - * @returns - * 1 if there is space to write a character, - * 0 otherwise - */ - int writeable() { return 1; } // always return 1, for write operation is blocking - - /** - * 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 (*fptr)(void)) { - if(fptr != NULL) { - rx.attach(fptr); - } - } - - /** - * Attach a callback to call when serial's settings are changed. - * - * @param fptr function pointer - */ - void attach(void (*fptr)(int baud, int bits, int parity, int stop)) { - settingsChangedCallback = fptr; - } - -protected: - virtual bool EP2_OUT_callback(); - virtual void lineCodingChanged(int baud, int bits, int parity, int stop){ - if (settingsChangedCallback) { - settingsChangedCallback(baud, bits, parity, stop); - } - } - -private: - FunctionPointer rx; - CircBuffer<uint8_t> buf; - void (*settingsChangedCallback)(int baud, int bits, int parity, int stop); -}; - -#endif