static int open_device(struct olimex_transport *tr, struct usb_device *dev) { struct usb_config_descriptor *c = &dev->config[0]; int i; for (i = 0; i < c->bNumInterfaces; i++) { struct usb_interface *intf = &c->interface[i]; struct usb_interface_descriptor *desc = &intf->altsetting[0]; if (desc->bInterfaceClass == V1_INTERFACE_CLASS && !open_interface(tr, dev, desc->bInterfaceNumber)) { printc_dbg("olimex: rev 1 device\n"); tr->in_ep = V1_IN_EP; tr->out_ep = V1_OUT_EP; return 0; } else if (desc->bInterfaceClass == V2_INTERFACE_CLASS && !open_interface(tr, dev, desc->bInterfaceNumber)) { printc_dbg("olimex: rev 2 device\n"); tr->in_ep = V2_IN_EP; tr->out_ep = V2_OUT_EP; return 0; } } return -1; }
static void trigger_capture(struct timer *tr, int which, int oldval, int value) { uint16_t edge_flags = 0; tr->ctls[which] &= ~CCI; if (value) tr->ctls[which] |= CCI; if (oldval && !value) edge_flags |= CM1; if (!oldval && value) edge_flags |= CM0; printc_dbg("Timer channel %d: %s => %s\n", which, oldval ? "H" : "L", value ? "H" : "L"); if ((tr->ctls[which] & edge_flags) && (tr->ctls[which] & CAP)) { if (tr->ctls[which] & CCIFG) { printc_dbg("Timer capture overflow\n"); tr->ctls[which] |= COV; } else { printc_dbg("Timer capture interrupt triggered\n"); tr->ccrs[which] = tr->tar; tr->ctls[which] |= CCIFG; } } }
int tilib_api_init(void) { int ret; lib_handle = dynload_open(tilib_filename); if (!lib_handle) { printc_err("tilib_api: can't find %s: %s\n", tilib_filename, dynload_error()); return -1; } if (dynload_sym(lib_handle, "MSP430_HIL_MEMAP")) { printc_dbg("Using new (SLAC460L+) API\n"); ret = init_new_api(); } else { printc_dbg("Using old API\n"); ret = init_old_api(); } if (ret < 0) { dynload_close(lib_handle); return -1; } return 0; }
static int config_channel(struct timer *tr, char **arg_text) { char *which_text = get_arg(arg_text); char *value_text = get_arg(arg_text); address_t which; address_t value; int oldval; uint16_t edge_flags = 0; if (!(which_text && value_text)) { printc_err("timer: config: expected channel and value\n"); return -1; } if (expr_eval(which_text, &which) < 0) { printc_err("timer: can't parse channel number: %s\n", which_text); return -1; } if (expr_eval(value_text, &value) < 0) { printc_err("timer: can't parse channel value: %s\n", value_text); return -1; } if (which > tr->size) { printc_err("timer: invalid channel number: %d\n", which); return -1; } oldval = tr->ctls[which] & CCI; tr->ctls[which] &= ~CCI; if (value) tr->ctls[which] |= CCI; if (oldval && !value) edge_flags |= CM1; if (!oldval && value) edge_flags |= CM0; printc_dbg("Timer channel %d: %s => %s\n", which, oldval ? "H" : "L", value ? "H" : "L"); if ((tr->ctls[which] & edge_flags) && (tr->ctls[which] & CAP)) { if (tr->ctls[which] & CCIFG) { printc_dbg("Timer capture overflow\n"); tr->ctls[which] |= COV; } else { printc_dbg("Timer capture interrupt triggered\n"); tr->ccrs[which] = tr->tar; tr->ctls[which] |= CCIFG; } } return 0; }
static device_t bsl_open(const struct device_args *args) { struct bsl_device *dev; dev = malloc(sizeof(*dev)); if (!dev) { pr_error("bsl: can't allocate memory"); return NULL; } memset(dev, 0, sizeof(*dev)); dev->base.type = &device_bsl; if (args->flags & DEVICE_FLAG_TTY) dev->serial = comport_open(args->path, 460800); else dev->serial = ti3410_open(args->path, args->requested_serial); if (!dev->serial) { free(dev); return NULL; } if (enter_via_fet(dev) < 0) printc_err("bsl: warning: FET firmware not responding\n"); delay_ms(500); /* Show chip info */ if (bsl_xfer(dev, CMD_TX_DATA, 0xff0, NULL, 0x10) < 0) { printc_err("bsl: failed to read chip info\n"); goto fail; } if (dev->reply_len < 0x16) { printc_err("bsl: missing chip info\n"); goto fail; } printc_dbg("Device ID: 0x%02x%02x\n", dev->reply_buf[4], dev->reply_buf[5]); printc_dbg("BSL version is %x.%02x\n", dev->reply_buf[14], dev->reply_buf[15]); return (device_t)dev; fail: dev->serial->ops->destroy(dev->serial); free(dev); return NULL; }
static void tilib_destroy(device_t dev_base) { struct tilib_device *dev = (struct tilib_device *)dev_base; printc_dbg("MSP430_Run\n"); if (dev->MSP430_Run(FREE_RUN, 1) < 0) report_error(dev, "MSP430_Run"); printc_dbg("MSP430_Close\n"); dev->MSP430_Close(0); dynload_close(dev->hnd); threads_lock_destroy(&dev->mb_lock); free(dev); }
static int init_device(sport_t fd) { struct packet pkt; printc_dbg("Initializing...\n"); if (xfer(fd, APP_JTAG430, GLOBAL_NOK, 0, NULL, &pkt) < 0) { printc_err("goodfet: comms test failed\n"); return -1; } printc_dbg("Setting up JTAG pins\n"); if (xfer(fd, APP_JTAG430, GLOBAL_SETUP, 0, NULL, &pkt) < 0) { printc_err("goodfet: SETUP command failed\n"); return -1; } printc_dbg("Starting JTAG\n"); if (xfer(fd, APP_JTAG430, GLOBAL_START, 0, NULL, &pkt) < 0) { printc_err("goodfet: START command failed\n"); return -1; } if (pkt.len < 1) { printc_err("goodfet: bad response to JTAG START\n"); return -1; } printc("JTAG ID: 0x%02x\n", pkt.data[0]); if (pkt.data[0] != 0x89 && pkt.data[0] != 0x91) { printc_err("goodfet: unexpected JTAG ID: 0x%02x\n", pkt.data[0]); xfer(fd, APP_JTAG430, GLOBAL_STOP, 0, NULL, &pkt); return -1; } printc_dbg("Halting CPU\n"); if (xfer(fd, APP_JTAG430, JTAG430_HALTCPU, 0, NULL, &pkt) < 0) { printc_err("goodfet: HALTCPU command failed\n"); xfer(fd, APP_JTAG430, GLOBAL_STOP, 0, NULL, &pkt); return -1; } return 0; }
static int recv_packet(sport_t fd, struct packet *pkt) { uint8_t header[4]; if (sport_read_all(fd, header, 4) < 0) { printc_err("goodfet: recv_packet (header): %s\n", last_error()); return -1; } pkt->app = header[0]; pkt->verb = header[1]; pkt->len = ((uint16_t)header[2]) | (((uint16_t)header[3]) << 8); if (pkt->len > MAX_LEN) { printc_err("goodfet: recv_packet: maximum length " "exceeded (%d)\n", pkt->len); return -1; } if (sport_read_all(fd, pkt->data, pkt->len) < 0) { printc_err("goodfet: recv_packet (data): %s\n", last_error()); return -1; } #ifdef DEBUG_GOODFET printc_dbg("RECV: %02x/%02x\n", pkt->app, pkt->verb); if (pkt->len) debug_hexdump("Data", pkt->data, pkt->len); #endif return 0; }
static int send_packet(sport_t fd, uint8_t app, uint8_t verb, uint16_t len, const uint8_t *data) { uint8_t raw[MAX_LEN + 4]; if (len > MAX_LEN) { printc_err("goodfet: send_packet: maximum length " "exceeded (%d)\n", len); return -1; } #ifdef DEBUG_GOODFET printc_dbg("SEND: %02x/%02x\n", app, verb); if (len) debug_hexdump("Data", data, len); #endif raw[0] = app; raw[1] = verb; raw[2] = len & 0xff; raw[3] = len >> 8; memcpy(raw + 4, data, len); if (sport_write_all(fd, raw, len + 4) < 0) { printc_err("goodfet: send_packet: %s\n", last_error()); return -1; } return 0; }
static int xfer(sport_t fd, uint8_t app, uint8_t verb, uint16_t len, const uint8_t *data, struct packet *pkt) { if (send_packet(fd, app, verb, len, data) < 0) goto fail; while (recv_packet(fd, pkt) >= 0) { if (pkt->app == APP_DEBUG && pkt->verb == GLOBAL_DEBUG) { char text[MAX_LEN + 1]; memcpy(text, pkt->data, pkt->len); text[pkt->len] = 0; printc_dbg("[GoodFET debug] %s\n", text); } if (pkt->app == app && pkt->verb == verb) return 0; } fail: printc_err("goodfet: command 0x%02x/0x%02x " "failed\n", app, verb); return -1; }
int prog_flush(struct prog_data *prog) { if (!prog->len) return 0; if (!prog->have_erased && (prog->flags & PROG_WANT_ERASE)) { printc("Erasing...\n"); if (device_erase(DEVICE_ERASE_MAIN, 0) < 0) return -1; printc("Programming...\n"); prog->have_erased = 1; } printc_dbg("%s %4d bytes at %04x", (prog->flags & PROG_VERIFY) ? "Verifying" : "Writing", prog->len, prog->addr); if (prog->section[0]) printc_dbg(" [section: %s]", prog->section); printc_dbg("...\n"); if (prog->flags & PROG_VERIFY) { uint8_t cmp_buf[PROG_BUFSIZE]; int i; if (device_readmem(prog->addr, cmp_buf, prog->len) < 0) return -1; for (i = 0; i < prog->len; i++) if (cmp_buf[i] != prog->buf[i]) { printc("\x1b[1mERROR:\x1b[0m " "mismatch at %04x (read %02x, " "expected %02x)\n", prog->addr + i, cmp_buf[i], prog->buf[i]); return -1; } } else { if (device_writemem(prog->addr, prog->buf, prog->len) < 0) return -1; } prog->total_written += prog->len; prog->addr += prog->len; prog->len = 0; return 0; }
static int open_device(struct bslhid_transport *tr, struct usb_device *dev) { if (find_interface(tr, dev) < 0) return -1; printc_dbg("Opening interface %d (config %d)...\n", tr->int_number, tr->cfg_number); if (find_endpoints(tr, dev) < 0) return -1; printc_dbg("Found endpoints: IN: 0x%02x, OUT: 0x%02x\n", tr->in_ep, tr->out_ep); tr->handle = usb_open(dev); if (!tr->handle) { pr_error("bslhid: can't open device"); return -1; } #ifdef __Windows__ if (usb_set_configuration(tr->handle, tr->cfg_number) < 0) pr_error("warning: bslhid: can't set configuration"); #endif #ifdef __linux__ if (usb_detach_kernel_driver_np(tr->handle, tr->int_number) < 0) pr_error("warning: bslhid: can't detach kernel driver"); #endif if (usb_claim_interface(tr->handle, tr->int_number) < 0) { pr_error("bslhid: can't claim interface"); usb_close(tr->handle); return -1; } /* Save the bus path for a future suspend/resume */ strncpy(tr->bus_name, dev->bus->dirname, sizeof(tr->bus_name)); tr->bus_name[sizeof(tr->bus_name) - 1] = 0; return 0; }
static int open_interface(struct cp210x_transport *tr, struct usb_device *dev, int ino, int baud_rate) { #if defined(__linux__) int drv; char drName[256]; #endif printc_dbg(__FILE__": Trying to open interface %d on %s\n", ino, dev->filename); tr->int_number = ino; tr->handle = usb_open(dev); if (!tr->handle) { pr_error(__FILE__": can't open device"); return -1; } #if defined(__linux__) drv = usb_get_driver_np(tr->handle, tr->int_number, drName, sizeof(drName)); printc(__FILE__" : driver %d\n", drv); if (drv >= 0) { if (usb_detach_kernel_driver_np(tr->handle, tr->int_number) < 0) pr_error(__FILE__": warning: can't detach " "kernel driver"); } #endif #ifdef __Windows__ if (usb_set_configuration(tr->handle, 1) < 0) { pr_error(__FILE__": can't set configuration 1"); usb_close(tr->handle); return -1; } #endif if (usb_claim_interface(tr->handle, tr->int_number) < 0) { pr_error(__FILE__": can't claim interface"); usb_close(tr->handle); return -1; } if (configure_port(tr, baud_rate) < 0) { printc_err("Failed to configure for V1 device\n"); usb_close(tr->handle); return -1; } return 0; }
int main(int argc, char **argv) { struct cmdline_args args = {0}; int ret = 0; opdb_reset(); ctrlc_init(); args.devarg.vcc_mv = 3000; args.devarg.requested_serial = NULL; if (parse_cmdline_args(argc, argv, &args) < 0) return -1; if (sockets_init() < 0) return -1; printc_dbg("%s\n", version_text); if (setup_driver(&args) < 0) { sockets_exit(); return -1; } simio_init(); if (!args.no_rc) process_rc_file(); /* Process commands */ if (optind < argc) { while (optind < argc) { if (process_command(argv[optind++]) < 0) { ret = -1; break; } } } else { reader_loop(); } simio_exit(); stab_exit(); device_destroy(); sockets_exit(); return ret; }
static int reset_sequence(sport_t fd) { static const int states[] = { SPORT_MC_RTS, SPORT_MC_RTS | SPORT_MC_DTR, SPORT_MC_DTR }; int i; printc_dbg("Resetting GoodFET...\n"); for (i = 0; i < 3; i++) { if (sport_set_modem(fd, states[i]) < 0) { printc_err("goodfet: failed at step %d: %s\n", i, last_error()); return -1; } delay_ms(20); } return 0; }
static int do_init(struct tilib_device *dev, const struct device_args *args) { long version; char buf[1024]; union DEVICE_T device; /* Not sure if the path is actually modified by MSP430_Initialize, * but the argument isn't const, so probably safest to copy it. */ strncpy(buf, args->path, sizeof(buf)); buf[sizeof(buf) - 1] = 0; printc_dbg("MSP430_Initialize: %s\n", buf); if (dev->MSP430_Initialize(buf, &version) < 0) { report_error(dev, "MSP430_Initialize"); return -1; } if (version < 0) { printc("FET firmware update is required.\n"); if (args->flags & DEVICE_FLAG_DO_FWUPDATE) { if (do_fw_update(dev) < 0) { dev->MSP430_Close(0); return -1; } } else { printc("Re-run with --allow-fw-update to perform " "a firmware update.\n"); dev->MSP430_Close(0); return -1; } } else { printc_dbg("Firmware version is %d\n", version); } printc_dbg("MSP430_VCC: %d mV\n", args->vcc_mv); if (dev->MSP430_VCC(args->vcc_mv) < 0) { report_error(dev, "MSP430_VCC"); dev->MSP430_Close(0); return -1; } /* Without this delay, MSP430_OpenDevice will often hang. */ usleep(1000000); printc_dbg("MSP430_OpenDevice\n"); if (dev->MSP430_OpenDevice("DEVICE_UNKNOWN", "", 0, 0, 0) < 0) { report_error(dev, "MSP430_OpenDevice"); dev->MSP430_Close(0); return -1; } printc_dbg("MSP430_GetFoundDevice\n"); if (dev->MSP430_GetFoundDevice(device.buffer, sizeof(device.buffer)) < 0) { report_error(dev, "MSP430_GetFoundDevice"); dev->MSP430_Close(0); return -1; } printc_dbg("Device: %s (id = 0x%04x)\n", device.string, device.id); printc_dbg("%d breakpoints available\n", device.nBreakpoints); dev->base.max_breakpoints = device.nBreakpoints; if (dev->base.max_breakpoints > DEVICE_MAX_BREAKPOINTS) dev->base.max_breakpoints = DEVICE_MAX_BREAKPOINTS; printc_dbg("MSP430_EEM_Init\n"); threads_lock_init(&dev->mb_lock); if (dev->MSP430_EEM_Init(event_notify, (long)dev, (MessageID_t *)&my_message_ids) < 0) { report_error(dev, "MSP430_EEM_Init"); dev->MSP430_Close(0); threads_lock_destroy(&dev->mb_lock); return -1; } return 0; }
int cmd_erase(char **arg) { const char *type_text = get_arg(arg); const char *seg_text = get_arg(arg); device_erase_type_t type = DEVICE_ERASE_MAIN; address_t segment = 0; address_t total_size = 0; address_t segment_size = 0; if (seg_text && expr_eval(seg_text, &segment) < 0) { printc_err("erase: invalid expression: %s\n", seg_text); return -1; } if (type_text) { if (!strcasecmp(type_text, "all")) { type = DEVICE_ERASE_ALL; } else if (!strcasecmp(type_text, "segment")) { type = DEVICE_ERASE_SEGMENT; if (!seg_text) { printc_err("erase: expected segment " "address\n"); return -1; } } else if (!strcasecmp(type_text, "segrange")) { const char *total_text = get_arg(arg); const char *ss_text = get_arg(arg); if (!(total_text && ss_text)) { printc_err("erase: you must specify " "total and segment sizes\n"); return -1; } if (expr_eval(total_text, &total_size) < 0) { printc_err("erase: invalid expression: %s\n", total_text); return -1; } if (expr_eval(ss_text, &segment_size) < 0) { printc_err("erase: invalid expression: %s\n", ss_text); return -1; } if (segment_size > 0x200 || segment_size < 0x40) { printc_err("erase: invalid segment size: " "0x%x\n", segment_size); return -1; } } else { printc_err("erase: unknown erase type: %s\n", type_text); return -1; } } if (device_ctl(DEVICE_CTL_HALT) < 0) return -1; if (!segment_size) { printc("Erasing...\n"); return device_erase(type, segment); } else { printc("Erasing segments...\n"); while (total_size >= segment_size) { printc_dbg("Erasing 0x%04x...\n", segment); if (device_erase(DEVICE_ERASE_SEGMENT, segment) < 0) return -1; total_size -= segment_size; segment += segment_size; } } return 0; }
int main(int argc, char **argv) { struct cmdline_args args = {0}; int ret = 0; setvbuf(stderr, NULL, _IOFBF, 0); setvbuf(stdout, NULL, _IOFBF, 0); opdb_reset(); ctrlc_init(); args.devarg.vcc_mv = 3000; args.devarg.requested_serial = NULL; if (parse_cmdline_args(argc, argv, &args) < 0) goto fail_parse; if (args.flags & OPT_EMBEDDED) input_module = &input_async; if (input_module->init() < 0) goto fail_input; output_set_embedded(args.flags & OPT_EMBEDDED); if (sockets_init() < 0) { ret = -1; goto fail_sockets; } printc_dbg("%s", version_text); printc_dbg("%s\n", chipinfo_copyright()); if (setup_driver(&args) < 0) { ret = -1; goto fail_driver; } if (device_probe_id(device_default, args.devarg.forced_chip_id) < 0) printc_err("warning: device ID probe failed\n"); simio_init(); if (!(args.flags & OPT_NO_RC)) process_rc_file(args.alt_config); /* Process commands */ if (optind < argc) { while (optind < argc) { if (process_command(argv[optind++]) < 0) { ret = -1; break; } } } else { reader_loop(); } simio_exit(); device_destroy(); stab_exit(); fail_driver: sockets_exit(); fail_sockets: input_module->exit(); fail_input: fail_parse: /* We need to do this on Windows, because in embedded mode we * may still have a running background thread for input. If so, * returning from main() won't cause the process to terminate. */ #if defined(__CYGWIN__) cygwin_internal(CW_EXIT_PROCESS, (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE, 1); #elif defined(__Windows__) ExitProcess(ret); #endif return ret; }