Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBDevice_STM32F103 by
Revision 71:52ef20e36cab, committed 2017-12-04
- Comitter:
- geekylou
- Date:
- Mon Dec 04 23:05:41 2017 +0000
- Parent:
- 70:c74dbe78ca5b
- Commit message:
- Incorporate fixes from the main mbed USBSerial driver.
Changed in this revision
--- a/USBSerial/CircBuffer.h Sun Dec 03 21:14:26 2017 +0000
+++ b/USBSerial/CircBuffer.h Mon Dec 04 23:05:41 2017 +0000
@@ -19,16 +19,10 @@
#ifndef CIRCBUFFER_H
#define CIRCBUFFER_H
-template <class T>
+template <class T, int Size>
class CircBuffer {
public:
- CircBuffer(int length) {
- write = 0;
- read = 0;
- size = length + 1;
- buf = (T *)malloc(size * sizeof(T));
- };
-
+ CircBuffer():write(0), read(0){}
bool isFull() {
return ((write + 1) % size == read);
};
@@ -62,8 +56,8 @@
private:
volatile uint16_t write;
volatile uint16_t read;
- uint16_t size;
- T * buf;
+ static const int size = Size+1; //a modern optimizer should be able to remove this so it uses no ram.
+ T buf[Size+1];
};
#endif
--- a/USBSerial/USBCDC.cpp Sun Dec 03 21:14:26 2017 +0000
+++ b/USBSerial/USBCDC.cpp Mon Dec 04 23:05:41 2017 +0000
@@ -27,6 +27,10 @@
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
+// Control Line State bits
+#define CLS_DTR (1 << 0)
+#define CLS_RTS (1 << 1)
+
#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) {
@@ -34,6 +38,10 @@
USBDevice::connect(connect_blocking);
}
+void USBCDC::USBCallback_busReset(void) {
+ terminal_connected = false;
+};
+
bool USBCDC::USBCallback_request(void) {
/* Called in ISR context */
@@ -52,11 +60,15 @@
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;
+ if (transfer->setup.wValue & CLS_DTR) {
+ terminal_connected = true;
+ } else {
+ terminal_connected = false;
+ }
success = true;
break;
default:
@@ -67,6 +79,31 @@
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
@@ -116,8 +153,8 @@
0, // bDeviceSubClass
0, // bDeviceProtocol
MAX_PACKET_SIZE_EP0, // bMaxPacketSize0
- LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
- LSB(PRODUCT_ID), MSB(PRODUCT_ID),// idProduct
+ (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
@@ -160,7 +197,7 @@
0, // iConfiguration
0x80, // bmAttributes
50, // bMaxPower
-
+
// IAD to associate the two CDC interfaces
0x08, // bLength
0x0b, // bDescriptorType
@@ -251,4 +288,3 @@
};
return configDescriptor;
}
-
--- a/USBSerial/USBCDC.h Sun Dec 03 21:14:26 2017 +0000
+++ b/USBSerial/USBCDC.h Mon Dec 04 23:05:41 2017 +0000
@@ -40,35 +40,35 @@
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
*
@@ -78,7 +78,7 @@
* @returns true if successful
*/
bool send(uint8_t * buffer, uint32_t size);
-
+
/*
* Read a buffer from a certain endpoint. Warning: blocking
*
@@ -89,7 +89,7 @@
* @returns true if successful
*/
bool readEP(uint8_t * buffer, uint32_t * size);
-
+
/*
* Read a buffer from a certain endpoint. Warning: non blocking
*
@@ -100,13 +100,25 @@
* @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);
+ virtual void USBCallback_busReset(void);
volatile bool terminal_connected;
};
#endif
-
--- a/USBSerial/USBSerial.cpp Sun Dec 03 21:14:26 2017 +0000
+++ b/USBSerial/USBSerial.cpp Mon Dec 04 23:05:41 2017 +0000
@@ -27,7 +27,7 @@
}
int USBSerial::_getc() {
- uint8_t c;
+ uint8_t c = 0;
while (buf.isEmpty());
buf.dequeue(&c);
return c;
@@ -46,24 +46,27 @@
-bool USBSerial::EP2_OUT_callback() {
+bool USBSerial::EPBULK_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 (int i = 0; i < size; i++) {
+ for (uint32_t i = 0; i < size; i++) {
buf.queue(c[i]);
}
- //call a potential handler
- rx.call();
+ //call a potential handlenr
+ if (rx)
+ 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();
}
+
+bool USBSerial::connected() {
+ return terminal_connected;
+}
--- a/USBSerial/USBSerial.h Sun Dec 03 21:14:26 2017 +0000
+++ b/USBSerial/USBSerial.h Mon Dec 04 23:05:41 2017 +0000
@@ -22,7 +22,7 @@
#include "USBCDC.h"
#include "Stream.h"
#include "CircBuffer.h"
-
+#include "Callback.h"
/**
* USBSerial example
@@ -56,7 +56,9 @@
* @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){ };
+ 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){
+ settingsChangedCallback = 0;
+ };
/**
@@ -66,23 +68,46 @@
* @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();
-
+ uint8_t available();
+
+ /**
+ * Check if the terminal is connected.
+ *
+ * @returns connection status
+ */
+ bool connected();
+
+ /** 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.
+ * Write a block of data.
*
* For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written.
*
@@ -94,7 +119,7 @@
bool writeBlock(uint8_t * buf, uint16_t size);
/**
- * Attach a member function to call when a packet is received.
+ * 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
@@ -111,19 +136,33 @@
*
* @param fptr function pointer
*/
- void attach(void (*fn)(void)) {
- if(fn != NULL) {
- rx.attach(fn);
+ 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 bool EPBULK_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;
+ Callback<void()> rx;
+ CircBuffer<uint8_t,128> buf;
+ void (*settingsChangedCallback)(int baud, int bits, int parity, int stop);
};
#endif
