usb vritual serial to uart

Dependencies:   BufferedSerial USBDevice mbed

Fork of USB2UART by Yihui Xiong

Committer:
swxu
Date:
Mon May 22 07:47:13 2017 +0000
Revision:
7:630d09697776
Parent:
6:40182fd79c75
refactor and add BREAK support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:8c4eea221dcf 1 /**
yihui 0:8c4eea221dcf 2 * USB to UART Bridge
yihui 0:8c4eea221dcf 3 */
yihui 0:8c4eea221dcf 4
yihui 0:8c4eea221dcf 5 #include "mbed.h"
yihui 0:8c4eea221dcf 6 #include "USBSerial.h"
yihui 4:9c038f12d460 7 #include "BufferedSerial.h"
yihui 0:8c4eea221dcf 8
swxu 7:630d09697776 9 #define CDC_SEND_BREAK 0x23
swxu 7:630d09697776 10
swxu 7:630d09697776 11 class USB_UART_Bridge : public USBSerial
swxu 7:630d09697776 12 {
swxu 7:630d09697776 13 public:
swxu 7:630d09697776 14 static USB_UART_Bridge& instance() {
swxu 7:630d09697776 15 static USB_UART_Bridge stub;
swxu 7:630d09697776 16 return stub;
swxu 7:630d09697776 17 }
swxu 7:630d09697776 18
swxu 7:630d09697776 19 void update_txrx_indicator()
swxu 7:630d09697776 20 {
swxu 7:630d09697776 21 if (_tx_flag) {
swxu 7:630d09697776 22 _tx_indicator = !_tx_indicator;
swxu 7:630d09697776 23 _tx_flag = false;
swxu 7:630d09697776 24 } else {
swxu 7:630d09697776 25 _tx_indicator = 1;
swxu 7:630d09697776 26 }
swxu 7:630d09697776 27
swxu 7:630d09697776 28 if (_rx_flag) {
swxu 7:630d09697776 29 _rx_indicator = !_rx_indicator;
swxu 7:630d09697776 30 _rx_flag = false;
swxu 7:630d09697776 31 } else {
swxu 7:630d09697776 32 _rx_indicator = 1;
swxu 7:630d09697776 33 }
swxu 7:630d09697776 34 }
swxu 7:630d09697776 35
swxu 7:630d09697776 36 void update_state_indicator()
swxu 7:630d09697776 37 {
swxu 7:630d09697776 38 _state_indicator = !_state_indicator;
swxu 7:630d09697776 39 }
swxu 7:630d09697776 40
swxu 7:630d09697776 41 void check_reset_button()
swxu 7:630d09697776 42 {
swxu 7:630d09697776 43 if (!_reset_button.read()) {
swxu 7:630d09697776 44 _reset_pin = 0;
swxu 7:630d09697776 45 _state_indicator = 0;
swxu 7:630d09697776 46 }
swxu 7:630d09697776 47 }
swxu 7:630d09697776 48
swxu 7:630d09697776 49 protected:
swxu 7:630d09697776 50 virtual bool USBCallback_request() {
swxu 7:630d09697776 51 if (USBSerial::USBCallback_request()) {
swxu 7:630d09697776 52 return true;
swxu 7:630d09697776 53 }
swxu 7:630d09697776 54
swxu 7:630d09697776 55 /* Called in ISR context */
swxu 7:630d09697776 56 bool success = false;
swxu 7:630d09697776 57 CONTROL_TRANSFER * transfer = getTransferPtr();
swxu 7:630d09697776 58
swxu 7:630d09697776 59 /* Process class-specific requests */
swxu 7:630d09697776 60 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
swxu 7:630d09697776 61 switch (transfer->setup.bRequest) {
swxu 7:630d09697776 62 case CDC_SEND_BREAK:
swxu 7:630d09697776 63 _uart.send_break();
swxu 7:630d09697776 64 success = true;
swxu 7:630d09697776 65 default:
swxu 7:630d09697776 66 break;
swxu 7:630d09697776 67 }
swxu 7:630d09697776 68 }
swxu 7:630d09697776 69
swxu 7:630d09697776 70 return success;
swxu 7:630d09697776 71 }
swxu 7:630d09697776 72
swxu 7:630d09697776 73 // Called by ISR
swxu 7:630d09697776 74 static void on_setting_changed(int baud, int bits, int parity, int stop)
swxu 7:630d09697776 75 {
swxu 7:630d09697776 76 static const Serial::Parity parityTable[] = {Serial::None, Serial::Odd, Serial::Even, Serial::Forced0, Serial::Forced1};
swxu 7:630d09697776 77
swxu 7:630d09697776 78 instance()._state_indicator = 1;
swxu 7:630d09697776 79 if (stop != 2) {
swxu 7:630d09697776 80 stop = 1; // stop bit(s) = 1 or 1.5
swxu 7:630d09697776 81 }
swxu 7:630d09697776 82 instance()._uart.baud(baud);
swxu 7:630d09697776 83 instance()._uart.format(bits, parityTable[parity], stop);
swxu 7:630d09697776 84 instance()._state_indicator = 0;
swxu 7:630d09697776 85 }
swxu 7:630d09697776 86
swxu 7:630d09697776 87 void on_usb_received() {
swxu 7:630d09697776 88 while (this->readable()) {
swxu 7:630d09697776 89 char c = this->getc();
swxu 7:630d09697776 90 _tx_flag = true;
swxu 7:630d09697776 91 _uart.putc(c);
swxu 7:630d09697776 92 }
swxu 7:630d09697776 93 }
swxu 7:630d09697776 94
swxu 7:630d09697776 95 void on_uart_received() {
swxu 7:630d09697776 96 while (_uart.readable()) {
swxu 7:630d09697776 97 char c = _uart.getc();
swxu 7:630d09697776 98 _rx_flag = true;
swxu 7:630d09697776 99 this->putc(c);
swxu 7:630d09697776 100 }
swxu 7:630d09697776 101 }
swxu 7:630d09697776 102
swxu 7:630d09697776 103 private:
swxu 7:630d09697776 104 USB_UART_Bridge() :
swxu 7:630d09697776 105 _uart(P0_19, P0_18, 512),
swxu 7:630d09697776 106 _tx_indicator(P0_20),
swxu 7:630d09697776 107 _rx_indicator(P0_21),
swxu 7:630d09697776 108 _state_indicator(P0_11),
swxu 7:630d09697776 109 _reset_pin(P0_2),
swxu 7:630d09697776 110 _reset_button(P0_1, PullUp),
swxu 7:630d09697776 111 _rx_flag(false),
swxu 7:630d09697776 112 _tx_flag(false)
swxu 7:630d09697776 113 {
swxu 7:630d09697776 114 this->attach(&USB_UART_Bridge::on_setting_changed);
swxu 7:630d09697776 115 this->attach(this, &USB_UART_Bridge::on_usb_received);
swxu 7:630d09697776 116 _uart.attach(this, &USB_UART_Bridge::on_uart_received);
swxu 7:630d09697776 117 }
swxu 7:630d09697776 118
swxu 7:630d09697776 119 private:
swxu 7:630d09697776 120 BufferedSerial _uart;
swxu 7:630d09697776 121 DigitalOut _tx_indicator;
swxu 7:630d09697776 122 DigitalOut _rx_indicator;
swxu 7:630d09697776 123 DigitalOut _state_indicator;
swxu 7:630d09697776 124 DigitalOut _reset_pin;
swxu 7:630d09697776 125 DigitalIn _reset_button;
swxu 7:630d09697776 126
swxu 7:630d09697776 127 volatile bool _rx_flag;
swxu 7:630d09697776 128 volatile bool _tx_flag;
swxu 7:630d09697776 129 };
swxu 7:630d09697776 130
swxu 6:40182fd79c75 131 Ticker txrx_ticker;
swxu 6:40182fd79c75 132 Ticker state_ticker;
swxu 6:40182fd79c75 133 Ticker reset_ticker;
yihui 3:2b4d2284bab0 134
swxu 7:630d09697776 135 int main()
yihui 5:10fccccbbb11 136 {
swxu 7:630d09697776 137 USB_UART_Bridge& bridge = USB_UART_Bridge::instance();
swxu 7:630d09697776 138
swxu 7:630d09697776 139 #ifndef callback
swxu 7:630d09697776 140 #define callback(obj, mfp) FunctionPointer(obj, mfp).get_function()
swxu 7:630d09697776 141 #endif
swxu 7:630d09697776 142
swxu 7:630d09697776 143 state_ticker.attach(callback(&bridge, &USB_UART_Bridge::update_state_indicator), 1);
swxu 7:630d09697776 144 txrx_ticker.attach_us(callback(&bridge, &USB_UART_Bridge::update_txrx_indicator), 10*1000);
swxu 7:630d09697776 145 reset_ticker.attach_us(callback(&bridge, &USB_UART_Bridge::check_reset_button), 20*1000);
swxu 7:630d09697776 146
swxu 7:630d09697776 147 while (1) {
swxu 7:630d09697776 148 __WFI();
swxu 6:40182fd79c75 149 }
swxu 6:40182fd79c75 150 }