static int buspirate_start_spi_mode_bin(struct programmer_t *pgm) { char buf[20] = { '\0' }; /* == Switch to binmode - send 20x '\0' == */ buspirate_send_bin(pgm, buf, sizeof(buf)); /* Expecting 'BBIOx' reply */ memset(buf, 0, sizeof(buf)); buspirate_recv_bin(pgm, buf, 5); if (sscanf(buf, "BBIO%d", &PDATA(pgm)->binmode_version) != 1) { fprintf(stderr, "Binary mode not confirmed: '%s'\n", buf); buspirate_reset_from_binmode(pgm); return -1; } if (verbose) fprintf(stderr, "BusPirate binmode version: %d\n", PDATA(pgm)->binmode_version); pgm->flag |= BP_FLAG_IN_BINMODE; /* == Enter SPI mode == */ buf[0] = 0x01; /* Enter raw SPI mode */ buspirate_send_bin(pgm, buf, 1); memset(buf, 0, sizeof(buf)); buspirate_recv_bin(pgm, buf, 4); if (sscanf(buf, "SPI%d", &PDATA(pgm)->bin_spi_version) != 1) { fprintf(stderr, "SPI mode not confirmed: '%s'\n", buf); buspirate_reset_from_binmode(pgm); return -1; } if (verbose) fprintf(stderr, "BusPirate SPI version: %d\n", PDATA(pgm)->bin_spi_version); /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS * we want power (0x48) and all reset pins high. */ PDATA(pgm)->current_peripherals_config = 0x48; PDATA(pgm)->current_peripherals_config |= BP_RESET_CS; PDATA(pgm)->current_peripherals_config |= BP_RESET_AUX; if (buspirate_has_aux2(pgm)) PDATA(pgm)->current_peripherals_config |= BP_RESET_AUX2; buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01); usleep(50000); // sleep for 50ms after power up /* 01100xxx - SPI speed * xxx = 000=30kHz, 001=125kHz, 010=250kHz, 011=1MHz, * 100=2MHz, 101=2.6MHz, 110=4MHz, 111=8MHz * use 30kHz = 0x60 */ buspirate_expect_bin_byte(pgm, 0x60 | PDATA(pgm)->spifreq, 0x01); /* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample * we want: 3.3V(1), idle low(0), data change on trailing edge (1), * sample in the middle of the pulse (0) * => 0b10001010 = 0x8a */ buspirate_expect_bin_byte(pgm, 0x8A, 0x01); return 0; }
static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p) { unsigned char cmd[4]; unsigned char res[4]; if (pgm->flag & BP_FLAG_IN_BINMODE) { /* Clear configured reset pin(s): CS and/or AUX and/or AUX2 */ PDATA(pgm)->current_peripherals_config &= ~PDATA(pgm)->reset; buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01); } else buspirate_expect(pgm, "{\n", "CS ENABLED", 1); if (p->op[AVR_OP_PGM_ENABLE] == NULL) { fprintf(stderr, "program enable instruction not defined for part \"%s\"\n", p->desc); return -1; } memset(cmd, 0, sizeof(cmd)); avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); pgm->cmd(pgm, cmd, res); if (res[2] != cmd[1]) return -2; return 0; }
static void buspirate_powerdown(struct programmer_t *pgm) { if (pgm->flag & BP_FLAG_IN_BINMODE) { /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups, y=AUX, z=CS * we want everything off -- 0b01000000 = 0x40 */ if (buspirate_expect_bin_byte(pgm, 0x40, 0x01)) return; } else if (buspirate_expect(pgm, "w\n", "POWER SUPPLIES OFF", 1)) return; fprintf(stderr, "%s: warning: did not get a response to PowerDown command.\n", progname); }
static int buspirate_cmd_bin(struct programmer_t *pgm, unsigned char cmd[4], unsigned char res[4]) { /* 0001xxxx - Bulk SPI transfer, send/read 1-16 bytes (0=1byte!) * we are sending 4 bytes -> 0x13 */ if (!buspirate_expect_bin_byte(pgm, 0x13, 0x01)) return -1; buspirate_send_bin(pgm, (char *)cmd, 4); buspirate_recv_bin(pgm, (char *)res, 4); return 0; }
static void buspirate_powerdown(struct programmer_t *pgm) { if (pgm->flag & BP_FLAG_IN_BINMODE) { /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups, y=AUX, z=CS * we want everything off -- 0b01000000 = 0x40 */ if (buspirate_expect_bin_byte(pgm, 0x40, 0x01)) return; } else { if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) { if (!buspirate_expect(pgm, "g\n", "PWM disabled", 1)) { fprintf(stderr, "%s: warning: did not get a response to stop PWM command.\n", progname); } } if (buspirate_expect(pgm, "w\n", "Power supplies OFF", 1)) return; } fprintf(stderr, "%s: warning: did not get a response to PowerDown command.\n", progname); }
static int buspirate_start_spi_mode_bin(struct programmer_t *pgm) { char buf[20] = { '\0' }; /* == Switch to binmode - send 20x '\0' == */ buspirate_send_bin(pgm, buf, sizeof(buf)); /* Expecting 'BBIOx' reply */ memset(buf, 0, sizeof(buf)); buspirate_recv_bin(pgm, buf, 5); if (sscanf(buf, "BBIO%d", &PDATA(pgm)->binmode_version) != 1) { fprintf(stderr, "Binary mode not confirmed: '%s'\n", buf); buspirate_reset_from_binmode(pgm); return -1; } if (verbose) fprintf(stderr, "BusPirate binmode version: %d\n", PDATA(pgm)->binmode_version); pgm->flag |= BP_FLAG_IN_BINMODE; /* == Enter SPI mode == */ buf[0] = 0x01; /* Enter raw SPI mode */ buspirate_send_bin(pgm, buf, 1); memset(buf, 0, sizeof(buf)); buspirate_recv_bin(pgm, buf, 4); if (sscanf(buf, "SPI%d", &PDATA(pgm)->bin_spi_version) != 1) { fprintf(stderr, "SPI mode not confirmed: '%s'\n", buf); buspirate_reset_from_binmode(pgm); return -1; } if (verbose) fprintf(stderr, "BusPirate SPI version: %d\n", PDATA(pgm)->bin_spi_version); if (pgm->flag & BP_FLAG_NOPAGEDWRITE) { if (verbose) fprintf(stderr, "%s: Paged flash write disabled.\n", progname); } else { /* Check for write-then-read without !CS/CS and disable paged_write if absent: */ strncpy(buf, "\x5\x0\x0\x0\x0", 5); buspirate_send_bin(pgm, buf, 5); buspirate_recv_bin(pgm, buf, 1); if (buf[0] != 0x01) { /* Disable paged write: */ pgm->flag |= BP_FLAG_NOPAGEDWRITE; /* Return to SPI mode (0x00s have landed us back in binary bitbang mode): */ buf[0] = 0x1; buspirate_send_bin(pgm, buf, 1); if (verbose) fprintf(stderr, "%s: Disabling paged flash write. (Need BusPirate firmware >=v5.10.)\n", progname); /* Flush serial buffer: */ serial_drain(&pgm->fd, 0); } else { if (verbose) fprintf(stderr, "%s: Paged flash write enabled.\n", progname); } } /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS * we want power (0x48) and all reset pins high. */ PDATA(pgm)->current_peripherals_config = 0x48 | PDATA(pgm)->reset; buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01); usleep(50000); // sleep for 50ms after power up /* 01100xxx - SPI speed * xxx = 000=30kHz, 001=125kHz, 010=250kHz, 011=1MHz, * 100=2MHz, 101=2.6MHz, 110=4MHz, 111=8MHz * use 30kHz = 0x60 */ buspirate_expect_bin_byte(pgm, 0x60 | PDATA(pgm)->spifreq, 0x01); /* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample * we want: 3.3V(1), idle low(0), data change on trailing edge (1), * sample in the middle of the pulse (0) * => 0b10001010 = 0x8a */ buspirate_expect_bin_byte(pgm, 0x8A, 0x01); return 0; }