aboutsummaryrefslogtreecommitdiffstats
path: root/dediprog.c
diff options
context:
space:
mode:
Diffstat (limited to 'dediprog.c')
-rw-r--r--dediprog.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/dediprog.c b/dediprog.c
index c99c9225..03675e57 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -360,8 +360,9 @@ static int dediprog_set_spi_speed(unsigned int spispeed_idx)
return 0;
}
-static void fill_rw_cmd_payload(uint8_t *data_packet, unsigned int count, uint8_t dedi_spi_cmd,
- unsigned int *value, unsigned int *idx, unsigned int start, int is_read) {
+static void prepare_rw_cmd(
+ struct flashctx *const flash, uint8_t *data_packet, unsigned int count,
+ uint8_t dedi_spi_cmd, unsigned int *value, unsigned int *idx, unsigned int start, int is_read) {
/* First 5 bytes are common in both generations. */
data_packet[0] = count & 0xff;
data_packet[1] = (count >> 8) & 0xff;
@@ -370,6 +371,15 @@ static void fill_rw_cmd_payload(uint8_t *data_packet, unsigned int count, uint8_
data_packet[4] = 0; /* "Opcode". Specs imply necessity only for READ_MODE_4B_ADDR_FAST and WRITE_MODE_4B_ADDR_256B_PAGE_PGM */
if (protocol() >= PROTOCOL_V2) {
+ if (is_read && flash->chip->feature_bits & FEATURE_4BA_FAST_READ) {
+ data_packet[3] = READ_MODE_4B_ADDR_FAST_0x0C;
+ data_packet[4] = JEDEC_READ_4BA_FAST;
+ } else if (dedi_spi_cmd == WRITE_MODE_PAGE_PGM
+ && (flash->chip->feature_bits & FEATURE_4BA_WRITE)) {
+ data_packet[3] = WRITE_MODE_4B_ADDR_256B_PAGE_PGM_0x12;
+ data_packet[4] = JEDEC_BYTE_PROGRAM_4BA;
+ }
+
*value = *idx = 0;
data_packet[5] = 0; /* RFU */
data_packet[6] = (start >> 0) & 0xff;
@@ -438,7 +448,7 @@ static int dediprog_spi_bulk_read(struct flashctx *flash, uint8_t *buf, unsigned
uint8_t data_packet[command_packet_size];
unsigned int value, idx;
- fill_rw_cmd_payload(data_packet, count, READ_MODE_STD, &value, &idx, start, 1);
+ prepare_rw_cmd(flash, data_packet, count, READ_MODE_STD, &value, &idx, start, 1);
int ret = dediprog_write(CMD_READ, value, idx, data_packet, sizeof(data_packet));
if (ret != sizeof(data_packet)) {
@@ -594,7 +604,7 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, const uint8_t *buf, u
uint8_t data_packet[command_packet_size];
unsigned int value, idx;
- fill_rw_cmd_payload(data_packet, count, dedi_spi_cmd, &value, &idx, start, 0);
+ prepare_rw_cmd(flash, data_packet, count, dedi_spi_cmd, &value, &idx, start, 0);
int ret = dediprog_write(CMD_WRITE, value, idx, data_packet, sizeof(data_packet));
if (ret != sizeof(data_packet)) {
msg_perr("Command Write SPI Bulk failed, %s!\n", libusb_error_name(ret));
@@ -638,8 +648,8 @@ static int dediprog_spi_write(struct flashctx *flash, const uint8_t *buf,
if (residue) {
msg_pdbg("Slow write for partial block from 0x%x, length 0x%x\n",
start, residue);
- /* No idea about the real limit. Maybe 12, maybe more. */
- ret = spi_write_chunked(flash, buf, start, residue, 12);
+ /* No idea about the real limit. Maybe 16 including command and address, maybe more. */
+ ret = spi_write_chunked(flash, buf, start, residue, 11);
if (ret) {
dediprog_set_leds(LED_ERROR);
return ret;
@@ -659,7 +669,7 @@ static int dediprog_spi_write(struct flashctx *flash, const uint8_t *buf,
msg_pdbg("Slow write for partial block from 0x%x, length 0x%x\n",
start, len);
ret = spi_write_chunked(flash, buf + residue + bulklen,
- start + residue + bulklen, len, 12);
+ start + residue + bulklen, len, 11);
if (ret) {
dediprog_set_leds(LED_ERROR);
return ret;
@@ -931,7 +941,7 @@ static int parse_voltage(char *voltage)
return millivolt;
}
-static const struct spi_master spi_master_dediprog = {
+static struct spi_master spi_master_dediprog = {
.type = SPI_CONTROLLER_DEDIPROG,
.features = SPI_MASTER_NO_4BA_MODES,
.max_data_read = 16, /* 18 seems to work fine as well, but 19 times out sometimes with FW 5.15. */
@@ -1124,6 +1134,9 @@ int dediprog_init(void)
if (dediprog_standalone_mode())
return 1;
+ if (dediprog_devicetype == DEV_SF600 && protocol() == PROTOCOL_V2)
+ spi_master_dediprog.features |= SPI_MASTER_4BA;
+
if (register_spi_master(&spi_master_dediprog) || dediprog_set_leds(LED_NONE))
return 1;