diff options
Diffstat (limited to 'buspirate_spi.c')
-rw-r--r-- | buspirate_spi.c | 191 |
1 files changed, 93 insertions, 98 deletions
diff --git a/buspirate_spi.c b/buspirate_spi.c index fdfc0e45..eee8daa4 100644 --- a/buspirate_spi.c +++ b/buspirate_spi.c @@ -128,11 +128,6 @@ static int buspirate_wait_for_string(unsigned char *buf, const char *key) return ret; } -static int buspirate_spi_send_command_v1(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, - const unsigned char *writearr, unsigned char *readarr); -static int buspirate_spi_send_command_v2(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, - const unsigned char *writearr, unsigned char *readarr); - static struct spi_master spi_master_buspirate = { .features = SPI_MASTER_4BA, .max_data_read = MAX_DATA_UNSPECIFIED, @@ -205,6 +200,99 @@ out_shutdown: return ret; } +static int buspirate_spi_send_command_v1(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, unsigned char *readarr) +{ + unsigned int i = 0; + int ret = 0; + + if (writecnt > 16 || readcnt > 16 || (readcnt + writecnt) > 16) + return SPI_INVALID_LENGTH; + + /* 3 bytes extra for CS#, len, CS#. */ + if (buspirate_commbuf_grow(writecnt + readcnt + 3)) + return ERROR_OOM; + + /* Assert CS# */ + bp_commbuf[i++] = 0x02; + + bp_commbuf[i++] = 0x10 | (writecnt + readcnt - 1); + memcpy(bp_commbuf + i, writearr, writecnt); + i += writecnt; + memset(bp_commbuf + i, 0, readcnt); + + i += readcnt; + /* De-assert CS# */ + bp_commbuf[i++] = 0x03; + + ret = buspirate_sendrecv(bp_commbuf, i, i); + + if (ret) { + msg_perr("Bus Pirate communication error!\n"); + return SPI_GENERIC_ERROR; + } + + if (bp_commbuf[0] != 0x01) { + msg_perr("Protocol error while lowering CS#!\n"); + return SPI_GENERIC_ERROR; + } + + if (bp_commbuf[1] != 0x01) { + msg_perr("Protocol error while reading/writing SPI!\n"); + return SPI_GENERIC_ERROR; + } + + if (bp_commbuf[i - 1] != 0x01) { + msg_perr("Protocol error while raising CS#!\n"); + return SPI_GENERIC_ERROR; + } + + /* Skip CS#, length, writearr. */ + memcpy(readarr, bp_commbuf + 2 + writecnt, readcnt); + + return ret; +} + +static int buspirate_spi_send_command_v2(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, unsigned char *readarr) +{ + int i = 0, ret = 0; + + if (writecnt > 4096 || readcnt > 4096 || (readcnt + writecnt) > 4096) + return SPI_INVALID_LENGTH; + + /* 5 bytes extra for command, writelen, readlen. + * 1 byte extra for Ack/Nack. + */ + if (buspirate_commbuf_grow(max(writecnt + 5, readcnt + 1))) + return ERROR_OOM; + + /* Combined SPI write/read. */ + bp_commbuf[i++] = 0x04; + bp_commbuf[i++] = (writecnt >> 8) & 0xff; + bp_commbuf[i++] = writecnt & 0xff; + bp_commbuf[i++] = (readcnt >> 8) & 0xff; + bp_commbuf[i++] = readcnt & 0xff; + memcpy(bp_commbuf + i, writearr, writecnt); + + ret = buspirate_sendrecv(bp_commbuf, i + writecnt, 1 + readcnt); + + if (ret) { + msg_perr("Bus Pirate communication error!\n"); + return SPI_GENERIC_ERROR; + } + + if (bp_commbuf[0] != 0x01) { + msg_perr("Protocol error while sending SPI write/read!\n"); + return SPI_GENERIC_ERROR; + } + + /* Skip Ack. */ + memcpy(readarr, bp_commbuf + 1, readcnt); + + return ret; +} + #define BP_FWVERSION(a,b) ((a) << 8 | (b)) #define BP_HWVERSION(a,b) BP_FWVERSION(a,b) @@ -571,96 +659,3 @@ int buspirate_spi_init(void) return 0; } - -static int buspirate_spi_send_command_v1(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, - const unsigned char *writearr, unsigned char *readarr) -{ - unsigned int i = 0; - int ret = 0; - - if (writecnt > 16 || readcnt > 16 || (readcnt + writecnt) > 16) - return SPI_INVALID_LENGTH; - - /* 3 bytes extra for CS#, len, CS#. */ - if (buspirate_commbuf_grow(writecnt + readcnt + 3)) - return ERROR_OOM; - - /* Assert CS# */ - bp_commbuf[i++] = 0x02; - - bp_commbuf[i++] = 0x10 | (writecnt + readcnt - 1); - memcpy(bp_commbuf + i, writearr, writecnt); - i += writecnt; - memset(bp_commbuf + i, 0, readcnt); - - i += readcnt; - /* De-assert CS# */ - bp_commbuf[i++] = 0x03; - - ret = buspirate_sendrecv(bp_commbuf, i, i); - - if (ret) { - msg_perr("Bus Pirate communication error!\n"); - return SPI_GENERIC_ERROR; - } - - if (bp_commbuf[0] != 0x01) { - msg_perr("Protocol error while lowering CS#!\n"); - return SPI_GENERIC_ERROR; - } - - if (bp_commbuf[1] != 0x01) { - msg_perr("Protocol error while reading/writing SPI!\n"); - return SPI_GENERIC_ERROR; - } - - if (bp_commbuf[i - 1] != 0x01) { - msg_perr("Protocol error while raising CS#!\n"); - return SPI_GENERIC_ERROR; - } - - /* Skip CS#, length, writearr. */ - memcpy(readarr, bp_commbuf + 2 + writecnt, readcnt); - - return ret; -} - -static int buspirate_spi_send_command_v2(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, - const unsigned char *writearr, unsigned char *readarr) -{ - int i = 0, ret = 0; - - if (writecnt > 4096 || readcnt > 4096 || (readcnt + writecnt) > 4096) - return SPI_INVALID_LENGTH; - - /* 5 bytes extra for command, writelen, readlen. - * 1 byte extra for Ack/Nack. - */ - if (buspirate_commbuf_grow(max(writecnt + 5, readcnt + 1))) - return ERROR_OOM; - - /* Combined SPI write/read. */ - bp_commbuf[i++] = 0x04; - bp_commbuf[i++] = (writecnt >> 8) & 0xff; - bp_commbuf[i++] = writecnt & 0xff; - bp_commbuf[i++] = (readcnt >> 8) & 0xff; - bp_commbuf[i++] = readcnt & 0xff; - memcpy(bp_commbuf + i, writearr, writecnt); - - ret = buspirate_sendrecv(bp_commbuf, i + writecnt, 1 + readcnt); - - if (ret) { - msg_perr("Bus Pirate communication error!\n"); - return SPI_GENERIC_ERROR; - } - - if (bp_commbuf[0] != 0x01) { - msg_perr("Protocol error while sending SPI write/read!\n"); - return SPI_GENERIC_ERROR; - } - - /* Skip Ack. */ - memcpy(readarr, bp_commbuf + 1, readcnt); - - return ret; -} |