Fork of https://developer.mbed.org/users/bscott/code/STM32_USBDevice/

Fork of STM32_USBDevice by Bradley Scott

Committer:
Troels Nilsson
Date:
Thu Jul 19 12:57:27 2018 +0200
Branch:
feature_WebUSB
Revision:
76:eef92651f52f
Child:
77:a98f786d05d4
Added USBWebUSBSerial class

The class implements a composite device with CDC and a WebUSB compatible interface

Data is read and written from either the CDC or the WebUSB interface depending on the mode.
Default mode is CDC - it can be changed to WebUSB by sending a control message from the host.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Troels Nilsson 76:eef92651f52f 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
Troels Nilsson 76:eef92651f52f 2 *
Troels Nilsson 76:eef92651f52f 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Troels Nilsson 76:eef92651f52f 4 * and associated documentation files (the "Software"), to deal in the Software without
Troels Nilsson 76:eef92651f52f 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
Troels Nilsson 76:eef92651f52f 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Troels Nilsson 76:eef92651f52f 7 * Software is furnished to do so, subject to the following conditions:
Troels Nilsson 76:eef92651f52f 8 *
Troels Nilsson 76:eef92651f52f 9 * The above copyright notice and this permission notice shall be included in all copies or
Troels Nilsson 76:eef92651f52f 10 * substantial portions of the Software.
Troels Nilsson 76:eef92651f52f 11 *
Troels Nilsson 76:eef92651f52f 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Troels Nilsson 76:eef92651f52f 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Troels Nilsson 76:eef92651f52f 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Troels Nilsson 76:eef92651f52f 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Troels Nilsson 76:eef92651f52f 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Troels Nilsson 76:eef92651f52f 17 */
Troels Nilsson 76:eef92651f52f 18
Troels Nilsson 76:eef92651f52f 19 #ifndef USBWEBUSBSERIAL_H
Troels Nilsson 76:eef92651f52f 20 #define USBWEBUSBSERIAL_H
Troels Nilsson 76:eef92651f52f 21
Troels Nilsson 76:eef92651f52f 22 #include <string>
Troels Nilsson 76:eef92651f52f 23 #include "USBDevice.h"
Troels Nilsson 76:eef92651f52f 24 #include "Stream.h"
Troels Nilsson 76:eef92651f52f 25 #include "CircBuffer.h"
Troels Nilsson 76:eef92651f52f 26 #include "USBEndpoints.h"
Troels Nilsson 76:eef92651f52f 27 #include "USBDescriptor.h"
Troels Nilsson 76:eef92651f52f 28 #include "USBDevice_Types.h"
Troels Nilsson 76:eef92651f52f 29
Troels Nilsson 76:eef92651f52f 30 #ifndef USBWEBUSBSERIAL_INPUT_BUFFER_SIZE
Troels Nilsson 76:eef92651f52f 31 #define USBWEBUSBSERIAL_INPUT_BUFFER_SIZE 128
Troels Nilsson 76:eef92651f52f 32 #endif
Troels Nilsson 76:eef92651f52f 33
Troels Nilsson 76:eef92651f52f 34 /**
Troels Nilsson 76:eef92651f52f 35 * WebUSB/USBSerial composite device class
Troels Nilsson 76:eef92651f52f 36 * Handles outputting to standard CDC or WebUSB endpoint depending on mode
Troels Nilsson 76:eef92651f52f 37 *
Troels Nilsson 76:eef92651f52f 38 */
Troels Nilsson 76:eef92651f52f 39 class USBWebUSBSerial: public USBDevice, public Stream
Troels Nilsson 76:eef92651f52f 40 {
Troels Nilsson 76:eef92651f52f 41 public:
Troels Nilsson 76:eef92651f52f 42
Troels Nilsson 76:eef92651f52f 43 /**
Troels Nilsson 76:eef92651f52f 44 * Constructor
Troels Nilsson 76:eef92651f52f 45 *
Troels Nilsson 76:eef92651f52f 46 * @param vendor_id Your vendor_id
Troels Nilsson 76:eef92651f52f 47 * @param product_id Your product_id
Troels Nilsson 76:eef92651f52f 48 * @param product_release Your product_release (default: 0x0001)
Troels Nilsson 76:eef92651f52f 49 * @param connect_blocking define if the connection must be blocked if USB not plugged in
Troels Nilsson 76:eef92651f52f 50 *
Troels Nilsson 76:eef92651f52f 51 */
Troels Nilsson 76:eef92651f52f 52 USBWebUSBSerial(uint16_t vendor_id, uint16_t product_id, uint16_t product_release = 0x0001, bool connect_blocking = true);
Troels Nilsson 76:eef92651f52f 53
Troels Nilsson 76:eef92651f52f 54 const std::string& manufacturerName() const { return m_manufacturerName; }
Troels Nilsson 76:eef92651f52f 55 void setManufacturerName(const std::string &manufacturerName);
Troels Nilsson 76:eef92651f52f 56
Troels Nilsson 76:eef92651f52f 57 const std::string& productName() const { return m_productName; }
Troels Nilsson 76:eef92651f52f 58 void setProductName(const std::string &productName);
Troels Nilsson 76:eef92651f52f 59
Troels Nilsson 76:eef92651f52f 60 const std::string& serialNumber() const { return m_serialNumber; }
Troels Nilsson 76:eef92651f52f 61 void setSerialNumber(const std::string &serialNumber);
Troels Nilsson 76:eef92651f52f 62
Troels Nilsson 76:eef92651f52f 63 /**
Troels Nilsson 76:eef92651f52f 64 * Send a character. You can use puts, printf.
Troels Nilsson 76:eef92651f52f 65 *
Troels Nilsson 76:eef92651f52f 66 * @param c character to be sent
Troels Nilsson 76:eef92651f52f 67 * @returns true if there is no error, false otherwise
Troels Nilsson 76:eef92651f52f 68 */
Troels Nilsson 76:eef92651f52f 69 virtual int _putc(int c);
Troels Nilsson 76:eef92651f52f 70
Troels Nilsson 76:eef92651f52f 71 /**
Troels Nilsson 76:eef92651f52f 72 * Read a character: blocking
Troels Nilsson 76:eef92651f52f 73 *
Troels Nilsson 76:eef92651f52f 74 * @returns character read
Troels Nilsson 76:eef92651f52f 75 */
Troels Nilsson 76:eef92651f52f 76 virtual int _getc();
Troels Nilsson 76:eef92651f52f 77
Troels Nilsson 76:eef92651f52f 78 /**
Troels Nilsson 76:eef92651f52f 79 * Check the number of bytes available.
Troels Nilsson 76:eef92651f52f 80 *
Troels Nilsson 76:eef92651f52f 81 * @returns the number of bytes available
Troels Nilsson 76:eef92651f52f 82 */
Troels Nilsson 76:eef92651f52f 83 uint8_t available();
Troels Nilsson 76:eef92651f52f 84
Troels Nilsson 76:eef92651f52f 85 /** Determine if there is a character available to read
Troels Nilsson 76:eef92651f52f 86 *
Troels Nilsson 76:eef92651f52f 87 * @returns
Troels Nilsson 76:eef92651f52f 88 * 1 if there is a character available to read,
Troels Nilsson 76:eef92651f52f 89 * 0 otherwise
Troels Nilsson 76:eef92651f52f 90 */
Troels Nilsson 76:eef92651f52f 91 int readable() { return available() ? 1 : 0; }
Troels Nilsson 76:eef92651f52f 92
Troels Nilsson 76:eef92651f52f 93 /** Determine if there is space available to write a character
Troels Nilsson 76:eef92651f52f 94 *
Troels Nilsson 76:eef92651f52f 95 * @returns
Troels Nilsson 76:eef92651f52f 96 * 1 if there is space to write a character,
Troels Nilsson 76:eef92651f52f 97 * 0 otherwise
Troels Nilsson 76:eef92651f52f 98 */
Troels Nilsson 76:eef92651f52f 99 int writeable() { return 1; } // always return 1, for write operation is blocking
Troels Nilsson 76:eef92651f52f 100
Troels Nilsson 76:eef92651f52f 101 /**
Troels Nilsson 76:eef92651f52f 102 * Write a block of data.
Troels Nilsson 76:eef92651f52f 103 *
Troels Nilsson 76:eef92651f52f 104 * For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written.
Troels Nilsson 76:eef92651f52f 105 *
Troels Nilsson 76:eef92651f52f 106 * @param buf pointer on data which will be written
Troels Nilsson 76:eef92651f52f 107 * @param size size of the buffer. The maximum size of a block is limited by the size of the endpoint (64 bytes)
Troels Nilsson 76:eef92651f52f 108 *
Troels Nilsson 76:eef92651f52f 109 * @returns true if successfull
Troels Nilsson 76:eef92651f52f 110 */
Troels Nilsson 76:eef92651f52f 111 bool writeBlock(const uint8_t * buf, uint16_t size);
Troels Nilsson 76:eef92651f52f 112
Troels Nilsson 76:eef92651f52f 113 /**
Troels Nilsson 76:eef92651f52f 114 * Attach a member function to call when a packet is received.
Troels Nilsson 76:eef92651f52f 115 *
Troels Nilsson 76:eef92651f52f 116 * @param tptr pointer to the object to call the member function on
Troels Nilsson 76:eef92651f52f 117 * @param mptr pointer to the member function to be called
Troels Nilsson 76:eef92651f52f 118 */
Troels Nilsson 76:eef92651f52f 119 template<typename T>
Troels Nilsson 76:eef92651f52f 120 void attach(T* tptr, void (T::*mptr)(void))
Troels Nilsson 76:eef92651f52f 121 {
Troels Nilsson 76:eef92651f52f 122 if (mptr && tptr)
Troels Nilsson 76:eef92651f52f 123 {
Troels Nilsson 76:eef92651f52f 124 m_rx.attach(tptr, mptr);
Troels Nilsson 76:eef92651f52f 125 }
Troels Nilsson 76:eef92651f52f 126 }
Troels Nilsson 76:eef92651f52f 127
Troels Nilsson 76:eef92651f52f 128 /**
Troels Nilsson 76:eef92651f52f 129 * Attach a callback called when a packet is received
Troels Nilsson 76:eef92651f52f 130 *
Troels Nilsson 76:eef92651f52f 131 * @param fptr function pointer
Troels Nilsson 76:eef92651f52f 132 */
Troels Nilsson 76:eef92651f52f 133 void attach(void (*fptr)(void))
Troels Nilsson 76:eef92651f52f 134 {
Troels Nilsson 76:eef92651f52f 135 if (fptr)
Troels Nilsson 76:eef92651f52f 136 {
Troels Nilsson 76:eef92651f52f 137 m_rx.attach(fptr);
Troels Nilsson 76:eef92651f52f 138 }
Troels Nilsson 76:eef92651f52f 139 }
Troels Nilsson 76:eef92651f52f 140
Troels Nilsson 76:eef92651f52f 141 /**
Troels Nilsson 76:eef92651f52f 142 * Attach a callback to call when serial's settings are changed.
Troels Nilsson 76:eef92651f52f 143 *
Troels Nilsson 76:eef92651f52f 144 * @param fptr function pointer
Troels Nilsson 76:eef92651f52f 145 */
Troels Nilsson 76:eef92651f52f 146 void attach(void (*fptr)(int baud, int bits, int parity, int stop))
Troels Nilsson 76:eef92651f52f 147 {
Troels Nilsson 76:eef92651f52f 148 m_settingsChangedCallback = fptr;
Troels Nilsson 76:eef92651f52f 149 }
Troels Nilsson 76:eef92651f52f 150
Troels Nilsson 76:eef92651f52f 151 protected:
Troels Nilsson 76:eef92651f52f 152
Troels Nilsson 76:eef92651f52f 153 /*
Troels Nilsson 76:eef92651f52f 154 * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
Troels Nilsson 76:eef92651f52f 155 *
Troels Nilsson 76:eef92651f52f 156 * @returns pointer to the device descriptor
Troels Nilsson 76:eef92651f52f 157 */
Troels Nilsson 76:eef92651f52f 158 virtual uint8_t * deviceDesc();
Troels Nilsson 76:eef92651f52f 159
Troels Nilsson 76:eef92651f52f 160 /*
Troels Nilsson 76:eef92651f52f 161 * Get string manufacturer descriptor
Troels Nilsson 76:eef92651f52f 162 *
Troels Nilsson 76:eef92651f52f 163 * @returns pointer to the string manufacturer descriptor
Troels Nilsson 76:eef92651f52f 164 */
Troels Nilsson 76:eef92651f52f 165 virtual uint8_t * stringImanufacturerDesc();
Troels Nilsson 76:eef92651f52f 166
Troels Nilsson 76:eef92651f52f 167 /*
Troels Nilsson 76:eef92651f52f 168 * Get string product descriptor
Troels Nilsson 76:eef92651f52f 169 *
Troels Nilsson 76:eef92651f52f 170 * @returns pointer to the string product descriptor
Troels Nilsson 76:eef92651f52f 171 */
Troels Nilsson 76:eef92651f52f 172 virtual uint8_t * stringIproductDesc();
Troels Nilsson 76:eef92651f52f 173
Troels Nilsson 76:eef92651f52f 174 /*
Troels Nilsson 76:eef92651f52f 175 * Get string serial descriptor
Troels Nilsson 76:eef92651f52f 176 *
Troels Nilsson 76:eef92651f52f 177 * @returns pointer to the string serial descriptor
Troels Nilsson 76:eef92651f52f 178 */
Troels Nilsson 76:eef92651f52f 179 virtual uint8_t * stringIserialDesc();
Troels Nilsson 76:eef92651f52f 180
Troels Nilsson 76:eef92651f52f 181 /*
Troels Nilsson 76:eef92651f52f 182 * Get configuration descriptor
Troels Nilsson 76:eef92651f52f 183 *
Troels Nilsson 76:eef92651f52f 184 * @returns pointer to the configuration descriptor
Troels Nilsson 76:eef92651f52f 185 */
Troels Nilsson 76:eef92651f52f 186 virtual uint8_t * configurationDesc();
Troels Nilsson 76:eef92651f52f 187
Troels Nilsson 76:eef92651f52f 188 /*
Troels Nilsson 76:eef92651f52f 189 * Get BOS descriptor
Troels Nilsson 76:eef92651f52f 190 *
Troels Nilsson 76:eef92651f52f 191 * @returns pointer to the BOS descriptor
Troels Nilsson 76:eef92651f52f 192 */
Troels Nilsson 76:eef92651f52f 193 virtual uint8_t * bosDesc();
Troels Nilsson 76:eef92651f52f 194
Troels Nilsson 76:eef92651f52f 195 /*
Troels Nilsson 76:eef92651f52f 196 * Send a buffer and wait for it to be read
Troels Nilsson 76:eef92651f52f 197 *
Troels Nilsson 76:eef92651f52f 198 * @param buffer buffer to be sent
Troels Nilsson 76:eef92651f52f 199 * @param size length of the buffer
Troels Nilsson 76:eef92651f52f 200 * @returns true if successful
Troels Nilsson 76:eef92651f52f 201 */
Troels Nilsson 76:eef92651f52f 202 bool send(const uint8_t * buffer, uint32_t size);
Troels Nilsson 76:eef92651f52f 203
Troels Nilsson 76:eef92651f52f 204 /*
Troels Nilsson 76:eef92651f52f 205 * Read from the active endpoint into the internal buffer (non-blocking)
Troels Nilsson 76:eef92651f52f 206 *
Troels Nilsson 76:eef92651f52f 207 * @returns true if successful
Troels Nilsson 76:eef92651f52f 208 */
Troels Nilsson 76:eef92651f52f 209 bool readActiveEP();
Troels Nilsson 76:eef92651f52f 210
Troels Nilsson 76:eef92651f52f 211 /*
Troels Nilsson 76:eef92651f52f 212 * Called by USBCallback_requestCompleted when CDC line coding is changed
Troels Nilsson 76:eef92651f52f 213 * Warning: Called in ISR
Troels Nilsson 76:eef92651f52f 214 *
Troels Nilsson 76:eef92651f52f 215 * @param baud The baud rate
Troels Nilsson 76:eef92651f52f 216 * @param bits The number of bits in a word (5-8)
Troels Nilsson 76:eef92651f52f 217 * @param parity The parity
Troels Nilsson 76:eef92651f52f 218 * @param stop The number of stop bits (1 or 2)
Troels Nilsson 76:eef92651f52f 219 */
Troels Nilsson 76:eef92651f52f 220 virtual void lineCodingChanged(int baud, int bits, int parity, int stop)
Troels Nilsson 76:eef92651f52f 221 {
Troels Nilsson 76:eef92651f52f 222 if (m_settingsChangedCallback)
Troels Nilsson 76:eef92651f52f 223 {
Troels Nilsson 76:eef92651f52f 224 m_settingsChangedCallback(baud, bits, parity, stop);
Troels Nilsson 76:eef92651f52f 225 }
Troels Nilsson 76:eef92651f52f 226 }
Troels Nilsson 76:eef92651f52f 227
Troels Nilsson 76:eef92651f52f 228 virtual bool USBCallback_request();
Troels Nilsson 76:eef92651f52f 229 virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length);
Troels Nilsson 76:eef92651f52f 230 virtual bool USBCallback_setConfiguration(uint8_t configuration);
Troels Nilsson 76:eef92651f52f 231 virtual void USBCallback_busReset(void);
Troels Nilsson 76:eef92651f52f 232
Troels Nilsson 76:eef92651f52f 233 virtual bool EPCDC_OUT_callback();
Troels Nilsson 76:eef92651f52f 234 virtual bool EPWEBUSB_OUT_callback();
Troels Nilsson 76:eef92651f52f 235 virtual bool EPOUTCallbackHandler(uint8_t endpoint);
Troels Nilsson 76:eef92651f52f 236
Troels Nilsson 76:eef92651f52f 237 private:
Troels Nilsson 76:eef92651f52f 238 uint8_t activeOutEndpoint() const { return m_webUSBMode ? EPWEBUSB_OUT : EPCDC_OUT; }
Troels Nilsson 76:eef92651f52f 239 uint8_t activeInEndpoint() const { return m_webUSBMode ? EPWEBUSB_IN : EPCDC_IN; }
Troels Nilsson 76:eef92651f52f 240 void createDynamicDescriptors();
Troels Nilsson 76:eef92651f52f 241 uint8_t *createStringDescriptor(const std::string &string) const;
Troels Nilsson 76:eef92651f52f 242
Troels Nilsson 76:eef92651f52f 243 static uint8_t s_MSOS2Descriptor[];
Troels Nilsson 76:eef92651f52f 244 volatile bool m_terminalConnected;
Troels Nilsson 76:eef92651f52f 245 FunctionPointer m_rx;
Troels Nilsson 76:eef92651f52f 246 CircBuffer<uint8_t,USBWEBUSBSERIAL_INPUT_BUFFER_SIZE> m_buffer;
Troels Nilsson 76:eef92651f52f 247 void (*m_settingsChangedCallback)(int baud, int bits, int parity, int stop) = nullptr;
Troels Nilsson 76:eef92651f52f 248 std::string m_manufacturerName = "mbed.org";
Troels Nilsson 76:eef92651f52f 249 uint8_t *m_manufacturerStringDesc = nullptr;
Troels Nilsson 76:eef92651f52f 250 std::string m_productName = "CDC/WebUSB Device";
Troels Nilsson 76:eef92651f52f 251 uint8_t *m_productStringDesc = nullptr;
Troels Nilsson 76:eef92651f52f 252 std::string m_serialNumber = "0123456789";
Troels Nilsson 76:eef92651f52f 253 uint8_t *m_serialStringDesc = nullptr;
Troels Nilsson 76:eef92651f52f 254 bool m_webUSBMode = false;
Troels Nilsson 76:eef92651f52f 255 };
Troels Nilsson 76:eef92651f52f 256
Troels Nilsson 76:eef92651f52f 257 #endif