changeset 62:6fb41cfa773d

fc-loadtool: flash erase implemented, compiles
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 27 Jun 2013 04:56:17 +0000
parents a10491da8c3a
children cc1d2413991a
files loadtools/Makefile loadtools/flerase.c loadtools/flutil.c loadtools/ltflash.c loadtools/tpinterf3.c
diffstat 5 files changed, 206 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/loadtools/Makefile	Mon Jun 24 17:46:15 2013 +0000
+++ b/loadtools/Makefile	Thu Jun 27 04:56:17 2013 +0000
@@ -9,10 +9,10 @@
 IRAM_OBJS=	defpath.o hexdecode.o hwparam.o hwparamstubs.o romload.o \
 		sercomm.o sertool.o srecreader.o ttypassthru.o
 
-LOADTOOL_OBJS=	crc32tab.o defpath.o flutil.o hexdecode.o hwparam.o labaud.o \
-		ltdispatch.o ltdump.o ltexit.o ltflash.o ltmain.o ltpassthru.o \
-		ltscript.o romload.o sercomm.o srecreader.o tpinterf.o \
-		tpinterf2.o
+LOADTOOL_OBJS=	crc32tab.o defpath.o flerase.o flutil.o hexdecode.o hwparam.o \
+		labaud.o ltdispatch.o ltdump.o ltexit.o ltflash.o ltmain.o \
+		ltpassthru.o ltscript.o romload.o sercomm.o srecreader.o \
+		tpinterf.o tpinterf2.o tpinterf3.o
 
 XRAM_OBJS=	chainload.o clmain.o defpath.o hexdecode.o hwparam.o \
 		hwparamstubs.o initscript.o labaud.o romload.o sercomm.o \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loadtools/flerase.c	Thu Jun 27 04:56:17 2013 +0000
@@ -0,0 +1,110 @@
+/*
+ * This module implements the flash erase operation
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <time.h>
+#include "flash.h"
+
+extern struct flash_bank_info flash_bank_info[2];
+
+do_sector_erase(bi, sp)
+	struct flash_bank_info *bi;
+	struct sector_info *sp;
+{
+	int stat;
+	uint16_t flstat;
+	time_t start_time, curtime;
+
+	stat = do_w16(bi->base_addr + sp->start + 0xAAA, 0xAA);
+	if (stat) {
+bad_w16:	fprintf(stderr,
+	"unexpected response to w16 in erase cmd sequence - aborting\n");
+		return(-1);
+	}
+	stat = do_w16(bi->base_addr + sp->start + 0x554, 0x55);
+	if (stat)
+		goto bad_w16;
+	stat = do_w16(bi->base_addr + sp->start + 0xAAA, 0x80);
+	if (stat)
+		goto bad_w16;
+	stat = do_w16(bi->base_addr + sp->start + 0xAAA, 0xAA);
+	if (stat)
+		goto bad_w16;
+	stat = do_w16(bi->base_addr + sp->start + 0x554, 0x55);
+	if (stat)
+		goto bad_w16;
+	stat = do_w16(bi->base_addr + sp->start + 0xAAA, 0x30);
+	if (stat)
+		goto bad_w16;
+	start_time = time(0);
+	for (;;) {
+		stat = do_r16(bi->base_addr + sp->start, &flstat);
+		if (stat)
+			return(stat);	/* error msg already printed */
+		if (flstat == 0xFFFF)
+			return(0);
+		curtime = time(0);
+		if (curtime >= start_time + 20) {
+			fprintf(stderr, "erase timeout, aborting\n");
+			return(-1);
+		}
+	}
+}
+
+flashcmd_erase(argc, argv, bank)
+	char **argv;
+{
+	struct flash_bank_info *bi;
+	u_long offset, len;
+	char *strtoul_endp;
+	struct sector_info *startsec, *endsec, *sp;
+	int stat;
+
+	if (argc != 4) {
+inv:		fprintf(stderr, "usage: %s %s hex-start-offset hex-length\n",
+			argv[0], argv[1]);
+		return(-1);
+	}
+	offset = strtoul(argv[2], &strtoul_endp, 16);
+	if (*strtoul_endp)
+		goto inv;
+	bi = flash_bank_info + bank;
+	if (offset >= bi->total_size) {
+		fprintf(stderr,
+		"error: specified offset exceeds flash bank size (0x%lx)\n",
+			(u_long) bi->total_size);
+		return(-1);
+	}
+	len = strtoul(argv[3], &strtoul_endp, 16);
+	if (*strtoul_endp)
+		goto inv;
+	if (len > bi->total_size - offset) {
+		fprintf(stderr,
+	"error: specified offset+length exceed flash bank size (0x%lx)\n",
+			(u_long) bi->total_size);
+		return(-1);
+	}
+	if (!len) {
+		printf("Zero length specified - nothing to do!\n");
+		return(0);
+	}
+	/* now enforce sector alignment for both offset and length */
+	if (get_flash_sector_table(bank) < 0)
+		return(-1);
+	if (get_flash_sector_range(bi, offset, len, &startsec, &endsec) < 0)
+		return(-1);
+	printf("Erasing %d sector(s)\n", endsec - startsec);
+	for (sp = startsec; sp < endsec; sp++) {
+		stat = do_sector_erase(bi, sp);
+		if (stat)
+			return(stat);
+		putchar('.');
+		fflush(stdout);
+	}
+	putchar('\n');
+	return(0);
+}
--- a/loadtools/flutil.c	Mon Jun 24 17:46:15 2013 +0000
+++ b/loadtools/flutil.c	Thu Jun 27 04:56:17 2013 +0000
@@ -99,3 +99,33 @@
 		printf("%08lX  %lx\n", (u_long) sp->start, (u_long) sp->size);
 	return(0);
 }
