OSDN Git Service

233643eeec62a739e4e4a961c34e14c0d83e9d47
[openi2cradio/OpenI2CRadio.git] / uart_termio.c
1 /*
2  * OpenI2CRADIO
3  * EUSART Handler
4  * Copyright (C) 2013-06-20 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
43 #define TERM_NONSREC -1
44 #define TERM_STRERR -2
45 #define TERM_SUMERR -3
46
47 unsigned char uart_term_putstr(unsigned char *s)
48 {
49     unsigned char p = 0;
50     if((uart_getstat() & UART_WAKEUP) == 0) return 0; // Error
51     while(s[p] != 0x00)
52     {
53         uart_pushchar(s[p], 0x0000);
54         p++;
55         if(p >= 255) return 0; // Overlen
56     }
57     return 0xff;
58 }
59
60 void uart_term_getstr(unsigned char *s, unsigned char maxlen, unsigned char echo)
61 {
62     unsigned int i = 0;
63     unsigned char c = 0x00;
64     while(c != '\n'){
65         c = uart_pullchar();
66         if(c != 0x00) {
67             s[i] = c;
68             if(echo != 0) uart_pushchar(c, 0); // Echoback
69             i++;
70             if(i >= maxlen) break;
71         }
72     }
73     s[i] = '\0';
74 }
75
76 unsigned char c2h(unsigned char c)
77 {
78     if(c < '1') return 0xff;
79     if(c > 'F') return 0xff;
80     if(c <= '9') return c - '0';
81     if(c >= 'A') return c - 'A' + 10;
82     return 0xff;
83 }
84
85 char str_hex2bin(unsigned char *s, unsigned char *p, unsigned char len)
86 {
87     unsigned char sum = 0;
88     unsigned char pp;
89     unsigned char i;
90     unsigned char h, l;
91     unsigned char c;
92     // Get Header
93     if((s[0] != 'S') || (s[1] != '0')) {
94         // Header
95         return TERM_NONSREC;
96     }
97     i = 2;
98     for(pp = 0; pp <= len ; pp++){
99         h = c2h(s[i]);
100         if(h >= 0x10) return TERM_STRERR;
101         l = c2h(s[i + 1]);
102         if(l >= 0x10) return TERM_STRERR;
103         c =  (h << 8 ) + l;
104         sum += c;
105         p[pp] = c;
106         i += 2;
107     }
108     h = c2h(s[i]);
109     if(h >= 0x10) return TERM_STRERR;
110     l = c2h(s[i + 1]);
111     if(l >= 0x10) return TERM_STRERR;
112     c = (h << 8) + l;
113     if(c != sum) return TERM_SUMERR;
114     return 0;
115 }
116
117 unsigned char shell_strlen(char *s)
118 {
119     unsigned char i = 0;
120     while(i < 128) {
121         if(s[i] == '\0') break;
122         i++;
123     }
124     return i;
125 }
126
127 unsigned char shell_gettok(char *dst, char *src)
128 {
129     unsigned char i;
130     i = 0;
131     while(src[i] != '\0') {
132         if(src[i] == ' ') break;
133         if(src[i] == '\t') break;
134         dst[i] = src[i];
135         i++;
136         if(i > 128) break;
137     }
138     dst[i] = '\0';
139     return i;
140 }
141
142 int shell_strcmp(char *from, char *to)
143 {
144     unsigned char f, t;
145     unsigned char i;
146     int p = 0;
147     
148     f = strlen(from);
149     t = strlen(to);
150     i = f;
151     if(i > t) i = t;
152     while(i != 0){
153         if(from[p] != to[p]) return -1;
154         p++;
155         i--;
156     }
157     return p;
158 }
159
160 #define SHELL_CMD_NONE -1
161 #define SHELL_CMD_NOTFOUND -2
162 #define SHELL_CMD_ILLTOKEN -3
163 #define SHELL_CMD_TOOLONG -4
164 #define SHELL_CMD_OK 0
165
166 char shellstr[192];
167
168 #define SHELL_TOPCMDS 16
169 const char *cmdstr[SHELL_TOPCMDS] = {
170     "HELP",
171     "FREQ",
172     "STAT",
173     "LOAD",
174     "SAVE",
175     "FM",
176     "AM",
177     "POFF",
178     "PON",
179     "SEQ",
180     "LOG",
181     "SCAN",
182     "BAND",
183     "SET",
184     "PRINT",
185     "EXIT"
186 };
187
188 long term_getuint(char *pool)
189 {
190     long i = 0;
191     unsigned char p = 0;
192     unsigned char c;
193
194     do {
195         c = pool[p];
196         if((c < '0') || (c > '9')) return -1;
197         if(c == '\0') break;
198         i *= 10;
199         i = i + (c - '0');
200         p++;
201     } while(p <= 10);
202
203     return i;
204 }
205
206 void term_printnum(char *pool, unsigned int num)
207 {
208     char p[5];
209     unsigned char i, j, ii;
210
211     for(i = 0; i < 5; i++){
212         p[i] = num % 10;
213         num = num / 10;
214     }
215     i = 4;
216     do {
217         if(p[i] != 0) break;
218         i--;
219     } while(i != 0);
220     if(i == 0){
221         pool[0] = '0';
222         pool[1] = '\0';
223         return;
224     }
225     ii = i;
226     for(j = 0; j <= ii; j++) {
227         pool[j] = p[i] + '0';
228         i--;
229     }
230     pool[j] = '\0';
231     return;
232 }
233 /*
234  * Set Frequency: Arg1 = Freq.
235  */
236 static void term_freq(char *p)
237 {
238     unsigned int freq;
239     long l;
240     char pp[6];
241
242     l = term_getuint(p);
243     uart_term_putstr("\nSet Freq:");
244     if((l < 0) || (l > 30000)) {
245         uart_term_putstr("\nE:Illegal freq range.\n");
246         return;
247     }
248     freq = (unsigned int)l;
249     if(setup.fm == 0){
250         term_printnum(pp, setup.amfreq);
251         // AM
252         setup.amfreq = freq;
253     } else {
254         term_printnum(pp, setup.fmfreq);
255         // FM
256         setup.fmfreq = freq;
257     }
258     uart_term_putstr(pp);
259     uart_term_putstr("->");
260     term_printnum(pp, freq);
261     uart_term_putstr(pp);
262
263     akc6955_set_freq(freq);
264     uart_term_putstr("\ndone.\n");
265 }
266
267 /*
268  * Print status
269  * Arg = none.
270  */
271 static void term_printstatus(char *p)
272 {
273     char pp[6];
274     uart_term_putstr("\nStatus:\n");
275     if(setup.fm == 0){
276         uart_term_putstr("AM \nBand = ");
277         term_printnum(pp, setup.amband);
278         uart_term_putstr(pp);
279         uart_term_putstr("\nFreq = ");
280         term_printnum(pp, setup.amfreq);
281         uart_term_putstr(pp);
282         uart_term_putstr("\n");
283     } else {
284         uart_term_putstr("FM \nBand = ");
285         term_printnum(pp, setup.fmband);
286         uart_term_putstr(pp);
287         uart_term_putstr("\nFreq = ");
288         term_printnum(pp, setup.fmfreq);
289         uart_term_putstr(pp);
290         uart_term_putstr("\n");
291     }
292     
293     uart_term_putstr("\n");
294 }
295
296
297 /*
298  * Open the Shell: Return cmdcode.
299  */
300 char term_shell(unsigned int timeout)
301 {
302     unsigned int t;
303     unsigned char pp;
304     unsigned char c;
305     int i;
306     unsigned int ii;
307     char pool[128];
308
309     shellstr[0] = '\0';
310     if(timeout != 0) {
311         t = timeout;
312         while((uart_getstat() & UART_WAKEUP) == 0) {
313             if(t == 0) return SHELL_CMD_NONE;
314             t--;
315             idle_time_ms(1);
316         }
317     } else {
318         if((uart_getstat() & UART_WAKEUP) == 0) return SHELL_CMD_NONE;
319     }
320     uart_term_putstr("\n$>");
321     uart_term_getstr(shellstr, 128, 1); // With Echo
322
323     ii = shell_gettok(pool, shellstr);
324     if(ii >= 128) return SHELL_CMD_TOOLONG;
325
326     for(t = 0; t < SHELL_TOPCMDS; t++) 
327     {
328         i = shell_strcmp((char *)cmdstr[t], pool);
329         if(i > 0) break;
330     }
331     if(i <= 0) return SHELL_CMD_NOTFOUND;
332     ii = shell_gettok(pool, &shellstr[ii]);
333     switch(t){
334         case 1: // Freq
335             term_freq(pool);
336             break;
337         case 2:
338             term_printstatus(pool);
339             break;
340         default:
341             break;
342     }
343
344     return SHELL_CMD_OK;
345 }