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  *  Copyright (C) 1998, 1999, Kekoa Proudfoot.  All Rights Reserved.
00003  *
00004  *  License to copy, use, and modify this software is granted provided that
00005  *  this notice is retained in any copies of any part of this software.
00006  *
00007  *  The author makes no guarantee that this software will compile or
00008  *  function correctly.  Also, if you use this software, you do so at your
00009  *  own risk.
00010  *
00011  *  Kekoa Proudfoot
00012  *  kekoa@graphics.stanford.edu
00013  *  10/3/98
00014  */
00015 /* S-record routines */
00016 
00017 /* srec.c */
00018 
00019 #include <stdio.h>
00020 
00021 #include "srec.h"
00022 
00023 static signed char ctab[256] = {
00024     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00025     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00026     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00027      0, 1, 2, 3, 4, 5, 6, 7,   8, 9,-1,-1,-1,-1,-1,-1,
00028      0,10,11,12,13,14,15,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00029     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00030      0,10,11,12,13,14,15,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00031     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00032     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
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     -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00037     -1,-1,-1,-1,-1,-1,-1,-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,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,
00040 };
00041 
00042 static int ltab[10] = {4,4,6,8,0,4,0,8,6,4};
00043 
00044 #define C1(l,p)  (ctab[l[p]])
00045 #define C2(l,p)  ((C1(l,p)<<4)|C1(l,p+1))
00046 
00047 int
00048 srec_decode(srec_t *srec, char *_line)
00049 {
00050     int len, pos = 0, count, alen, sum = 0;
00051     unsigned char *line = (unsigned char *)_line;
00052 
00053     if (!srec || !line)
00054         return S_NULL;
00055 
00056     for (len = 0; line[len]; len++)
00057         if (line[len] == '\n' || line[len] == '\r')
00058             break;
00059 
00060     if (len < 4)
00061         return S_INVALID_HDR;
00062 
00063     if (line[0] != 'S')
00064         return S_INVALID_HDR;
00065 
00066     for (pos = 1; pos < len; pos++) {
00067         if (C1(line, pos) < 0)
00068             return S_INVALID_CHAR;
00069     }
00070 
00071     srec->type = C1(line, 1);
00072     count = C2(line, 2);
00073 
00074     if (srec->type > 9)
00075         return S_INVALID_TYPE;
00076     alen = ltab[srec->type];
00077     if (alen == 0)
00078         return S_INVALID_TYPE;
00079     if (len < alen + 6 || len < count * 2 + 4)
00080         return S_TOO_SHORT;
00081     if (count > 37 || len > count * 2 + 4)
00082         return S_TOO_LONG;
00083 
00084     sum += count;
00085 
00086     len -= 4;
00087     line += 4;
00088 
00089     srec->addr = 0;
00090     for (pos = 0; pos < alen; pos += 2) {
00091         unsigned char value = C2(line, pos);
00092         srec->addr = (srec->addr << 8) | value;
00093         sum += value;
00094     }
00095 
00096     len -= alen;
00097     line += alen;
00098 
00099     for (pos = 0; pos < len - 2; pos += 2) {
00100         unsigned char value = C2(line, pos);
00101         srec->data[pos / 2] = value;
00102         sum += value;
00103     }
00104 
00105     srec->count = count - (alen / 2) - 1;
00106 
00107     sum += C2(line, pos);
00108 
00109     if ((sum & 0xff) != 0xff)
00110         return S_INVALID_CKSUM;
00111 
00112     return S_OK;
00113 }
00114 
00115 int
00116 srec_encode(srec_t *srec, char *line)
00117 {
00118     int alen, count, sum = 0, pos;
00119 
00120     if (srec->type > 9)
00121         return S_INVALID_TYPE;
00122     alen = ltab[srec->type];
00123     if (alen == 0)
00124         return S_INVALID_TYPE;
00125 
00126     line += sprintf(line, "S%d", srec->type);
00127 
00128     if (srec->count > 32)
00129         return S_TOO_LONG; 
00130     count = srec->count + (alen / 2) + 1;
00131     line += sprintf(line, "%02X", count);
00132     sum += count;
00133 
00134     while (alen) {
00135         int value;
00136         alen -= 2;
00137         value = (srec->addr >> (alen * 4)) & 0xff;
00138         line += sprintf(line, "%02X", value);
00139         sum += value;
00140     }
00141 
00142     for (pos = 0; pos < srec->count; pos++) {
00143         line += sprintf(line, "%02X", srec->data[pos]);
00144         sum += srec->data[pos];
00145     }
00146 
00147     sprintf(line, "%02X\n", (~sum) & 0xff);
00148 
00149     return S_OK;
00150 }

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