+
+get_flash_sector_range(bi, useroff, userlen, startp, endp)
+	struct flash_bank_info *bi;
+	u_long useroff, userlen;
+	struct sector_info **startp, **endp;
+{
+	struct sector_info *sp;
+	uint32_t remlen;
+
+	for (sp = bi->sectors; sp->size; sp++)
+		if (sp->start == useroff)
+			break;
+	if (!sp->size) {
+		fprintf(stderr,
+	"error: specified offset not aligned to a flash sector boundary\n");
+		return(-1);
+	}
+	*startp = sp;
+	for (remlen = userlen; remlen; ) {
+		if (remlen < sp->size) {
+			fprintf(stderr,
+	"error: specified length not aligned to a flash sector boundary\n");
+			return(-1);
+		}
+		remlen -= sp->size;
+		sp++;
+	}
+	*endp = sp;
+	return(0);
+}
--- a/loadtools/ltflash.c	Mon Jun 24 17:46:15 2013 +0000
+++ b/loadtools/ltflash.c	Thu Jun 27 04:56:17 2013 +0000
@@ -247,6 +247,7 @@
 	return(0);
 }
 
+extern int flashcmd_erase();
 extern int flashcmd_sectors();
 
 static struct cmdtab {
@@ -256,6 +257,7 @@
 	{"blankchk", flashcmd_blankchk},
 	{"dump2bin", flashcmd_dump2file},
 	{"dump2srec", flashcmd_dump2file},
+	{"erase", flashcmd_erase},
 	{"info", flashcmd_info},
 	{"sectors", flashcmd_sectors},
 	{0, 0}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loadtools/tpinterf3.c	Thu Jun 27 04:56:17 2013 +0000
@@ -0,0 +1,60 @@
+/*
+ * The do_r16() and do_w16() functions implemented in this module
+ * provide programmatic access to the r16 and w16 commands on the target.
+ * They will be used to implement some flash operations.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+extern char target_response_line[];
+
+do_r16(addr, retptr)
+	uint32_t addr;
+	uint16_t *retptr;
+{
+	char addr_arg[10], *argv[3];
+	int stat;
+	char *strtoul_endp;
+
+	sprintf(addr_arg, "%lx", (u_long) addr);
+	argv[0] = "r16";
+	argv[1] = addr_arg;
+	argv[2] = 0;
+	tpinterf_make_cmd(argv);
+	if (tpinterf_send_cmd() < 0)
+		return(-1);
+	stat = tpinterf_capture_output_oneline(1);
+	if (stat != 1) {
+errout:		fprintf(stderr, "error: malformed response to r16 command\n");
+		return(-1);
+	}
+	if (strlen(target_response_line) != 4)
+		goto errout;
+	*retptr = strtoul(target_response_line, &strtoul_endp, 16);
+	if (strtoul_endp != target_response_line + 4)
+		goto errout;
+	return(0);
+}
+
+do_w16(addr, data)
+	uint32_t addr;
+	uint16_t data;
+{
+	char addr_arg[10], data_arg[10], *argv[4];
+
+	sprintf(addr_arg, "%lx", (u_long) addr);
+	sprintf(data_arg, "%lx", (u_long) data);
+	argv[0] = "w16";
+	argv[1] = addr_arg;
+	argv[2] = data_arg;
+	argv[3] = 0;
+	tpinterf_make_cmd(argv);
+	if (tpinterf_send_cmd() < 0)
+		return(-1);
+	return tpinterf_pass_output(1);
+}