X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=app%2Ftriface%2Fprotocol.c;h=57fefa4c7127440595f2344136a351270d07511d;hb=627654bcdc254cd0d104035996661a5839974fa9;hp=8be3d3c96b113eb0981f1ed4a0301a7ddb93a090;hpb=5f3952176a4e9a00ca8dd5ec4a6b994958f89e0a;p=bertos.git diff --git a/app/triface/protocol.c b/app/triface/protocol.c index 8be3d3c9..57fefa4c 100644 --- a/app/triface/protocol.c +++ b/app/triface/protocol.c @@ -1,7 +1,34 @@ /** * \file * * * \brief Implementation of the command protocol between the board and the host @@ -12,49 +39,36 @@ * \author Giovanni Bajo * \author Marco Benelli * \author Bernardo Innocenti + * \author Daniele Basile */ -/*#* - *#* $Log$ - *#* Revision 1.7 2007/01/09 09:00:16 bernie - *#* Doxygen fix. - *#* - *#* Revision 1.6 2006/09/20 13:54:04 marco - *#* Usage examples of MAKE_CMD. - *#* - *#* Revision 1.5 2006/06/14 01:03:01 marco - *#* Add response code. Add command ping. - *#* - *#* Revision 1.4 2006/06/14 00:26:48 marco - *#* Use new macros for defining commands. - *#* - *#* Revision 1.3 2006/06/13 19:07:31 marco - *#* Fixed a bug in protocol_reply. Simplified rpc. - *#* - *#* Revision 1.2 2006/06/12 21:37:02 marco - *#* implemented some commands (ver and sleep) - *#* - *#* Revision 1.1 2006/06/01 12:29:21 marco - *#* Add first simple protocol command (version request). - *#* - *#*/ - #include "protocol.h" +#include "cmd_ctor.h" // MAKE_CMD, REGISTER_CMD +#include "verstag.h" +#include "hw_adc.h" +#include "hw_input.h" -#include #include +#include +#include +#include +#include + #include #include + #include #include -#include + +#include #include #include -//#include +#include "appconfig.h" -#include "cmd_ctor.h" // MAKE_CMD, REGISTER_CMD +// Define the format string for ADC +#define ADC_FORMAT_STR "dddd" // DEBUG: set to 1 to force interactive mode #define FORCE_INTERACTIVE 1 @@ -71,53 +85,58 @@ static bool interactive; /// Readline context, used for interactive mode. static struct RLContext rl_ctx; - +uint8_t reg_status_dout; /** * Send a NAK asking the host to send the current message again. * - * \param ser serial port handle to output to. - * \param err human-readable description of the error for debug purposes. + * \a fd kfile handler for serial. + * \a err human-readable description of the error for debug purposes. */ -INLINE void NAK(Serial *ser, const char *err) +INLINE void NAK(KFile *fd, const char *err) { #ifdef _DEBUG - ser_printf(ser, "NAK \"%s\"\r\n", err); + kfile_printf(fd, "NAK \"%s\"\r\n", err); #else - ser_printf(ser, "NAK\r\n"); + kfile_printf(fd, "NAK\r\n"); #endif } +static void protocol_prompt(KFile *fd) +{ + kfile_print(fd, ">> "); +} + /* * Print args on s, with format specified in t->result_fmt. * Return number of valid arguments or -1 in case of error. */ -static bool protocol_reply(Serial *s, const struct CmdTemplate *t, +static bool protocol_reply(KFile *fd, const struct CmdTemplate *t, const parms *args) { unsigned short offset = strlen(t->arg_fmt) + 1; unsigned short nres = strlen(t->result_fmt); - ser_printf(s, "0"); for (unsigned short i = 0; i < nres; ++i) { if (t->result_fmt[i] == 'd') { - ser_printf(s, " %ld", args[offset+i].l); + kfile_printf(fd, " %ld", args[offset+i].l); } else if (t->result_fmt[i] == 's') { - ser_printf(s, " %s", args[offset+i].s); + kfile_printf(fd, " %s", args[offset+i].s); } + else { abort(); } } - ser_printf(s, "\r\n"); + kfile_printf(fd, "\r\n"); return true; } -static void protocol_parse(Serial *ser, const char *buf) +static void protocol_parse(KFile *fd, const char *buf) { const struct CmdTemplate *templ; @@ -125,7 +144,8 @@ static void protocol_parse(Serial *ser, const char *buf) templ = parser_get_cmd_template(buf); if (!templ) { - ser_print(ser, "-1 Invalid command."); + kfile_print(fd, "-1 Invalid command.\r\n"); + protocol_prompt(fd); return; } @@ -134,23 +154,26 @@ static void protocol_parse(Serial *ser, const char *buf) /* Args Check. TODO: Handle different case. see doc/PROTOCOL . */ if (!parser_get_cmd_arguments(buf, templ, args)) { - ser_print(ser, "-2 Invalid arguments."); + kfile_print(fd, "-2 Invalid arguments.\r\n"); + protocol_prompt(fd); return; } /* Execute. */ if(!parser_execute_cmd(templ, args)) { - NAK(ser, "Error in executing command."); + NAK(fd, "Error in executing command."); } - if (!protocol_reply(ser, templ, args)) + if (!protocol_reply(fd, templ, args)) { - NAK(ser, "Invalid return format."); + NAK(fd, "Invalid return format."); } + + protocol_prompt(fd); return; } -void protocol_run(Serial *ser) +void protocol_run(KFile *fd) { /** * \todo to be removed, we could probably access the serial FIFO @@ -160,23 +183,27 @@ void protocol_run(Serial *ser) if (!interactive) { - ser_gets(ser, linebuf, sizeof(linebuf)); + kfile_gets(fd, linebuf, sizeof(linebuf)); // reset serial port error anyway - ser_setstatus(ser, 0); + kfile_clearerr(fd); // check message minimum length if (linebuf[0]) { - if (linebuf[0] == 0x1B && linebuf[1] == 0x1B) // ESC + /* If we enter lines beginning with sharp(#) + they are stripped out from commands */ + if(linebuf[0] != '#') { - interactive = true; - ser_printf(ser, - "Entering interactive mode\r\n"); - } - else - { - protocol_parse(ser, linebuf); + if (linebuf[0] == 0x1B && linebuf[1] == 0x1B) // ESC + { + interactive = true; + kfile_printf(fd, "Entering interactive mode\r\n"); + } + else + { + protocol_parse(fd, linebuf); + } } } } @@ -194,25 +221,29 @@ void protocol_run(Serial *ser) */ buf = rl_readline(&rl_ctx); - if (buf && buf[0] != '\0') + /* If we enter lines beginning with sharp(#) + they are stripped out from commands */ + if(buf && buf[0] != '#') { - // exit special case to immediately change serial input - if (!strcmp(buf, "exit") || !strcmp(buf, "quit")) - { - rl_clear_history(&rl_ctx); - ser_printf(ser, - "Leaving interactive mode...\r\n"); - interactive = FORCE_INTERACTIVE; - } - else + if (buf[0] != '\0') { - //TODO: remove sequence numbers - linebuf[0] = '0'; - linebuf[1] = ' '; - - strncpy(linebuf + 2, buf, sizeof(linebuf) - 3); - linebuf[sizeof(linebuf) - 1] = '\0'; - protocol_parse(ser, linebuf); + // exit special case to immediately change serial input + if (!strcmp(buf, "exit") || !strcmp(buf, "quit")) + { + rl_clear_history(&rl_ctx); + kfile_printf(fd, "Leaving interactive mode...\r\n"); + interactive = FORCE_INTERACTIVE; + } + else + { + //TODO: remove sequence numbers + linebuf[0] = '0'; + linebuf[1] = ' '; + + strncpy(linebuf + 2, buf, sizeof(linebuf) - 3); + linebuf[sizeof(linebuf) - 1] = '\0'; + protocol_parse(fd, linebuf); + } } } } @@ -225,26 +256,91 @@ void protocol_run(Serial *ser) * */ -/* Version. Example of declaring function and passing it to MAKE_CMD. */ -static int ver_fn(const char **str) -{ - *str = VERS_TAG; - return 0; -} -MAKE_CMD(ver, "", "s", ver_fn(&args[1].s)) +MAKE_CMD(ver, "", "ddd", +({ + args[1].l = VERS_MAJOR; + args[2].l = VERS_MINOR; + args[3].l = VERS_REV; + 0; +}), 0); /* Sleep. Example of declaring function body directly in macro call. */ MAKE_CMD(sleep, "d", "", ({ timer_delay((mtime_t)args[1].l); 0; -})) +}), 0) /* Ping. */ MAKE_CMD(ping, "", "", ({ + //Silence "args not used" warning. + (void)args; + 0; +}), 0) + +/* Dout */ +MAKE_CMD(dout, "d", "", +({ + sipo_putchar((uint8_t)args[1].l); + + //Store status of dout ports. + reg_status_dout = (uint8_t)args[1].l; 0; -})) +}), 0) + +/* rdout read the status of out ports.*/ +MAKE_CMD(rdout, "", "d", +({ + args[1].l = reg_status_dout; + 0; +}), 0) + +/* Doutx sperimentale....... */ +MAKE_CMD(doutx, "d", "", + ({ + sipo_putchar((uint8_t)args[1].l); + + //Store status of dout ports. + reg_status_dout = (uint8_t)args[1].l; + 0; + }), 0) + +/* Reset */ +MAKE_CMD(reset, "", "", +({ + //Silence "args not used" warning. + (void)args; + wdt_init(7); + wdt_start(); + 0; +}), 0) + +/* Din */ +MAKE_CMD(din, "", "d", +({ + args[1].l = INPUT_GET(); + 0; +}), 0) + + + +/* Ain */ +MAKE_CMD(ain, "", ADC_FORMAT_STR, +({ + STATIC_ASSERT((sizeof(ADC_FORMAT_STR) - 1) == ADC_CHANNEL_NUM); + for(int i = 0; i < ADC_CHANNEL_NUM; i++) + args[i+1].l = adc_read_ai_channel(i); + + 0; +}), 0) + +/* Beep */ +MAKE_CMD(beep, "d", "", +({ + buz_beep(args[1].l); + 0; +}), 0) /* Register commands. */ static void protocol_registerCmds(void) @@ -252,20 +348,32 @@ static void protocol_registerCmds(void) REGISTER_CMD(ver); REGISTER_CMD(sleep); REGISTER_CMD(ping); + REGISTER_CMD(dout); + //Set off all dout ports. + reg_status_dout = 0; + REGISTER_CMD(rdout); + REGISTER_CMD(doutx); + REGISTER_CMD(reset); + REGISTER_CMD(din); + REGISTER_CMD(ain); + REGISTER_CMD(beep); } /* Initialization: readline context, parser and register commands. */ -void protocol_init(Serial *ser) +void protocol_init(KFile *fd) { interactive = FORCE_INTERACTIVE; rl_init_ctx(&rl_ctx); - rl_setprompt(&rl_ctx, ">> "); - rl_sethook_get(&rl_ctx, (getc_hook)ser_getchar, ser); - rl_sethook_put(&rl_ctx, (putc_hook)ser_putchar, ser); + //rl_setprompt(&rl_ctx, ">> "); + rl_sethook_get(&rl_ctx, (getc_hook)kfile_getc, fd); + rl_sethook_put(&rl_ctx, (putc_hook)kfile_putc, fd); rl_sethook_match(&rl_ctx, parser_rl_match, NULL); + rl_sethook_clear(&rl_ctx, (clear_hook)kfile_clearerr,fd); parser_init(); protocol_registerCmds(); + + protocol_prompt(fd); }