Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

srec.c

Go to the documentation of this file.
00001 /*
00002  *  srec.c
00003  *
00004  *  S-record routines.
00005  *
00006  *  The contents of this file are subject to the Mozilla Public License
00007  *  Version 1.0 (the "License"); you may not use this file except in
00008  *  compliance with the License. You may obtain a copy of the License at
00009  *  http://www.mozilla.org/MPL/
00010  *
00011  *  Software distributed under the License is distributed on an "AS IS"
00012  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00013  *  License for the specific language governing rights and limitations
00014  *  under the License.
00015  *
00016  *  The Original Code is Firmdl code, released October 3, 1998.
00017  *
00018  *  The Initial Developer of the Original Code is Kekoa Proudfoot.
00019  *  Portions created by Kekoa Proudfoot are Copyright (C) 1998, 1999
00020  *  Kekoa Proudfoot. All Rights Reserved.
00021  *
00022  *  Contributor(s): Kekoa Proudfoot <kekoa@graphics.stanford.edu>
00023  */
00024 
00025 #include <stdio.h>
00026 #include <ctype.h>
00027 
00028 #include "srec.h"
00029 
00030 /* Tables */
00031 
00032 static signed char ctab[256] = {
00033     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00034     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00035     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00036      0, 1, 2, 3, 4, 5, 6, 7,   8, 9,-1,-1,-1,-1,-1,-1,
00037     -1,10,11,12,13,14,15,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00038     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00039     -1,10,11,12,13,14,15,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00040     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00041     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00042     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00043     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00044     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00045     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00046     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00047     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00048     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00049 };
00050 
00051 static int ltab[10] = {4,4,6,8,0,4,0,8,6,4};
00052 
00053 /* Macros */
00054 
00055 #define C1(l,p)    (ctab[l[p]])
00056 #define C2(l,p)    ((C1(l,p)<<4)|C1(l,p+1))
00057 
00058 /* Static functions */
00059 
00060 int
00061 srec_decode(srec_t *srec, char *_line)
00062 {
00063     int len, pos = 0, count, alen, sum = 0;
00064     unsigned char *line = (unsigned char *)_line;
00065 
00066     if (!srec || !line)
00067         return SREC_NULL;
00068 
00069     for (len = 0; line[len]; len++)
00070         if (line[len] == '\n' || line[len] == '\r')
00071             break;
00072 
00073     if (len < 4)
00074         return SREC_INVALID_HDR;
00075 
00076     if (line[0] != 'S')
00077         return SREC_INVALID_HDR;
00078 
00079     for (pos = 1; pos < len; pos++) {
00080         if (C1(line, pos) < 0)
00081             return SREC_INVALID_CHAR;
00082     }
00083 
00084     srec->type = C1(line, 1);
00085     count = C2(line, 2);
00086 
00087     if (srec->type > 9)
00088         return SREC_INVALID_TYPE;
00089     alen = ltab[srec->type];
00090     if (alen == 0)
00091         return SREC_INVALID_TYPE;
00092     if (len < alen + 6)
00093         return SREC_TOO_SHORT;
00094     if (count > alen + SREC_DATA_SIZE + 2)
00095         return SREC_TOO_LONG;
00096     if (len != count * 2 + 4)
00097         return SREC_INVALID_LEN;
00098 
00099     sum += count;
00100 
00101     len -= 4;
00102     line += 4;
00103 
00104     srec->addr = 0;
00105     for (pos = 0; pos < alen; pos += 2) {
00106         unsigned char value = C2(line, pos);
00107         srec->addr = (srec->addr << 8) | value;
00108         sum += value;
00109     }
00110 
00111     len -= alen;
00112     line += alen;
00113 
00114     for (pos = 0; pos < len - 2; pos += 2) {
00115         unsigned char value = C2(line, pos);
00116         srec->data[pos / 2] = value;
00117         sum += value;
00118     }
00119 
00120     srec->count = count - (alen / 2) - 1;
00121 
00122     sum += C2(line, pos);
00123 
00124     if ((sum & 0xff) != 0xff)
00125         return SREC_INVALID_CKSUM;
00126 
00127     return SREC_OK;
00128 }
00129 
00130 int
00131 srec_encode(srec_t *srec, char *line)
00132 {
00133     int alen, count, sum = 0, pos;
00134 
00135     if (srec->type > 9)
00136         return SREC_INVALID_TYPE;
00137     alen = ltab[srec->type];
00138     if (alen == 0)
00139         return SREC_INVALID_TYPE;
00140 
00141     line += sprintf(line, "S%d", srec->type);
00142 
00143     if (srec->count > 32)
00144         return SREC_TOO_LONG;
00145     count = srec->count + (alen / 2) + 1;
00146     line += sprintf(line, "%02X", count);
00147     sum += count;
00148 
00149     while (alen) {
00150         int value;
00151         alen -= 2;
00152         value = (srec->addr >> (alen * 4)) & 0xff;
00153         line += sprintf(line, "%02X", value);
00154         sum += value;
00155     }
00156 
00157     for (pos = 0; pos < srec->count; pos++) {
00158         line += sprintf(line, "%02X", srec->data[pos]);
00159         sum += srec->data[pos];
00160     }
00161 
00162     sprintf(line, "%02X\n", (~sum) & 0xff);
00163 
00164     return SREC_OK;
00165 }
00166 
00167 char *
00168 srec_strerror (int error)
00169 {
00170     switch (error) {
00171     case SREC_OK: return "no error";
00172     case SREC_NULL: return "null string error";
00173     case SREC_INVALID_HDR: return "invalid header";
00174     case SREC_INVALID_CHAR: return "invalid character";
00175     case SREC_TOO_SHORT: return "line too short";
00176     case SREC_TOO_LONG: return "line too long";
00177     case SREC_INVALID_LEN: return "length error";
00178     case SREC_INVALID_CKSUM: return "checksum error";
00179     default: return "unknown error";
00180     }
00181 }

Generated on Fri Feb 25 08:02:40 2005 for brickos by  doxygen 1.3.9.1