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

Fork of STM32_USBDevice by Bradley Scott

Committer:
Troels Nilsson
Date:
Wed Jul 25 14:04:48 2018 +0200
Revision:
79:d28244984385
Parent:
78:ba3f68a86e6d
Merge feature_WebUSB into default

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 "CircBuffer.h"
Troels Nilsson 76:eef92651f52f 25 #include "USBEndpoints.h"
Troels Nilsson 76:eef92651f52f 26 #include "USBDescriptor.h"
Troels Nilsson 76:eef92651f52f 27 #include "USBDevice_Types.h"
Troels Nilsson 76:eef92651f52f 28
Troels Nilsson 76:eef92651f52f 29 #ifndef USBWEBUSBSERIAL_INPUT_BUFFER_SIZE
Troels Nilsson 76:eef92651f52f 30 #define USBWEBUSBSERIAL_INPUT_BUFFER_SIZE 128
Troels Nilsson 76:eef92651f52f 31 #endif
Troels Nilsson 76:eef92651f52f 32
Troels Nilsson 77:a98f786d05d4 33 #ifndef USBWEBUSBSERIAL_OUTPUT_BUFFER_SIZE
Troels Nilsson 77:a98f786d05d4 34 #define USBWEBUSBSERIAL_OUTPUT_BUFFER_SIZE 512
Troels Nilsson 77:a98f786d05d4 35 #endif
Troels Nilsson 77:a98f786d05d4 36
Troels Nilsson 76:eef92651f52f 37 /**
Troels Nilsson 76:eef92651f52f 38 * WebUSB/USBSerial composite device class
Troels Nilsson 76:eef92651f52f 39 * Handles outputting to standard CDC or WebUSB endpoint depending on mode
Troels Nilsson 76:eef92651f52f 40 *
Troels Nilsson 76:eef92651f52f 41 */
Troels Nilsson 78:ba3f68a86e6d 42 class USBWebUSBSerial: public USBDevice
Troels Nilsson 76:eef92651f52f 43 {
Troels Nilsson 76:eef92651f52f 44 public:
Troels Nilsson 76:eef92651f52f 45
Troels Nilsson 76:eef92651f52f 46 /**
Troels Nilsson 76:eef92651f52f 47 * Constructor
Troels Nilsson 76:eef92651f52f 48 *
Troels Nilsson 76:eef92651f52f 49 * @param vendor_id Your vendor_id
Troels Nilsson 76:eef92651f52f 50 * @param product_id Your product_id
Troels Nilsson 76:eef92651f52f 51 * @param product_release Your product_release (default: 0x0001)
Troels Nilsson 76:eef92651f52f 52 * @param connect_blocking define if the connection must be blocked if USB not plugged in
Troels Nilsson 76:eef92651f52f 53 *
Troels Nilsson 76:eef92651f52f 54 */
Troels Nilsson 76:eef92651f52f 55 USBWebUSBSerial(uint16_t vendor_id, uint16_t product_id, uint16_t product_release = 0x0001, bool connect_blocking = true);
Troels Nilsson 78:ba3f68a86e6d 56 virtual ~USBWebUSBSerial();
Troels Nilsson 76:eef92651f52f 57
Troels Nilsson 76:eef92651f52f 58 const std::string& manufacturerName() const { return m_manufacturerName; }
Troels Nilsson 76:eef92651f52f 59 void setManufacturerName(const std::string &manufacturerName);
Troels Nilsson 76:eef92651f52f 60
Troels Nilsson 76:eef92651f52f 61 const std::string& productName() const { return m_productName; }
Troels Nilsson 76:eef92651f52f 62 void setProductName(const std::string &productName);
Troels Nilsson 76:eef92651f52f 63
Troels Nilsson 76:eef92651f52f 64 const std::string& serialNumber() const { return m_serialNumber; }
Troels Nilsson 76:eef92651f52f 65 void setSerialNumber(const std::string &serialNumber);
Troels Nilsson 76:eef92651f52f 66
Troels Nilsson 76:eef92651f52f 67 /**
Troels Nilsson 78:ba3f68a86e6d 68 * Read up to size bytes from input buffer
Troels Nilsson 76:eef92651f52f 69 *
Troels Nilsson 78:ba3f68a86e6d 70 * @returns the number of bytes read
Troels Nilsson 76:eef92651f52f 71 */
Troels Nilsson 76:eef92651f52f 72
Troels Nilsson 78:ba3f68a86e6d 73 int read(uint8_t *buf, uint16_t size);
Troels Nilsson 76:eef92651f52f 74
Troels Nilsson 76:eef92651f52f 75 /**
Troels Nilsson 76:eef92651f52f 76 * Check the number of bytes available.
Troels Nilsson 76:eef92651f52f 77 *
Troels Nilsson 76:eef92651f52f 78 * @returns the number of bytes available
Troels Nilsson 76:eef92651f52f 79 */
Troels Nilsson 76:eef92651f52f 80 uint8_t available();
Troels Nilsson 76:eef92651f52f 81
Troels Nilsson 76:eef92651f52f 82 /** Determine if there is a character available to read
Troels Nilsson 76:eef92651f52f 83 *
Troels Nilsson 76:eef92651f52f 84 * @returns
Troels Nilsson 76:eef92651f52f 85 * 1 if there is a character available to read,
Troels Nilsson 76:eef92651f52f 86 * 0 otherwise
Troels Nilsson 76:eef92651f52f 87 */
Troels Nilsson 76:eef92651f52f 88 int readable() { return available() ? 1 : 0; }
Troels Nilsson 76:eef92651f52f 89
Troels Nilsson 76:eef92651f52f 90 /** Determine if there is space available to write a character
Troels Nilsson 76:eef92651f52f 91 *
Troels Nilsson 76:eef92651f52f 92 * @returns
Troels Nilsson 76:eef92651f52f 93 * 1 if there is space to write a character,
Troels Nilsson 76:eef92651f52f 94 * 0 otherwise
Troels Nilsson 76:eef92651f52f 95 */
Troels Nilsson 77:a98f786d05d4 96 int writeable() { return 1; } // Always return 1 since we use a circular buffer
Troels Nilsson 76:eef92651f52f 97
Troels Nilsson 76:eef92651f52f 98 /**
Troels Nilsson 77:a98f786d05d4 99 * Write data asynchronously using internal output buffer
Troels Nilsson 76:eef92651f52f 100 *
Troels Nilsson 77:a98f786d05d4 101 * @param buf pointer to data
Troels Nilsson 77:a98f786d05d4 102 * @param size size of the buffer. The maximum size of data is limited by the size of the internal buffer
Troels Nilsson 76:eef92651f52f 103 *
Troels Nilsson 76:eef92651f52f 104 * @returns true if successfull
Troels Nilsson 76:eef92651f52f 105 */
Troels Nilsson 77:a98f786d05d4 106 bool writeBuffered(const uint8_t * buf, uint16_t size);
Troels Nilsson 76:eef92651f52f 107
Troels Nilsson 76:eef92651f52f 108 /**
Troels Nilsson 76:eef92651f52f 109 * Attach a member function to call when a packet is received.
Troels Nilsson 76:eef92651f52f 110 *
Troels Nilsson 76:eef92651f52f 111 * @param tptr pointer to the object to call the member function on
Troels Nilsson 76:eef92651f52f 112 * @param mptr pointer to the member function to be called
Troels Nilsson 76:eef92651f52f 113 */
Troels Nilsson 76:eef92651f52f 114 template<typename T>
Troels Nilsson 76:eef92651f52f 115 void attach(T* tptr, void (T::*mptr)(void))
Troels Nilsson 76:eef92651f52f 116 {
Troels Nilsson 76:eef92651f52f 117 if (mptr && tptr)
Troels Nilsson 76:eef92651f52f 118 {
Troels Nilsson 76:eef92651f52f 119 m_rx.attach(tptr, mptr);
Troels Nilsson 76:eef92651f52f 120 }
Troels Nilsson 76:eef92651f52f 121 }
Troels Nilsson 76:eef92651f52f 122
Troels Nilsson 76:eef92651f52f 123 /**
Troels Nilsson 76:eef92651f52f 124 * Attach a callback called when a packet is received
Troels Nilsson 76:eef92651f52f 125 *
Troels Nilsson 76:eef92651f52f 126 * @param fptr function pointer
Troels Nilsson 76:eef92651f52f 127 */
Troels Nilsson 76:eef92651f52f 128 void attach(void (*fptr)(void))
Troels Nilsson 76:eef92651f52f 129 {
Troels Nilsson 76:eef92651f52f 130 if (fptr)
Troels Nilsson 76:eef92651f52f 131 {
Troels Nilsson 76:eef92651f52f 132 m_rx.attach(fptr);
Troels Nilsson 76:eef92651f52f 133 }
Troels Nilsson 76:eef92651f52f 134 }
Troels Nilsson 76:eef92651f52f 135
Troels Nilsson 76:eef92651f52f 136 /**
Troels Nilsson 76:eef92651f52f 137 * Attach a callback to call when serial's settings are changed.
Troels Nilsson 76:eef92651f52f 138 *
Troels Nilsson 76:eef92651f52f 139 * @param fptr function pointer
Troels Nilsson 76:eef92651f52f 140 */
Troels Nilsson 76:eef92651f52f 141 void attach(void (*fptr)(int baud, int bits, int parity, int stop))
Troels Nilsson 76:eef92651f52f 142 {
Troels Nilsson 76:eef92651f52f 143 m_settingsChangedCallback = fptr;
Troels Nilsson 76:eef92651f52f 144 }
Troels Nilsson 76:eef92651f52f 145
Troels Nilsson 76:eef92651f52f 146 protected:
Troels Nilsson 76:eef92651f52f 147
Troels Nilsson 76:eef92651f52f 148 /*
Troels Nilsson 76:eef92651f52f 149 * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
Troels Nilsson 76:eef92651f52f 150 *
Troels Nilsson 76:eef92651f52f 151 * @returns pointer to the device descriptor
Troels Nilsson 76:eef92651f52f 152 */
Troels Nilsson 76:eef92651f52f 153 virtual uint8_t * deviceDesc();
Troels Nilsson 76:eef92651f52f 154
Troels Nilsson 76:eef92651f52f 155 /*
Troels Nilsson 76:eef92651f52f 156 * Get string manufacturer descriptor
Troels Nilsson 76:eef92651f52f 157 *
Troels Nilsson 76:eef92651f52f 158 * @returns pointer to the string manufacturer descriptor
Troels Nilsson 76:eef92651f52f 159 */
Troels Nilsson 76:eef92651f52f 160 virtual uint8_t * stringImanufacturerDesc();
Troels Nilsson 76:eef92651f52f 161
Troels Nilsson 76:eef92651f52f 162 /*
Troels Nilsson 76:eef92651f52f 163 * Get string product descriptor
Troels Nilsson 76:eef92651f52f 164 *
Troels Nilsson 76:eef92651f52f 165 * @returns pointer to the string product descriptor
Troels Nilsson 76:eef92651f52f 166 */
Troels Nilsson 76:eef92651f52f 167 virtual uint8_t * stringIproductDesc();
Troels Nilsson 76:eef92651f52f 168
Troels Nilsson 76:eef92651f52f 169 /*
Troels Nilsson 76:eef92651f52f 170 * Get string serial descriptor
Troels Nilsson 76:eef92651f52f 171 *
Troels Nilsson 76:eef92651f52f 172 * @returns pointer to the string serial descriptor
Troels Nilsson 76:eef92651f52f 173 */
Troels Nilsson 76:eef92651f52f 174 virtual uint8_t * stringIserialDesc();
Troels Nilsson 76:eef92651f52f 175
Troels Nilsson 76:eef92651f52f 176 /*
Troels Nilsson 76:eef92651f52f 177 * Get configuration descriptor
Troels Nilsson 76:eef92651f52f 178 *
Troels Nilsson 76:eef92651f52f 179 * @returns pointer to the configuration descriptor
Troels Nilsson 76:eef92651f52f 180 */
Troels Nilsson 76:eef92651f52f 181 virtual uint8_t * configurationDesc();
Troels Nilsson 76:eef92651f52f 182
Troels Nilsson 76:eef92651f52f 183 /*
Troels Nilsson 76:eef92651f52f 184 * Get BOS descriptor
Troels Nilsson 76:eef92651f52f 185 *
Troels Nilsson 76:eef92651f52f 186 * @returns pointer to the BOS descriptor
Troels Nilsson 76:eef92651f52f 187 */
Troels Nilsson 76:eef92651f52f 188 virtual uint8_t * bosDesc();
Troels Nilsson 76:eef92651f52f 189
Troels Nilsson 76:eef92651f52f 190 /*
Troels Nilsson 77:a98f786d05d4 191 * Write from internal buffer to active endpoint
Troels Nilsson 76:eef92651f52f 192 */
Troels Nilsson 77:a98f786d05d4 193 void writeToActiveEndpoint();
Troels Nilsson 76:eef92651f52f 194
Troels Nilsson 76:eef92651f52f 195 /*
Troels Nilsson 76:eef92651f52f 196 * Read from the active endpoint into the internal buffer (non-blocking)
Troels Nilsson 76:eef92651f52f 197 *
Troels Nilsson 76:eef92651f52f 198 * @returns true if successful
Troels Nilsson 76:eef92651f52f 199 */
Troels Nilsson 76:eef92651f52f 200 bool readActiveEP();
Troels Nilsson 76:eef92651f52f 201
Troels Nilsson 76:eef92651f52f 202 /*
Troels Nilsson 76:eef92651f52f 203 * Called by USBCallback_requestCompleted when CDC line coding is changed
Troels Nilsson 76:eef92651f52f 204 * Warning: Called in ISR
Troels Nilsson 76:eef92651f52f 205 *
Troels Nilsson 76:eef92651f52f 206 * @param baud The baud rate
Troels Nilsson 76:eef92651f52f 207 * @param bits The number of bits in a word (5-8)
Troels Nilsson 76:eef92651f52f 208 * @param parity The parity
Troels Nilsson 76:eef92651f52f 209 * @param stop The number of stop bits (1 or 2)
Troels Nilsson 76:eef92651f52f 210 */
Troels Nilsson 76:eef92651f52f 211 virtual void lineCodingChanged(int baud, int bits, int parity, int stop)
Troels Nilsson 76:eef92651f52f 212 {
Troels Nilsson 76:eef92651f52f 213 if (m_settingsChangedCallback)
Troels Nilsson 76:eef92651f52f 214 {
Troels Nilsson 76:eef92651f52f 215 m_settingsChangedCallback(baud, bits, parity, stop);
Troels Nilsson 76:eef92651f52f 216 }
Troels Nilsson 76:eef92651f52f 217 }
Troels Nilsson 76:eef92651f52f 218
Troels Nilsson 76:eef92651f52f 219 virtual bool USBCallback_request();
Troels Nilsson 76:eef92651f52f 220 virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length);
Troels Nilsson 76:eef92651f52f 221 virtual bool USBCallback_setConfiguration(uint8_t configuration);
Troels Nilsson 76:eef92651f52f 222 virtual void USBCallback_busReset(void);
Troels Nilsson 76:eef92651f52f 223
Troels Nilsson 76:eef92651f52f 224 virtual bool EPCDC_OUT_callback();
Troels Nilsson 76:eef92651f52f 225 virtual bool EPWEBUSB_OUT_callback();
Troels Nilsson 76:eef92651f52f 226 virtual bool EPOUTCallbackHandler(uint8_t endpoint);
Troels Nilsson 76:eef92651f52f 227
Troels Nilsson 77:a98f786d05d4 228 virtual bool EPCDC_IN_callback();
Troels Nilsson 77:a98f786d05d4 229 virtual bool EPWEBUSB_IN_callback();
Troels Nilsson 77:a98f786d05d4 230
Troels Nilsson 76:eef92651f52f 231 private:
Troels Nilsson 76:eef92651f52f 232 uint8_t activeOutEndpoint() const { return m_webUSBMode ? EPWEBUSB_OUT : EPCDC_OUT; }
Troels Nilsson 76:eef92651f52f 233 uint8_t activeInEndpoint() const { return m_webUSBMode ? EPWEBUSB_IN : EPCDC_IN; }
Troels Nilsson 76:eef92651f52f 234 void createDynamicDescriptors();
Troels Nilsson 76:eef92651f52f 235 uint8_t *createStringDescriptor(const std::string &string) const;
Troels Nilsson 77:a98f786d05d4 236 void setWebUSBMode(bool webUSBMode);
Troels Nilsson 77:a98f786d05d4 237 uint32_t timeSinceWrite() const;
Troels Nilsson 76:eef92651f52f 238
Troels Nilsson 76:eef92651f52f 239 static uint8_t s_MSOS2Descriptor[];
Troels Nilsson 76:eef92651f52f 240 volatile bool m_terminalConnected;
Troels Nilsson 76:eef92651f52f 241 FunctionPointer m_rx;
Troels Nilsson 77:a98f786d05d4 242 CircBuffer<uint8_t,USBWEBUSBSERIAL_INPUT_BUFFER_SIZE> m_inputBuffer;
Troels Nilsson 77:a98f786d05d4 243 CircBuffer<uint8_t,USBWEBUSBSERIAL_OUTPUT_BUFFER_SIZE> m_outputBuffer;
Troels Nilsson 76:eef92651f52f 244 void (*m_settingsChangedCallback)(int baud, int bits, int parity, int stop) = nullptr;
Troels Nilsson 77:a98f786d05d4 245
Troels Nilsson 77:a98f786d05d4 246 bool m_pendingWrite = false;
Troels Nilsson 77:a98f786d05d4 247 uint32_t m_lastWriteTime = 0;
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 77:a98f786d05d4 254
Troels Nilsson 76:eef92651f52f 255 bool m_webUSBMode = false;
Troels Nilsson 76:eef92651f52f 256 };
Troels Nilsson 76:eef92651f52f 257
Troels Nilsson 76:eef92651f52f 258 #endif