Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: TS_DISCO_F746NG mbed Servo LCD_DISCO_F746NG BSP_DISCO_F746NG QSPI_DISCO_F746NG AsyncSerial FastPWM
cli_nortos.cpp
- Committer:
- JonFreeman
- Date:
- 2018-05-09
- Revision:
- 6:57dc760effd4
- Parent:
- 5:21a8ac83142c
File content as of revision 6:57dc760effd4:
//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 () ;
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) ;
void uprpm_cmd (struct parameters & a) // controller rec'd rpm from driver boards
{
rpm_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},
{"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
// }
}
*/