OSDN Git Service

[SHELL] POFF: Accept 'Y'.
[openi2cradio/OpenI2CRadio.git] / term_shell.c
1 /*
2  * OpenI2CRADIO
3  * Shell Handler
4  * Copyright (C) 2013-11-07 K.Ohta <whatisthis.sowhat ai gmail.com>
5  *
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.
14  *
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,
18  *  MA 02110-1301, USA.
19  *
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.
26  */
27
28 #if defined(__SDCC)
29 #include <sdcc-lib.h>
30 #include <pic18fregs.h> /* ONLY FOR PIC18x */
31 #include <delay.h>
32 #else
33 #include <xc.h>
34 #endif
35 #include <signal.h>
36
37 #include "iodef.h"
38 #include "idle.h"
39 #include "ioports.h"
40 #include "euart.h"
41 #include "menu.h"
42 #include "power.h"
43 #include "shell_strutl.h"
44 #include "uart_termio.h"
45 #include "term_shell.h"
46
47
48 char cmd_shellstr[255];
49 static char shell_strbuf[255];
50 static char xarg1[128];
51 static char xarg2[128];
52 static char xarg3[128];
53
54 #define SHELL_CMD_NONE -1
55 #define SHELL_CMD_NOTFOUND -2
56 #define SHELL_CMD_ILLTOKEN -3
57 #define SHELL_CMD_TOOLONG -4
58 #define SHELL_CMD_OK 0
59
60 #define SHELL_TOPCMDS 16
61
62 static void shell_printnum(unsigned int v)
63 {
64     char s[32];
65     s[0] = '\0';
66     term_printnum(s, v);
67     uart_term_putstr(s);
68 }
69 /*
70  * Set Frequency: Arg1 = Freq.
71  */
72 static void term_freq(char *p)
73 {
74     unsigned int freq;
75     long l;
76
77     l = term_getuint(p);
78     uart_term_putstr("\nSet Freq:");
79     if((l < 0) || (l > 30000)) {
80         uart_term_putstr("\nE:Illegal freq range.\n");
81         return;
82     }
83     freq = (unsigned int)l;
84     if(setup.fm == 0){
85         shell_printnum(setup.amfreq);
86         // AM
87         setup.amfreq = freq;
88     } else {
89         shell_printnum(setup.fmfreq);
90         // FM
91         setup.fmfreq = freq;
92     }
93     uart_term_putstr("->");
94     shell_printnum(freq);
95
96     akc6955_set_freq(freq);
97     uart_term_putstr("\ndone.\n");
98 }
99
100 /*
101  * Print status
102  * Arg = none.
103  */
104 static void term_printstatus(char *p)
105 {
106     uart_term_putstr("\nStatus:\n");
107     if(setup.fm == 0){
108         uart_term_putstr("AM \nBand = ");
109         shell_printnum(setup.amband);
110         uart_term_putstr("\nFreq = ");
111         shell_printnum(setup.amfreq);
112         uart_term_putstr("\n");
113     } else {
114         uart_term_putstr("FM \nBand = ");
115         shell_printnum(setup.fmband);
116         uart_term_putstr("\nFreq = ");
117         shell_printnum(setup.fmfreq);
118         uart_term_putstr("\n");
119     }
120
121     uart_term_putstr("\n");
122 }
123
124 static void term_help(char *p)
125 {
126
127 }
128
129 /*
130  * Poweroff.
131  * Arg1: 'N'/'n' : not save.
132  */
133 static void term_poweroff(char *p)
134 {
135     unsigned char s[16];
136     unsigned char slen;
137     unsigned char savef = 0xff;
138     xarg1[0] = '\0';
139     slen = shell_gettok(xarg1, p);
140     if(shell_strlen(xarg1) != 0) {
141         if((xarg1[0] == 'N') || (xarg1[0] == 'n')) savef = 0;
142     }
143     uart_term_putstr("\n*** Power OFF ***\nOK? (Yes = Y)");
144     uart_term_getstr(s, 15, 0xff);
145     if(shell_strlen(s) >= 3) return;
146     if(s[0] == 'Y') shutdown(savef);
147 }
148
149
150 static void term_poweron(char *p)
151 {
152 }
153
154 static unsigned char put_hexline(unsigned char *dat, unsigned int addr, unsigned char len)
155 {
156     unsigned char l;
157     l = str_bin2hex((unsigned char *)shell_strbuf, dat, addr, len);
158     uart_term_putstr(shell_strbuf);
159     return l;
160 }
161
162 static void put_hexheader(char *fname)
163 {
164     uart_term_putstr("Start of save value.\n--- BEGIN ---\n");
165     str_put_shexheader(shell_strbuf, fname);
166     uart_term_putstr(shell_strbuf);
167 }
168
169
170 static void put_hexfooter(void)
171 {
172     str_put_shexfooter(shell_strbuf);
173     uart_term_putstr(shell_strbuf);
174     uart_term_putstr("\n--- END---\n");
175 }
176
177 /*
178  * Save ROM as S record.
179  */
180 static void save_to_term(unsigned char *p)
181 {
182     unsigned char slen;
183     unsigned int len;
184     unsigned int pp;
185     long i;
186     int addr;
187     unsigned char *pv;
188
189     slen = shell_gettok(xarg1, p);
190     addr = 0;
191
192     if(shell_strcmp(xarg1, "INT") == 0) { // Internal EEPROM
193         put_hexheader("INT_EEPROM");
194         len = sizeof(__radioset_t);
195         pv = &setup;
196         for(pp = 0; pp < sizeof(__radioset_t); pp += 16){
197             if(len > 16) {
198                 put_hexline(&pv[pp], pp, 16);
199                 len -= 16;
200             } else {
201                 put_hexline(&pv[pp], pp, len);
202             }
203         }
204         put_hexfooter();
205     } else if(shell_strcmp(xarg1, "FTBL") == 0) { // External EEPROM, Freq TBL
206         put_hexheader("EXT_FREQTBL");
207         put_hexfooter();
208     } else if(shell_strcmp(xarg1, "BAND") == 0) { // band
209         put_hexheader("EXT_BANDTBL");
210         put_hexfooter();
211     }
212 }
213
214 /*
215  * Open the Shell: Return cmdcode.
216  */
217 const char *cmdstr[SHELL_TOPCMDS] = {
218     "HELP",
219     "FREQ",
220     "STAT",
221     "LOAD",
222     "SAVE",
223     "FM",
224     "AM",
225     "POFF",
226     "PON",
227     "SEQ",
228     "LOG",
229     "SCAN",
230     "BAND",
231     "SET",
232     "PRINT",
233     "EXIT"
234 };
235
236 static void cmd_printhelp(char cmdnum)
237 {
238     uart_term_putstr("\nSynopsys:\n");
239     switch(cmdnum){
240         case 0:
241             uart_term_putstr("HELP [about-command]\n");
242             uart_term_putstr(" -- Online help.\n");
243             break;
244         case 1:
245             uart_term_putstr("FREQ frequency\n");
246             uart_term_putstr(" -- Set frequency.\n");
247             break;
248         case 2:
249             uart_term_putstr("\nSTAT\n");
250             uart_term_putstr(" -- Print status.\n");
251             break;
252         case 3:
253             uart_term_putstr("\nLOAD direction [S]\n");
254             uart_term_putstr(" -- Load settings from terminal.\n");
255             uart_term_putstr("      Arg2: if 'S' then Save to internal EEPROM.\n");
256            break;
257         case 4:
258             uart_term_putstr("\nSAVE section\n");
259             uart_term_putstr(" -- Save settings  to terminal.\n");
260             break;
261         case 5:
262             uart_term_putstr("\nFM\n");
263             uart_term_putstr(" -- Change to FM\n");
264             break;
265         case 6:
266             uart_term_putstr("\nAM\n");
267             uart_term_putstr(" -- Change to AM\n");
268             break;
269         case 7:
270             uart_term_putstr("\nPOFF [savef]\n");
271             uart_term_putstr(" -- Power OFF\n");
272             uart_term_putstr("      savef: if 'N' then power-off without saving.\n");
273             break;
274         case 8:
275             uart_term_putstr("\nPON\n");
276             uart_term_putstr(" -- Power ON\n");
277             break;
278         case 9:
279             uart_term_putstr("\nSEQ\n");
280             break;
281         case 10:
282             uart_term_putstr("\nLOG\n");
283             uart_term_putstr(" -- View LOG(Reserved command)\n");
284             break;
285         case 11:
286             uart_term_putstr("\nSCAN [direction]\n");
287             uart_term_putstr(" -- DO Scan\n");
288             uart_term_putstr("    direction : UP / DOWN\n");
289             break;
290         case 12:
291             uart_term_putstr("\nBAND [band-name]\n");
292             uart_term_putstr(" -- Set band\n");
293             break;
294         case 13:
295             uart_term_putstr("\nSET offset value\n");
296             uart_term_putstr(" -- Set system value.\n");
297             break;
298         case 14:
299             uart_term_putstr("\nPRINT offset\n");
300             uart_term_putstr(" -- PRINT system value.\n");
301             break;
302         case 15:
303             uart_term_putstr("\nEXIT\n");
304             uart_term_putstr(" -- EXIT shell\n");
305             break;
306         default:
307             break;
308     }
309 }
310
311 static void cmd_help(char *p)
312 {
313     unsigned char i;
314     unsigned char slen;
315     int f;
316
317     slen = shell_gettok(p, xarg1);
318     if(slen != 0) {
319         for(i = 0; i < SHELL_TOPCMDS; i++){
320             f = shell_strcmp(xarg1, cmdstr[i]);
321             if(f > 0) {
322                 cmd_printhelp(f);
323                 return;
324             }
325         }
326     }
327    uart_term_putstr("\nAvailable commands:\n");
328    for(i = 0; i < SHELL_TOPCMDS; i++){
329        uart_term_putstr(cmdstr[i]);
330        uart_term_putstr("\n");
331     }
332     uart_term_putstr("See Details : HELP [cmd].\n");
333 }
334
335 char term_shell(unsigned int timeout)
336 {
337     unsigned int t;
338     unsigned char pp;
339     unsigned char c;
340     int i;
341     unsigned int ii;
342     char pool[128];
343
344     cmd_shellstr[0] = '\0';
345     if(timeout != 0) {
346         t = timeout;
347         while((uart_getstat() & UART_WAKEUP) == 0) {
348             if(t == 0) return SHELL_CMD_NONE;
349             t--;
350             idle_time_ms(1);
351         }
352     } else {
353         if((uart_getstat() & UART_WAKEUP) == 0) return SHELL_CMD_NONE;
354     }
355
356     uart_term_putstr("\nOpen I2C Radio v2.0\n(C)2013- Kyuma Ohta\n");
357     uart_term_putstr("\n\nWelcome to shell mode (^^).\nPress help to show usage.\n");
358     do {
359         uart_term_putstr("\n$>");
360         uart_term_getstr(cmd_shellstr, 128, 1); // With Echo
361         ClrWdt();
362         ii = shell_gettok(pool, cmd_shellstr);
363 //        if(ii >= 128) return SHELL_CMD_TOOLONG;
364         if(ii >= 128) continue; // Discard
365
366         for(t = 0; t < SHELL_TOPCMDS; t++){
367             i = shell_strcmp((char *)cmdstr[t], pool);
368             if(i > 0) break;
369         }
370         if(cmd_shellstr[ii] == ' ') {
371            //if(i <= 0) return SHELL_CMD_NOTFOUND;
372            ii = shell_gettok(pool, &cmd_shellstr[ii + 1]);
373         }
374        
375         switch(t){
376             case 0:
377                 cmd_help(pool);
378                 break;
379             case 1: // Freq
380                 term_freq(pool);
381                 break;
382             case 2:
383                 term_printstatus(pool);
384                 break;
385             case 4:
386                 save_to_term(pool);
387                 break;
388             case 7:
389                 term_poweroff(pool);
390                 break;
391             case 8:
392                 term_poweron(pool);
393                 break;
394             case 15: // Exit
395                 uart_term_putstr("\nBye... (^^)/~~\n");
396                 uart_init();
397                 return SHELL_CMD_OK;
398                 break;
399             default:
400                 uart_term_putstr("\n?? CMD Error\n");
401                 break;
402         }
403
404     } while(1);
405     return SHELL_CMD_OK;
406 }