/* * dbgrst.c - Reset a Neo through the debug board * * Copyright (C) 2008 by OpenMoko, Inc. * Written by Werner Almesberger * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include #define nTRST_ENABLE 0x1 /* ACBUS0/GPIOH0 */ #define nTRST 0x2 /* ACBUS1/GPIOH1 */ #define nSRST_ENABLE 0x4 /* ACBUS2/GPIOH2 */ #define nSRST 0x8 /* ACBUS3/GPIOH3 */ static const struct id { uint16_t vendor; uint16_t product; } ids[] = { { 0x0403, 0x6010 }, /* FTDI default IDs */ { 0x1457, 0x5118 }, /* Neo1973 debug board (FIC) */ { 0x1d50, 0x5118 }, /* Neo1973 debug board (OpenMoko) */ { 0 } }; static struct ftdi_context ftdi; static void open_ftdi(void) { const struct id *id; if (ftdi_init(&ftdi) < 0) { fprintf(stderr, "ftdi_init failed\n"); exit(1); } for (id = ids; id->vendor; id++) if (ftdi_usb_open(&ftdi, id->vendor, id->product) >= 0) break; if (!id->vendor) { fprintf(stderr, "no debug board found\n"); exit(1); } #if 0 /* not needed */ fprintf(stderr, "%04x:%04x\n", id->vendor, id->product); ftdi_set_interface(&ftdi, INTERFACE_A); ftdi_usb_reset(&ftdi); ftdi_set_latency_timer(&ftdi, 2); #endif if (ftdi_set_bitmode(&ftdi, 0x0b, BITMODE_MPSSE) < 0) { fprintf(stderr, "ftdi_set_bitmode: %s\n", ftdi_get_error_string(&ftdi)); exit(1); } } static void set_high(uint8_t data, uint8_t direction) { uint8_t buf[3] = { SET_BITS_HIGH, data, direction, }; int i; /* * For some reason, the FTDI sometimes doesn't accept the setting. * So we repeat a number of times to make it clear that compliance * is not optional. */ for (i = 0; i != 10; i++) if (ftdi_write_data(&ftdi, buf, 3) < 0) { fprintf(stderr, "ftdi_write_data: %s\n", ftdi_get_error_string(&ftdi)); exit(1); } } static void pulse_reset(void) { /* * We also have to make sure we don't assert nTRST. */ set_high(nTRST | nTRST_ENABLE, 0x0f); set_high(nTRST | nTRST_ENABLE | nSRST | nSRST_ENABLE, 0x0f); } static void usage(const char *name) { fprintf(stderr, "usage; %s\n", name); exit(1); } int main(int argc, char **argv) { if (argc != 1) usage(*argv); open_ftdi(); pulse_reset(); return 0; }