Also, move the macro list to its own file.
Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at --- Implemented and tested with my atmegaXXu2 flasher, works great with my coreboot target. Does anybody have an idea for a better macro name? Maybe just S_CMD_S_DRIVERS?
Documentation/serprog-protocol.txt | 33 +++++++--------------------- serprog.c | 42 +++++++++++++++--------------------- serprog.h | 25 +++++++++++++++++++++ 3 files changed, 50 insertions(+), 50 deletions(-) create mode 100644 serprog.h
diff --git a/Documentation/serprog-protocol.txt b/Documentation/serprog-protocol.txt index d8733cc..58f4417 100644 --- a/Documentation/serprog-protocol.txt +++ b/Documentation/serprog-protocol.txt @@ -34,6 +34,7 @@ COMMAND Description Parameters Return Value 0x13 Perform SPI operation 24-bit slen + 24-bit rlen ACK + rlen bytes of data / NAK + slen bytes of data 0x14 Set SPI clock frequency in Hz 32-bit requested frequency ACK + 32-bit set frequency / NAK +0x15 Toggle flash chip pin drivers 8-bit (0 disable, else enable) ACK / NAK 0x?? unimplemented command - invalid.
@@ -82,6 +83,12 @@ Additional information of the above commands: lower than the one requested. If there is no lower frequency available the lowest possible should be used. The value chosen is sent back in the reply with an ACK. + 0x15 (S_CMD_S_PIN_STATE): + Sets the state of the pin drivers connected to the flash chip. Disabling them allows other + devices (e.g. a mainboard's chipset) to access the chip. This way the serprog controller can + remain attached to the flash chip even when the board is running. The user is responsible to + NOT connect VCC and other permanently externally driven signals to the programmer as needed. + If the value is 0, then the drivers should be disabled, otherwise they should be enabled. About mandatory commands: The only truly mandatory commands for any device are 0x00, 0x01, 0x02 and 0x10, but one can't really do anything with these commands. @@ -92,28 +99,4 @@ Additional information of the above commands: In addition, support for these commands is recommended: S_CMD_Q_PGMNAME, S_CMD_Q_BUSTYPE, S_CMD_Q_CHIPSIZE (if parallel).
- -This define listing should help C coders - (it's here to be the single source for copying - will be a .h someday i think) -#define S_ACK 0x06 -#define S_NAK 0x15 -#define S_CMD_NOP 0x00 /* No operation */ -#define S_CMD_Q_IFACE 0x01 /* Query interface version */ -#define S_CMD_Q_CMDMAP 0x02 /* Query supported commands bitmap */ -#define S_CMD_Q_PGMNAME 0x03 /* Query programmer name */ -#define S_CMD_Q_SERBUF 0x04 /* Query Serial Buffer Size */ -#define S_CMD_Q_BUSTYPE 0x05 /* Query supported bustypes */ -#define S_CMD_Q_CHIPSIZE 0x06 /* Query supported chipsize (2^n format) */ -#define S_CMD_Q_OPBUF 0x07 /* Query operation buffer size */ -#define S_CMD_Q_WRNMAXLEN 0x08 /* Query Write to opbuf: Write-N maximum length */ -#define S_CMD_R_BYTE 0x09 /* Read a single byte */ -#define S_CMD_R_NBYTES 0x0A /* Read n bytes */ -#define S_CMD_O_INIT 0x0B /* Initialize operation buffer */ -#define S_CMD_O_WRITEB 0x0C /* Write opbuf: Write byte with address */ -#define S_CMD_O_WRITEN 0x0D /* Write to opbuf: Write-N */ -#define S_CMD_O_DELAY 0x0E /* Write opbuf: udelay */ -#define S_CMD_O_EXEC 0x0F /* Execute operation buffer */ -#define S_CMD_SYNCNOP 0x10 /* Special no-operation that returns NAK+ACK */ -#define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */ -#define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */ -#define S_CMD_O_SPIOP 0x13 /* Perform SPI operation. */ -#define S_CMD_S_SPI_FREQ 0x14 /* Set SPI clock frequency */ +See also serprog.h. diff --git a/serprog.c b/serprog.c index b179ea4..0f31696 100644 --- a/serprog.c +++ b/serprog.c @@ -38,6 +38,7 @@ #include "flash.h" #include "programmer.h" #include "chipdrivers.h" +#include "serprog.h"
#define MSGHEADER "serprog: "
@@ -48,30 +49,6 @@ */ static int serprog_shutdown(void *data);
-#define S_ACK 0x06 -#define S_NAK 0x15 -#define S_CMD_NOP 0x00 /* No operation */ -#define S_CMD_Q_IFACE 0x01 /* Query interface version */ -#define S_CMD_Q_CMDMAP 0x02 /* Query supported commands bitmap */ -#define S_CMD_Q_PGMNAME 0x03 /* Query programmer name */ -#define S_CMD_Q_SERBUF 0x04 /* Query Serial Buffer Size */ -#define S_CMD_Q_BUSTYPE 0x05 /* Query supported bustypes */ -#define S_CMD_Q_CHIPSIZE 0x06 /* Query supported chipsize (2^n format) */ -#define S_CMD_Q_OPBUF 0x07 /* Query operation buffer size */ -#define S_CMD_Q_WRNMAXLEN 0x08 /* Query opbuf-write-N maximum length */ -#define S_CMD_R_BYTE 0x09 /* Read a single byte */ -#define S_CMD_R_NBYTES 0x0A /* Read n bytes */ -#define S_CMD_O_INIT 0x0B /* Initialize operation buffer */ -#define S_CMD_O_WRITEB 0x0C /* Write opbuf: Write byte with address */ -#define S_CMD_O_WRITEN 0x0D /* Write to opbuf: Write-N */ -#define S_CMD_O_DELAY 0x0E /* Write opbuf: udelay */ -#define S_CMD_O_EXEC 0x0F /* Execute operation buffer */ -#define S_CMD_SYNCNOP 0x10 /* Special no-operation that returns NAK+ACK */ -#define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */ -#define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */ -#define S_CMD_O_SPIOP 0x13 /* Perform SPI operation. */ -#define S_CMD_S_SPI_FREQ 0x14 /* Set SPI clock frequency */ - static uint16_t sp_device_serbuf_size = 16; static uint16_t sp_device_opbuf_size = 300; /* Bitmap of supported commands */ @@ -687,6 +664,15 @@ int serprog_init(void) sp_device_opbuf_size); }
+ if (sp_check_commandavail(S_CMD_S_PIN_STATE)) { + uint8_t en = 1; + if (sp_docommand(S_CMD_S_PIN_STATE, 1, &en, 0, NULL) != 0) { + msg_perr("Error: could not enable output buffers\n"); + return 1; + } else + msg_pdbg(MSGHEADER "Output drivers enabled\n"); + } else + msg_pdbg(MSGHEADER "Warning: Programmer does not support toggling its output drivers\n"); sp_prev_was_write = 0; sp_streamed_transmit_ops = 0; sp_streamed_transmit_bytes = 0; @@ -759,9 +745,15 @@ static void sp_execute_opbuf(void)
static int serprog_shutdown(void *data) { - msg_pspew("%s\n", __func__); if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) sp_execute_opbuf(); + if (sp_check_commandavail(S_CMD_S_PIN_STATE)) { + uint8_t dis = 0; + if (sp_docommand(S_CMD_S_PIN_STATE, 1, &dis, 0, NULL) == 0) + msg_pdbg(MSGHEADER "Output drivers disabled\n"); + else + msg_perr(MSGHEADER "%s: Warning: could not disable output buffers\n", __func__); + } /* FIXME: fix sockets on windows(?), especially closing */ serialport_shutdown(&sp_fd); if (sp_max_write_n) diff --git a/serprog.h b/serprog.h new file mode 100644 index 0000000..b54aaea --- /dev/null +++ b/serprog.h @@ -0,0 +1,25 @@ +/* According to Serial Flasher Protocol Specification - version 1 */ +#define S_ACK 0x06 +#define S_NAK 0x15 +#define S_CMD_NOP 0x00 /* No operation */ +#define S_CMD_Q_IFACE 0x01 /* Query interface version */ +#define S_CMD_Q_CMDMAP 0x02 /* Query supported commands bitmap */ +#define S_CMD_Q_PGMNAME 0x03 /* Query programmer name */ +#define S_CMD_Q_SERBUF 0x04 /* Query Serial Buffer Size */ +#define S_CMD_Q_BUSTYPE 0x05 /* Query supported bustypes */ +#define S_CMD_Q_CHIPSIZE 0x06 /* Query supported chipsize (2^n format) */ +#define S_CMD_Q_OPBUF 0x07 /* Query operation buffer size */ +#define S_CMD_Q_WRNMAXLEN 0x08 /* Query Write to opbuf: Write-N maximum length */ +#define S_CMD_R_BYTE 0x09 /* Read a single byte */ +#define S_CMD_R_NBYTES 0x0A /* Read n bytes */ +#define S_CMD_O_INIT 0x0B /* Initialize operation buffer */ +#define S_CMD_O_WRITEB 0x0C /* Write opbuf: Write byte with address */ +#define S_CMD_O_WRITEN 0x0D /* Write to opbuf: Write-N */ +#define S_CMD_O_DELAY 0x0E /* Write opbuf: udelay */ +#define S_CMD_O_EXEC 0x0F /* Execute operation buffer */ +#define S_CMD_SYNCNOP 0x10 /* Special no-operation that returns NAK+ACK */ +#define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */ +#define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */ +#define S_CMD_O_SPIOP 0x13 /* Perform SPI operation. */ +#define S_CMD_S_SPI_FREQ 0x14 /* Set SPI clock frequency */ +#define S_CMD_S_PIN_STATE 0x15 /* Enable/disable output drivers */