This allows to drive MCU RST lines or similar with the ch341a during a flashrom run. CS1 is active low and CS2 is active high; note that the tristate state is a weak pullup, thus using CS2 would need an external pull-down.
Signed-off-by: Urja Rannikko urjaman@gmail.com --- ch341a_spi.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/ch341a_spi.c b/ch341a_spi.c index 6eb2804..7e5d577 100644 --- a/ch341a_spi.c +++ b/ch341a_spi.c @@ -303,8 +303,12 @@ static uint8_t swap_byte(uint8_t x) static int32_t enable_pins(bool enable) { uint8_t buf[] = { + /* We provide CS1 as "nACT" and CS2 as "ACT" during operation for ISP + * designs to drive eg. reset lines, meaning CS1 is driven low during + * flashrom run and CS2 high. Note that the tristate state is a weak + * pullup, thus using CS2 needs an external pull-down. */ CH341A_CMD_UIO_STREAM, - CH341A_CMD_UIO_STM_OUT | 0x37, // CS high (all of them), SCK=0, DOUT*=1 + CH341A_CMD_UIO_STM_OUT | (enable ? 0x35 : 0x33), // SCK=0, DOUT*=1 CH341A_CMD_UIO_STM_DIR | (enable ? 0x3F : 0x00), // Interface output enable / disable CH341A_CMD_UIO_STM_END, }; @@ -327,11 +331,11 @@ static void pluck_cs(uint8_t *ptr) stored_delay_us = 0; } *ptr++ = CH341A_CMD_UIO_STREAM; - *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x37; /* deasserted */ + *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x35; /* deasserted */ int i; for (i = 0; i < delay_cnt; i++) - *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x37; /* "delay" */ - *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x36; /* asserted */ + *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x35; /* "delay" */ + *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x34; /* asserted */ *ptr++ = CH341A_CMD_UIO_STM_END; }
This allows to drive MCU RST lines or similar with the ch341a during a flashrom run. CS1 is active low and CS2 is active high; note that the tristate state is a weak pullup, thus using CS2 would need an external pull-down.
Signed-off-by: Urja Rannikko urjaman@gmail.com --- ch341a_spi.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/ch341a_spi.c b/ch341a_spi.c index 6eb2804..80717f8 100644 --- a/ch341a_spi.c +++ b/ch341a_spi.c @@ -288,10 +288,10 @@ static uint8_t swap_byte(uint8_t x) }
/* The assumed map between UIO command bits, pins on CH341A chip and pins on SPI chip: - * UIO CH341A SPI CH341A SPI name + * UIO CH341A SPI CH341A SPI name Comment * 0 D0/15 CS/1 (CS0) - * 1 D1/16 unused (CS1) - * 2 D2/17 unused (CS2) + * 1 D1/16 unused (CS1) nACT, drives low when flashrom active + * 2 D2/17 unused (CS2) ACT, drives high when flashrom active * 3 D3/18 SCK/6 (DCK) * 4 D4/19 unused (DOUT2) * 5 D5/20 SI/5 (DOUT) @@ -299,12 +299,15 @@ static uint8_t swap_byte(uint8_t x) * mapped as follows: * D6/21 unused (DIN2) * D7/22 SO/2 (DIN) + * CS1 and CS2 are driven nACT & ACT as a bonus by flashrom for ISP uses to drive a + * reset signal or similar. Note that the tristate state is a weak pullup, so using + * CS2 would need an external pull-down. */ static int32_t enable_pins(bool enable) { uint8_t buf[] = { CH341A_CMD_UIO_STREAM, - CH341A_CMD_UIO_STM_OUT | 0x37, // CS high (all of them), SCK=0, DOUT*=1 + CH341A_CMD_UIO_STM_OUT | (enable ? 0x35 : 0x33), // SCK=0, DOUT*=1, CS*= see above CH341A_CMD_UIO_STM_DIR | (enable ? 0x3F : 0x00), // Interface output enable / disable CH341A_CMD_UIO_STM_END, }; @@ -327,11 +330,11 @@ static void pluck_cs(uint8_t *ptr) stored_delay_us = 0; } *ptr++ = CH341A_CMD_UIO_STREAM; - *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x37; /* deasserted */ + *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x35; /* deasserted */ int i; for (i = 0; i < delay_cnt; i++) - *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x37; /* "delay" */ - *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x36; /* asserted */ + *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x35; /* "delay" */ + *ptr++ = CH341A_CMD_UIO_STM_OUT | 0x34; /* asserted */ *ptr++ = CH341A_CMD_UIO_STM_END; }