OSDN Git Service

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