Fernando Cosentino / uTerminal

Dependencies:   USBDevice

Dependents:   uTerminal_Example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uTerminal.cpp Source File

uTerminal.cpp

00001 #include "uTerminal.h"
00002 
00003 uTerminal::uTerminal(PinName PinTX, PinName PinRX) {
00004     is_usb = 0;
00005     _serial = new Serial(PinTX, PinRX);
00006     _serial->attach(this, &uTerminal::_rx_irq, Serial::RxIrq);
00007     init();
00008 }
00009 
00010 uTerminal::uTerminal(Serial * serial_object) {
00011     is_usb = 0;
00012     _serial = serial_object;
00013     _serial->attach(this, &uTerminal::_rx_irq, Serial::RxIrq);
00014     init();
00015 }
00016 
00017 uTerminal::uTerminal(USBSerial * usbserial_object) {
00018     is_usb = 1;
00019     _usbserial = usbserial_object;
00020     _usbserial->attach(this, &uTerminal::_rx_irq);
00021     init();
00022 }
00023     
00024 void uTerminal::init() {
00025     _callback = 0;
00026     cursor = 0;
00027     param_cursor = 0;
00028     buffer_len = 0;
00029     params_len = 0;
00030     has_command = 0;
00031     NumParams = 0;
00032     ParamLen = 0;
00033     auto_mode = 0;
00034 }
00035 
00036 bool uTerminal::readable() {
00037     if (is_usb) {
00038         if (_usbserial->connected()) return _usbserial->readable();
00039         else return 0;
00040     }
00041     else return _serial->readable();
00042 }
00043 unsigned char uTerminal::getc() {
00044     if (is_usb) {
00045         if (_usbserial->connected()) return _usbserial->getc();
00046         else return 0;
00047     }
00048     else return _serial->getc();
00049 }
00050 
00051 void uTerminal::ModeAuto() {
00052     auto_mode = 1;
00053 }
00054 
00055 void uTerminal::ModeManual() {
00056     auto_mode = 0;
00057 }
00058 
00059 void uTerminal::attach( void (*callback)() ) {
00060     _callback = callback;
00061 }
00062 
00063 void uTerminal::_rx_irq() {
00064     unsigned char val;
00065     if(readable()) {
00066         val = getc();
00067         if ((val == 10) || (val == 13)) {
00068             // Received a return character (Linux = 10, Windows = 13,10)
00069             // When #13#10 is received, the #10 will trigger this "if" with empty command. Ignore it.
00070             if (cursor > 0) {
00071                 // Ok, we indeed have a command.
00072                 has_command = 1; // 1-> Successful command (return). 2->Buffer full
00073                 _buffer[cursor++] = 0x00; // make a null-terminated safe string
00074                 buffer_len = cursor; // Includes terminating null
00075                 cursor = 0;
00076                 transfer_buffers(); // prepare the Command and Value buffers
00077             }
00078         }
00079         else {
00080             has_command = 0; // If had unread command in buffer, cancel it. Sorry, you lost it.
00081             _buffer[cursor++] = val;
00082             if (cursor >= UTERMINAL_BUF_SIZE) {
00083                 // Even if it's not a return, we must not continue since buffer is full
00084                 // Consider input done, but with result=2 instead of 1, to tell it's buffer size
00085                 has_command = 2;
00086                 buffer_len = UTERMINAL_BUF_SIZE; // all valid characters
00087                 _buffer[cursor] = 0x00; // make a null-terminated safe string
00088                 cursor = 0; // reset cursor to avoid overflow
00089                 transfer_buffers(); // prepare the Command and Value buffers
00090             }
00091         }
00092     }
00093 }
00094 
00095 void uTerminal::transfer_buffers() {
00096     int i;
00097     int j;
00098     char c;
00099     
00100     // transfer cmd buffer
00101     i = 0;
00102     j = 0;
00103     while (i < buffer_len) {
00104         c = _buffer[i++];
00105         if ((c == '=') || (c == 0)) {
00106             Command[j] = 0; // null-terminated string
00107             break;
00108         }
00109         else {
00110             Command[j++] = c;
00111         }
00112     }
00113     if (i >= buffer_len) Command[j] = 0; // null-terminated safe
00114     
00115     // transfer param buffer
00116     if (c == '=') { // if we have parameters
00117         NumParams = 1;
00118         j = 0;
00119         while (i < buffer_len) {
00120             c = _buffer[i++];
00121             Value[j++] = c;
00122             if (c == ',') NumParams++;
00123             if (c == 0) break;
00124         }
00125         params_len = j; // length includes terminating null
00126     }
00127     else {
00128         Value[0] = 0; // empty string
00129         NumParams = 0;
00130         params_len = 0;
00131     }
00132     
00133     Param[0] = 0; // Param always begins as empty string
00134     ParamLen = 0;
00135     
00136     param_cursor = 0;
00137     
00138     // If in auto-mode, invoke the callback
00139     if (auto_mode) Process();
00140 }
00141 
00142 char* uTerminal::GetParam() {
00143     int i;
00144     char c;
00145     
00146     i = 0;
00147     while (param_cursor < params_len) {
00148         c = Value[param_cursor];
00149         if (c == ',') {
00150             Param[i] = 0;
00151             param_cursor++;
00152             break;
00153         }
00154         if (c == 0) {
00155             Param[i] = 0;
00156             break;
00157         }
00158         else {
00159             Param[i++] = c;
00160             param_cursor++;
00161         }
00162     }
00163     if (param_cursor >= params_len) Param[i] = 0; // null-terminated safe
00164     
00165     ParamLen = i; // does not include terminating null
00166     
00167     return Param;
00168 }
00169 
00170 
00171 int uTerminal::Process() {
00172     // Be ready for next message in the background
00173     int _has_cmd = has_command;
00174     has_command = 0;
00175 
00176     // invoke the callback
00177     if ((_has_cmd > 0) && (_callback != 0)) _callback();
00178     
00179     // Return status
00180     return _has_cmd;
00181 }
00182 
00183 void uTerminal::print(char* str) {
00184     if (is_usb) {
00185         while (!_usbserial->connected()); // block until connected
00186         _usbserial->printf(str);
00187     }
00188     else _serial->printf(str);
00189 }
00190 
00191 void uTerminal::print(const char* str) {
00192     print((char*)str);
00193 }
00194