diff options
author | Jett Rink <jettrink@chromium.org> | 2019-10-24 15:29:27 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-07 23:02:31 +0000 |
commit | b3cb8a6f818f425bfe11b817d7b873dd36d239a8 (patch) | |
tree | dc3e8843de3ff149fa227ec978be498937c8302f | |
parent | 6af3073ed1993c5b4ef3281a2fb8a9a7dad7ab02 (diff) | |
download | chrome-ec-b3cb8a6f818f425bfe11b817d7b873dd36d239a8.tar.gz |
servo_micro: add usart cmd to hold pins low
To enabled UART (UUT) programming mode for some ECs, we need to
drive the EC_TX_SERVO_RX line low while the EC is rebooting.
Add a console command that is controllable by dut-control that will
drive the UART pins low while the UART is disabled, until the command to
re-enable the UART is sent on the console.
Also, remove unnecessary alternate mode initialization for USART4
(UART3).
BRANCH=firmware-servo-11011.B
BUG=b:143163043
TEST=flashed phaser with reworked servo_micro
Change-Id: I1af1af7b48bf446936211740e16008a80ab2a39f
Signed-off-by: Jett Rink <jettrink@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1884190
Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r-- | board/servo_micro/board.c | 91 | ||||
-rw-r--r-- | board/servo_micro/board.h | 4 | ||||
-rw-r--r-- | board/servo_micro/gpio.inc | 14 |
3 files changed, 105 insertions, 4 deletions
diff --git a/board/servo_micro/board.c b/board/servo_micro/board.c index 0c966176fc..ebea396a4d 100644 --- a/board/servo_micro/board.c +++ b/board/servo_micro/board.c @@ -236,6 +236,95 @@ DECLARE_CONSOLE_COMMAND(baud, command_uart_baud, "Set baud rate on uart"); /****************************************************************************** + * Hold the usart pins low while disabling it, or return it to normal. + */ +static int command_hold_usart_low(int argc, char **argv) +{ + /* Each bit represents if that port is being held low */ + static int usart_status; + + const struct usart_config *usart; + int usart_mask; + enum gpio_signal tx, rx; + + if (argc > 3 || argc < 2) + return EC_ERROR_PARAM_COUNT; + + if (!strcasecmp(argv[1], "usart2")) { + usart = &usart2; + usart_mask = 1 << 2; + tx = GPIO_USART2_SERVO_TX_DUT_RX; + rx = GPIO_USART2_SERVO_RX_DUT_TX; + } else if (!strcasecmp(argv[1], "usart3")) { + usart = &usart3; + usart_mask = 1 << 3; + tx = GPIO_USART3_SERVO_TX_DUT_RX; + rx = GPIO_USART3_SERVO_RX_DUT_TX; + } else if (!strcasecmp(argv[1], "usart4")) { + usart = &usart4; + usart_mask = 1 << 4; + tx = GPIO_USART4_SERVO_TX_DUT_RX; + rx = GPIO_USART4_SERVO_RX_DUT_TX; + } else { + return EC_ERROR_PARAM1; + } + + /* Updating the status of this port */ + if (argc == 3) { + char *e; + const int hold_low = strtoi(argv[2], &e, 0); + + if (*e || (hold_low < 0) || (hold_low > 1)) + return EC_ERROR_PARAM2; + + if (!!(usart_status & usart_mask) == hold_low) { + /* Do nothing since there is no change */ + } else if (hold_low) { + /* + * Only one USART can be held low at a time, because + * re-initializing one USART will pull all of the USART + * GPIO pins back into alternate mode. + */ + if (usart_status) + return EC_ERROR_BUSY; + + /* + * Shutdown the USB uart, + * turn off alternate mode, then set the RX line + * pin to output low to enter UART programming mode. + */ + usart_shutdown(usart); + gpio_config_pin(MODULE_USART, rx, 0); + gpio_config_pin(MODULE_USART, tx, 0); + gpio_set_flags(rx, GPIO_OUT_LOW); + + usart_status |= usart_mask; + } else { + /* + * This will reset the alternate mode of the + * GPIO pins appropriately and restart USB UART + */ + usart_init(usart); + + /* + * Since only one USART can be held low at a time, the + * uart_status will always be 0 after this call. + */ + usart_status = 0; + } + } + + /* Print status for get and set case. */ + ccprintf("USART status: %s\n", + usart_status & usart_mask ? "held low" : "normal"); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(hold_usart_low, command_hold_usart_low, + "usart[2|3|4] [0|1]?", + "Get/set the hold-low state for usart port"); + +/****************************************************************************** * Commands for sending the magic non-I2C handshake over I2C bus wires to an * ITE IT8320 EC chip to enable direct firmware update (DFU) over I2C mode. */ @@ -643,7 +732,5 @@ static void board_init(void) gpio_set_level(GPIO_JTAG_BUFIN_EN_L, 0); gpio_set_level(GPIO_SERVO_JTAG_TDO_BUFFER_EN, 1); gpio_set_level(GPIO_SERVO_JTAG_TDO_SEL, 1); - gpio_set_flags(GPIO_UART3_RX_JTAG_BUFFER_TO_SERVO_TDO, GPIO_ALTERNATE); - gpio_set_flags(GPIO_UART3_TX_SERVO_JTAG_TCK, GPIO_ALTERNATE); } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); diff --git a/board/servo_micro/board.h b/board/servo_micro/board.h index a7a2116d89..2806a70d25 100644 --- a/board/servo_micro/board.h +++ b/board/servo_micro/board.h @@ -130,6 +130,10 @@ #include "gpio_signal.h" +/* GPIO signal mapping */ +#define GPIO_USART4_SERVO_TX_DUT_RX GPIO_UART3_TX_SERVO_JTAG_TCK +#define GPIO_USART4_SERVO_RX_DUT_TX GPIO_UART3_RX_JTAG_BUFFER_TO_SERVO_TDO + /* USB string indexes */ enum usb_strings { USB_STR_DESC = 0, diff --git a/board/servo_micro/gpio.inc b/board/servo_micro/gpio.inc index ea05c74907..5780d30f0a 100644 --- a/board/servo_micro/gpio.inc +++ b/board/servo_micro/gpio.inc @@ -28,8 +28,6 @@ GPIO(JTAG_BUFIN_EN_L, PIN(F, 1), GPIO_OUT_LOW) /* Inputs */ GPIO(SERVO_JTAG_TMS, PIN(A, 4), GPIO_INPUT) -GPIO(UART3_TX_SERVO_JTAG_TCK, PIN(A, 0), GPIO_ALTERNATE) -GPIO(UART3_RX_JTAG_BUFFER_TO_SERVO_TDO, PIN(A, 1), GPIO_ALTERNATE) GPIO(SERVO_JTAG_TDO_BUFFER_EN, PIN(A, 6), GPIO_OUT_HIGH) GPIO(SERVO_JTAG_TDI, PIN(A, 7), GPIO_INPUT) @@ -46,6 +44,18 @@ GPIO(SPI_MOSI, PIN(B, 15), GPIO_INPUT) GPIO(MASTER_I2C_SCL, PIN(B, 8), GPIO_INPUT) GPIO(MASTER_I2C_SDA, PIN(B, 9), GPIO_INPUT) +/* These pins are used for USART and are set to alternate mode below */ +GPIO(USART2_SERVO_TX_DUT_RX, PIN(A, 2), GPIO_INPUT) +GPIO(USART2_SERVO_RX_DUT_TX, PIN(A, 3), GPIO_INPUT) +GPIO(USART3_SERVO_TX_DUT_RX, PIN(B, 10), GPIO_INPUT) +GPIO(USART3_SERVO_RX_DUT_TX, PIN(B, 11), GPIO_INPUT) +/* + * The USART4 (UART3) names are already in use by dut-controls, so they can't + * be easily updated. They are aliased in board.h though. + */ +GPIO(UART3_TX_SERVO_JTAG_TCK, PIN(A, 0), GPIO_INPUT) +GPIO(UART3_RX_JTAG_BUFFER_TO_SERVO_TDO, PIN(A, 1), GPIO_INPUT) + /* Unimplemented signals since we are not an EC */ UNIMPLEMENTED(ENTERING_RW) UNIMPLEMENTED(WP_L) |