USB composite device example program, drag-and-drop flash writer.

Dependencies:   SWD USBDevice mbed BaseDAP

Committer:
va009039
Date:
Sat Sep 28 03:21:14 2013 +0000
Revision:
1:ea8e179320d7
add USBMSD_Drop class. add CDC(Virtual COM) and HID(for example CMSIS-DAP), but KL25Z not work.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 1:ea8e179320d7 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
va009039 1:ea8e179320d7 2 *
va009039 1:ea8e179320d7 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
va009039 1:ea8e179320d7 4 * and associated documentation files (the "Software"), to deal in the Software without
va009039 1:ea8e179320d7 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
va009039 1:ea8e179320d7 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
va009039 1:ea8e179320d7 7 * Software is furnished to do so, subject to the following conditions:
va009039 1:ea8e179320d7 8 *
va009039 1:ea8e179320d7 9 * The above copyright notice and this permission notice shall be included in all copies or
va009039 1:ea8e179320d7 10 * substantial portions of the Software.
va009039 1:ea8e179320d7 11 *
va009039 1:ea8e179320d7 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
va009039 1:ea8e179320d7 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
va009039 1:ea8e179320d7 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
va009039 1:ea8e179320d7 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
va009039 1:ea8e179320d7 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
va009039 1:ea8e179320d7 17 */
va009039 1:ea8e179320d7 18
va009039 1:ea8e179320d7 19 #include "stdint.h"
va009039 1:ea8e179320d7 20 #include "USB_CDC.h"
va009039 1:ea8e179320d7 21 #define MY_DEBUG
va009039 1:ea8e179320d7 22 #include "mydebug.h"
va009039 1:ea8e179320d7 23
va009039 1:ea8e179320d7 24 #define CDC_SET_LINE_CODING 0x20
va009039 1:ea8e179320d7 25 #define CDC_GET_LINE_CODING 0x21
va009039 1:ea8e179320d7 26 #define CDC_SET_CONTROL_LINE_STATE 0x22
va009039 1:ea8e179320d7 27 #define CDC_SEND_BREAK 0x23
va009039 1:ea8e179320d7 28
va009039 1:ea8e179320d7 29 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
va009039 1:ea8e179320d7 30
va009039 1:ea8e179320d7 31 USB_CDC::USB_CDC(USBDevice* device) : _device(device), _rx_buf(128)
va009039 1:ea8e179320d7 32 {
va009039 1:ea8e179320d7 33 terminal_connected = false;
va009039 1:ea8e179320d7 34 //USBDevice::connect();
va009039 1:ea8e179320d7 35 }
va009039 1:ea8e179320d7 36
va009039 1:ea8e179320d7 37 void USB_CDC::putc(int c)
va009039 1:ea8e179320d7 38 {
va009039 1:ea8e179320d7 39 if (terminal_connected) {
va009039 1:ea8e179320d7 40 uint8_t buf[1];
va009039 1:ea8e179320d7 41 buf[0] = c;
va009039 1:ea8e179320d7 42 _device->write(CDC_EPBULK_IN, buf, sizeof(buf), MAX_CDC_REPORT_SIZE);
va009039 1:ea8e179320d7 43 }
va009039 1:ea8e179320d7 44 }
va009039 1:ea8e179320d7 45
va009039 1:ea8e179320d7 46 int USB_CDC::getc()
va009039 1:ea8e179320d7 47 {
va009039 1:ea8e179320d7 48 uint8_t c = 0;
va009039 1:ea8e179320d7 49 while (_rx_buf.isEmpty());
va009039 1:ea8e179320d7 50 _rx_buf.dequeue(&c);
va009039 1:ea8e179320d7 51 return c;
va009039 1:ea8e179320d7 52 }
va009039 1:ea8e179320d7 53
va009039 1:ea8e179320d7 54 int USB_CDC::readable()
va009039 1:ea8e179320d7 55 {
va009039 1:ea8e179320d7 56 return _rx_buf.available() > 0 ? 1 : 0;
va009039 1:ea8e179320d7 57 }
va009039 1:ea8e179320d7 58
va009039 1:ea8e179320d7 59 int USB_CDC::writeable()
va009039 1:ea8e179320d7 60 {
va009039 1:ea8e179320d7 61 return 1;
va009039 1:ea8e179320d7 62 }
va009039 1:ea8e179320d7 63
va009039 1:ea8e179320d7 64 void USB_CDC::baud_callback(int baudrate)
va009039 1:ea8e179320d7 65 {
va009039 1:ea8e179320d7 66 DBG("baudrate=%d", baudrate);
va009039 1:ea8e179320d7 67 }
va009039 1:ea8e179320d7 68
va009039 1:ea8e179320d7 69 void USB_CDC::send_break_callback(uint16_t duration)
va009039 1:ea8e179320d7 70 {
va009039 1:ea8e179320d7 71 DBG("duration=%04x", duration);
va009039 1:ea8e179320d7 72 }
va009039 1:ea8e179320d7 73
va009039 1:ea8e179320d7 74 void USB_CDC::control_line_callback(int rts, int dtr)
va009039 1:ea8e179320d7 75 {
va009039 1:ea8e179320d7 76 DBG("rts=%d, dtr=%d", rts, dtr);
va009039 1:ea8e179320d7 77 }
va009039 1:ea8e179320d7 78
va009039 1:ea8e179320d7 79 bool USB_CDC::send(uint8_t * buffer, uint32_t size) {
va009039 1:ea8e179320d7 80 return _device->write(CDC_EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
va009039 1:ea8e179320d7 81 }
va009039 1:ea8e179320d7 82
va009039 1:ea8e179320d7 83 bool USB_CDC::readEP(uint8_t * buffer, uint32_t * size) {
va009039 1:ea8e179320d7 84 if (!_device->readEP(CDC_EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
va009039 1:ea8e179320d7 85 return false;
va009039 1:ea8e179320d7 86 if (!_device->readStart(CDC_EPBULK_OUT, MAX_CDC_REPORT_SIZE))
va009039 1:ea8e179320d7 87 return false;
va009039 1:ea8e179320d7 88 return true;
va009039 1:ea8e179320d7 89 }
va009039 1:ea8e179320d7 90
va009039 1:ea8e179320d7 91 bool USB_CDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
va009039 1:ea8e179320d7 92 if (!_device->readEP_NB(CDC_EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
va009039 1:ea8e179320d7 93 return false;
va009039 1:ea8e179320d7 94 if (!_device->readStart(CDC_EPBULK_OUT, MAX_CDC_REPORT_SIZE))
va009039 1:ea8e179320d7 95 return false;
va009039 1:ea8e179320d7 96 return true;
va009039 1:ea8e179320d7 97 }
va009039 1:ea8e179320d7 98
va009039 1:ea8e179320d7 99 bool USB_CDC::Request_callback(CONTROL_TRANSFER* transfer)
va009039 1:ea8e179320d7 100 {
va009039 1:ea8e179320d7 101 static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
va009039 1:ea8e179320d7 102
va009039 1:ea8e179320d7 103 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
va009039 1:ea8e179320d7 104 switch (transfer->setup.bRequest) {
va009039 1:ea8e179320d7 105 case CDC_SET_LINE_CODING: // 0x20
va009039 1:ea8e179320d7 106 transfer->remaining = 7;
va009039 1:ea8e179320d7 107 transfer->notify = true;
va009039 1:ea8e179320d7 108 terminal_connected = true;
va009039 1:ea8e179320d7 109 return true;
va009039 1:ea8e179320d7 110
va009039 1:ea8e179320d7 111 case CDC_GET_LINE_CODING: // x021
va009039 1:ea8e179320d7 112 transfer->remaining = 7;
va009039 1:ea8e179320d7 113 transfer->ptr = cdc_line_coding;
va009039 1:ea8e179320d7 114 transfer->direction = DEVICE_TO_HOST;
va009039 1:ea8e179320d7 115 return true;
va009039 1:ea8e179320d7 116
va009039 1:ea8e179320d7 117 case CDC_SET_CONTROL_LINE_STATE: // 0x22
va009039 1:ea8e179320d7 118 control_line_callback((transfer->setup.wValue>>1) & 1, (transfer->setup.wValue) & 1);
va009039 1:ea8e179320d7 119 terminal_connected = false;
va009039 1:ea8e179320d7 120 return true;
va009039 1:ea8e179320d7 121
va009039 1:ea8e179320d7 122 case CDC_SEND_BREAK: // 0x23
va009039 1:ea8e179320d7 123 send_break_callback(transfer->setup.wValue);
va009039 1:ea8e179320d7 124 return true;
va009039 1:ea8e179320d7 125 }
va009039 1:ea8e179320d7 126 }
va009039 1:ea8e179320d7 127 return false;
va009039 1:ea8e179320d7 128 }
va009039 1:ea8e179320d7 129
va009039 1:ea8e179320d7 130 static uint32_t LD32(uint8_t* buf)
va009039 1:ea8e179320d7 131 {
va009039 1:ea8e179320d7 132 return buf[0]|buf[1]<<8|buf[2]<<16|buf[3]<<24;
va009039 1:ea8e179320d7 133 }
va009039 1:ea8e179320d7 134
va009039 1:ea8e179320d7 135 bool USB_CDC::RequestCompleted_callback(CONTROL_TRANSFER* transfer, uint8_t* buf, int length)
va009039 1:ea8e179320d7 136 {
va009039 1:ea8e179320d7 137 int baudrate;
va009039 1:ea8e179320d7 138 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
va009039 1:ea8e179320d7 139 switch (transfer->setup.bRequest) {
va009039 1:ea8e179320d7 140 case CDC_SET_LINE_CODING: // 0x20
va009039 1:ea8e179320d7 141 baudrate = LD32(buf);
va009039 1:ea8e179320d7 142 baud_callback(baudrate);
va009039 1:ea8e179320d7 143 return true;
va009039 1:ea8e179320d7 144 }
va009039 1:ea8e179320d7 145 }
va009039 1:ea8e179320d7 146 DBG_HEX((uint8_t*)transfer, sizeof(CONTROL_TRANSFER));
va009039 1:ea8e179320d7 147 return false;
va009039 1:ea8e179320d7 148 }
va009039 1:ea8e179320d7 149
va009039 1:ea8e179320d7 150 bool USB_CDC::EPBULK_OUT_callback() // virtual COM to target
va009039 1:ea8e179320d7 151 {
va009039 1:ea8e179320d7 152 uint8_t buf[MAX_CDC_REPORT_SIZE];
va009039 1:ea8e179320d7 153 uint32_t size = 0;
va009039 1:ea8e179320d7 154 //we read the packet received and put it on the circular buffer
va009039 1:ea8e179320d7 155 _device->readEP(CDC_EPBULK_OUT, buf, &size, MAX_CDC_REPORT_SIZE);
va009039 1:ea8e179320d7 156 for(int i = 0; i < size; i++) {
va009039 1:ea8e179320d7 157 _rx_buf.queue(buf[i]);
va009039 1:ea8e179320d7 158 }
va009039 1:ea8e179320d7 159
va009039 1:ea8e179320d7 160 // We reactivate the endpoint to receive next characters
va009039 1:ea8e179320d7 161 _device->readStart(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
va009039 1:ea8e179320d7 162 return true;
va009039 1:ea8e179320d7 163 }