Touch screen drivers control dashboard for miniature locomotive. Features meters for speed, volts, power. Switches for lights, horns. Drives multiple STM3_ESC brushless motor controllers for complete brushless loco system as used in "The Brute" - www.jons-workshop.com

Dependencies:   TS_DISCO_F746NG mbed Servo LCD_DISCO_F746NG BSP_DISCO_F746NG QSPI_DISCO_F746NG AsyncSerial FastPWM

Revision:
12:a25bdf135348
Parent:
11:a573664b1a59
Child:
14:6bcec5ac21ca
--- a/cli_TS_nortos.cpp	Sat Jun 23 09:37:41 2018 +0000
+++ b/cli_TS_nortos.cpp	Mon Jan 14 16:39:41 2019 +0000
@@ -1,87 +1,131 @@
 //Loco_TS_2018
 #include "mbed.h"
-//#include "BufferedSerial.h"
 #include "AsyncSerial.hpp"
 #include <cctype>
 #include "Electric_Loco.h"
 using namespace std;
 
-//extern  int I_Am    ()  ;      //  Returns boards id number as ASCII char '0', '1' etc. Code for Broadcast = '\r'
-//typedef double  fl_typ;  //
-
 const int   BROADCAST   = '\r';
 
 //  WithOUT RTOS
 extern  Serial pc;
-extern  AsyncSerial com;
-extern  void    send_test   ()  ;
+extern  AsyncSerial com2escs;
+extern  error_handling_Jan_2019   Controller_Error    ;
+extern  const   char   const_version_string[] ;  //  Version string, readable from serial ports
 
