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

cli_TS_nortos.cpp

Committer:
JonFreeman
Date:
2018-06-23
Revision:
11:a573664b1a59
Parent:
cli_nortos.cpp@ 7:3b1f44cd4735
Child:
12:a25bdf135348

File content as of revision 11:a573664b1a59:

//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   ()  ;

genio::genio    (int dtype, int dlen)  {
    d_type = dtype;
    d_len = dlen;
    for (int i = 0; i < MAX_PARAMS; i++)    {
        ui[i] = 0;
        dbl[i] = 0.0;
    }
    count = 0;
    available = false;
}

void    genio::store   (struct parameters & a)  {   //
    count++;
    available = true;
    for (int i = 0; i < d_len; i++) {
        ui[i] = (int32_t)a.dbl[i];
        dbl[i] = a.dbl[i];
    }
}

bool    genio::read    (uint32_t ** addr)  {
    if  (!available)
        return  false;
    available = false;
    *addr = ui;
    return  true;
}

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]);
}


/*void    who_cmd (struct parameters & a)
{
    int i = I_Am    ();
    if  (I_Am() == a.target_unit)
        pc.printf ("Hi there, I am %c\r\n", a.target_unit);
}*/

struct kb_command  {
    const char * cmd_word;         //  points to text e.g. "menu"
    const char * explan;
    void (*f)(struct parameters &);   //  points to function
}  ;

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},
    {"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},
    {"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)
{
    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())
}


/*
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.
Commands without prefix digit - broadcast to all units, none to respond.
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;
    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
        else    {   //  key was CR, may or may not be command to lookup
            param_block.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]);
                }
                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 (int k = 0; k < MAX_PARAMS; k++)    {
                            param_block.dbl[k] = 0.0;
                        }
                        param_block.position_in_list = i;
                        param_block.numof_dbls = 0;
                        pEnd = cmd_line_ptr + wrdlen;
                        while   (*pEnd)  {          //  Assemble all numerics as doubles
                            param_block.dbl[param_block.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;
                        command_list[i].f(param_block);   //  execute command
                        i = numof_menu_items + 1;    //  to exit for loop
                    }   //  end of match found
                }       // End of for numof_menu_items
                if(i == numof_menu_items)
                    pc.printf("No Match Found for CMD [%s]\r\n", cmd_line);
            }           //  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
//    }
}
*/