Ondřej Hruška / ESPTerm
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers espterm.hpp Source File

espterm.hpp

00001 #ifndef ESPTERM_H
00002 #define ESPTERM_H
00003 #include "mbed.h"
00004 
00005 /*
00006 // Example
00007 
00008 DigitalOut led(LED1);
00009 ESPTerm term(PA_9, PA_10); // UART not used by the Nucleo ACM
00010 
00011 void onchar(char c);
00012 void onmouse(int row, int col, MouseEvent evt);
00013 
00014 int main()
00015 {   
00016     // Wait for ESP ready (send "Device Status Query" and wait for "Device OK")
00017     term.clear_status();
00018     while (term.query_status() == false) {
00019         wait_ms(100);        
00020         led = !led;    
00021     }
00022     
00023     // Connect handlers
00024     term.on_char_rx = onchar; 
00025     term.on_mouse = onmouse;
00026     
00027     // others: (check the declarations)
00028     // term.on_esp_reset - on esp reset, we should re-init the screen etc
00029     // term.on_key - user pushed an arrow key
00030     // term.on_button - user pushed a button under the screen
00031     
00032     term.set_screen_size(25, 60);
00033 
00034     int i = 0;
00035     while(1) {
00036         wait_ms(1000);        
00037         led = !led; // heartbeat       
00038         term.println("> %d", i++);
00039     }
00040 }
00041 
00042 // --- handlers ---
00043 
00044 // User typed a character that's not part of a control sequence
00045 void onchar(char c)
00046 {
00047     // change it to indicate we did something
00048     term.putc(c+1);   
00049 }
00050 
00051 // User clicked (events other than 0 are not implemented as of v0.5.5)
00052 void onmouse(int row, int col, MouseEvent event)
00053 {
00054     term.fg(GREEN);
00055     term.println("Mouse evt %d @ %d, %d", event, row, col);    
00056     term.rst();
00057 }
00058 
00059 */
00060 
00061 
00062 
00063 /*
00064  * ESP8266 Wireless Terminal interfacing library
00065  * ---------------------------------------------
00066  *
00067  * Tested with ESP firmware v0.5.4
00068  *
00069  * This library provides simplified 
00070  */
00071  
00072 // Max nr of CSI parameters
00073 #define CSI_N_MAX 3
00074 #define OSC_BUF_LEN 16
00075    
00076     
00077 /** 
00078  * ANSI colors supported by the ESP Terminal
00079  */
00080 enum Color {
00081     BLACK = 0, RED, GREEN, YELLOW, BLUE, PURPLE, CYAN, GRAY_LT,
00082     GRAY, RED_LT, GREEN_LT, YELLOW_LT, BLUE_LT, PURPLE_LT, CYAN_LT, WHITE,
00083     
00084     // aliases    
00085     RED_DK=1, GREEN_DK=2, YELLOW_DK=3, BLUE_DK=4, PURPLE_DK=5, CYAN_DK=6, SILVER=7,
00086 };
00087 
00088 
00089 /**
00090  * Argument for screen or line clear commands
00091  */
00092 enum ClearMode {
00093     CLEAR_TO_CURSOR = 0,
00094     CLEAR_FROM_CURSOR = 1,        
00095     CLEAR_ALL = 2,
00096 };
00097 
00098 
00099 enum CtlKey {
00100     KEY_LEFT  = 0, 
00101     KEY_RIGHT = 1, 
00102     KEY_UP    = 2, 
00103     KEY_DOWN  = 3,
00104 };
00105 
00106 
00107 /**
00108  * NOTE: not all may be implemented
00109  *
00110  * DOWN (and UP) are fired when the button stays pressed for
00111  * more than a certain time interval (typ. 200 ms)
00112  */
00113 enum MouseEvent {
00114     // Left button
00115     LEFT_CLICK  = 0,
00116     LEFT_DOWN   = 1,
00117     LEFT_UP     = 2,
00118     
00119     // Right button
00120     RIGHT_CLICK = 10,
00121     RIGHT_DOWN  = 11, // Probably not working
00122     RIGHT_UP    = 12, // ditto
00123     
00124     // Common
00125     MOUSE_MOVE  = 20, // When coords of the cell under mouse changed
00126     
00127     // Wheel events 
00128     WHEEL_CLICK = 30,
00129     WHEEL_DOWN  = 31, // This refers to the push button
00130     WHEEL_UP    = 32,
00131     SCROLL_DOWN = 33, // Here's the scrolling events
00132     SCROLL_UP   = 34,
00133 };
00134 
00135 
00136 
00137 /**
00138  * ESP8266 Wireless Terminal interface
00139  *
00140  * Can also be used for sending ANSI sequences to a regular serial terminal
00141  */
00142 class ESPTerm
00143 {
00144     /** 
00145      * Status flag set by the rx handler when device responds with "device OK".
00146      * Cleared before sending Device Status Request.
00147      */
00148     bool device_ok;
00149     
00150     
00151     /** Serial comm used to talk to the ESP */
00152     Serial* ser;
00153     
00154     
00155     /** Internal init func, called from constructor */
00156     void init(Serial* ser);
00157     
00158     
00159     /** Internal rxchar handler with parser */
00160     void ser_rx_char(void);
00161     
00162     // ---- Ragel parser variables ----
00163     int cs;
00164 
00165     // The CSI code is built here
00166     char csi_leading;      //!< Leading char, 0 if none
00167     int  csi_ni;           //!< Number of the active digit
00168     int  csi_n[CSI_N_MAX]; //!< Param digits
00169     char csi_char;         //!< CSI action char (end)
00170 
00171     char osc_buff[OSC_BUF_LEN];
00172     int osc_i;
00173     
00174     // Ragel parser funcs
00175     void ansi_parser(const char *newdata, size_t len);
00176     void apars_handle_plainchar(char c);
00177     void apars_handle_csi(char lead, const int* nums, char keychar);
00178     void apars_handle_osc(const char *c);
00179     void apars_handle_badseq(void);
00180     
00181     
00182 public:   
00183     
00184     /** Fired when user taps the screen at the given coords */
00185     void (*on_mouse)(int row, int col, MouseEvent event);
00186     
00187     
00188     /** Fired when the user presses one of the blue buttons (index is 1 thru 5) */
00189     void (*on_button)(int index);
00190     
00191     
00192     /** Fired on each key press (keyboard arrows etc) */
00193     void (*on_key)(CtlKey key);
00194     
00195     
00196     /** Fired on rx of the "ESP reset notification" byte */
00197     void (*on_esp_reset)(void);
00198     
00199     
00200     /** Fired on each received plain character */
00201     void (*on_char_rx)(char c);
00202     
00203     
00204     /** Handle generic OSC command (may be used in the future) */
00205     void (*on_osc_rx)(const char *str);
00206     
00207 
00208     /**
00209      * @brief Create a terminal instance from already initialized serial port
00210      *
00211      * Example:
00212      * Serial ser(PA_2, PA_3, 115200); // eg. for STM32F042
00213      * ESPTerm term(&ser);
00214      */
00215     ESPTerm(Serial *s);
00216     
00217 
00218     /**
00219      * @brief Create a terminal instance with given params
00220      */
00221     ESPTerm(PinName txPin, PinName rxPin, int baud=115200);
00222     
00223 
00224     /**
00225      * @brief Create a terminal instance with given params & 115200 baud
00226      */
00227     //ESPTerm(PinName txPin, PinName rxPin);
00228     
00229     
00230     /**
00231      * @brief Create with Serial at (PA_2, PA_3, 115200)
00232      */
00233     ESPTerm(void);
00234     
00235     
00236     // ----- Printing -----
00237     
00238     
00239     /** 
00240      * @brief printf() over the Serial
00241      *
00242      * Use for raw strings without formatting, or with custom escape sequences.
00243      */
00244     int printf(const char *fmt, ...);
00245     
00246     
00247     /** 
00248      * @brief Alias for printf()
00249      */
00250     int print(const char *fmt, ...);
00251     
00252     
00253     /** 
00254      * @brief Print with no args
00255      */
00256     int puts(const char *str) 
00257     {    
00258         return ser->puts(str);
00259     }
00260     
00261     
00262     /** 
00263      * @brief Print a single char
00264      */
00265     void putc(const char c) 
00266     {
00267         ser->putc(c);    
00268     }
00269     
00270     
00271     /** 
00272      * printf() over the Serial, followed by a newline (\\r\\n)
00273      *
00274      * Use for raw strings without formatting, or with custom escape sequences.
00275      * Especially useful for log messages, automatically terminating the line.
00276      */
00277     int println(const char *fmt, ...);    
00278     
00279     
00280     // ----- Colors -----
00281     
00282     
00283     /** 
00284      * @brief Set foreground text color
00285      * @param c - color
00286      */    
00287     void fg(Color c);
00288     
00289     
00290     /** 
00291      * @brief Set background text color
00292      * @param c - color
00293      */ 
00294     void bg(Color c);
00295     
00296     
00297     /** 
00298      * @brief Set both text colors
00299      * @param fg - foregorund color
00300      * @param bg - background color
00301      */ 
00302     void colors(Color fg, Color bg)
00303     {
00304         this->fg(fg);
00305         this->bg(bg);
00306     }
00307     
00308     
00309     /** 
00310      * @brief Send \\e[0m - reset all attributes
00311      */ 
00312     void reset_attribs(void);
00313     
00314     
00315     /** 
00316      * @brief Reset all attributes (alias)
00317      */ 
00318     void rst(void)
00319     {
00320         this->reset_attribs();
00321     }
00322     
00323     
00324     // ----- Cursor & clearing -----
00325     
00326     
00327     /**
00328      * @brief Move cursor to a given position
00329      *
00330      * Screen coordinates are 1-based, starting left-top,
00331      * growing down and right.
00332      *
00333      * @param y - row
00334      * @param x - column
00335      */     
00336     void go_to(int y, int x);
00337     
00338     
00339     /**
00340      * @brief Move cursor relatively to the current position
00341      *
00342      * @param dy - vertical offset (positive = down)
00343      * @param dx - horizontal offset (positive = right)
00344      */  
00345     void move(int dy, int dx);
00346     
00347     
00348     /**
00349      * @brief Clear screen
00350      *
00351      * Replace part of the screen with spaces (ASCII 32) of the currently 
00352      * selected foregorund and background colors.
00353      *
00354      * @param mode - what to clear: part or all
00355      */
00356     void clear_screen(ClearMode mode);
00357     
00358     
00359     /**
00360      * @brief Clear in line
00361      *
00362      * Replace part of the current line with spaces (ASCII 32) of the 
00363      * currently selected foregorund and background colors.
00364      *
00365      * @param mode - what to clear: part or all
00366      */
00367     void clear_line(ClearMode mode);
00368     
00369     
00370     /**
00371      * @brief Clear the whole screen and move cursor to 1,1
00372      */
00373     void screen_reset(void);
00374     
00375     
00376     /**
00377      * @brief Scroll the screen up or down.
00378      *
00379      * Moves the screen content in the specified direction, replacing the 
00380      * vacated lines with spaces (32) of the current colors.
00381      *
00382      * @param lines - number of lines, positive = down, negative = up.
00383      */
00384     void scroll(int lines);
00385     
00386     
00387     /**
00388      * @brief Set cursor visibility
00389      *
00390      * If hidden, there will be no blinking square on the screen,
00391      * but the cursor still works (ie. go_to works).
00392      *
00393      * Hiding the cursor is useful for ASCII-art GUIs (dialog boxes etc)
00394      */
00395     void show_cursor(bool yes);
00396     
00397     
00398     /**
00399      * @brief Push the cursor (there's only one slot)
00400      *
00401      * @param with_attribs - store also the colors and attributes
00402      */
00403     void cursor_push(bool with_attribs=true);
00404     
00405     
00406     /**
00407      * @brief Pop the cursor (if stored)
00408      *
00409      * @param with_attribs - restore also the colors and attributes
00410      */
00411     void cursor_pop(bool with_attribs=true);
00412     
00413     
00414     /**
00415      * @brief Enable or disable wrapping at EOL (and automatic scrolling)
00416      *
00417      * @param yes - enable wrap
00418      */
00419     void wrap_enable(bool yes);
00420     
00421     
00422     // ----- System cmds -----
00423     
00424     
00425     /**
00426      * @brief Perform a factory reset of the ESP Terminal
00427      *
00428      * This clears any saved WiFi config, restores the default AP name
00429      * and switches to AP mode. The module will reset itself.
00430      *
00431      * Expect some ASCII output from the module (and a burst of garbage
00432      * during the reset).
00433      */
00434     void factory_reset(void);
00435 
00436 
00437     /**
00438      * @brief Set screen size
00439      *
00440      * The total number of characters (rows*cols) is limited by the Terminal
00441      * firmware, at v0.5.2 that is 2000 characters (25x80)
00442      * 
00443      * @param rows - number of rows (screen height)
00444      * @param cols - number of columns (screen width)
00445      */
00446     void set_screen_size(int rows, int cols);
00447     
00448     
00449     /** 
00450      * @brief Clear the Device OK flag 
00451      */
00452     void clear_status(void)
00453     {
00454         device_ok = false;    
00455     }
00456       
00457         
00458     /**
00459      * @brief Query device status.
00460      *
00461      * To use the query function, call clear_status() first, and then poll 
00462      * query_status() with some delays in between.
00463      *
00464      * @return the status flag from a previous query; 
00465      *         if true, does not send another query, and just returns.
00466      */
00467     bool query_status(void);
00468 };
00469 
00470 
00471 /** Convenience alias for using class enums etc */
00472 typedef ESPTerm VT;
00473 
00474 #endif /* ESPTERM_H */