-genio::genio    (int dtype, int dlen)  {
+extern  STM3_ESC_Interface    My_STM3_ESC_boards   ;
+
+/*genio::genio    (int dtype, int dlen)  {    //  constructor
     d_type = dtype;
     d_len = dlen;
     for (int i = 0; i < MAX_PARAMS; i++)    {
-        ui[i] = 0;
+        si[i] = 0;
         dbl[i] = 0.0;
     }
-    count = 0;
-    available = false;
+    count = 0;  //  running total of times called
+    available = false;  //  bool
+    //available = 0; // if using integer rather than bool
 }
 
-void    genio::store   (struct parameters & a)  {   //
-    count++;
+void    genio::store   (struct parameters & a)  {   //  copies up to MAX_PARAMS into int and double arrays
+    count++;            //  number of times this response rec'd this session
     available = true;
-    for (int i = 0; i < d_len; i++) {
-        ui[i] = (int32_t)a.dbl[i];
+    for (int i = 0; i < d_len; i++) {   //  dlen //  loaded on setup indicating expected num of parameters to handle. Why not just use MAX_PARAMS ?
+        si[i] = (int32_t)a.dbl[i];
         dbl[i] = a.dbl[i];
     }
 }
 
-bool    genio::read    (uint32_t ** addr)  {
+bool    genio::read    (int32_t ** addr)  {
     if  (!available)
         return  false;
     available = false;
-    *addr = ui;
+    *addr = si;         //      int32_t    ui[MAX_PARAMS];
     return  true;
 }
+*/
+
+command_line_interpreter_core::command_line_interpreter_core    (int p, int menulen, struct kb_command const * clistp)  {
+    clist = clistp;
+    a.numof_menu_items = menulen;
+    a.numof_cl_values_read = 0;
+    portio = p;
+    cl_index = 0;
+}
+
+int     command_line_interpreter_core::clreadable    ()  {
+    if  (portio == 0)
+        return  pc.readable();
+    return  com2escs.readable();
+}  
+
+void    command_line_interpreter_core::clputc    (int c)  {
+    if  (portio == 0)
+        pc.putc (c);
+    else
+        com2escs.putc   (c);
+}  
+
+int     command_line_interpreter_core::clgetc    ()  {
+    if  (portio == 0)
+        return  pc.getc();
+    return  com2escs.getc();
+}  
+
 
 void    null_cmd (struct parameters & a)
 {
     pc.printf   ("At null_cmd, parameters : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]);
 }
 
-
 void    menucmd (struct parameters & a);
 
 void    kd_cmd (struct parameters & a)  //  kick the watchdog
 {
 }
 
-extern  void    rpm_push    (struct parameters & a)  ;
-extern  void    mph_push    (struct parameters & a)  ;
-void    uprpm_cmd (struct parameters & a)  //  controller rec'd rpm from driver boards
-{
-    rpm_push    (a);
-//    a.gp_i ^= 1;    //  toggle lsb
-}
-
 void    upmph_cmd (struct parameters & a)  //  controller rec'd mph from driver boards
 {
-    mph_push    (a);
-//    a.gp_i ^= 1;    //  toggle lsb
-}
-
-void    uprdi_cmd (struct parameters & a)  //  controller rec'd rpm from driver boards
-{
-//    pc.printf   ("RPM %d %d\r\n", (int)a.dbl[0], (int)a.dbl[1]);
+    My_STM3_ESC_boards.mph_update  (a.dbl[1]);
 }
 
 
-/*void    who_cmd (struct parameters & a)
+void    TSver_cmd (struct parameters & a)  //   Report current TS software version to pc
 {
-    int i = I_Am    ();
-    if  (I_Am() == a.target_unit)
-        pc.printf ("Hi there, I am %c\r\n", a.target_unit);
-}*/
+    pc.printf   ("ver %s\r\n", const_version_string);
+}
+
+void    boards_cmd  (struct parameters & a) {
+    int boards[MAX_ESCS], count = 0;
+    My_STM3_ESC_boards.get_boards_list   (boards);
+    while  (boards[count] && count < MAX_ESCS)
+        count++;
+    pc.printf   ("Board Count = %d\r\n", count);
+    if  (count) {
+        pc.printf   ("Boards found ^");
+        for (int i = 0; i < count; i++)
+            pc.printf   ("%c ", boards[i]);
+        pc.printf   ("\r\n");
+    }
+    else
+        pc.printf   ("No STM3_ESC boards found\r\n");
+}
+
+void    who_cmd (struct parameters & a)  //   Have read "whon" back from STM3_ESC where 'n' is STM3_Esc board ID number (ascii digit)
+{
+    int v = (int)a.dbl[0] | '0';
+    if  (a.numof_cl_values_read == 1 && isdigit(v)) {
+//        pc.printf   ("who%c, vals read %d\r\n", (int)a.dbl[0] | '0', a.numof_cl_values_read);
+        My_STM3_ESC_boards.set_board_ID  (v);//        set_board_id    (v);  //  just to test and prove can not add same board twice
+    }
+    else
+        pc.printf   ("Garbage response to 'who', numof vals %d, value %c\r\n", a.numof_cl_values_read, v);
+}
+
+void    ver_req_cmd (struct parameters & a)  //   Touch Screen controller requesting version string from one specific ESC board
+{
+    pc.printf   ("ver_req_cmd not yet implemented\r\n");
+}
 
 struct kb_command  {
     const char * cmd_word;         //  points to text e.g. "menu"
@@ -92,142 +136,32 @@
 struct  kb_command const command_list[] = {
     {"ls", "Lists available commands", menucmd},
     {"?", "Lists available commands, same as ls", menucmd},
-//    {"fw", "forward", fw_cmd},
-//    {"re", "reverse", re_cmd},
-//    {"rb", "regen brake 0 to 99 %", rb_cmd},
-//    {"hb", "hand brake", hb_cmd},
-//    {"v", "set motors V percent RANGE 0 to 100", v_cmd},
-//    {"i", "set motors I percent RANGE 0 to 100", i_cmd},
-//    {"vi", "set motors V and I percent RANGE 0 to 100", vi_cmd},
-//    {"who", "search for connected units, e.g. 3who returs 'Hi there' if found", who_cmd},
-//    {"mode", "read or set params in eeprom", mode_cmd},
-//    {"erase", "set eeprom contents to all 0xff", erase_cmd},
+    {"ver", "report const_version_string", TSver_cmd},        //  Report TS controller version
+    {"boards", "List STM3_ESC boards connected", boards_cmd},
     {"kd", "kick the dog", kd_cmd},
-    {"rpm", "rpm reading from 2 motors", uprpm_cmd},
     {"nu", "do nothing", null_cmd},
 };
 
-const int numof_menu_items = sizeof(command_list) / sizeof(kb_command);
-void    menucmd (struct parameters & a)
-{
-//    struct kb_command const * cl = command_list;
-    pc.printf("\r\n\nTS_2018 Locomotive Touch Screen Controller\r\nAt menucmd function - listing commands:-\r\n");
-    for(int i = 0; i < numof_menu_items; i++)
-        pc.printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan);
-    pc.printf("End of List of Commands\r\n");
-}
-
 struct  kb_command const loco_command_list[] = {
     {"ls", "Lists available commands", menucmd},
     {"?", "Lists available commands, same as ls", menucmd},
-    {"rpm", "rpm reading from 2 motors", uprpm_cmd},
+    {"who", "Reads 'whon' response from STM3_ESC where 'n' is board num ascii from eeprom", who_cmd},
+    {"ver", "report const_version_string", ver_req_cmd},    //  Request software version of one specific ESC board
     {"mph", "bogie mph reading", upmph_cmd},    //  22/06/2018
-    {"rdi", "rpm reading from 2 motors", uprdi_cmd},
     {"nu", "do nothing", null_cmd},
 }   ;
 
-struct parameters pccom, lococom;
 
-/*struct  parameters  {
-    struct kb_command const * clist;
-    char    cmd_line[120];
-    char    * cmd_line_ptr;
-    int32_t position_in_list, numof_dbls, target_unit, numof_menu_items;
-    double  dbl[MAX_PARAMS];
-    bool    respond;
-}   ;
-*/
-int getc    (int which_port)
-{
-    if  (which_port == 0)
-        return  pc.getc ();
-    if  (which_port == 1)
-        return  com.getc    ();
-    return  -1;
-}
-int readable    (int which_port)
-{
-    if  (which_port == 0)
-        return  pc.readable ();
-    if  (which_port == 1)
-        return  com.readable    ();
-    return  -1;
-
-}
-
-void setup_pccom ()
-{
-    pccom.clist = command_list;
-    pccom.numof_menu_items = sizeof(command_list) / sizeof(kb_command);
-    pccom.com_no    = 0;
-    pccom.cl_index  = 0;
-    pccom.gp_i      = 0;    //  general puropse integer, not used to 30/4/2018
-}
-
-void    setup_lococom ()
-{
-    lococom.clist = loco_command_list;
-    lococom.numof_menu_items = sizeof(loco_command_list) / sizeof(kb_command);
-    lococom.com_no  = 1;
-    lococom.cl_index    = 0;
-    lococom.gp_i        = 0;    //  general puropse integer, toggles 0 / 1 to best guess source of rpm
-}
-
-void    clicore (struct parameters & a)
+void    menucmd (struct parameters & a)
 {
-    int ch;
-    char * pEnd;
-    while   (readable(a.com_no))    {
-        ch = getc   (a.com_no);
-        if(ch != '\r')  //  was this the 'Enter' key?
-            a.cmd_line[a.cl_index++] = ch;  //  added char to command being assembled
-        else    {   //  key was CR, may or may not be command to lookup
-            a.target_unit = BROADCAST;    //  Broadcast
-            a.cmd_line_ptr = a.cmd_line;
-            a.cmd_line[a.cl_index] = 0; //  null terminate command string
-            if(a.cl_index)    {   //  If have got some chars to lookup
-                int i, wrdlen;
-                if  (isdigit(a.cmd_line[0]))  {   //  Look for command with prefix digit
-                    a.cmd_line_ptr++;     //  point past identified digit prefix
-                    a.target_unit = a.cmd_line[0];  //  '0' to '9'
-                    //pc.printf ("Got prefix %c\r\n", cmd_line[0]);
-                }
-                for (i = 0; i < a.numof_menu_items; i++)   {   //  Look for input match in command list
-                    wrdlen = strlen(a.clist[i].cmd_word);
-                    if(strncmp(a.clist[i].cmd_word, a.cmd_line_ptr, wrdlen) == 0 && !isalpha(a.cmd_line_ptr[wrdlen]))  {   //  If match found
-                        for (int k = 0; k < MAX_PARAMS; k++)    {
-                            a.dbl[k] = 0.0;
-                        }
-                        a.position_in_list = i;
-                        a.numof_dbls = 0;
-                        pEnd = a.cmd_line_ptr + wrdlen;
-                        while   (*pEnd)  {          //  Assemble all numerics as doubles
-                            a.dbl[a.numof_dbls++] = strtod    (pEnd, &pEnd);
-                            while   (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd)  {
-                                pEnd++;
-                            }
-                        }
-                        //pc.printf   ("\r\n");   //  Not allowed as many may output this.
-                        //for (int k = 0; k < param_block.numof_dbls; k++)
-                        //    pc.printf   ("Read %.3f\r\n", param_block.dbl[k]);
-//                            param_block.times[i] = clock();
-//                            if  ((param_block.target_unit == BROADCAST) && (I_Am() == '0'))
-//                                param_block.respond = true;
-                        a.clist[i].f(a);   //  execute command
-                        i = a.numof_menu_items + 1;    //  to exit for loop
-                    }   //  end of match found
-                }       // End of for numof_menu_items
-                if(i == a.numof_menu_items)
-                    pc.printf("No Match Found for CMD [%s]\r\n", a.cmd_line);
-            }           //  End of If have got some chars to lookup
-            //pc.printf("\r\n>");
-            a.cl_index = 0;
-        }               // End of else key was CR, may or may not be command to lookup
-    }                   //  End of while (pc.readable())
+    pc.printf("\r\n\nTS_2018 Locomotive Touch Screen Controller\r\nAt menucmd function - listing commands:-\r\n");
+    for(int i = 0; i < a.numof_menu_items; i++)
+        pc.printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan);
+    pc.printf("End of List of Commands\r\n");
 }
 
 
