1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2009, 2010, 2011, 2012 Carl-Daniel Hailfinger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16 #include <stdio.h>
17 #include <strings.h>
18 #include <string.h>
19 #include <stdbool.h>
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include <unistd.h>
23 #include "flash.h"
24 #include "programmer.h"
25 #include "spi.h"
26
27 /* Change this to #define if you want to test without a serial implementation */
28 #undef FAKE_COMMUNICATION
29
30 struct buspirate_speeds {
31 const char *name;
32 const int speed;
33 };
34
35 #define BP_DEFAULTBAUD 115200
36
37 #ifndef FAKE_COMMUNICATION
buspirate_serialport_setup(char * dev)38 static int buspirate_serialport_setup(char *dev)
39 {
40 /* 115200bps, 8 databits, no parity, 1 stopbit */
41 sp_fd = sp_openserport(dev, BP_DEFAULTBAUD);
42 if (sp_fd == SER_INV_FD)
43 return 1;
44 return 0;
45 }
46 #else
47 #define buspirate_serialport_setup(...) 0
48 #define serialport_shutdown(...) 0
49 #define serialport_write(...) 0
50 #define serialport_read(...) 0
51 #define sp_flush_incoming(...) 0
52 #endif
53
54 struct bp_spi_data {
55 unsigned char *commbuf;
56 int commbufsize;
57 };
58
buspirate_commbuf_grow(int bufsize,unsigned char ** bp_commbuf,int * bp_commbufsize)59 static int buspirate_commbuf_grow(int bufsize, unsigned char **bp_commbuf, int *bp_commbufsize)
60 {
61 unsigned char *tmpbuf;
62
63 /* Never shrink. realloc() calls are expensive. */
64 if (bufsize <= *bp_commbufsize)
65 return 0;
66
67 tmpbuf = realloc(*bp_commbuf, bufsize);
68 if (!tmpbuf) {
69 /* Keep the existing buffer because memory is already tight. */
70 msg_perr("Out of memory!\n");
71 return ERROR_OOM;
72 }
73
74 *bp_commbuf = tmpbuf;
75 *bp_commbufsize = bufsize;
76 return 0;
77 }
78
buspirate_sendrecv(unsigned char * buf,unsigned int writecnt,unsigned int readcnt)79 static int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt,
80 unsigned int readcnt)
81 {
82 unsigned int i;
83 int ret = 0;
84
85 msg_pspew("%s: write %i, read %i ", __func__, writecnt, readcnt);
86 if (!writecnt && !readcnt) {
87 msg_perr("Zero length command!\n");
88 return 1;
89 }
90 if (writecnt)
91 msg_pspew("Sending");
92 for (i = 0; i < writecnt; i++)
93 msg_pspew(" 0x%02x", buf[i]);
94 #ifdef FAKE_COMMUNICATION
95 /* Placate the caller for now. */
96 if (readcnt) {
97 buf[0] = 0x01;
98 memset(buf + 1, 0xff, readcnt - 1);
99 }
100 ret = 0;
101 #else
102 if (writecnt)
103 ret = serialport_write(buf, writecnt);
104 if (ret)
105 return ret;
106 if (readcnt)
107 ret = serialport_read(buf, readcnt);
108 if (ret)
109 return ret;
110 #endif
111 if (readcnt)
112 msg_pspew(", receiving");
113 for (i = 0; i < readcnt; i++)
114 msg_pspew(" 0x%02x", buf[i]);
115 msg_pspew("\n");
116 return 0;
117 }
118
buspirate_wait_for_string(unsigned char * buf,const char * key)119 static int buspirate_wait_for_string(unsigned char *buf, const char *key)
120 {
121 unsigned int keylen = strlen(key);
122 int ret;
123
124 ret = buspirate_sendrecv(buf, 0, keylen);
125 while (!ret) {
126 if (!memcmp(buf, key, keylen))
127 return 0;
128 memmove(buf, buf + 1, keylen - 1);
129 ret = buspirate_sendrecv(buf + keylen - 1, 0, 1);
130 }
131 return ret;
132 }
133
buspirate_spi_shutdown(void * data)134 static int buspirate_spi_shutdown(void *data)
135 {
136 struct bp_spi_data *bp_data = data;
137 unsigned char *const bp_commbuf = bp_data->commbuf;
138 int ret = 0, ret2 = 0;
139 /* No need to allocate a buffer here, we know that bp_commbuf is at least DEFAULT_BUFSIZE big. */
140
141 /* Exit raw SPI mode (enter raw bitbang mode) */
142 bp_commbuf[0] = 0x00;
143 if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
144 goto out_shutdown;
145 if ((ret = buspirate_wait_for_string(bp_commbuf, "BBIO")))
146 goto out_shutdown;
147 if ((ret = buspirate_sendrecv(bp_commbuf, 0, 1)))
148 goto out_shutdown;
149 msg_pdbg("Raw bitbang mode version %c\n", bp_commbuf[0]);
150 if (bp_commbuf[0] != '1') {
151 msg_perr("Can't handle raw bitbang mode version %c!\n", bp_commbuf[0]);
152 ret = 1;
153 goto out_shutdown;
154 }
155 /* Reset Bus Pirate (return to user terminal) */
156 bp_commbuf[0] = 0x0f;
157 ret = buspirate_sendrecv(bp_commbuf, 1, 0);
158
159 out_shutdown:
160 /* Shut down serial port communication */
161 ret2 = serialport_shutdown(NULL);
162 /* Keep the oldest error, it is probably the best indicator. */
163 if (ret2 && !ret)
164 ret = ret2;
165
166 free(bp_commbuf);
167 if (ret)
168 msg_pdbg("Bus Pirate shutdown failed.\n");
169 else
170 msg_pdbg("Bus Pirate shutdown completed.\n");
171
172 free(data);
173 return ret;
174 }
175
176 static struct spi_master spi_master_buspirate = {
177 .features = SPI_MASTER_4BA,
178 .max_data_read = MAX_DATA_UNSPECIFIED,
179 .max_data_write = MAX_DATA_UNSPECIFIED,
180 .command = NULL,
181 .read = default_spi_read,
182 .write_256 = default_spi_write_256,
183 .shutdown = buspirate_spi_shutdown,
184 };
185
186 static const struct buspirate_speeds spispeeds[] = {
187 {"30k", 0x0},
188 {"125k", 0x1},
189 {"250k", 0x2},
190 {"1M", 0x3},
191 {"2M", 0x4},
192 {"2.6M", 0x5},
193 {"4M", 0x6},
194 {"8M", 0x7},
195 {NULL, 0x0}
196 };
197
198 static const struct buspirate_speeds serialspeeds[] = {
199 {"115200", 115200},
200 {"230400", 230400},
201 {"250000", 250000},
202 {"2000000", 2000000},
203 {"2M", 2000000},
204 {NULL, 0}
205 };
206
buspirate_spi_send_command_v1(const struct flashctx * flash,unsigned int writecnt,unsigned int readcnt,const unsigned char * writearr,unsigned char * readarr)207 static int buspirate_spi_send_command_v1(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
208 const unsigned char *writearr, unsigned char *readarr)
209 {
210 unsigned int i = 0;
211 int ret = 0;
212 struct bp_spi_data *bp_data = flash->mst->spi.data;
213
214 if (writecnt > 16 || readcnt > 16 || (readcnt + writecnt) > 16)
215 return SPI_INVALID_LENGTH;
216
217 /* 3 bytes extra for CS#, len, CS#. */
218 if (buspirate_commbuf_grow(writecnt + readcnt + 3, &bp_data->commbuf, &bp_data->commbufsize))
219 return ERROR_OOM;
220
221 unsigned char *const bp_commbuf = bp_data->commbuf;
222
223 /* Assert CS# */
224 bp_commbuf[i++] = 0x02;
225
226 bp_commbuf[i++] = 0x10 | (writecnt + readcnt - 1);
227 memcpy(bp_commbuf + i, writearr, writecnt);
228 i += writecnt;
229 memset(bp_commbuf + i, 0, readcnt);
230
231 i += readcnt;
232 /* De-assert CS# */
233 bp_commbuf[i++] = 0x03;
234
235 ret = buspirate_sendrecv(bp_commbuf, i, i);
236
237 if (ret) {
238 msg_perr("Bus Pirate communication error!\n");
239 return SPI_GENERIC_ERROR;
240 }
241
242 if (bp_commbuf[0] != 0x01) {
243 msg_perr("Protocol error while lowering CS#!\n");
244 return SPI_GENERIC_ERROR;
245 }
246
247 if (bp_commbuf[1] != 0x01) {
248 msg_perr("Protocol error while reading/writing SPI!\n");
249 return SPI_GENERIC_ERROR;
250 }
251
252 if (bp_commbuf[i - 1] != 0x01) {
253 msg_perr("Protocol error while raising CS#!\n");
254 return SPI_GENERIC_ERROR;
255 }
256
257 /* Skip CS#, length, writearr. */
258 memcpy(readarr, bp_commbuf + 2 + writecnt, readcnt);
259
260 return ret;
261 }
262
buspirate_spi_send_command_v2(const struct flashctx * flash,unsigned int writecnt,unsigned int readcnt,const unsigned char * writearr,unsigned char * readarr)263 static int buspirate_spi_send_command_v2(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
264 const unsigned char *writearr, unsigned char *readarr)
265 {
266 int i = 0, ret = 0;
267 struct bp_spi_data *bp_data = flash->mst->spi.data;
268
269 if (writecnt > 4096 || readcnt > 4096 || (readcnt + writecnt) > 4096)
270 return SPI_INVALID_LENGTH;
271
272 /* 5 bytes extra for command, writelen, readlen.
273 * 1 byte extra for Ack/Nack.
274 */
275 if (buspirate_commbuf_grow(max(writecnt + 5, readcnt + 1), &bp_data->commbuf, &bp_data->commbufsize))
276 return ERROR_OOM;
277
278 unsigned char *const bp_commbuf = bp_data->commbuf;
279
280 /* Combined SPI write/read. */
281 bp_commbuf[i++] = 0x04;
282 bp_commbuf[i++] = (writecnt >> 8) & 0xff;
283 bp_commbuf[i++] = writecnt & 0xff;
284 bp_commbuf[i++] = (readcnt >> 8) & 0xff;
285 bp_commbuf[i++] = readcnt & 0xff;
286 memcpy(bp_commbuf + i, writearr, writecnt);
287
288 ret = buspirate_sendrecv(bp_commbuf, i + writecnt, 1 + readcnt);
289
290 if (ret) {
291 msg_perr("Bus Pirate communication error!\n");
292 return SPI_GENERIC_ERROR;
293 }
294
295 if (bp_commbuf[0] != 0x01) {
296 msg_perr("Protocol error while sending SPI write/read!\n");
297 return SPI_GENERIC_ERROR;
298 }
299
300 /* Skip Ack. */
301 memcpy(readarr, bp_commbuf + 1, readcnt);
302
303 return ret;
304 }
305
306 #define BP_FWVERSION(a,b) ((a) << 8 | (b))
307 #define BP_HWVERSION(a,b) BP_FWVERSION(a,b)
308
309 /**
310 * The Bus Pirate's PIC microcontroller supports custom baud rates by manually specifying a
311 * clock divisor that can be calculated with the formula (16000000 / (4 * baud)) - 1.
312 */
313 #define BP_DIVISOR(baud) ((4000000/(baud)) - 1)
314
buspirate_spi_init(const struct programmer_cfg * cfg)315 static int buspirate_spi_init(const struct programmer_cfg *cfg)
316 {
317 char *tmp;
318 char *dev;
319 int i;
320 int cnt;
321 unsigned int fw_version_major = 0;
322 unsigned int fw_version_minor = 0;
323 unsigned int hw_version_major = 0;
324 unsigned int hw_version_minor = 0;
325 int spispeed = 0x7;
326 int serialspeed_index = -1;
327 int ret = 0;
328 bool hiz = false;
329 bool pullup = false;
330 bool psu = false;
331 bool aux = true;
332 unsigned char *bp_commbuf;
333 int bp_commbufsize;
334
335 dev = extract_programmer_param_str(cfg, "dev");
336 if (dev && !strlen(dev)) {
337 free(dev);
338 dev = NULL;
339 }
340 if (!dev) {
341 msg_perr("No serial device given. Use flashrom -p buspirate_spi:dev=/dev/ttyUSB0\n");
342 return 1;
343 }
344
345 tmp = extract_programmer_param_str(cfg, "spispeed");
346 if (tmp) {
347 for (i = 0; spispeeds[i].name; i++) {
348 if (!strncasecmp(spispeeds[i].name, tmp, strlen(spispeeds[i].name))) {
349 spispeed = spispeeds[i].speed;
350 break;
351 }
352 }
353 if (!spispeeds[i].name)
354 msg_perr("Invalid SPI speed, using default.\n");
355 }
356 free(tmp);
357
358 /* Extract serialspeed parameter */
359 tmp = extract_programmer_param_str(cfg, "serialspeed");
360 if (tmp) {
361 for (i = 0; serialspeeds[i].name; i++) {
362 if (!strncasecmp(serialspeeds[i].name, tmp, strlen(serialspeeds[i].name))) {
363 serialspeed_index = i;
364 break;
365 }
366 }
367 if (!serialspeeds[i].name)
368 msg_perr("Invalid serial speed %s, using default.\n", tmp);
369 }
370 free(tmp);
371
372 tmp = extract_programmer_param_str(cfg, "pullups");
373 if (tmp) {
374 if (strcasecmp("on", tmp) == 0) {
375 pullup = true;
376 } else if (strcasecmp("off", tmp) == 0) {
377 ; // ignore
378 } else {
379 msg_perr("Invalid pullups state. Use on/off.\n");
380 free(tmp);
381 return 1;
382 }
383 }
384 free(tmp);
385
386 tmp = extract_programmer_param_str(cfg, "hiz");
387 if (tmp) {
388 if (strcasecmp("on", tmp) == 0) {
389 hiz = true;
390 } else if (strcasecmp("off", tmp) == 0) {
391 if (pullup) {
392 msg_perr("Invalid combination: pullups=on & hiz=off at same time is not possible.\n");
393 free(tmp);
394 return 1;
395 } else {
396 ; // ignore
397 }
398 } else {
399 msg_perr("Invalid hiz state. Use on/off.\n");
400 free(tmp);
401 return 1;
402 }
403 }
404 free(tmp);
405
406 tmp = extract_programmer_param_str(cfg, "psus");
407 if (tmp) {
408 if (strcasecmp("on", tmp) == 0) {
409 psu = true;
410 } else if (strcasecmp("off", tmp) == 0) {
411 ; // ignore
412 } else {
413 msg_perr("Invalid psus state. Use on/off.\n");
414 free(tmp);
415 return 1;
416 }
417 }
418 free(tmp);
419
420 tmp = extract_programmer_param_str(cfg, "aux");
421 if (tmp) {
422 if (strcasecmp("high", tmp) == 0)
423 ; /* Default */
424 else if (strcasecmp("low", tmp) == 0)
425 aux = false;
426 else
427 msg_perr("Invalid AUX state, driving high by default.\n");
428 }
429 free(tmp);
430
431 /* Default buffer size is 19: 16 bytes data, 3 bytes control. */
432 #define DEFAULT_BUFSIZE (16 + 3)
433 bp_commbuf = malloc(DEFAULT_BUFSIZE);
434 if (!bp_commbuf) {
435 msg_perr("Out of memory!\n");
436 free(dev);
437 return ERROR_OOM;
438 }
439 bp_commbufsize = DEFAULT_BUFSIZE;
440
441 ret = buspirate_serialport_setup(dev);
442 free(dev);
443 if (ret) {
444 free(bp_commbuf);
445 return ret;
446 }
447
448
449 struct bp_spi_data *bp_data = calloc(1, sizeof(*bp_data));
450 if (!bp_data) {
451 msg_perr("Unable to allocate space for SPI master data\n");
452 free(bp_commbuf);
453 return 1;
454 }
455 bp_data->commbuf = bp_commbuf;
456 bp_data->commbufsize = bp_commbufsize;
457
458 /* This is the brute force version, but it should work.
459 * It is likely to fail if a previous flashrom run was aborted during a write with the new SPI commands
460 * in firmware v5.5 because that firmware may wait for up to 4096 bytes of input before responding to
461 * 0x00 again. The obvious workaround (sending 4096 bytes of \0) may cause significant startup delays.
462 */
463 for (i = 0; i < 20; i++) {
464 /* Enter raw bitbang mode */
465 bp_commbuf[0] = 0x00;
466 /* Send the command, don't read the response. */
467 ret = buspirate_sendrecv(bp_commbuf, 1, 0);
468 if (ret)
469 goto init_err_cleanup_exit;
470 /* The old way to handle responses from a Bus Pirate already in BBIO mode was to flush any
471 * response which came in over serial. Unfortunately that does not work reliably on Linux
472 * with FTDI USB-serial.
473 */
474 //sp_flush_incoming();
475 /* The Bus Pirate can't handle UART input buffer overflow in BBIO mode, and sending a sequence
476 * of 0x00 too fast apparently triggers such an UART input buffer overflow.
477 */
478 internal_sleep(10000);
479 }
480 /* We know that 20 commands of \0 should elicit at least one BBIO1 response. */
481 if ((ret = buspirate_wait_for_string(bp_commbuf, "BBIO")))
482 goto init_err_cleanup_exit;
483
484 /* Reset the Bus Pirate. */
485 bp_commbuf[0] = 0x0f;
486 /* Send the command, don't read the response. */
487 if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
488 goto init_err_cleanup_exit;
489 if ((ret = buspirate_wait_for_string(bp_commbuf, "irate ")))
490 goto init_err_cleanup_exit;
491 /* Read the hardware version string. Last byte of the buffer is reserved for \0. */
492 for (i = 0; i < DEFAULT_BUFSIZE - 1; i++) {
493 if ((ret = buspirate_sendrecv(bp_commbuf + i, 0, 1)))
494 goto init_err_cleanup_exit;
495 if (strchr("\r\n\t ", bp_commbuf[i]))
496 break;
497 }
498 bp_commbuf[i] = '\0';
499 msg_pdbg("Detected Bus Pirate hardware ");
500 if (bp_commbuf[0] != 'v')
501 msg_pdbg("(unknown version number format)");
502 else if (!strchr("0123456789", bp_commbuf[1]))
503 msg_pdbg("(unknown version number format)");
504 else {
505 hw_version_major = strtoul((char *)bp_commbuf + 1, &tmp, 10);
506 while ((*tmp != '\0') && !strchr("0123456789", *tmp))
507 tmp++;
508 hw_version_minor = strtoul(tmp, NULL, 10);
509 msg_pdbg("%u.%u", hw_version_major, hw_version_minor);
510 }
511 msg_pdbg2(" (\"%s\")", bp_commbuf);
512 msg_pdbg("\n");
513
514 if ((ret = buspirate_wait_for_string(bp_commbuf, "irmware ")))
515 goto init_err_cleanup_exit;
516 /* Read the firmware version string. Last byte of the buffer is reserved for \0. */
517 for (i = 0; i < DEFAULT_BUFSIZE - 1; i++) {
518 if ((ret = buspirate_sendrecv(bp_commbuf + i, 0, 1)))
519 goto init_err_cleanup_exit;
520 if (strchr("\r\n\t ", bp_commbuf[i]))
521 break;
522 }
523 bp_commbuf[i] = '\0';
524 msg_pdbg("Detected Bus Pirate firmware ");
525 if (bp_commbuf[0] != 'v')
526 msg_pdbg("(unknown version number format)");
527 else if (!strchr("0123456789", bp_commbuf[1]))
528 msg_pdbg("(unknown version number format)");
529 else {
530 fw_version_major = strtoul((char *)bp_commbuf + 1, &tmp, 10);
531 while ((*tmp != '\0') && !strchr("0123456789", *tmp))
532 tmp++;
533 fw_version_minor = strtoul(tmp, NULL, 10);
534 msg_pdbg("%u.%u", fw_version_major, fw_version_minor);
535 }
536 msg_pdbg2(" (\"%s\")", bp_commbuf);
537 msg_pdbg("\n");
538
539 if ((ret = buspirate_wait_for_string(bp_commbuf, "HiZ>")))
540 goto init_err_cleanup_exit;
541
542 /* Tell the user about missing SPI binary mode in firmware 2.3 and older. */
543 if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(2, 4)) {
544 msg_pinfo("Bus Pirate firmware 2.3 and older does not support binary SPI access.\n");
545 msg_pinfo("Please upgrade to the latest firmware (at least 2.4).\n");
546 ret = SPI_PROGRAMMER_ERROR;
547 goto init_err_cleanup_exit;
548 }
549
550 /* Use fast SPI mode in firmware 5.5 and newer. */
551 if (BP_FWVERSION(fw_version_major, fw_version_minor) >= BP_FWVERSION(5, 5)) {
552 msg_pdbg("Using SPI command set v2.\n");
553 /* Sensible default buffer size. */
554 if (buspirate_commbuf_grow(260 + 5, &bp_commbuf, &bp_commbufsize)) {
555 ret = ERROR_OOM;
556 goto init_err_cleanup_exit;
557 }
558 bp_data->commbuf = bp_commbuf;
559 bp_data->commbufsize = bp_commbufsize;
560 spi_master_buspirate.max_data_read = 2048;
561 spi_master_buspirate.max_data_write = 256;
562 spi_master_buspirate.command = buspirate_spi_send_command_v2;
563 } else {
564 msg_pinfo("Bus Pirate firmware 5.4 and older does not support fast SPI access.\n");
565 msg_pinfo("Reading/writing a flash chip may take hours.\n");
566 msg_pinfo("It is recommended to upgrade to firmware 5.5 or newer.\n");
567 /* Sensible default buffer size. */
568 if (buspirate_commbuf_grow(16 + 3, &bp_commbuf, &bp_commbufsize)) {
569 ret = ERROR_OOM;
570 goto init_err_cleanup_exit;
571 }
572 bp_data->commbuf = bp_commbuf;
573 bp_data->commbufsize = bp_commbufsize;
574 spi_master_buspirate.max_data_read = 12;
575 spi_master_buspirate.max_data_write = 12;
576 spi_master_buspirate.command = buspirate_spi_send_command_v1;
577 }
578
579 /* Workaround for broken speed settings in firmware 6.1 and older. */
580 if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(6, 2))
581 if (spispeed > 0x4) {
582 msg_perr("Bus Pirate firmware 6.1 and older does not support SPI speeds above 2 MHz. "
583 "Limiting speed to 2 MHz.\n");
584 msg_pinfo("It is recommended to upgrade to firmware 6.2 or newer.\n");
585 spispeed = 0x4;
586 }
587
588 /* This works because speeds numbering starts at 0 and is contiguous. */
589 msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed].name);
590
591 /* Set 2M baud serial speed by default on hardware 3.0 and newer if a custom speed was not set */
592 if (serialspeed_index == -1 && BP_HWVERSION(hw_version_major, hw_version_minor) >= BP_HWVERSION(3, 0)) {
593 serialspeed_index = ARRAY_SIZE(serialspeeds) - 2;
594 msg_pdbg("Bus Pirate v3 or newer detected. Set serial speed to 2M baud.\n");
595 }
596
597 /* Set custom serial speed if specified */
598 if (serialspeed_index != -1) {
599 if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(5, 5)) {
600 /* This feature requires firmware 5.5 or newer */
601 msg_perr("Bus Pirate firmware 5.4 and older does not support custom serial speeds."
602 "Using default speed of 115200 baud.\n");
603 } else if (serialspeeds[serialspeed_index].speed != BP_DEFAULTBAUD) {
604 /* Set the serial speed to match the user's choice if it doesn't already */
605
606 if (BP_HWVERSION(hw_version_major, hw_version_minor) < BP_HWVERSION(3, 0))
607 msg_pwarn("Increased serial speeds may not work on older (<3.0) Bus Pirates."
608 " Continue at your own risk.\n");
609
610 /* Enter baud rate configuration mode */
611 cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "b\n");
612 if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
613 goto init_err_cleanup_exit;
614 if ((ret = buspirate_wait_for_string(bp_commbuf, ">")))
615 goto init_err_cleanup_exit;
616
617 /* Enter manual clock divisor entry mode */
618 cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "10\n");
619 if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
620 goto init_err_cleanup_exit;
621 if ((ret = buspirate_wait_for_string(bp_commbuf, ">")))
622 goto init_err_cleanup_exit;
623
624 /* Set the clock divisor to the value calculated from the user's input */
625 cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "%d\n",
626 BP_DIVISOR(serialspeeds[serialspeed_index].speed));
627
628 if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
629 goto init_err_cleanup_exit;
630 sleep(1);
631
632 /* Reconfigure the host's serial baud rate to the new value */
633 if ((ret = serialport_config(sp_fd, serialspeeds[serialspeed_index].speed))) {
634 msg_perr("Unable to configure system baud rate to specified value.");
635 goto init_err_cleanup_exit;
636 }
637
638 /* Return to the main prompt */
639 bp_commbuf[0] = ' ';
640 if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
641 goto init_err_cleanup_exit;
642 if ((ret = buspirate_wait_for_string(bp_commbuf, "HiZ>")))
643 goto init_err_cleanup_exit;
644
645 msg_pdbg("Serial speed is %d baud\n", serialspeeds[serialspeed_index].speed);
646 }
647
648 }
649
650
651
652 /* Enter raw bitbang mode */
653 for (i = 0; i < 20; i++) {
654 bp_commbuf[0] = 0x00;
655 if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
656 goto init_err_cleanup_exit;
657 }
658 if ((ret = buspirate_wait_for_string(bp_commbuf, "BBIO")))
659 goto init_err_cleanup_exit;
660 if ((ret = buspirate_sendrecv(bp_commbuf, 0, 1)))
661 goto init_err_cleanup_exit;
662 msg_pdbg("Raw bitbang mode version %c\n", bp_commbuf[0]);
663 if (bp_commbuf[0] != '1') {
664 msg_perr("Can't handle raw bitbang mode version %c!\n", bp_commbuf[0]);
665 ret = 1;
666 goto init_err_cleanup_exit;
667 }
668 /* Enter raw SPI mode */
669 bp_commbuf[0] = 0x01;
670 ret = buspirate_sendrecv(bp_commbuf, 1, 0);
671 if (ret)
672 goto init_err_cleanup_exit;
673 if ((ret = buspirate_wait_for_string(bp_commbuf, "SPI")))
674 goto init_err_cleanup_exit;
675 if ((ret = buspirate_sendrecv(bp_commbuf, 0, 1)))
676 goto init_err_cleanup_exit;
677 msg_pdbg("Raw SPI mode version %c\n", bp_commbuf[0]);
678 if (bp_commbuf[0] != '1') {
679 msg_perr("Can't handle raw SPI mode version %c!\n", bp_commbuf[0]);
680 ret = 1;
681 goto init_err_cleanup_exit;
682 }
683
684 /* Initial setup (SPI peripherals config): Enable power, CS high */
685 bp_commbuf[0] = 0x40 | 0x09;
686 if (pullup) {
687 bp_commbuf[0] |= (1 << 2);
688 msg_pdbg("Enabling pull-up resistors.\n");
689 }
690 if (psu) {
691 bp_commbuf[0] |= (1 << 3);
692 msg_pdbg("Enabling PSUs.\n");
693 }
694 if (aux) {
695 bp_commbuf[0] |= (1 << 1);
696 msg_pdbg("Driving AUX high.\n");
697 } else {
698 msg_pdbg("Driving AUX low.\n");
699 }
700 ret = buspirate_sendrecv(bp_commbuf, 1, 1);
701 if (ret)
702 goto init_err_cleanup_exit;
703 if (bp_commbuf[0] != 0x01) {
704 msg_perr("Protocol error while setting power/CS/AUX(/Pull-up resistors)!\n");
705 ret = 1;
706 goto init_err_cleanup_exit;
707 }
708
709 /* Set SPI speed */
710 bp_commbuf[0] = 0x60 | spispeed;
711 ret = buspirate_sendrecv(bp_commbuf, 1, 1);
712 if (ret)
713 goto init_err_cleanup_exit;
714 if (bp_commbuf[0] != 0x01) {
715 msg_perr("Protocol error while setting SPI speed!\n");
716 ret = 1;
717 goto init_err_cleanup_exit;
718 }
719
720 /* Set SPI config: output type, idle, clock edge, sample */
721 bp_commbuf[0] = 0x80 | 0xa;
722 if (pullup || hiz) {
723 bp_commbuf[0] &= ~(1 << 3);
724 msg_pdbg("Pull-ups or HiZ enabled, so using HiZ pin output! (Open-Drain mode)\n");
725 }
726 ret = buspirate_sendrecv(bp_commbuf, 1, 1);
727 if (ret)
728 goto init_err_cleanup_exit;
729 if (bp_commbuf[0] != 0x01) {
730 msg_perr("Protocol error while setting SPI config!\n");
731 ret = 1;
732 goto init_err_cleanup_exit;
733 }
734
735 /* De-assert CS# */
736 bp_commbuf[0] = 0x03;
737 ret = buspirate_sendrecv(bp_commbuf, 1, 1);
738 if (ret)
739 goto init_err_cleanup_exit;
740 if (bp_commbuf[0] != 0x01) {
741 msg_perr("Protocol error while raising CS#!\n");
742 ret = 1;
743 goto init_err_cleanup_exit;
744 }
745
746 return register_spi_master(&spi_master_buspirate, bp_data);
747
748 init_err_cleanup_exit:
749 buspirate_spi_shutdown(bp_data);
750 return ret;
751 }
752
753 const struct programmer_entry programmer_buspirate_spi = {
754 .name = "buspirate_spi",
755 .type = OTHER,
756 /* FIXME */
757 .devs.note = "Dangerous Prototypes Bus Pirate\n",
758 .init = buspirate_spi_init,
759 };
760