]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
Add command loadi (load intel hex file)
authorLeo C <erbl259-lmu@yahoo.de>
Sat, 18 Apr 2015 00:10:01 +0000 (02:10 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Sat, 18 Apr 2015 00:10:01 +0000 (02:10 +0200)
avr/Tupfile
avr/command_tbl.c
avr/ihex.c [new file with mode: 0644]

index 78e9744ed9ad33235b5724f6130cd51c150f03de..87eca70f5f6fe286b38675e08b55f6191d2df88b 100644 (file)
@@ -7,7 +7,7 @@ FATFS   = $(TOP)/fatfs/src/ff.c
 SRC            = main.c
 SRC            += cli.c cli_readline.c command.c command_tbl.c
 SRC            += cmd_help.c cmd_date.c cmd_mem.c cmd_boot.c cmd_gpio.c cmd_misc.c
-SRC            += cmd_sd.c cmd_fat.c
+SRC            += ihex.c cmd_sd.c cmd_fat.c
 SRC            += env.c xmalloc.c con-utils.c print-utils.c getopt-min.c
 SRC            += timer.c serial.c i2c.c pcf8583.c mmc.c
 SRC            += background.c z180-serv.c z80-if.c gpio.c
index d4ff6f2258bb0364150978fda0feccbf35ee91bf..2163526212bb405e6770d2898c1a7dbb1340ceb0 100644 (file)
@@ -16,6 +16,7 @@ extern command_ret_t do_env_default(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_env_set(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_env_save(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_loadf(cmd_tbl_t *, int, int, char * const []);
+extern command_ret_t do_loadihex(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_go(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_restart(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_console(cmd_tbl_t *, int, int, char * const []);
@@ -125,6 +126,11 @@ CMD_TBL_ITEM(
        "load srec_cat prepared image from controller flash",
        ""
 ),
+CMD_TBL_ITEM(
+       loadi,  2,      0,      do_loadihex,
+       "load intel hex file",
+       "[[-]offset]"
+),
 CMD_TBL_ITEM(
        go,     2,      0,      do_go,
        "start application at address 'addr'",
diff --git a/avr/ihex.c b/avr/ihex.c
new file mode 100644 (file)
index 0000000..2a9f033
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * (C) Copyright 2015 Leo C. <erbl259-lmu@yahoo.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include "common.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdbool.h>
+
+#include "command.h"
+#include "con-utils.h"
+#include "z80-if.h"
+//#include "debug.h"
+
+
+typedef enum {
+       IHX_OK,
+       IHX_BROKEN,
+       IHX_CHKSUMERR
+} ihx_rstat_t;
+
+typedef struct {
+       ihx_rstat_t status;
+       int8_t type;
+       uint8_t len;
+       uint16_t address;
+       uint8_t *data;
+} ihex_t;
+
+
+static
+int get_hexdigit(void) {
+
+       int c;
+       c = toupper(my_getchar(1));
+       if (isxdigit(c)) {
+               c -= '0';
+               if (c > 9)
+                       c -= ('A' - '0' - 10);
+               return c;
+       } else
+               return -1;
+}
+
+static
+int get_hexbyte(void) {
+
+       uint8_t i,j;
+
+       if ((i = (uint8_t) get_hexdigit()) < 0x10)
+               if ((j = (uint8_t) get_hexdigit()) < 0x10) {
+                       return (i<<4) + j;
+               }
+
+       return -1;
+}
+
+static
+ihex_t ihex_get_record() {
+
+       int i;
+       uint8_t sum, c;
+       ihex_t rec = { IHX_BROKEN, 0, 0, 0, 0 };
+
+
+       while ((c = my_getchar(0)) != ':')
+               if (c == 0x03)
+                       return rec;
+
+       if ((i = get_hexbyte()) < 0)            /* Start code */
+                       return rec;
+       sum = i;
+       rec.len = i;
+       if ((i = get_hexbyte()) < 0)            /* Byte Count */
+                       return rec;
+       sum += i;
+       rec.address = i * 256;
+       if ((i = get_hexbyte()) < 0)            /* Address */
+                       return rec;
+       sum += i;
+       rec.address += i;
+       if ((i = get_hexbyte()) < 0)            /* Record type */
+               return rec;
+       sum += i;
+       rec.type = i;
+
+       if (rec.len) {                                          /* Record Data */
+               uint8_t *p;     int k;
+               if ((rec.data = malloc(rec.len)) == 0)
+                       return rec;
+               for (p=rec.data, k=rec.len; k; k--) {
+                       if ((i = get_hexbyte()) < 0)
+                               break;
+                       sum += i;
+                       *p++ = i;
+               }
+               if (k) {
+                       free(rec.data); rec.data = 0;
+                       return rec;
+               }
+       }
+       if ((i = get_hexbyte()) < 0)            /* Check sum */
+               return rec;
+       sum += i;
+       if (sum) {
+               free(rec.data); rec.data = 0;
+               rec.status = IHX_CHKSUMERR;
+       } else
+               rec.status = IHX_OK;
+
+       return rec;
+}
+
+
+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_high = 0;
+       bool done = false;
+       command_ret_t rcode = CMD_RET_FAILURE;
+       ihex_t rec;
+
+       (void) cmdtp;
+       (void) flag;
+
+       if (argc > 1)
+               offset = strtol(argv[1], NULL, 16);
+
+       while (!done) {
+               rec = ihex_get_record();
+
+               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);
+                                       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;
+
+                       }
+
+               } else
+                       done = true;
+       }
+
+       switch (rec.status) {
+       case IHX_OK:
+               rcode = CMD_RET_SUCCESS;
+               break;
+
+       case IHX_BROKEN:
+       case IHX_CHKSUMERR:
+               printf_P(PSTR("Broken Hex Record or loading interrupted!\n"));
+               break;
+       }
+
+       printf_P(PSTR("Data loaded - "));
+       if (address_low >= address_high)
+               printf_P(PSTR("None.\n"));
+       else
+               printf_P(PSTR("low: 0x%.5lX high: 0x%.5lX\n"), address_low, address_high);
+
+       return rcode;
+}