Beispiel #1
0
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;
}
Beispiel #2
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");
}
Beispiel #3
0
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;
}
Beispiel #4
0
static int buspirate_expect_bin(struct programmer_t *pgm,
				char *send_data, size_t send_len,
				char *expect_data, size_t expect_len)
{
	char *recv_buf = alloca(expect_len);
	if (!pgm->flag & BP_FLAG_IN_BINMODE) {
		fprintf(stderr, "BusPirate: Internal error: buspirate_send_bin() called from ascii mode");
		exit(1);
	}

	buspirate_send_bin(pgm, send_data, send_len);
	buspirate_recv_bin(pgm, recv_buf, expect_len);
	if (memcmp(expect_data, recv_buf, expect_len) != 0)
		return 0;
	return 1;
}
Beispiel #5
0
/* Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction */
static int buspirate_paged_write(struct programmer_t *pgm,
		AVRPART *p,
		AVRMEM *m,
		unsigned int page_size,
		unsigned int base_addr,
		unsigned int n_data_bytes)
{
	int page, i;
	int addr = base_addr;
	int n_page_writes;
	int this_page_size;
	char cmd_buf[4096] = {'\0'};
	char send_byte, recv_byte;

	if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
		/* Return if we are not in binary mode. */
		return -1;
	}

	if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
		/* Return if we've nominated not to use paged writes. */
		return -1;
	}

	if (page_size>1024) {
		/* Page sizes greater than 1kB not yet supported. */
		return -1;
	}

	if (strcmp(m->desc,"flash") != 0) {
		/* Only flash memory currently supported. */
		return -1;
	}

	/* pre-check opcodes */
	if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
		fprintf(stderr,
			"%s failure: %s command not defined for %s\n",
			progname, "AVR_OP_LOADPAGE_LO", p->desc);
		return -1;
	}
	if (m->op[AVR_OP_LOADPAGE_HI] == NULL) {
		fprintf(stderr,
			"%s failure: %s command not defined for %s\n",
			progname, "AVR_OP_LOADPAGE_HI", p->desc);
		return -1;
	}

	/* Calculate total number of page writes needed: */
	n_page_writes = n_data_bytes/page_size;
	if (n_data_bytes%page_size >0)
		n_page_writes++;

	/* Ensure error LED is off: */
	pgm->err_led(pgm, OFF);

	/* Loop over pages: */
	for (page=0; page<n_page_writes; page++) {

		/* Determine bytes to write in this page: */
		this_page_size = page_size;
		if (page == n_page_writes-1)
			this_page_size = n_data_bytes - page_size*page;

		/* Set up command buffer: */
		memset(cmd_buf, 0, 4*this_page_size);
		for (i=0; i<this_page_size; i++) {

			addr = base_addr + page*page_size + i;

			if (i%2 == 0) {
				avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]));
				avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), addr/2);
				avr_set_input(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), m->buf[addr]);
			} else {
				avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]));
				avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), addr/2);
				avr_set_input(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), m->buf[addr]);
			}
		}

		/* 00000100 - Write then read */
		send_byte = 0x05;
		buspirate_send_bin(pgm, &send_byte, 1);

		/* Number of bytes to write: */
		send_byte = (4*this_page_size)/0x100;
		buspirate_send_bin(pgm, &send_byte, 1); /* High byte */
		send_byte = (4*this_page_size)%0x100;
		buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */

		/* Number of bytes to read: */
		send_byte = 0x0;
		buspirate_send_bin(pgm, &send_byte, 1); /* High byte */
		buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */

		/* Set programming LED: */
		pgm->pgm_led(pgm, ON);

		/* Send command buffer: */
		buspirate_send_bin(pgm, cmd_buf, 4*this_page_size);

		/* Check for write failure: */
		if ((buspirate_recv_bin(pgm, &recv_byte, 1) == EOF) || (recv_byte != 0x01)) {
			fprintf(stderr, "BusPirate: Fatal error: Write Then Read did not succeed.\n");
			pgm->pgm_led(pgm, OFF);
			pgm->err_led(pgm, ON);
			exit(1);
		}

		/* Unset programming LED: */
		pgm->pgm_led(pgm, OFF);

		/* Write loaded page to flash: */
		avr_write_page(pgm, p, m, addr);
	}

	return n_data_bytes;
}
Beispiel #6
0
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;
}