OSDN Git Service

[SCHEMATIC] Modify SW/MW/LW Preamp, insert galbanic-isolator replace of common-mode...
[openi2cradio/OpenI2CRadio.git] / shell_strutl.c
1 /*
2  * OpenI2CRADIO
3  * String utls
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 "shell_strutl.h"
38 #include "euart.h"
39 #include "uart_termio.h"
40
41 void bin2hex(char *s, unsigned char v)
42 {
43     unsigned char c;
44     c = v >> 4;
45     if(c > 9) {
46         c = c - 10 + 'A';
47     } else {
48         c = c + '0';
49     }
50     s[0] = c;
51
52     c = v & 0x0f;
53     if(c > 9) {
54         c = c - 10 + 'A';
55     } else {
56         c = c + '0';
57     }
58     s[1] = c;
59     s[2] = 0x00;
60 }
61 unsigned char c2h(unsigned char c)
62 {
63     if(c < '0') return 0xff;
64     if(c > 'F') return 0xff;
65     if(c <= '9') return c - '0';
66     if(c >= 'A') return c - 'A' + 10;
67     return 0xff;
68 }
69
70 unsigned char hex2byte(unsigned char *p)
71 {
72     unsigned char h, l;
73     h = c2h(p[0]);
74     l = c2h(p[1]);
75     if((h >= 0x10) || (l >= 0x10)) return 0;
76     return (h << 4) | l;
77 }
78
79 unsigned char check_eol(unsigned char *p)
80 {
81     unsigned char i;
82     unsigned char c;
83     for(i = 0; i < 2; i++){
84         c = p[i];
85         switch(c){
86             case '\0':
87             case '\n':
88             case '\r':
89                 return 0xff;
90                 break;
91             default:
92                 break;
93         }
94 //        if(c < '0') return 0xff;
95 //        if(c > 'F') return 0xff;
96     }
97     return 0;
98 }
99
100 unsigned char migrate_hex(unsigned char *p)
101 {
102     unsigned char i;
103     unsigned char c;
104     for(i = 0; i < 2; i++){
105         c = p[i];
106         if(c < '0') return 0;
107         if(c > 'F') return 0;
108         if((c > '9') && (c < 'A')) return 0;
109     }
110     return 0xff;
111 }
112
113 int  search_head_s(unsigned char *s)
114 {
115    int i;
116    for(i = 0; i < 127; i++) {
117       switch(s[i]) {
118        case 'S':
119          return i;
120          break;
121        case '\0':
122          return -1; // Not found 'S' until eoln.
123          break;
124        default:
125          break;
126       }
127    }
128    return -1; // Error
129 }
130
131 /*
132  * Saving or Loading use MOTOROLLA S FORMAT with 24bit address.
133  * See details:
134  * http://www.geocities.jp/chako_ratta/micon/s_format.html (written in Japanese)
135  * 
136  */
137 int str_shexheader(unsigned char *s, unsigned char *file)
138 {
139     unsigned char pp;
140     unsigned char sum;
141     unsigned char c;
142     unsigned char bytes;
143     unsigned int i;
144     unsigned char sbuf[4];
145 //    if(check_eol(s) != 0) return TERM_NULL;
146
147     if((s[0] != 'S') || (s[1] != '0')) return TERM_NONSREC;
148     uart_term_putstr("\nHEAD");
149     if(migrate_hex(&s[2])  == 0) return TERM_NONSREC;
150     bytes = hex2byte(&s[2]);
151     if(bytes <= 2) return TERM_SRECERR;
152     for(i = 4; i < 8; i++) if(s[i] != '0') return TERM_NONHDR;
153     sum = bytes;
154     bytes -= 3;
155     pp = 0;
156     while(bytes > 0) {
157         if(migrate_hex(&s[i]) == 0) return TERM_SRECERR;
158         c = hex2byte(&s[i]);
159         sum += c;
160         file[pp] = c;
161         i += 2;
162         pp++;
163         bytes--;
164     }
165     file[pp] = '\0';
166     if(migrate_hex(&s[i]) == 0) return TERM_SRECERR;
167     c = hex2byte(&s[i]);
168     sum = ~sum;
169     bin2hex(sbuf, sum);
170     uart_term_putstr(sbuf);
171
172     if(c != sum) return TERM_SUMERR;
173     uart_term_putstr("...OK\n");
174     return TERM_OK;
175 }
176
177
178 /*
179  * 'S1' record to hex
180  * Accept only S2 and S8.
181  */
182 int str_shex2bin(unsigned char *s, unsigned char *p, unsigned long *addr, unsigned char *len)
183 {
184     unsigned char sum = 0;
185     unsigned char pp;
186     unsigned int i;
187     unsigned char bytes;
188     unsigned char h, l, l2;
189     unsigned char c;
190     // Get Header
191     if(s[0] != 'S')  return TERM_NONSREC;
192     if(s[1] == '2') { //  Data core
193         for(i = 2; i < 10; i += 2) if(migrate_hex(&s[i]) == 0) return TERM_SRECERR;
194         bytes = hex2byte(&s[2]);
195         if(bytes <= 3) return TERM_SRECERR;
196         sum = bytes;
197         h = hex2byte(&s[4]);
198         l  = hex2byte(&s[6]);
199         l2  = hex2byte(&s[8]);
200         *addr = (h * 65536) | (l << 8) | l2;
201         sum = sum + h + l + l2;
202         bytes -= 3;
203         *len = bytes - 1;
204         pp = 0;
205         i = 10;
206         while(bytes > 1) {
207             if(migrate_hex(&s[i]) == 0) return TERM_SRECERR;
208             c = hex2byte(&s[i]);
209             sum += c;
210             p[pp] = c;
211             i += 2;
212             pp++;
213             bytes--;
214         }
215         if(migrate_hex(&s[i]) == 0) return TERM_SUMERR;
216         c = hex2byte(&s[i]);
217         sum = ~sum;
218         if(c != sum) return TERM_SUMERR;
219         /*
220          * OK!
221          */
222     } else if(s[1] == '8') {
223         if((s[2] != '0') || (s[3] != '4')) return TERM_SRECERR;
224         uart_term_putstr("TAIL");
225         for(i = 4; i < 10; i += 2)  if(migrate_hex(&s[i]) == 0) return TERM_SRECERR;
226         sum = 4;
227         h = hex2byte(&s[4]);
228         l = hex2byte(&s[6]);
229         l2 = hex2byte(&s[8]);
230         c = hex2byte(&s[10]);
231 //        *addr = (h * 65536) | (l << 8) | l2;
232         *len = 0;
233         sum = ~(sum + h + l + l2);
234         if(c != sum) return TERM_SUMERR;
235         uart_term_putstr(" OK.");
236         return TERM_SRECEND;
237     } else {
238         return TERM_UNDSREC;
239     }
240     return TERM_OK;
241 }
242
243
244 /*
245  * Set "S1" Record
246  */
247 unsigned char str_bin2hex(unsigned char *s, unsigned char *p, unsigned long addr, unsigned char len)
248 {
249     unsigned int pp;
250     unsigned char pv;
251     unsigned char sum;
252     unsigned char i;
253     unsigned char c;
254     s[0] = 'S';
255     s[1] = '2';
256     if(len > 254) len = 254;
257     i = len + 4; //HEX
258     sum = i;
259     bin2hex(&s[2], i);
260
261     c = (addr >> 16) & 255;
262     sum += c;
263     bin2hex(&s[4], c);
264
265     c = (addr >> 8) & 255;
266     sum += c;
267     bin2hex(&s[6], c);
268
269     c = addr  & 255;
270     sum += c;
271     bin2hex(&s[8], c);
272
273     pp = 10;
274     for(pv = 0; pv < len ; pv++){
275         c = p[pv];
276         sum += c;
277         bin2hex(&s[pp], c);
278         pp += 2;
279     }
280     sum = ~sum;
281     bin2hex(&s[pp], sum);
282     pp += 2;
283     s[pp] = '\n';
284     s[pp + 1] = '\0';
285     return len;
286 }
287
288 unsigned char str_put_shexheader(unsigned char *s, char *filename)
289 {
290     unsigned int i;
291     unsigned char pp;
292     unsigned char len;
293     unsigned char sum;
294     s[0] = 'S';
295     s[1] = '0';
296     len = shell_strlen(filename);
297     if(len > 252) len = 252;
298     sum = len + 3;
299     bin2hex(&s[2], len + 3);
300
301     for(i = 4; i < 8; i++) s[i] = '0';
302     i = 8;
303     pp = 0;
304     while(pp != len){
305         bin2hex(&s[i], filename[pp]);
306         sum += filename[pp];
307         i += 2;
308         pp++;
309     }
310     sum = ~sum;
311     bin2hex(&s[i], sum);
312     s[i + 2] = '\n';
313     s[i + 3] = '\0';
314     return len;
315 }
316
317 unsigned char str_put_shexfooter(unsigned char *s)
318 {
319     unsigned int i;
320     unsigned char pp;
321     unsigned char sum;
322     s[0] = 'S';
323     s[1] = '8';
324     s[2] = '0';
325     s[3] = '4';
326     sum = 4;
327     for(pp = 4; pp < 10; pp++) s[pp] = '0';
328     sum = ~sum;
329     bin2hex(&s[pp], sum);
330
331     s[pp + 2] = '\n';
332     s[pp + 3] = '\0';
333     return 0;
334 }
335
336
337 unsigned char shell_strlen(char *s)
338 {
339     unsigned char i = 0;
340     while(i < 255) {
341         if(s[i] == '\0') break;
342         i++;
343     }
344     return i;
345 }
346
347 unsigned char shell_gettok(char *dst, char *src)
348 {
349     unsigned char i;
350     char c;
351     i = 0;
352     while(1) {
353         c = src[i];
354         if(c == '\0') break;
355         if(c == ' ') break;
356         if(c == '\t') break;
357         if(c == '\n') break;
358         dst[i] = c;
359         i++;
360         if(i > 126) break;
361     }
362     dst[i] = '\0';
363     return i;
364 }
365
366 int shell_strcmp(char *from, char *to)
367 {
368     unsigned char f, t;
369     unsigned char i;
370     int p = 0;
371
372     while(from[p] != '\0'){
373         if(from[p] != to[p]) return -1;
374         p++;
375     }
376     return p;
377 }
378
379 long term_getuint(char *pool)
380 {
381     long i = 0;
382     unsigned char p = 0;
383     unsigned char c;
384
385     do {
386         c = pool[p];
387         if(c == '\0') break;
388         if(c == '\n') break;
389         if(c == '\t') break;
390         if(c == ' ') break;
391         if((c < '0') || (c > '9')) return -1;
392         i *= 10;
393         i = i + (c - '0');
394         p++;
395     } while(p <= 10);
396
397     return i;
398 }
399
400 void term_printnum(char *pool, unsigned int num)
401 {
402     char p[5];
403     int j;
404     int i, ii;
405
406     for(i = 0; i < 5; i++){
407         p[i] = num % 10;
408         num = num / 10;
409     }
410     i = 4;
411     do {
412         if(p[i] != 0) break;
413         i--;
414     } while(i >= 0);
415    
416     if(i < 0){
417         pool[0] = '0';
418         pool[1] = '\0';
419         return;
420     }
421     ii = i;
422     for(j = 0; j <= ii; j++) {
423         pool[j] = p[i] + '0';
424         i--;
425     }
426     pool[j] = '\0';
427     return;
428 }