4 * Copyright (C) 2013-11-07 K.Ohta <whatisthis.sowhat ai gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2,
9 * or (at your option) any later version.
10 * This library / program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this library; see the file COPYING. If not, write to the
17 * Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
20 * As a special exception, if you link this(includeed from sdcc) library
21 * with other files, some of which are compiled with SDCC,
22 * to produce an executable, this library does not by itself cause
23 * the resulting executable to be covered by the GNU General Public License.
24 * This exception does not however invalidate any other reasons why
25 * the executable file might be covered by the GNU General Public License.
30 #include <pic18fregs.h> /* ONLY FOR PIC18x */
43 #include "shell_strutl.h"
44 #include "uart_termio.h"
45 #include "term_shell.h"
46 #include "eeprom_util.h"
49 unsigned char cmd_shellstr[130];
50 static char shell_strbuf[130];
51 static char xarg1[66];
52 static char xarg2[66];
53 static char xarg3[66];
54 static unsigned char tmparea[256];
56 #define SHELL_CMD_NONE -1
57 #define SHELL_CMD_NOTFOUND -2
58 #define SHELL_CMD_ILLTOKEN -3
59 #define SHELL_CMD_TOOLONG -4
60 #define SHELL_CMD_OK 0
62 #define SHELL_TOPCMDS 16
64 static void shell_printnum(unsigned int v)
72 * Set Frequency: Arg1 = Freq.
74 static void term_freq(char *p)
80 uart_term_putstr("\nSet Freq:");
81 if((l < 0) || (l > 30000)) {
82 uart_term_putstr("\nE:Illegal freq range.\n");
85 freq = (unsigned int)l;
87 shell_printnum(setup.amfreq);
91 shell_printnum(setup.fmfreq);
95 uart_term_putstr("->");
98 akc6955_set_freq(freq);
99 uart_term_putstr("\ndone.\n");
106 static void term_printstatus(char *p)
108 uart_term_putstr("\nStatus:\n");
110 uart_term_putstr("AM \nBand = ");
111 shell_printnum(setup.amband);
112 uart_term_putstr("\nFreq = ");
113 shell_printnum(setup.amfreq);
114 uart_term_putstr("\n");
116 uart_term_putstr("FM \nBand = ");
117 shell_printnum(setup.fmband);
118 uart_term_putstr("\nFreq = ");
119 shell_printnum(setup.fmfreq);
120 uart_term_putstr("\n");
123 uart_term_putstr("\n");
129 * Arg1: 'N'/'n' : not save.
131 static void term_poweroff(char *p)
135 unsigned char savef = 0xff;
137 slen = shell_gettok(xarg1, p);
138 if(shell_strlen(xarg1) != 0) {
139 if((xarg1[0] == 'N') || (xarg1[0] == 'n')) savef = 0;
141 uart_term_putstr("\n*** Power OFF ***\nOK? (Yes = Y)");
142 uart_term_getstr(s, 15, 0xff);
143 if(shell_strlen(s) >= 3) return;
144 if(s[0] == 'Y') shutdown(savef);
148 static void term_poweron(char *p)
152 static unsigned char put_hexline(unsigned char *dat, unsigned long addr, unsigned char len)
155 l = str_bin2hex((unsigned char *)shell_strbuf, dat, addr, len);
156 uart_term_putstr(shell_strbuf);
160 static void put_hexheader(char *fname)
162 uart_term_putstr("Start of save value.\n--- BEGIN ---\n");
163 str_put_shexheader(shell_strbuf, fname);
164 uart_term_putstr(shell_strbuf);
168 static void put_hexfooter(void)
170 str_put_shexfooter(shell_strbuf);
171 uart_term_putstr(shell_strbuf);
172 uart_term_putstr("\n--- END---\n");
177 static void save_hex_page(unsigned char *p, unsigned int len, unsigned long baseaddr)
180 unsigned int l = len;
181 for(pp = 0; pp < len; pp += 16){
183 put_hexline(&p[pp], pp + baseaddr, 16);
186 put_hexline(&p[pp], pp + baseaddr, l);
189 idle_time_ms(100); // Line wait.
194 void shell_memcpy(unsigned char *to, unsigned char *from, unsigned char len)
197 for(l = 0; l < len; l++) to[l] = from[l];
201 static char wait_for_sheader(unsigned char *file, unsigned char retry)
203 unsigned char _try = 0;
204 unsigned char _err = 0;
209 shell_strbuf[0] = '\0';
210 uart_term_getstr(shell_strbuf, 100, 0); // With Echo, timeout=10Sec.
211 stat = search_head_s(shell_strbuf);
214 if(_err > 100) return -1; // Error
218 stat = str_shexheader(&shell_strbuf[stat], file);
219 if(stat == TERM_OK) break;
221 } while(_try <= retry);
225 static unsigned long load_hex_page(unsigned char *p, unsigned long *addr, unsigned int len)
230 unsigned char __err = 0;
231 unsigned long bytes = 0;
233 unsigned char sbuf[20];
238 shell_strbuf[0] = '\0';
239 uart_term_getstr(shell_strbuf, 1000, 0); // Without Echo, timeout=100Sec.
241 stat = search_head_s(shell_strbuf);
245 return 0xffffffff; // Error
253 stat = str_shex2bin(&shell_strbuf[stat], p, &a, &l);
254 if(stat == TERM_SRECEND) {
255 return bytes; // Return head
258 if(stat != TERM_OK) {
259 return 0xffffffff; // Some error
264 if(l >= len) break; // End addr
268 // Check return header
269 shell_strbuf[0] = '\0';
270 uart_term_getstr(shell_strbuf, 1000, 0); // Without Echo, timeout=100Sec.
271 stat = search_head_s(shell_strbuf);
272 if(stat < 0) return 0xffffffff;
273 stat = str_shex2bin(&shell_strbuf[stat], p, &a, &l);
274 if(stat != TERM_SRECEND) return 0xffffffff;
278 * Load from S record.
280 static void load_from_term(unsigned char *p)
282 unsigned char slen = shell_gettok(xarg1, p);
283 unsigned long addr = 0;
286 unsigned char fbuf[128];
290 if(shell_strcmp(xarg1, "INT") > 0) { // Internal EEPROM
291 uart_term_putstr("\nPls. start internal eeprom data...\n");
293 stat = wait_for_sheader(fbuf, 10);
295 if(stat != TERM_OK) goto _loaderr;
296 if(shell_strcmp(fbuf, "INT_EEPROM") < 0) goto _fileerr;
297 len = sizeof(__radioset_t);
300 l = load_hex_page(pv, &addr, len);
301 if(l == 0xffffffff) goto _loaderr;
302 if(addr >= 255) goto _loaderr; // Too large
304 shell_memcpy((unsigned char *)(&setup) , &tmparea, len);
305 setup_akc6955(); // DO!
306 } else if(shell_strcmp(xarg1, "FTBL") > 0) { // External EEPROM, Freq TBL
307 } else if(shell_strcmp(xarg1, "BAND") > 0) { // band
311 uart_term_putstr("\nOK.\n");
315 uart_term_putstr("\nERR: LOAD Error\n");
318 uart_term_putstr("\nERR: Address Error\n");
321 uart_term_putstr("\nERR: Not correct filename\n");
326 * Save ROM as S record.
328 static void save_to_term(unsigned char *p)
337 slen = shell_gettok(xarg1, p);
340 if(shell_strcmp(xarg1, "INT") > 0) { // Internal EEPROM
341 put_hexheader("INT_EEPROM");
342 len = sizeof(__radioset_t);
344 save_hex_page(pv, len, 0);
346 } else if(shell_strcmp(xarg1, "FTBL") > 0) { // External EEPROM, Freq TBL
347 put_hexheader("EXT_FREQTBL");
349 for(pp = 0; pp < USER_MEMORY_BANKS; pp++) {
350 if(load_frequencies(pp, 0xff) != 0) break; // Error
351 save_hex_page((unsigned char *)(&freqset_temp), sizeof(__freqset_t), base + (pp << 9)) ;
354 } else if(shell_strcmp(xarg1, "BAND") > 0) { // band
355 put_hexheader("EXT_BANDTBL");
361 * Open the Shell: Return cmdcode.
363 const char *cmdstr[SHELL_TOPCMDS] = {
382 static void cmd_printhelp(char cmdnum)
384 uart_term_putstr("\nSynopsys:\n");
387 uart_term_putstr("HELP [about-command]\n");
388 uart_term_putstr(" -- Online help.\n");
391 uart_term_putstr("FREQ frequency\n");
392 uart_term_putstr(" -- Set frequency.\n");
395 uart_term_putstr("\nSTAT\n");
396 uart_term_putstr(" -- Print status.\n");
399 uart_term_putstr("\nLOAD section [S]\n");
400 uart_term_putstr(" -- Load settings from terminal.\n");
401 uart_term_putstr(" Arg2: if 'S' then Save to internal EEPROM.\n");
404 uart_term_putstr("\nSAVE section\n");
405 uart_term_putstr(" -- Save settings to terminal.\n");
406 uart_term_putstr(" section :\n");
407 uart_term_putstr(" INT : Internal EEPROM\n");
408 uart_term_putstr(" FTBL : Freq table");
409 uart_term_putstr(" FREQ num : Save user freq #num.");
410 uart_term_putstr(" BAND : Save user band table.");
413 uart_term_putstr("\nFM\n");
414 uart_term_putstr(" -- Change to FM\n");
417 uart_term_putstr("\nAM\n");
418 uart_term_putstr(" -- Change to AM\n");
421 uart_term_putstr("\nPOFF [savef]\n");
422 uart_term_putstr(" -- Power OFF\n");
423 uart_term_putstr(" savef: if 'N' then power-off without saving.\n");
426 uart_term_putstr("\nPON\n");
427 uart_term_putstr(" -- Power ON\n");
430 uart_term_putstr("\nSEQ\n");
433 uart_term_putstr("\nLOG\n");
434 uart_term_putstr(" -- View LOG(Reserved command)\n");
437 uart_term_putstr("\nSCAN [direction]\n");
438 uart_term_putstr(" -- DO Scan\n");
439 uart_term_putstr(" direction : UP / DOWN\n");
442 uart_term_putstr("\nBAND [band-name]\n");
443 uart_term_putstr(" -- Set band\n");
446 uart_term_putstr("\nSET offset value\n");
447 uart_term_putstr(" -- Set system value.\n");
450 uart_term_putstr("\nPRINT offset\n");
451 uart_term_putstr(" -- PRINT system value.\n");
454 uart_term_putstr("\nEXIT\n");
455 uart_term_putstr(" -- EXIT shell\n");
462 static void cmd_help(char *p)
468 slen = shell_gettok(xarg1, p);
470 for(i = 0; i < SHELL_TOPCMDS; i++){
471 f = shell_strcmp(xarg1, cmdstr[i]);
478 uart_term_putstr("\nAvailable commands:\n");
479 for(i = 0; i < SHELL_TOPCMDS; i++){
480 uart_term_putstr(cmdstr[i]);
481 uart_term_putstr("\n");
483 uart_term_putstr("See Details : HELP [cmd].\n");
486 char term_shell(unsigned int timeout)
495 //cmd_shellstr[0] = '\0';
498 while((uart_getstat() & UART_WAKEUP) == 0) {
499 if(t == 0) return SHELL_CMD_NONE;
504 if((uart_getstat() & UART_WAKEUP) == 0) return SHELL_CMD_NONE;
507 uart_term_putstr("\nOpen I2C Radio v2.0\n(C)2013- Kyuma Ohta\n");
508 uart_term_putstr("\n\nWelcome to shell mode (^^).\nPress help to show usage.\n");
510 cmd_shellstr[0] = '\0';
511 uart_term_putstr("\n$>");
512 uart_term_getstr(cmd_shellstr, 100, 1); // With Echo, timeout=10Sec.
513 if(cmd_shellstr[0] == TERM_CHAR_TIMEOUT){
514 uart_term_putstr("\nTimeout.\n");
516 return SHELL_CMD_NONE; // TimeOut
522 ii = shell_gettok(pool, cmd_shellstr);
523 // if(ii >= 126) return SHELL_CMD_TOOLONG;
524 if(ii >= 126) continue; // Discard
525 for(t = 0; t < SHELL_TOPCMDS; t++){
526 i = shell_strcmp((char *)cmdstr[t], pool);
530 if(cmd_shellstr[ii] == ' ') {
531 //if(i <= 0) return SHELL_CMD_NOTFOUND;
532 ii = shell_gettok(pool, &cmd_shellstr[ii + 1]);
534 if(ii >= 126) t = 127; // Error
543 term_printstatus(pool);
546 load_from_term(pool);
558 uart_term_putstr("\nBye... (^^)/~~\n");
562 uart_term_putstr("\n?? CMD Error\n");