view helpers/srec4ram.c @ 75:8697f358f505

backlight rework: Condat light driver accepts levels The present change is another intermediate step on the path toward new FreeCalypso backlight handling. At this intermediate step the Condat light driver accepts 0-255 backlight levels driven by MFW, and puts them out on PWL on Luna development boards. At the same time on C139 it is now possible to turn on the display backlight with or without the keypad bl - the lsb of the 0-255 backlight level controls the keypad bl. MFW presently drives only 0 and 255 backlight levels, thus there is no visible behavioral change yet - but the plan for subsequent stages of this backlight rework is to add a dimmed backlight state (no keypad bl on C139) during active calls.
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 24 Oct 2020 20:44:04 +0000
parents 1fb47f5b597a
children
line wrap: on
line source

/*
 * This ad hoc utility is used as part of building RAM-loadable
 * firmware images for targets with large RAM.  It reads the ramimage.m0
 * S-record file produced by TI's hex470 post-linker and re-emits it
 * in another SREC form that is suitable for feeding to fc-xram.
 */

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

char *infname;
FILE *inf, *outf;
char srecbuf[80];
u_char srecbin[40], srecout[40];
int lineno;

decode_hex_byte(s)
	char *s;
{
	register int u, l;

	if (!isxdigit(s[0]) || !isxdigit(s[1]))
		return(-1);
	if (isdigit(s[0]))
		u = s[0] - '0';
	else if (isupper(s[0]))
		u = s[0] - 'A' + 10;
	else
		u = s[0] - 'a' + 10;
	if (isdigit(s[1]))
		l = s[1] - '0';
	else if (isupper(s[1]))
		l = s[1] - 'A' + 10;
	else
		l = s[1] - 'a' + 10;
	return((u << 4) | l);
}

srec2bin()
{
	register int i, l, b;

	l = decode_hex_byte(srecbuf + 2);
	if (l < 1) {
		fprintf(stderr, "%s line %d: S-record length octet is bad\n",
			infname, lineno);
		exit(1);
	}
	srecbin[0] = l;
	if (l > 35) {
		fprintf(stderr,
			"%s line %d: S-record is longer than expected\n",
			infname, lineno);
		exit(1);
	}
	for (i = 1; i <= l; i++) {
		b = decode_hex_byte(srecbuf + i*2 + 2);
		if (b < 0) {
			fprintf(stderr, "%s line %d: hex decode error\n",
				infname, lineno);
			exit(1);
		}
		srecbin[i] = b;
	}
	return(0);
}

srec_cksum()
{
	u_char accum;
	register int i, len;

	len = srecbin[0] + 1;
	accum = 0;
	for (i = 0; i < len; i++)
		accum += srecbin[i];
	if (accum != 0xFF) {
		fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno);
		exit(1);
	}
	return(0);
}

emit_output_srec(type, buf)
	u_char *buf;
{
	int i;
	u_char accum = 0;

	putc('S', outf);
	putc(type, outf);
	for (i = 0; i < buf[0]; i++) {
		fprintf(outf, "%02X", buf[i]);
		accum += buf[i];
	}
	fprintf(outf, "%02X\n", ~accum & 0xFF);
	return 0;
}

transform_s3()
{
	int datalen;
	u_char *sp, *dp;
	int i;

	if (srecbin[0] < 6) {
		fprintf(stderr,
			"%s line %d: S3 record is too short\n",
			infname, lineno);
		exit(1);
	}
	datalen = srecbin[0] - 5;
	if (datalen & 1) {
		fprintf(stderr, "%s line %d: odd data length\n",
			infname, lineno);
		exit(1);
	}
	sp = srecbin;
	dp = srecout;
	for (i = 0; i < 5; i++)
		*dp++ = *sp++;
	for (i = 0; i < datalen; i += 2) {
		dp[0] = sp[1];
		dp[1] = sp[0];
		sp += 2;
		dp += 2;
	}
	return 0;
}

generate_vectors_record()
{
	u_char *dp;
	u_long addr;
	int i;

	srecout[0] = 28 + 5;
	srecout[1] = 0x00;
	srecout[2] = 0x80;
	srecout[3] = 0x00;
	srecout[4] = 0x00;
	dp = srecout + 5;
	for (i = 0; i < 7; i++) {
		addr = 0x01004000 + i * 4;
		*dp++ = addr;
		*dp++ = addr >> 8;
		*dp++ = addr >> 16;
		*dp++ = addr >> 24;
	}
	emit_output_srec('3', srecout);
	return 0;
}

generate_jump_record()
{
	srecout[0] = 5;
	srecout[1] = 0x01;
	srecout[2] = 0x00;
	srecout[3] = 0x40;
	srecout[4] = 0x58;
	emit_output_srec('7', srecout);
	return 0;
}

main(argc, argv)
	char **argv;
{
	if (argc < 2 || argc > 3) {
		fprintf(stderr, "usage: %s input.m0 [output.srec]\n", argv[0]);
		exit(1);
	}
	infname = argv[1];
	inf = fopen(infname, "r");
	if (!inf) {
		perror(infname);
		exit(1);
	}
	if (argc > 2) {
		outf = fopen(argv[2], "w");
		if (!outf) {
			perror(argv[2]);
			exit(1);
		}
	} else
		outf = stdout;
	for (lineno = 1; ; lineno++) {
		if (!fgets(srecbuf, sizeof srecbuf, inf)) {
			fprintf(stderr, "%s: premature EOF\n", infname);
			exit(1);
		}
		if (srecbuf[0] != 'S') {
			fprintf(stderr, "%s line %d: not an S-record\n",
				infname, lineno);
			exit(1);
		}
		srec2bin();
		srec_cksum();
		switch (srecbuf[1]) {
		case '0':
			emit_output_srec('0', srecbin);
			continue;
		case '3':
			transform_s3();
			emit_output_srec('3', srecout);
			continue;
		case '7':
			break;
		default:
			fprintf(stderr, "%s line %d: unexpected S%c record\n",
				infname, lineno, srecbuf[1]);
			exit(1);
		}
		break;
	}
	generate_vectors_record();
	generate_jump_record();
	exit(0);
}