X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=ao-tools%2Fao-stmload%2Fao-stmload.c;h=4210a11150419c0f25bc0028ca123dcc2de5c2c5;hp=6e3906fd691a1f40f10e29ffdddd4a02254c58db;hb=25aaf6122cbddcbc6a80460dac8ccb9f45743ae0;hpb=95a8180f3d7929dbad65c80421f99c925f245af0 diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index 6e3906fd..4210a111 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -25,93 +25,16 @@ #include #include #include +#include #include "stlink-common.h" #include "ao-elf.h" #include "ccdbg.h" -#include "cc-usb.h" #include "cc.h" #include "ao-stmload.h" +#include "ao-selfload.h" +#include "ao-verbose.h" +#include "ao-editaltos.h" -#define AO_USB_DESC_STRING 3 - -struct ao_elf_sym ao_symbols[] = { - - { 0, AO_BOOT_APPLICATION_BASE + 0x100, "ao_romconfig_version", 1 }, -#define AO_ROMCONFIG_VERSION (ao_symbols[0].addr) - - { 0, AO_BOOT_APPLICATION_BASE + 0x102, "ao_romconfig_check", 1 }, -#define AO_ROMCONFIG_CHECK (ao_symbols[1].addr) - - { 0, AO_BOOT_APPLICATION_BASE + 0x104, "ao_serial_number", 1 }, -#define AO_SERIAL_NUMBER (ao_symbols[2].addr) - - { 0, AO_BOOT_APPLICATION_BASE + 0x108, "ao_radio_cal", 0 }, -#define AO_RADIO_CAL (ao_symbols[3].addr) - - { 0, AO_BOOT_APPLICATION_BASE + 0x10c, "ao_usb_descriptors", 0 }, -#define AO_USB_DESCRIPTORS (ao_symbols[4].addr) -}; - -#define NUM_SYMBOLS 5 -#define NUM_REQUIRED_SYMBOLS 3 - -int ao_num_symbols = NUM_SYMBOLS; -int ao_num_required_symbols = NUM_REQUIRED_SYMBOLS; - -/* - * Edit the to-be-written memory block - */ -static int -rewrite(struct ao_hex_image *load, unsigned address, uint8_t *data, int length) -{ - int i; - - if (address < load->address || load->address + load->length < address + length) - return 0; - - printf("rewrite %04x:", address); - for (i = 0; i < length; i++) - printf (" %02x", load->data[address - load->address + i]); - printf(" ->"); - for (i = 0; i < length; i++) - printf (" %02x", data[i]); - printf("\n"); - memcpy(load->data + address - load->address, data, length); -} - -/* - * Read a 16-bit value from the USB target - */ - -static uint16_t -get_uint16_cc(struct cc_usb *cc, uint32_t addr) -{ - struct ao_hex_image *hex = ao_self_read(cc, addr, 2); - uint16_t v; - uint8_t *data; - - if (!hex) - return 0; - data = hex->data + addr - hex->address; - v = data[0] | (data[1] << 8); - free(hex); - return v; -} - -static uint32_t -get_uint32_cc(struct cc_usb *cc, uint32_t addr) -{ - struct ao_hex_image *hex = ao_self_read(cc, addr, 4); - uint32_t v; - uint8_t *data; - - if (!hex) - return 0; - data = hex->data + addr - hex->address; - v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - free(hex); - return v; -} /* * Read a 16-bit value from the target device with arbitrary @@ -141,13 +64,10 @@ get_uint16_sl(stlink_t *sl, uint32_t addr) } static uint16_t -get_uint16(stlink_t *sl, struct cc_usb *cc, uint32_t addr) +get_uint16(stlink_t *sl, uint32_t addr) { uint16_t result; - if (cc) - result = get_uint16_cc(cc, addr); - else - result = get_uint16_sl(sl, addr); + result = get_uint16_sl(sl, addr); printf ("read 0x%08x = 0x%04x\n", addr, result); return result; } @@ -185,14 +105,11 @@ get_uint32_sl(stlink_t *sl, uint32_t addr) * alignment */ static uint32_t -get_uint32(stlink_t *sl, struct cc_usb *cc, uint32_t addr) +get_uint32(stlink_t *sl, uint32_t addr) { uint32_t result; - if (cc) - result = get_uint32_cc(cc, addr); - else - result = get_uint32_sl(sl, addr); + result = get_uint32_sl(sl, addr); printf ("read 0x%08x = 0x%08x\n", addr, result); return result; } @@ -206,10 +123,10 @@ get_uint32(stlink_t *sl, struct cc_usb *cc, uint32_t addr) * places this at 0x100 from the start of the rom section */ static int -check_flashed(stlink_t *sl, struct cc_usb *cc) +check_flashed(stlink_t *sl) { - uint16_t romconfig_version = get_uint16(sl, cc, AO_ROMCONFIG_VERSION); - uint16_t romconfig_check = get_uint16(sl, cc, AO_ROMCONFIG_CHECK); + uint16_t romconfig_version = get_uint16(sl, AO_ROMCONFIG_VERSION); + uint16_t romconfig_check = get_uint16(sl, AO_ROMCONFIG_CHECK); if (romconfig_version != (uint16_t) ~romconfig_check) { fprintf (stderr, "Device has not been flashed before\n"); @@ -219,34 +136,27 @@ check_flashed(stlink_t *sl, struct cc_usb *cc) } static const struct option options[] = { - { .name = "stlink", .has_arg = 0, .val = 'S' }, - { .name = "tty", .has_arg = 1, .val = 'T' }, - { .name = "device", .has_arg = 1, .val = 'D' }, + { .name = "v1", .has_arg = 0, .val = '1' }, + { .name = "raw", .has_arg = 0, .val = 'r' }, { .name = "cal", .has_arg = 1, .val = 'c' }, { .name = "serial", .has_arg = 1, .val = 's' }, - { .name = "verbose", .has_arg = 0, .val = 'v' }, + { .name = "verbose", .has_arg = 1, .val = 'v' }, { 0, 0, 0, 0}, }; static void usage(char *program) { - fprintf(stderr, "usage: %s [--stlink] [--verbose] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); + fprintf(stderr, "usage: %s [--v1] [--raw] [--verbose=] [--cal=] [--serial=] file.{elf,ihx}\n", program); exit(1); } void -done(stlink_t *sl, struct cc_usb *cc, int code) +done(stlink_t *sl, int code) { - if (cc) { -/* cc_usb_printf(cc, "a\n"); */ - cc_usb_close(cc); - } - if (sl) { - stlink_reset(sl); - stlink_run(sl); - stlink_exit_debug_mode(sl); - stlink_close(sl); - } + stlink_reset(sl); + stlink_run(sl); + stlink_exit_debug_mode(sl); + stlink_close(sl); exit (code); } @@ -264,7 +174,8 @@ ends_with(char *whole, char *suffix) int main (int argc, char **argv) { - char *device = NULL; + int stlink_v1 = 0; + int raw = 0; char *filename; Elf *e; char *serial_end; @@ -283,19 +194,18 @@ main (int argc, char **argv) int was_flashed = 0; struct ao_hex_image *load; int tries; - struct cc_usb *cc = NULL; - int use_stlink = 0; - char *tty = NULL; int success; int verbose = 0; + struct ao_sym *file_symbols; + int num_file_symbols; - while ((c = getopt_long(argc, argv, "T:D:c:s:Sv", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "1rc:s:v:", options, NULL)) != -1) { switch (c) { - case 'T': - tty = optarg; + case '1': + stlink_v1 = 1; break; - case 'D': - device = optarg; + case 'r': + raw = 1; break; case 'c': cal = strtoul(optarg, &cal_end, 10); @@ -307,9 +217,6 @@ main (int argc, char **argv) if (serial_end == optarg || *serial_end != '\0') usage(argv[0]); break; - case 'S': - use_stlink = 1; - break; case 'v': verbose++; break; @@ -319,7 +226,7 @@ main (int argc, char **argv) } } - ao_self_verbose = verbose; + ao_verbose = verbose; if (verbose > 1) ccdbg_add_debug(CC_DEBUG_BITBANG); @@ -329,219 +236,102 @@ main (int argc, char **argv) usage(argv[0]); if (ends_with (filename, ".elf")) { - load = ao_load_elf(filename, ao_symbols, ao_num_symbols); + load = ao_load_elf(filename, &file_symbols, &num_file_symbols); } else if (ends_with (filename, ".ihx")) { - int i; - load = ao_hex_load(filename); - for (i = 0; i < ao_num_symbols; i++) - ao_symbols[i].addr = ao_symbols[i].default_addr; + load = ao_hex_load(filename, &file_symbols, &num_file_symbols); } else usage(argv[0]); - if (use_stlink) { - /* Connect to the programming dongle - */ + if (!raw) { + if (!ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) { + fprintf(stderr, "Cannot find required symbols\n"); + usage(argv[0]); + } + } + + /* Connect to the programming dongle + */ - for (tries = 0; tries < 3; tries++) { - if (device) { - sl = stlink_v1_open(50); - } else { - sl = stlink_open_usb(50); + for (tries = 0; tries < 3; tries++) { + if (stlink_v1) { + sl = stlink_v1_open(50); + } else { + sl = stlink_open_usb(50); - } - if (!sl) { - fprintf (stderr, "No STLink devices present\n"); - done (sl, NULL, 1); - } - - if (sl->chip_id != 0) - break; - stlink_reset(sl); - stlink_close(sl); - sl = NULL; } if (!sl) { - fprintf (stderr, "Debugger connection failed\n"); - exit(1); + fprintf (stderr, "No STLink devices present\n"); + done (sl, 1); } - /* Verify that the loaded image fits entirely within device flash - */ - if (load->address < sl->flash_base || - sl->flash_base + sl->flash_size < load->address + load->length) { - fprintf (stderr, "\%s\": Invalid memory range 0x%08x - 0x%08x\n", filename, - load->address, load->address + load->length); - done(sl, NULL, 1); - } - - /* Enter debugging mode - */ - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) - stlink_exit_dfu_mode(sl); - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(sl); - } else { - int is_loader; - int tries; - - for (tries = 0; tries < 3; tries++) { - char *this_tty = tty; - if (!this_tty) - this_tty = cc_usbdevs_find_by_arg(device, "AltosFlash"); - if (!this_tty) - this_tty = cc_usbdevs_find_by_arg(device, "MegaMetrum"); - if (!this_tty) - this_tty = getenv("ALTOS_TTY"); - if (!this_tty) - this_tty="/dev/ttyACM0"; - - cc = cc_usb_open(this_tty); - - if (!cc) - exit(1); - cc_usb_printf(cc, "v\n"); - is_loader = 0; - for (;;) { - char line[256]; - cc_usb_getline(cc, line, sizeof(line)); - if (!strncmp(line, "altos-loader", 12)) - is_loader = 1; - if (!strncmp(line, "software-version", 16)) - break; - } - if (is_loader) - break; - printf ("rebooting to loader\n"); - cc_usb_printf(cc, "X\n"); - cc_usb_close(cc); - sleep(1); - cc = NULL; - } - if (!is_loader) { - fprintf(stderr, "Cannot switch to boot loader\n"); - exit(1); - } -#if 0 - { - uint8_t check[256]; - int i = 0; - - ao_self_block_read(cc, AO_BOOT_APPLICATION_BASE, check); - for (;;) { - uint8_t block[256]; - putchar ('.'); - if (++i == 40) { - putchar('\n'); - i = 0; - } - fflush(stdout); - ao_self_block_write(cc, AO_BOOT_APPLICATION_BASE, block); - ao_self_block_read(cc, AO_BOOT_APPLICATION_BASE, block); - if (memcmp(block, check, 256) != 0) { - fprintf (stderr, "read differed\n"); - exit(1); - } - } - } -#endif + if (sl->chip_id != 0) + break; + stlink_reset(sl); + stlink_close(sl); + sl = NULL; } - - /* Go fetch existing config values - * if available - */ - was_flashed = check_flashed(sl, cc); - - if (!serial) { - if (!was_flashed) { - fprintf (stderr, "Must provide serial number\n"); - done(sl, cc, 1); - } - serial = get_uint16(sl, cc, AO_SERIAL_NUMBER); - if (!serial || serial == 0xffff) { - fprintf (stderr, "Invalid existing serial %d\n", serial); - done(sl, cc, 1); - } + if (!sl) { + fprintf (stderr, "Debugger connection failed\n"); + exit(1); } - if (!cal && AO_RADIO_CAL && was_flashed) { - cal = get_uint32(sl, cc, AO_RADIO_CAL); - if (!cal || cal == 0xffffffff) { - fprintf (stderr, "Invalid existing rf cal %d\n", cal); - done(sl, cc, 1); - } + /* Verify that the loaded image fits entirely within device flash + */ + if (load->address < sl->flash_base || + sl->flash_base + sl->flash_size < load->address + load->length) { + fprintf (stderr, "\%s\": Invalid memory range 0x%08x - 0x%08x\n", filename, + load->address, load->address + load->length); + done(sl, 1); } - /* Write the config values into the flash image + /* Enter debugging mode */ + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(sl); - serial_int[0] = serial & 0xff; - serial_int[1] = (serial >> 8) & 0xff; + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(sl); - if (!rewrite(load, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) { - fprintf(stderr, "Cannot rewrite serial integer at %08x\n", - AO_SERIAL_NUMBER); - done(sl, cc, 1); - } - if (AO_USB_DESCRIPTORS) { - uint32_t usb_descriptors = AO_USB_DESCRIPTORS - load->address; - string_num = 0; + if (!raw) { + /* Go fetch existing config values + * if available + */ + was_flashed = check_flashed(sl); - while (load->data[usb_descriptors] != 0 && usb_descriptors < load->length) { - if (load->data[usb_descriptors+1] == AO_USB_DESC_STRING) { - ++string_num; - if (string_num == 4) - break; + if (!serial) { + if (!was_flashed) { + fprintf (stderr, "Must provide serial number\n"); + done(sl, 1); + } + serial = get_uint16(sl, AO_SERIAL_NUMBER); + if (!serial || serial == 0xffff) { + fprintf (stderr, "Invalid existing serial %d\n", serial); + done(sl, 1); } - usb_descriptors += load->data[usb_descriptors]; - } - if (usb_descriptors >= load->length || load->data[usb_descriptors] == 0 ) { - fprintf(stderr, "Cannot rewrite serial string at %08x\n", AO_USB_DESCRIPTORS); - done(sl, cc, 1); } - serial_ucs2_len = load->data[usb_descriptors] - 2; - serial_ucs2 = malloc(serial_ucs2_len); - if (!serial_ucs2) { - fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len); - done(sl, cc, 1); - } - s = serial; - for (i = serial_ucs2_len / 2; i; i--) { - serial_ucs2[i * 2 - 1] = 0; - serial_ucs2[i * 2 - 2] = (s % 10) + '0'; - s /= 10; - } - if (!rewrite(load, usb_descriptors + 2 + load->address, serial_ucs2, serial_ucs2_len)) { - fprintf (stderr, "Cannot rewrite USB descriptor at %08x\n", AO_USB_DESCRIPTORS); - done(sl, cc, 1); + if (!cal && AO_RADIO_CAL && was_flashed) { + cal = get_uint32(sl, AO_RADIO_CAL); + if (!cal || cal == 0xffffffff) { + fprintf (stderr, "Invalid existing rf cal %d\n", cal); + done(sl, 1); + } } - } - - if (cal && AO_RADIO_CAL) { - cal_int[0] = cal & 0xff; - cal_int[1] = (cal >> 8) & 0xff; - cal_int[2] = (cal >> 16) & 0xff; - cal_int[3] = (cal >> 24) & 0xff; - if (!rewrite(load, AO_RADIO_CAL, cal_int, sizeof (cal_int))) { - fprintf(stderr, "Cannot rewrite radio calibration at %08x\n", AO_RADIO_CAL); - exit(1); - } + if (!ao_editaltos(load, serial, cal)) + done(sl, 1); } /* And flash the resulting image to the device */ - if (cc) - success = ao_self_write(cc, load); - else - success = (stlink_write_flash(sl, load->address, load->data, load->length) >= 0); + + success = (stlink_write_flash(sl, load->address, load->data, load->length) >= 0); if (!success) { fprintf (stderr, "\"%s\": Write failed\n", filename); - done(sl, cc, 1); + done(sl, 1); } - done(sl, cc, 0); + done(sl, 0); }