static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm) { int spi_cmd = -1; int cmd; char *rcvd, mode[11], buf[5]; buspirate_send(pgm, "m\n"); while(1) { rcvd = buspirate_readline(pgm, NULL, 0); if (spi_cmd == -1 && sscanf(rcvd, "%d. %10s", &cmd, mode)) { if (strcmp(mode, "SPI") == 0) spi_cmd = cmd; } if (buspirate_is_prompt(rcvd)) break; } if (spi_cmd == -1) { fprintf(stderr, "%s: SPI mode number not found. Does your BusPirate support SPI?\n", progname); fprintf(stderr, "%s: Try powercycling your BusPirate and try again.\n", progname); return -1; } snprintf(buf, sizeof(buf), "%d\n", spi_cmd); buspirate_send(pgm, buf); buf[0] = '\0'; while (1) { rcvd = buspirate_readline(pgm, NULL, 0); if (strstr(rcvd, "Normal (H=3.3V, L=GND)")) { /* BP firmware 2.1 defaults to Open-drain output. * That doesn't work on my board, even with pull-up * resistors. Select 3.3V output mode instead. */ sscanf(rcvd, " %d.", &cmd); snprintf(buf, sizeof(buf), "%d\n", cmd); } if (buspirate_is_prompt(rcvd)) { if (strncmp(rcvd, "SPI>", 4) == 0) { fprintf(stderr, "BusPirate is now configured for SPI\n"); break; } /* Not yet 'SPI>' prompt */ if (buf[0]) { buspirate_send(pgm, buf); buf[0] = '\0'; } else buspirate_send(pgm, "\n"); } } return 0; }
static int buspirate_cmd_ascii(struct programmer_t *pgm, unsigned char cmd[4], unsigned char res[4]) { char buf[25]; char *rcvd; int spi_write, spi_read, i = 0; snprintf(buf, sizeof(buf), "0x%02x 0x%02x 0x%02x 0x%02x\n", cmd[0], cmd[1], cmd[2], cmd[3]); buspirate_send(pgm, buf); while (i < 4) { rcvd = buspirate_readline(pgm, NULL, 0); /* WRITE: 0xAC READ: 0x04 */ if (sscanf(rcvd, "WRITE: 0x%x READ: 0x%x", &spi_write, &spi_read) == 2) { res[i++] = spi_read; } if (buspirate_is_prompt(rcvd)) break; } if (i != 4) { fprintf(stderr, "%s: error: SPI has not read 4 bytes back\n", progname); return -1; } /* wait for prompt */ while (buspirate_getc(pgm) != '>') /* do nothing */; return 0; }
static void buspirate_reset_from_binmode(struct programmer_t *pgm) { char buf[10]; buf[0] = 0x00; /* BinMode: revert to HiZ */ buspirate_send_bin(pgm, buf, 1); buf[0] = 0x0F; /* BinMode: reset */ buspirate_send_bin(pgm, buf, 1); /* read back all output */ memset(buf, '\0', sizeof(buf)); for (;;) { int rc; rc = buspirate_recv_bin(pgm, buf, sizeof(buf) - 1); if (buspirate_is_prompt(buf)) { pgm->flag &= ~BP_FLAG_IN_BINMODE; break; } if (rc == EOF) break; memset(buf, '\0', sizeof(buf)); } if (pgm->flag & BP_FLAG_IN_BINMODE) { fprintf(stderr, "BusPirate reset failed. You may need to powercycle it.\n"); exit(1); } if (verbose) fprintf(stderr, "BusPirate is back in the text mode\n"); }
static int buspirate_expect(struct programmer_t *pgm, char *send, char *expect, int wait_for_prompt) { int got_it = 0; size_t expect_len = strlen(expect); char *rcvd; buspirate_send(pgm, send); while (1) { rcvd = buspirate_readline(pgm, NULL, 0); if (strncmp(rcvd, expect, expect_len) == 0) { if (! wait_for_prompt) { serial_drain(&pgm->fd, 0); return 1; } else { got_it = 1; } } if (buspirate_is_prompt(rcvd)) break; } return got_it; }
static void buspirate_enable(struct programmer_t *pgm) { unsigned char *reset_str = "#\n"; unsigned char *accept_str = "y\n"; char *rcvd; int rc, print_banner = 0; /* Ensure configuration is self-consistant: */ if (buspirate_verifyconfig(pgm)<0) exit(1); /* Attempt to start binary SPI mode unless explicitly told otherwise: */ if (!buspirate_uses_ascii(pgm)) { fprintf(stderr, "Attempting to initiate BusPirate binary mode...\n"); /* Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode: */ buspirate_send_bin(pgm, "\n\n", 2); /* Clear input buffer: */ serial_drain(&pgm->fd, 0); /* Attempt to enter binary mode: */ if (buspirate_start_spi_mode_bin(pgm) >= 0) return; else fprintf(stderr, "%s: Failed to start binary SPI mode, falling back to ASCII...\n", progname); } fprintf(stderr, "Attempting to initiate BusPirate ASCII mode...\n"); /* Call buspirate_send_bin() instead of buspirate_send() * because we don't know if BP is in text or bin mode */ rc = buspirate_send_bin(pgm, reset_str, strlen(reset_str)); if (rc) { fprintf(stderr, "BusPirate is not responding. Serial port error: %d\n", rc); exit(1); } while(1) { rcvd = buspirate_readline_noexit(pgm, NULL, 0); if (! rcvd) { fprintf(stderr, "%s: Fatal: Programmer is not responding.\n", progname); exit(1); } if (strncmp(rcvd, "Are you sure?", 13) == 0) { buspirate_send_bin(pgm, accept_str, strlen(accept_str)); } if (strncmp(rcvd, "RESET", 5) == 0) { print_banner = 1; continue; } if (buspirate_is_prompt(rcvd)) { puts("**"); break; } if (print_banner) fprintf(stderr, "** %s", rcvd); } if (!(pgm->flag & BP_FLAG_IN_BINMODE)) { fprintf(stderr, "BusPirate: using ASCII mode\n"); if (buspirate_start_spi_mode_ascii(pgm) < 0) { fprintf(stderr, "%s: Failed to start ascii SPI mode\n", progname); exit(1); } } }
static void buspirate_enable(struct programmer_t *pgm) { unsigned char *reset_str = "#\n"; unsigned char *accept_str = "y\n"; char *rcvd; int fw_v1 = 0, fw_v2 = 0; int rc, print_banner = 0; fprintf(stderr, "Detecting BusPirate...\n"); /* Call buspirate_send_bin() instead of buspirate_send() * because we don't know if BP is in text or bin mode */ rc = buspirate_send_bin(pgm, reset_str, strlen(reset_str)); if (rc) { fprintf(stderr, "BusPirate is not responding. Serial port error: %d\n", rc); exit(1); } while(1) { rcvd = buspirate_readline_noexit(pgm, NULL, 0); if (! rcvd) { fprintf(stderr, "BusPirate is not responding. Attempting reset.\n"); buspirate_reset_from_binmode(pgm); /* re-run buspirate_enable() */ buspirate_enable(pgm); return; } if (strncmp(rcvd, "Are you sure?", 13) == 0) { buspirate_send_bin(pgm, accept_str, strlen(accept_str)); } if (strncmp(rcvd, "RESET", 5) == 0) { print_banner = 1; continue; } if (buspirate_is_prompt(rcvd)) { puts("**"); break; } sscanf(rcvd, "Bus Pirate %9s", PDATA(pgm)->hw_version); sscanf(rcvd, "Firmware v%d.%d", &fw_v1, &fw_v2); if (print_banner) fprintf(stderr, "** %s", rcvd); } PDATA(pgm)->fw_version = 100 * fw_v1 + fw_v2; if (PDATA(pgm)->hw_version[0] == 0 || PDATA(pgm)->fw_version == 0) { fprintf(stderr, "BusPirate not detected. Aborting.\n"); exit(1); } if (buspirate_verifyconfig(pgm) < 0) exit(1); if (PDATA(pgm)->fw_version >= FW_BINMODE_VER && !(pgm->flag & BP_FLAG_XPARM_FORCE_ASCII)) { fprintf(stderr, "BusPirate: using BINARY mode\n"); if (buspirate_start_spi_mode_bin(pgm) < 0) fprintf(stderr, "%s: Failed to start binary SPI mode\n", progname); } if (!pgm->flag & BP_FLAG_IN_BINMODE) { fprintf(stderr, "BusPirate: using ASCII mode\n"); if (buspirate_start_spi_mode_ascii(pgm) < 0) { fprintf(stderr, "%s: Failed to start ascii SPI mode\n", progname); exit(1); } } }