FreeCalypso > hg > freecalypso-sw
diff loadtools/flerase.c @ 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 | |
children | cd12d1049f91 |
line wrap: on
line diff
--- /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); +}