usb vritual serial to uart

Dependencies:   BufferedSerial USBDevice mbed

Fork of USB2UART by Yihui Xiong

Revision:
7:630d09697776
Parent:
6:40182fd79c75
--- a/main.cpp	Fri May 19 17:30:32 2017 +0000
+++ b/main.cpp	Mon May 22 07:47:13 2017 +0000
@@ -6,91 +6,145 @@
 #include "USBSerial.h"
 #include "BufferedSerial.h"
 
+#define CDC_SEND_BREAK             0x23
+
+class USB_UART_Bridge : public USBSerial
+{
+public:
+    static USB_UART_Bridge& instance() {
+        static USB_UART_Bridge stub;
+        return stub;
+    }
+
+    void update_txrx_indicator()
+    {
+        if (_tx_flag) {
+            _tx_indicator = !_tx_indicator;
+            _tx_flag = false;
+        } else {
+            _tx_indicator = 1;
+        }
+        
+        if (_rx_flag) {
+            _rx_indicator = !_rx_indicator;
+            _rx_flag = false;
+        } else {
+            _rx_indicator = 1;
+        }
+    }
+
+    void update_state_indicator()
+    {
+        _state_indicator = !_state_indicator;
+    }
+
+    void check_reset_button()
+    {
+        if (!_reset_button.read()) {
+            _reset_pin = 0;
+            _state_indicator = 0;
+        }
+    }
+
+protected:
+    virtual bool USBCallback_request() {
+        if (USBSerial::USBCallback_request()) {
+            return true;
+        }
+        
+        /* Called in ISR context */
+        bool success = false;
+        CONTROL_TRANSFER * transfer = getTransferPtr();
+
+        /* Process class-specific requests */
+        if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+            switch (transfer->setup.bRequest) {
+                case CDC_SEND_BREAK:
+                    _uart.send_break();
+                    success = true;
+                default:
+                    break;
+            }
+        }
+
+        return success;
+    }
+
+    // Called by ISR
+    static void on_setting_changed(int baud, int bits, int parity, int stop)
+    {
+        static const Serial::Parity parityTable[] = {Serial::None, Serial::Odd, Serial::Even, Serial::Forced0, Serial::Forced1};
+        
+        instance()._state_indicator = 1;
+        if (stop != 2) {
+            stop = 1;   // stop bit(s) = 1 or 1.5
+        }
+        instance()._uart.baud(baud);
+        instance()._uart.format(bits, parityTable[parity], stop);
+        instance()._state_indicator = 0;
+    }
+
+    void on_usb_received() {
+        while (this->readable()) {
+            char c = this->getc();
+            _tx_flag = true;
+            _uart.putc(c);
+        }
+    }
+
+    void on_uart_received() {
+        while (_uart.readable()) {
+            char c = _uart.getc();
+            _rx_flag = true;
+            this->putc(c);
+        }
+    }
+
+private:
+    USB_UART_Bridge() :
+        _uart(P0_19, P0_18, 512),
+        _tx_indicator(P0_20),
+        _rx_indicator(P0_21),
+        _state_indicator(P0_11),
+        _reset_pin(P0_2),
+        _reset_button(P0_1, PullUp),
+        _rx_flag(false),
+        _tx_flag(false)
+    {
+        this->attach(&USB_UART_Bridge::on_setting_changed);
+        this->attach(this, &USB_UART_Bridge::on_usb_received);
+        _uart.attach(this, &USB_UART_Bridge::on_uart_received);
+    }
+    
+private:
+    BufferedSerial _uart;
+    DigitalOut _tx_indicator;
+    DigitalOut _rx_indicator;
+    DigitalOut _state_indicator;
+    DigitalOut _reset_pin;
+    DigitalIn _reset_button;
+
+    volatile bool _rx_flag;
+    volatile bool _tx_flag;
+};
+
 Ticker txrx_ticker;
 Ticker state_ticker;
 Ticker reset_ticker;
 
-volatile bool rxflag = false;
-volatile bool txflag = false;
-volatile int rx_count = 0;
-volatile int tx_count = 0;
-
-DigitalOut tx_indicator(P0_20);
-DigitalOut rx_indicator(P0_21);
-DigitalOut state_indicator(P0_11);
-DigitalOut cc3200_reset(P0_2);
-DigitalIn reset_button(P0_1, PullUp);
-
-USBSerial vcom;
-BufferedSerial uart(P0_19, P0_18, 512);
-
-void update_txrx_indicator()
+int main()
 {
-    if (txflag) {
-        tx_indicator = !tx_indicator;
-        rxflag = false;
-    } else { // TX done
-        if (!tx_indicator) {
-            tx_indicator = 1;
-        }
-    }
-    
-    if (rxflag) {
-        rx_indicator = !rx_indicator;
-        rxflag = false;
-    } else { // RX done
-        if (!rx_indicator) {
-            rx_indicator = 1;
-        }
+    USB_UART_Bridge& bridge = USB_UART_Bridge::instance();
+
+#ifndef callback
+#define callback(obj, mfp) FunctionPointer(obj, mfp).get_function()
+#endif
+
+    state_ticker.attach(callback(&bridge, &USB_UART_Bridge::update_state_indicator), 1);
+    txrx_ticker.attach_us(callback(&bridge, &USB_UART_Bridge::update_txrx_indicator), 10*1000);
+    reset_ticker.attach_us(callback(&bridge, &USB_UART_Bridge::check_reset_button), 20*1000);
+
+    while (1) {
+        __WFI();
     }
 }
-
-void update_state_indicator()
-{
-    state_indicator = 0;
-}
-
-void check_reset_button()
-{
-    if (!reset_button.read()) {
-        cc3200_reset = 0;
-        state_indicator = 0;
-    }
-}
-
-// Called by ISR
-void settings_changed(int baud, int bits, int parity, int stop)
-{
-    static const Serial::Parity parityTable[] = {Serial::None, Serial::Odd, Serial::Even, Serial::Forced0, Serial::Forced1};
-    
-    state_indicator = 1;
-    if (stop != 2) {
-        stop = 1;   // stop bit(s) = 1 or 1.5
-    }
-    uart.baud(baud);
-    uart.format(bits, parityTable[parity], stop);
-    state_indicator = 0;
-}
-
-int main()
-{
-    vcom.attach(settings_changed);
-    state_ticker.attach(update_state_indicator, 0.3);
-    txrx_ticker.attach_us(update_txrx_indicator, 10*1000);
-    reset_ticker.attach_us(check_reset_button, 20*1000);
-
-    while (1) {
-        while (vcom.readable()) {
-            char c = vcom.getc();
-            tx_count++;
-            txflag = true;
-            uart.putc(c);
-        }
-        while (uart.readable()) {
-            char c = uart.getc();
-            rx_count++;
-            rxflag = true;
-            vcom.putc(c);
-        }
-    }
-}