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

Fork of STM32_USBDevice by Bradley Scott

Branch:
feature_WebUSB
Revision:
76:eef92651f52f
Child:
77:a98f786d05d4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBSerial/USBWebUSBSerial.h	Thu Jul 19 12:57:27 2018 +0200
@@ -0,0 +1,257 @@
+/* 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 USBWEBUSBSERIAL_H
+#define USBWEBUSBSERIAL_H
+
+#include <string>
+#include "USBDevice.h"
+#include "Stream.h"
+#include "CircBuffer.h"
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#ifndef USBWEBUSBSERIAL_INPUT_BUFFER_SIZE
+#define USBWEBUSBSERIAL_INPUT_BUFFER_SIZE 128
+#endif
+
+/**
+* WebUSB/USBSerial composite device class
+* Handles outputting to standard CDC or WebUSB endpoint depending on mode
+*
+*/
+class USBWebUSBSerial: public USBDevice, public Stream
+{
+public:
+
+    /**
+    *   Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your product_release (default: 0x0001)
+    * @param connect_blocking define if the connection must be blocked if USB not plugged in
+    *
+    */
+    USBWebUSBSerial(uint16_t vendor_id, uint16_t product_id, uint16_t product_release =  0x0001, bool connect_blocking = true);
+
+    const std::string& manufacturerName() const { return m_manufacturerName; }
+    void setManufacturerName(const std::string &manufacturerName);
+
+    const std::string& productName() const { return m_productName; }
+    void setProductName(const std::string &productName);
+
+    const std::string& serialNumber() const { return m_serialNumber; }
+    void setSerialNumber(const std::string &serialNumber);
+
+    /**
+    * 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(const 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 && tptr)
+        {
+            m_rx.attach(tptr, mptr);
+        }
+    }
+
+    /**
+     * Attach a callback called when a packet is received
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fptr)(void))
+    {
+        if (fptr)
+        {
+            m_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))
+    {
+        m_settingsChangedCallback = fptr;
+    }
+
+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 manufacturer descriptor
+    *
+    * @returns pointer to the string manufacturer descriptor
+    */
+    virtual uint8_t * stringImanufacturerDesc();
+
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+
+    /*
+    * Get string serial descriptor
+    *
+    * @returns pointer to the string serial descriptor
+    */
+    virtual uint8_t * stringIserialDesc();
+
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+
+    /*
+    * Get BOS descriptor
+    *
+    * @returns pointer to the BOS descriptor
+    */    
+    virtual uint8_t * bosDesc();
+
+    /*
+    * Send a buffer and wait for it to be read
+    *
+    * @param buffer buffer to be sent
+    * @param size length of the buffer
+    * @returns true if successful
+    */
+    bool send(const uint8_t * buffer, uint32_t size);
+
+    /*
+    * Read from the active endpoint into the internal buffer (non-blocking)
+    *
+    * @returns true if successful
+    */
+    bool readActiveEP();
+
+    /*
+    * 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)
+    {
+        if (m_settingsChangedCallback)
+        {
+            m_settingsChangedCallback(baud, bits, parity, stop);
+        }
+    }
+
+    virtual bool USBCallback_request();
+    virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length);
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+    virtual void USBCallback_busReset(void);
+
+    virtual bool EPCDC_OUT_callback();
+    virtual bool EPWEBUSB_OUT_callback();
+    virtual bool EPOUTCallbackHandler(uint8_t endpoint);
+
+private:
+    uint8_t activeOutEndpoint() const { return m_webUSBMode ? EPWEBUSB_OUT : EPCDC_OUT; }
+    uint8_t activeInEndpoint() const { return m_webUSBMode ? EPWEBUSB_IN : EPCDC_IN; }
+    void createDynamicDescriptors();
+    uint8_t *createStringDescriptor(const std::string &string) const;
+
+    static uint8_t s_MSOS2Descriptor[];
+    volatile bool m_terminalConnected;
+    FunctionPointer m_rx;
+    CircBuffer<uint8_t,USBWEBUSBSERIAL_INPUT_BUFFER_SIZE> m_buffer;
+    void (*m_settingsChangedCallback)(int baud, int bits, int parity, int stop) = nullptr;
+    std::string m_manufacturerName = "mbed.org";
+    uint8_t *m_manufacturerStringDesc = nullptr;
+    std::string m_productName = "CDC/WebUSB Device";
+    uint8_t *m_productStringDesc = nullptr;
+    std::string m_serialNumber = "0123456789";
+    uint8_t *m_serialStringDesc = nullptr;
+    bool m_webUSBMode = false;
+};
+
+#endif