50 |
50 |
#include "pgm.h"
|
51 |
51 |
#include "serial.h"
|
52 |
52 |
|
|
53 |
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a)[0])
|
|
54 |
|
53 |
55 |
/* ====== Private data structure ====== */
|
54 |
56 |
/* CS and AUX pin bitmasks in
|
55 |
57 |
* 0100wxyz - Configure peripherals command */
|
... | ... | |
60 |
62 |
#define BP_FLAG_IN_BINMODE (1<<0)
|
61 |
63 |
#define BP_FLAG_XPARM_FORCE_ASCII (1<<1)
|
62 |
64 |
#define BP_FLAG_XPARM_RESET (1<<2)
|
63 |
|
#define BP_FLAG_XPARM_SPIFREQ (1<<3)
|
|
65 |
#define BP_FLAG_BIN_SPI (1<<3)
|
|
66 |
#define BP_FLAG_BIN_RAW (1<<4)
|
64 |
67 |
|
65 |
68 |
struct pdata
|
66 |
69 |
{
|
67 |
70 |
char hw_version[10];
|
68 |
71 |
int fw_version; /* = 100*fw_major + fw_minor */
|
69 |
72 |
int binmode_version;
|
70 |
|
int bin_spi_version;
|
|
73 |
int submode_version;
|
71 |
74 |
int current_peripherals_config;
|
72 |
|
int spifreq; /* 0..7 - see buspirate manual for what freq each value means */
|
|
75 |
int speed; /* Value for "set speed" bin mode commands */
|
73 |
76 |
int reset; /* See BP_RESET_* above */
|
74 |
77 |
};
|
75 |
78 |
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
... | ... | |
309 |
312 |
fprintf(stderr, "BusPirate: see BusPirate manual for details.\n");
|
310 |
313 |
return -1;
|
311 |
314 |
}
|
312 |
|
PDATA(pgm)->spifreq = spifreq;
|
313 |
|
pgm->flag |= BP_FLAG_XPARM_SPIFREQ;
|
|
315 |
pgm->flag |= BP_FLAG_BIN_SPI;
|
|
316 |
PDATA(pgm)->speed = spifreq;
|
|
317 |
continue;
|
|
318 |
}
|
|
319 |
|
|
320 |
unsigned khz;
|
|
321 |
if (sscanf(extended_param, "khz=%u", &khz) == 1) {
|
|
322 |
static const struct
|
|
323 |
{unsigned khz; char flag; int speed;} freq_map[] = {
|
|
324 |
{.khz=8000, .flag=BP_FLAG_BIN_SPI, .speed=7},
|
|
325 |
{.khz=4000, .flag=BP_FLAG_BIN_SPI, .speed=6},
|
|
326 |
{.khz=2600, .flag=BP_FLAG_BIN_SPI, .speed=5},
|
|
327 |
{.khz=2000, .flag=BP_FLAG_BIN_SPI, .speed=4},
|
|
328 |
{.khz=1000, .flag=BP_FLAG_BIN_SPI, .speed=3},
|
|
329 |
{.khz=400, .flag=BP_FLAG_BIN_RAW, .speed=3},
|
|
330 |
{.khz=250, .flag=BP_FLAG_BIN_SPI, .speed=2},
|
|
331 |
{.khz=125, .flag=BP_FLAG_BIN_SPI, .speed=1},
|
|
332 |
{.khz=100, .flag=BP_FLAG_BIN_RAW, .speed=2},
|
|
333 |
{.khz=50, .flag=BP_FLAG_BIN_RAW, .speed=1},
|
|
334 |
{.khz=30, .flag=BP_FLAG_BIN_SPI, .speed=0},
|
|
335 |
{.khz=5, .flag=BP_FLAG_BIN_RAW, .speed=0},
|
|
336 |
};
|
|
337 |
|
|
338 |
/* Find closest frequency <= requested frequency */
|
|
339 |
size_t i;
|
|
340 |
for (i = 0; i < ARRAY_SIZE(freq_map); ++i) {
|
|
341 |
if (freq_map[i].khz <= khz) {
|
|
342 |
break;
|
|
343 |
}
|
|
344 |
}
|
|
345 |
if (i >= ARRAY_SIZE(freq_map)) {
|
|
346 |
fprintf(stderr, "BusPirate: Requested "
|
|
347 |
"frequency too low: %d kHz\n", khz);
|
|
348 |
return -1;
|
|
349 |
}
|
|
350 |
if (khz != freq_map[i].khz) {
|
|
351 |
fprintf(stderr, "BusPirate: Closest "
|
|
352 |
"matching frequency: %d kHz\n",
|
|
353 |
freq_map[i].khz);
|
|
354 |
}
|
|
355 |
pgm->flag |= freq_map[i].flag;
|
|
356 |
PDATA(pgm)->speed = freq_map[i].speed;
|
314 |
357 |
continue;
|
315 |
358 |
}
|
316 |
359 |
|
... | ... | |
358 |
401 |
return -1;
|
359 |
402 |
}
|
360 |
403 |
|
361 |
|
if ((pgm->flag & BP_FLAG_XPARM_SPIFREQ) && buspirate_uses_ascii(pgm)) {
|
362 |
|
fprintf(stderr, "BusPirate: SPI speed selection is not supported in ASCII mode\n");
|
|
404 |
if (((pgm->flag & BP_FLAG_BIN_SPI) || (pgm->flag & BP_FLAG_BIN_RAW))
|
|
405 |
&& buspirate_uses_ascii(pgm)) {
|
|
406 |
fprintf(stderr, "BusPirate: speed selection is not supported in ASCII mode\n");
|
363 |
407 |
return -1;
|
364 |
408 |
}
|
365 |
409 |
|
... | ... | |
424 |
468 |
fprintf(stderr, "BusPirate is back in the text mode\n");
|
425 |
469 |
}
|
426 |
470 |
|
427 |
|
static int buspirate_start_spi_mode_bin(struct programmer_t *pgm)
|
428 |
|
{
|
|
471 |
static int buspirate_start_mode_bin(struct programmer_t *pgm)
|
|
472 |
{
|
|
473 |
const struct submode {
|
|
474 |
const char* name; /* Name of mode for user messages */
|
|
475 |
char enter; /* Command to enter from base binary mode */
|
|
476 |
const char* entered_format; /* Response, for "scanf" */
|
|
477 |
char config; /* Command to setup submode parameters */
|
|
478 |
}* submode;
|
|
479 |
if (pgm->flag & BP_FLAG_BIN_RAW) {
|
|
480 |
submode = &(const struct submode){
|
|
481 |
.name = "Raw-wire",
|
|
482 |
.enter = 0x05,
|
|
483 |
.entered_format = "RAW%d",
|
|
484 |
.config = 0x8C,
|
|
485 |
};
|
|
486 |
} else {
|
|
487 |
submode = &(const struct submode){
|
|
488 |
.name = "SPI",
|
|
489 |
.enter = 0x01,
|
|
490 |
.entered_format = "SPI%d",
|
|
491 |
|
|
492 |
/* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample
|
|
493 |
* we want: 3.3V(1), idle low(0), data change on
|
|
494 |
* trailing edge (1), sample in the middle
|
|
495 |
* of the pulse (0)
|
|
496 |
* => 0b10001010 = 0x8a */
|
|
497 |
.config = 0x8A,
|
|
498 |
};
|
|
499 |
}
|
|
500 |
|
429 |
501 |
char buf[20] = { '\0' };
|
430 |
502 |
|
431 |
503 |
/* == Switch to binmode - send 20x '\0' == */
|
... | ... | |
445 |
517 |
|
446 |
518 |
pgm->flag |= BP_FLAG_IN_BINMODE;
|
447 |
519 |
|
448 |
|
/* == Enter SPI mode == */
|
449 |
|
buf[0] = 0x01; /* Enter raw SPI mode */
|
|
520 |
/* == Set protocol sub-mode of binary mode == */
|
|
521 |
buf[0] = submode->enter;
|
450 |
522 |
buspirate_send_bin(pgm, buf, 1);
|
451 |
523 |
memset(buf, 0, sizeof(buf));
|
452 |
524 |
buspirate_recv_bin(pgm, buf, 4);
|
453 |
|
if (sscanf(buf, "SPI%d", &PDATA(pgm)->bin_spi_version) != 1) {
|
454 |
|
fprintf(stderr, "SPI mode not confirmed: '%s'\n", buf);
|
|
525 |
if (sscanf(buf, submode->entered_format,
|
|
526 |
&PDATA(pgm)->submode_version) != 1) {
|
|
527 |
fprintf(stderr, "%s mode not confirmed: '%s'\n",
|
|
528 |
submode->name, buf);
|
455 |
529 |
buspirate_reset_from_binmode(pgm);
|
456 |
530 |
return -1;
|
457 |
531 |
}
|
458 |
532 |
if (verbose)
|
459 |
|
fprintf(stderr, "BusPirate SPI version: %d\n",
|
460 |
|
PDATA(pgm)->bin_spi_version);
|
|
533 |
fprintf(stderr, "BusPirate %s version: %d\n",
|
|
534 |
submode->name, PDATA(pgm)->submode_version);
|
461 |
535 |
|
462 |
536 |
/* 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS
|
463 |
537 |
* we want power (0x48) and all reset pins high. */
|
... | ... | |
469 |
543 |
buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01);
|
470 |
544 |
usleep(50000); // sleep for 50ms after power up
|
471 |
545 |
|
472 |
|
/* 01100xxx - SPI speed
|
473 |
|
* xxx = 000=30kHz, 001=125kHz, 010=250kHz, 011=1MHz,
|
474 |
|
* 100=2MHz, 101=2.6MHz, 110=4MHz, 111=8MHz
|
475 |
|
* use 30kHz = 0x60 */
|
476 |
|
buspirate_expect_bin_byte(pgm, 0x60 | PDATA(pgm)->spifreq, 0x01);
|
|
546 |
/* 01100xxx - Set speed */
|
|
547 |
buspirate_expect_bin_byte(pgm, 0x60 | PDATA(pgm)->speed, 0x01);
|
477 |
548 |
|
478 |
|
/* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample
|
479 |
|
* we want: 3.3V(1), idle low(0), data change on trailing edge (1),
|
480 |
|
* sample in the middle of the pulse (0)
|
481 |
|
* => 0b10001010 = 0x8a */
|
482 |
|
buspirate_expect_bin_byte(pgm, 0x8A, 0x01);
|
|
549 |
/* Submode config */
|
|
550 |
buspirate_expect_bin_byte(pgm, submode->config, 0x01);
|
483 |
551 |
|
484 |
552 |
return 0;
|
485 |
553 |
}
|
... | ... | |
591 |
659 |
|
592 |
660 |
if (PDATA(pgm)->fw_version >= FW_BINMODE_VER && !(pgm->flag & BP_FLAG_XPARM_FORCE_ASCII)) {
|
593 |
661 |
fprintf(stderr, "BusPirate: using BINARY mode\n");
|
594 |
|
if (buspirate_start_spi_mode_bin(pgm) < 0)
|
595 |
|
fprintf(stderr, "%s: Failed to start binary SPI mode\n", progname);
|
|
662 |
if (buspirate_start_mode_bin(pgm) < 0)
|
|
663 |
fprintf(stderr, "%s: Failed to start binary mode\n", progname);
|
596 |
664 |
}
|
597 |
665 |
if (!pgm->flag & BP_FLAG_IN_BINMODE) {
|
598 |
666 |
fprintf(stderr, "BusPirate: using ASCII mode\n");
|
... | ... | |
622 |
690 |
static void buspirate_powerup(struct programmer_t *pgm)
|
623 |
691 |
{
|
624 |
692 |
if (pgm->flag & BP_FLAG_IN_BINMODE) {
|
625 |
|
/* Powerup in BinMode is handled in SPI init */
|
|
693 |
/* Powerup in BinMode is handled in binary mode init */
|
626 |
694 |
return;
|
627 |
695 |
} else
|
628 |
696 |
if (buspirate_expect(pgm, "W\n", "POWER SUPPLIES ON", 1))
|
... | ... | |
650 |
718 |
unsigned char cmd[4],
|
651 |
719 |
unsigned char res[4])
|
652 |
720 |
{
|
653 |
|
/* 0001xxxx - Bulk SPI transfer, send/read 1-16 bytes (0=1byte!)
|
|
721 |
/* 0001xxxx - Bulk transfer, send/read 1-16 bytes (0=1byte!)
|
654 |
722 |
* we are sending 4 bytes -> 0x13 */
|
655 |
723 |
if (!buspirate_expect_bin_byte(pgm, 0x13, 0x01))
|
656 |
724 |
return -1;
|
657 |
|
-
|