usb vritual serial to uart
Dependencies: BufferedSerial USBDevice mbed
Fork of USB2UART by
Revision 7:630d09697776, committed 2017-05-22
- Comitter:
- swxu
- Date:
- Mon May 22 07:47:13 2017 +0000
- Parent:
- 6:40182fd79c75
- Commit message:
- refactor and add BREAK support
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 40182fd79c75 -r 630d09697776 main.cpp --- 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); - } - } -}