summaryrefslogtreecommitdiff
path: root/srecord.c
diff options
context:
space:
mode:
Diffstat (limited to 'srecord.c')
-rw-r--r--srecord.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/srecord.c b/srecord.c
new file mode 100644
index 00000000..2fb41cf5
--- /dev/null
+++ b/srecord.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2005 Chris Kuethe <chris.kuethe@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef _SRECORD_
+#include "cskprog.h"
+
+/*
+ * http://www.amelek.gda.pl/avr/uisp/srecord.htm
+ * S0: Comments
+ * S3: Memory Loadable Data, 4byte address
+ * S5: Count of S1, S2 and S3 Records
+ * S7: starting execution address intrepreted as a 4byte address
+ */
+
+/*
+ * bin2srec: turn a chunk of binary into an srecord file
+ * offset: used to specify load address
+ * num: up to 16 bytes can be encoded at one time
+ * bytes are read from bbuf and a ready-to-go srecord is placed in sbuf
+ */
+int
+bin2srec(int offset, int num, unsigned char *bbuf, unsigned char *sbuf){
+ unsigned char abuf[34], sum;
+ int len;
+
+ if ((num < 1) || (num > 16))
+ return -1;
+
+ len = 4 + num + 1;
+ bzero(abuf, 34);
+ bzero(sbuf, 64);
+ hexdump(num, bbuf, abuf);
+ sum = sr_sum(len, offset, bbuf);
+ snprintf((char *)sbuf, 49, "S3%02X%08X%s%02X\r\n", len, offset, abuf, sum);
+ return 0;
+}
+
+int
+srec_hdr(unsigned char *sbuf){
+ /* dlgsp2.bin looks for this header */
+ unsigned char hdr[] = "S00600004844521B\r\n";
+ bzero(sbuf, 64);
+ snprintf((char *)sbuf, 19, "%s", hdr);
+ return 0;
+}
+
+int
+srec_fin(int num, unsigned char *sbuf){
+ unsigned char bbuf[4], sum;
+
+ bzero(bbuf, 4);
+ bzero(sbuf, 64);
+
+ bbuf[0] = (unsigned char)(num & 0xff);
+ bbuf[1] = (unsigned char)((num >> 8) & 0xff);
+ sum = sr_sum(3, 0, bbuf);
+ snprintf((char *)sbuf, 13, "S503%04X%02X\r\n", num, sum);
+ return 0;
+}
+
+
+void
+hexdump(int j, unsigned char *bbuf, unsigned char *abuf){
+ int i;
+
+ bzero(abuf, 34);
+ if (j > 32)
+ j = 32;
+
+ for(i = 0; i < j; i++){
+ abuf[i*2] = hc((bbuf[i] &0xf0) >> 4);
+ abuf[i*2+1] = hc(bbuf[i] &0x0f);
+ }
+}
+
+char
+hc(char x){
+ switch(x){
+ case 15:
+ case 14:
+ case 13:
+ case 12:
+ case 11:
+ case 10:
+ return ('A' + x - 10);
+ break;
+ case 9:
+ case 8:
+ case 7:
+ case 6:
+ case 5:
+ case 4:
+ case 3:
+ case 2:
+ case 1:
+ case 0:
+ return ('0' + x);
+ break;
+
+ default:
+ return '0';
+ break;
+ }
+}
+
+unsigned char
+sr_sum(int count, int addr, unsigned char *bbuf){
+ int i, j;
+ unsigned char k, sum = 0;
+
+ sum = (count & 0xff);
+ sum += ((addr & 0x000000ff));
+ sum += ((addr & 0x0000ff00) >> 8);
+ sum += ((addr & 0x00ff0000) >> 16);
+ sum += ((addr & 0xff000000) >> 24);
+ j = count - 5;
+ for(i = 0; i < j; i++){
+ k = bbuf[i];
+ sum += k;
+ }
+ return ~sum;
+}
+
+#else
+extern int errno;
+#endif