From 5480dc651411edc6fdeca04ce38749a6d04245a5 Mon Sep 17 00:00:00 2001 From: Leo C Date: Wed, 22 Apr 2015 21:59:58 +0200 Subject: New memory test commands, loadi updates. Needs testing - rename loop to mloop - + mloopw - + mtest - + mdc - + mwc --- avr/ihex.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 155 insertions(+), 47 deletions(-) (limited to 'avr/ihex.c') diff --git a/avr/ihex.c b/avr/ihex.c index 4e7b1a8..01fb6b0 100644 --- a/avr/ihex.c +++ b/avr/ihex.c @@ -15,6 +15,42 @@ //#include "debug.h" +uint32_t detect_ramsize(void) +{ + uint32_t addr; + uint8_t save_addr, save_0; + const uint8_t PATTERN_1 = 0x55; + const uint8_t PATTERN_2 = ~PATTERN_1; + + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + my_puts_P(PSTR("Bus timeout\n")); + return 0; + } + + save_0 = z80_read(0); + z80_write(0, PATTERN_1); + + for (addr=1; addr < CONFIG_SYS_RAMSIZE_MAX; addr <<= 1) { + save_addr = z80_read(addr); + z80_write(addr, PATTERN_2); + if (z80_read(0) != PATTERN_1 || z80_read(addr) != PATTERN_2) + break; + z80_write(addr, save_addr); + } + z80_write(0, save_0); + z80_bus_cmd(Release); + + return addr; +} + +static uint32_t min(uint32_t a, uint32_t b) +{ + if (a < b) + return a; + return b; +} + + typedef enum { IHX_OK, IHX_BROKEN, @@ -26,7 +62,7 @@ typedef struct { int8_t type; uint8_t len; uint16_t address; - uint8_t *data; + uint8_t data[256]; } ihex_t; @@ -57,6 +93,8 @@ int get_hexbyte(void) { return -1; } +#if 0 + static ihex_t ihex_get_record() { @@ -122,73 +160,138 @@ ihex_t ihex_get_record() { return rec; } +#else + +static +int ihex_get_record(ihex_t *rec) { + + int c; + uint8_t sum; + + rec->status = IHX_BROKEN; + + + while ((c = my_getchar(0)) != ':') + if (c == 0x03) + return -1; + + if ((c = get_hexbyte()) < 0) /* Start code */ + return -1; + sum = c; + rec->len = c; + if ((c = get_hexbyte()) < 0) /* Byte Count */ + return -1; + sum += c; + rec->address = c * 256; + if ((c = get_hexbyte()) < 0) /* Address */ + return -1; + sum += c; + rec->address += c; + if ((c = get_hexbyte()) < 0) /* Record type */ + return -1; + sum += c; + rec->type = c; + + if (rec->len) { /* Record Data */ + uint8_t n; + + for (n = 0; n < rec->len; n++) { + if ((c = get_hexbyte()) < 0) + break; + sum += c; + rec->data[n] = c; + } + + if (n < rec->len) { + return -1; + } + } + + c = get_hexbyte(); /* Check sum */ + + if (c >= 0) { + sum += c; + if (sum == 0) + rec->status = IHX_OK; + else + rec->status = IHX_CHKSUMERR; + } + + return rec->len; +} + +#endif command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { long offset = 0; uint32_t base_address = 0; - uint32_t address_low = 0xffffffff; + uint32_t address_max = detect_ramsize(); uint32_t address_high = 0; - bool done = false; + uint32_t address_low = address_max; command_ret_t rcode = CMD_RET_FAILURE; ihex_t rec; - (void) cmdtp; - (void) flag; + (void) cmdtp; (void) flag; + + + printf_P(PSTR("RAM Size: 0x%.5lX\n"), address_max); + if (argc > 1) offset = strtol(argv[1], NULL, 16); - while (!done) { - rec = ihex_get_record(); + while (ihex_get_record(&rec) > 0 && + rec.status == IHX_OK && + rec.type != 1 ) { + + switch (rec.type) { + case 0: /* Data record */ + if (rec.len) { + uint32_t addr = base_address + rec.address + offset; + if (addr < address_low) + address_low = addr; + if (addr+rec.len > address_high) + address_high = addr + rec.len; - if (rec.status == IHX_OK) { - switch (rec.type) { - case 0: /* Data record */ - if (rec.len) { - uint32_t addr = base_address + rec.address + offset; - if (addr < address_low) - address_low = addr; - if (addr+rec.len > address_high) - address_high = addr + rec.len; - z80_bus_cmd(Request); +printf_P(PSTR("low: 0x%.5lX, high: 0x%.5lX, max: 0x%.5lX, addr: 0x%.5lX, len: %d\n"), + address_low, address_high, address_max, addr, rec.len); + + if (addr < address_max) { + uint32_t tmplen = address_max - addr; + if (rec.len > tmplen) + rec.len = tmplen; + + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + my_puts_P(PSTR("Bus timeout\n")); + return CMD_RET_FAILURE; + } z80_write_block(rec.data, /* src */ addr, /* dest */ rec.len); /* len */ z80_bus_cmd(Release); } - continue; - break; - - case 1: /* EOF record */ - - done = true; - break; - - case 2: /* Extended Segment Address Record */ - base_address = ((rec.data[0] << 8) + rec.data[1]) << 4; - continue; - break; - - case 4: /* Extended Linear Address Record */ - base_address = (uint32_t)((rec.data[0] << 8) + rec.data[1]) << 16; - continue; - break; - - case 3: /* Start Segment Address Record (ignored)*/ - case 5: /* Start Linear Address Record (ignored)*/ - continue; - break; - } + break; - } else - done = true; +#if 0 + case 1: /* EOF record */ + break; +#endif + case 2: /* Extended Segment Address Record */ + base_address = ((rec.data[0] << 8) + rec.data[1]) << 4; + break; - free(rec.data); - rec.data = 0; + case 4: /* Extended Linear Address Record */ + base_address = (uint32_t)((rec.data[0] << 8) + rec.data[1]) << 16; + break; + case 3: /* Start Segment Address Record (ignored)*/ + case 5: /* Start Linear Address Record (ignored)*/ + break; + + } } switch (rec.status) { @@ -202,11 +305,16 @@ command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg break; } - printf_P(PSTR("Data loaded - ")); - if (address_low >= address_high) + printf_P(PSTR("Data loaded: ")); + if (address_low >= min(address_high, address_max)) printf_P(PSTR("None.\n")); else - printf_P(PSTR("low: 0x%.5lX high: 0x%.5lX\n"), address_low, address_high); + printf_P(PSTR("low: 0x%.5lX high: 0x%.5lX\n"), address_low, + min(address_high, address_max) - 1); + + if (address_high > address_max) + printf_P(PSTR("Data above highest RAM address " + "(Range 0x%.5lX...0x%.5lX) ignored!\n"), address_max, address_high - 1); return rcode; } -- cgit v1.2.3