- mostly formatting - drop the 256 B write limit and set max_data_write to 2^24 in case of 0 - add debug output
Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at --- serprog-protocol.txt | 1 + serprog.c | 95 +++++++++++++++++++++++++++++--------------------- 2 files changed, 56 insertions(+), 40 deletions(-)
diff --git a/serprog-protocol.txt b/serprog-protocol.txt index cced0dc..2391aef 100644 --- a/serprog-protocol.txt +++ b/serprog-protocol.txt @@ -69,6 +69,7 @@ Additional information of the above commands: Sending a byte with more than 1 bit set will make the programmer decide among them on it's own. Bit values as with Q_BUSTYPE. 0x13 (O_SPIOP): + Send and receive bytes via SPI. Maximum slen is Q_WRNMAXLEN result after Q_BUSTYPE returns only SPI or S_BUSTYPE == SPI is used. Same for rlen and Q_RDNMAXLEN. This operation is immediate, meaning it doesnt use the operation buffer. diff --git a/serprog.c b/serprog.c index d61d0d7..5f2c014 100644 --- a/serprog.c +++ b/serprog.c @@ -425,14 +425,15 @@ int serprog_init(void)
if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) { msg_perr("Warning: NAK to query supported buses\n"); - c = CHIP_BUSTYPE_NONSPI; /* A reasonable default for now. */ + c = CHIP_BUSTYPE_NONSPI; /* A reasonable default for now. */ } buses_supported = c; /* Check for the minimum operational set of commands. */ if (buses_supported & CHIP_BUSTYPE_SPI) { uint8_t bt = CHIP_BUSTYPE_SPI; if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) { - msg_perr("Error: SPI operation not supported while the SPI bustype is\n"); + msg_perr("Error: SPI operation not supported while the " + "bustype is SPI\n"); exit(1); } /* Success of any of these commands is optional. We dont need @@ -445,21 +446,20 @@ int serprog_init(void) v = ((unsigned int)(rbuf[0]) << 0); v |= ((unsigned int)(rbuf[1]) << 8); v |= ((unsigned int)(rbuf[2]) << 16); - /* Limit to 256 because we dont need longer writes. */ - if ((v==0)||(v>256)) { - v = 256; - } + if (v == 0) + v = (1 << 24) - 1; /* SPI-op maximum. */ spi_programmer_serprog.max_data_write = v; + msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v); } if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) { uint32_t v; v = ((unsigned int)(rbuf[0]) << 0); v |= ((unsigned int)(rbuf[1]) << 8); v |= ((unsigned int)(rbuf[2]) << 16); - if (v==0) { - v = (1<<24)-1; /* SPI-op maximum. */ - } + if (v == 0) + v = (1 << 24) - 1; /* SPI-op maximum. */ spi_programmer_serprog.max_data_read = v; + msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v); } bt = buses_supported; sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL); @@ -468,12 +468,14 @@ int serprog_init(void)
if (buses_supported & CHIP_BUSTYPE_NONSPI) { if (sp_check_commandavail(S_CMD_O_INIT) == 0) { - msg_perr("Error: Initialize operation buffer not supported\n"); + msg_perr("Error: Initialize operation buffer " + "not supported\n"); exit(1); }
if (sp_check_commandavail(S_CMD_O_DELAY) == 0) { - msg_perr("Error: Write to opbuf: delay not supported\n"); + msg_perr("Error: Write to opbuf: " + "delay not supported\n"); exit(1); }
@@ -483,14 +485,15 @@ int serprog_init(void) msg_perr("Error: Single byte read not supported\n"); exit(1); } - /* This could be translated to single byte reads (if missing), * - * but now we dont support that. */ + /* This could be translated to single byte reads (if missing), + * but now we dont support that. */ if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) { msg_perr("Error: Read n bytes not supported\n"); exit(1); } if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) { - msg_perr("Error: Write to opbuf: write byte not supported\n"); + msg_perr("Error: Write to opbuf: " + "write byte not supported\n"); exit(1); }
@@ -502,27 +505,29 @@ int serprog_init(void) sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8); sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16); if (!sp_max_write_n) { - sp_max_write_n = (1<<24); + sp_max_write_n = (1 << 24); } - msg_pdbg(MSGHEADER "Maximum write-n length %d\n", - sp_max_write_n); + msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", + sp_max_write_n); sp_write_n_buf = malloc(sp_max_write_n); if (!sp_write_n_buf) { - msg_perr("Error: cannot allocate memory for Write-n buffer\n"); + msg_perr("Error: cannot allocate memory for " + "Write-n buffer\n"); exit(1); } sp_write_n_bytes = 0; }
- if ((sp_check_commandavail(S_CMD_Q_RDNMAXLEN)) - &&((sp_docommand(S_CMD_Q_RDNMAXLEN,0,NULL, 3, rbuf) == 0))) { + if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) && + (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) { sp_max_read_n = ((unsigned int)(rbuf[0]) << 0); sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8); sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16); - msg_pdbg(MSGHEADER "Maximum read-n length %d\n", - sp_max_read_n ? sp_max_read_n : (1<<24)); + msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", + sp_max_read_n ? sp_max_read_n : (1 << 24)); } else { - msg_pdbg(MSGHEADER "Maximum read-n length not reported\n"); + msg_pdbg(MSGHEADER "Maximum read-n length " + "not reported\n"); sp_max_read_n = 0; }
@@ -544,7 +549,8 @@ int serprog_init(void) if (sp_check_commandavail(S_CMD_O_INIT)) { /* This would be inconsistent. */ if (sp_check_commandavail(S_CMD_O_EXEC) == 0) { - msg_perr("Error: Execute operation buffer not supported\n"); + msg_perr("Error: Execute operation buffer not " + "supported\n"); exit(1); }
@@ -553,11 +559,13 @@ int serprog_init(void) exit(1); }
- if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2, &sp_device_opbuf_size)) { - msg_perr("Warning: NAK to query operation buffer size\n"); + if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2, + &sp_device_opbuf_size)) { + msg_perr("Warning: NAK to query operation buffer " + "size\n"); } msg_pdbg(MSGHEADER "operation buffer size %d\n", - sp_device_opbuf_size); + sp_device_opbuf_size); }
sp_prev_was_write = 0; @@ -757,38 +765,45 @@ void serprog_delay(int delay) }
int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, - const unsigned char *writearr, unsigned char *readarr) + const unsigned char *writearr, + unsigned char *readarr) { unsigned char *parmbuf; int ret; msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt); if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) sp_execute_opbuf(); - parmbuf = malloc(writecnt+6); - if (!parmbuf) sp_die("Error: cannot malloc SPI send param buffer"); + parmbuf = malloc(writecnt + 6); + if (!parmbuf) + sp_die("Error: cannot malloc SPI send param buffer"); parmbuf[0] = (writecnt >> 0) & 0xFF; parmbuf[1] = (writecnt >> 8) & 0xFF; parmbuf[2] = (writecnt >> 16) & 0xFF; parmbuf[3] = (readcnt >> 0) & 0xFF; parmbuf[4] = (readcnt >> 8) & 0xFF; parmbuf[5] = (readcnt >> 16) & 0xFF; - memcpy(parmbuf+6, writearr, writecnt); - ret = sp_docommand(S_CMD_O_SPIOP, writecnt+6, parmbuf, readcnt, readarr); + memcpy(parmbuf + 6, writearr, writecnt); + ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt, + readarr); free(parmbuf); return ret; }
+/* FIXME: This function is optimized so that it does not split each + * transaction into chip page_size long blocks unnecessarily like + * spi_read_chunked. When spi_read_chunked is fixed this method can be + * removed. */ int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { int i; - int max_read = spi_programmer_serprog.max_data_read; - /* This function is optimized in that it doesnt split the read into - chip page_size length blocks unnecessarily. */ - for(i=0;i<len;) { - int rv; - int len_left = ((len-i)>max_read) ? max_read : (len-i); - if ((rv=spi_nbyte_read(start+i, buf+i, len_left))) return rv; - i += len_left; + const int max_read = spi_programmer_serprog.max_data_read; + for(i = 0; i < len; ) { + int ret; + int cur_len = min(max_read, (len - i)); + ret = spi_nbyte_read(start + i, buf + i, cur_len); + if (ret) + return ret; + i += cur_len; } return 0; }