diff options
Diffstat (limited to 'srecord.c')
-rw-r--r-- | srecord.c | 139 |
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 |