Signed-off-by: Stefan Tauner <stefan.tauner(a)student.tuwien.ac.at>
---
serprog-protocol.txt | 8 ++++++++
serprog.c | 30 ++++++++++++++++++++++++++----
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/serprog-protocol.txt b/serprog-protocol.txt
index b22d1b2..0cf5432 100644
--- a/serprog-protocol.txt
+++ b/serprog-protocol.txt
@@ -33,6 +33,7 @@ COMMAND Description Parameters Return Value
0x12 Set used bustype 8-bit flags (as with 0x05) ACK / NAK
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 16-bit requested frequency ACK + 16-bit set frequency / NAK
0x?? unimplemented command - invalid.
@@ -73,6 +74,12 @@ Additional information of the above commands:
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.
+ 0x14 (S_SPI_SCK):
+ Set the SPI clock frequency.
+ The requested frequency should be mapped by the programmer software
+ to a supported frequency 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.
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.
@@ -107,3 +114,4 @@ This define listing should help C coders - (it's here to be the single source fo
#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_SCK 0x14 /* Set SPI clock frequency */
diff --git a/serprog.c b/serprog.c
index 182edd1..1b231a3 100644
--- a/serprog.c
+++ b/serprog.c
@@ -69,6 +69,7 @@ static int serprog_shutdown(void *data);
#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_SCK 0x14 /* Set SPI clock frequency */
static uint16_t sp_device_serbuf_size = 16;
static uint16_t sp_device_opbuf_size = 300;
@@ -424,13 +425,14 @@ int serprog_init(void)
}
buses_supported = c;
msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
- (c & CHIP_BUSTYPE_PARALLEL) ? "on" : "off",
- (c & CHIP_BUSTYPE_LPC) ? "on" : "off",
- (c & CHIP_BUSTYPE_FWH) ? "on" : "off",
- (c & CHIP_BUSTYPE_SPI) ? "on" : "off");
+ (c & BUS_PARALLEL) ? "on" : "off",
+ (c & BUS_LPC) ? "on" : "off",
+ (c & BUS_FWH) ? "on" : "off",
+ (c & BUS_SPI) ? "on" : "off");
/* Check for the minimum operational set of commands. */
if (buses_supported & BUS_SPI) {
uint8_t bt = BUS_SPI;
+ char *f_spi;
if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
msg_perr("Error: SPI operation not supported while the "
"bustype is SPI\n");
@@ -461,6 +463,26 @@ int serprog_init(void)
spi_programmer_serprog.max_data_read = v;
msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
}
+ f_spi = extract_programmer_param("sck");
+ if (f_spi && strlen(f_spi)) {
+ uint8_t buf[2];
+ uint16_t tmp = atoi(f_spi);
+ buf[0] = tmp & 0xFF;
+ buf[1] = tmp >> 8;
+ if (sp_check_commandavail(S_CMD_S_SPI_SCK) == 0)
+ msg_pdbg(MSGHEADER "Setting SPI clock rate is "
+ "not supported!\n");
+ else if (sp_docommand(S_CMD_S_SPI_SCK, 2, buf, 2, buf)
+ == 0) {
+ tmp = buf[0] | (buf[1]<<8);
+ msg_pdbg(MSGHEADER "Requested to set SPI clock "
+ "frequency to %s kHz. It was actually "
+ "set to %d kHz\n", f_spi, tmp);
+ } else
+ msg_pdbg(MSGHEADER "Setting SPI clock rate "
+ "failed!\n");
+ }
+ free(f_spi);
bt = buses_supported;
sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
register_spi_programmer(&spi_programmer_serprog);
--
1.7.1