-/*
+/**
 New - March 2018
 Using opto isolated serial port, paralleled up using same pair to multiple boards running this code.
 New feature - commands have optional prefix digit 0-9 indicating which unit message is addressed to.
@@ -235,68 +169,68 @@
 Only units recognising its address from prefix digit may respond. This avoids bus contention.
 But for BROADCAST commands, '0' may respond on behalf of the group
 */
-//void    command_line_interpreter    (void const *argument)
-/*void    command_line_interpreter    ()
-{
-    const int MAX_CMD_LEN = 120;
-    static  char    cmd_line[MAX_CMD_LEN + 4];
-    static  int     cl_index = 0;
+command_line_interpreter_core   pcli    (0, sizeof(command_list) / sizeof(kb_command), command_list);
+command_line_interpreter_core   ploco   (1, sizeof(loco_command_list) / sizeof(kb_command), loco_command_list);
+
+void    command_line_interpreter_core::sniff    ()  {   //  look for recieved commands and act upon them
     int ch;
-    char * pEnd, * cmd_line_ptr;
-    static struct  parameters  param_block  ;
-    while  (pc.readable()) {
-        ch = pc.getc();
-//            if  (cl_index > MAX_CMD_LEN)  {   //  trap out stupidly long command lines
-//                pc.printf   ("Error!! Stupidly long cmd line\r\n");
-//                cl_index = 0;
-//            }
-        if(ch != '\r')  //  was this the 'Enter' key?
-            cmd_line[cl_index++] = ch;  //  added char to command being assembled
+    char * pEnd;
+    while   (clreadable())    {
+        ch = clgetc   ();
+        if(ch != '\r')  {//  was this the 'Enter' key?
+            if  (ch != '\n')    {   //  Ignore line feeds
+                cmd_line[cl_index++] = ch;  //  added char to command being assembled
+                if  (cl_index >= MAX_CMD_LINE_LEN-2)  {
+                    cl_index = 0;     //  Line is garbage anyway, so might as well junk the lot ?
+                    pc.printf   ("cl_index=%d TOO LONG in clicore\r\n", cl_index);
+                    Controller_Error.set    (FAULT_COM_LINE_LEN, 1);
+                }
+            }       //  endof if(ch != '\n')    ignore line feeds
+        }           //  endof if(ch != '\r')    
         else    {   //  key was CR, may or may not be command to lookup
-            param_block.target_unit = BROADCAST;    //  Broadcast
+            target_unit = BROADCAST;    //  Broadcast
             cmd_line_ptr = cmd_line;
             cmd_line[cl_index] = 0; //  null terminate command string
             if(cl_index)    {   //  If have got some chars to lookup
                 int i, wrdlen;
                 if  (isdigit(cmd_line[0]))  {   //  Look for command with prefix digit
                     cmd_line_ptr++;     //  point past identified digit prefix
-                    param_block.target_unit = cmd_line[0];  //  '0' to '9'
-                    //pc.printf ("Got prefix %c\r\n", cmd_line[0]);
+                    target_unit = cmd_line[0];  //  '0' to '9'
+                    //pc.printf ("Got prefix %c\r\n", a.cmd_line[0]);
                 }
-                for (i = 0; i < numof_menu_items; i++)   {   //  Look for input match in command list
-                    wrdlen = strlen(command_list[i].cmd_word);
-                    if(strncmp(command_list[i].cmd_word, cmd_line_ptr, wrdlen) == 0 && !isalpha(cmd_line_ptr[wrdlen]))  {   //  If match found
+                for (i = 0; i < a.numof_menu_items; i++)   {   //  Look for input match in command list
+                    wrdlen = strlen(clist[i].cmd_word);
+                    if(strncmp(clist[i].cmd_word, cmd_line_ptr, wrdlen) == 0 && !isalpha(cmd_line_ptr[wrdlen]))  {   //  If match found
                         for (int k = 0; k < MAX_PARAMS; k++)    {
-                            param_block.dbl[k] = 0.0;
+                            a.dbl[k] = 0.0;
                         }
-                        param_block.position_in_list = i;
-                        param_block.numof_dbls = 0;
+                        //position_in_list = i;
+                        a.numof_cl_values_read = 0;
                         pEnd = cmd_line_ptr + wrdlen;
                         while   (*pEnd)  {          //  Assemble all numerics as doubles
-                            param_block.dbl[param_block.numof_dbls++] = strtod    (pEnd, &pEnd);
+                            a.dbl[a.numof_cl_values_read++] = strtod    (pEnd, &pEnd);
                             while   (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd)  {
                                 pEnd++;
                             }
                         }
                         //pc.printf   ("\r\n");   //  Not allowed as many may output this.
-                        //for (int k = 0; k < param_block.numof_dbls; k++)
+                        //for (int k = 0; k < param_block.a.numof_cl_values_read; k++)
                         //    pc.printf   ("Read %.3f\r\n", param_block.dbl[k]);
 //                            param_block.times[i] = clock();
 //                            if  ((param_block.target_unit == BROADCAST) && (I_Am() == '0'))
 //                                param_block.respond = true;
-                        command_list[i].f(param_block);   //  execute command
-                        i = numof_menu_items + 1;    //  to exit for loop
+                        clist[i].f(a);   //  execute command
+                        i = a.numof_menu_items + 1;    //  to exit for loop
                     }   //  end of match found
                 }       // End of for numof_menu_items
-                if(i == numof_menu_items)
+                if(i == a.numof_menu_items) {
                     pc.printf("No Match Found for CMD [%s]\r\n", cmd_line);
+                    Controller_Error.set    (FAULT_COM_NO_MATCH, 1);
+                }
             }           //  End of If have got some chars to lookup
-            //pc.printf("\r\n>");
             cl_index = 0;
         }               // End of else key was CR, may or may not be command to lookup
     }                   //  End of while (pc.readable())
-//        Thread::wait(20);  //  Using RTOS on this project
-//    }
-}
-*/
+}  
 
+