From 80e8bb770f855199f96359e872a68db77f71956e Mon Sep 17 00:00:00 2001 From: Baldanos Date: Sat, 30 Mar 2024 17:37:11 +0100 Subject: [PATCH] Add read with timeout feature (#165) Add support for timeout read in the following modes * UART * LIN * SMARTCARD * Add read with timeout in UART mode * Add timedout read on smartcard mode * Add timeout command * Add timeout read feature for hexdump mode --- src/common/mode_config.h | 1 + src/drv/stm32cube/bsp_smartcard.c | 42 +++++++------------- src/drv/stm32cube/bsp_smartcard.h | 3 +- src/drv/stm32cube/bsp_uart.c | 38 ++++++------------ src/drv/stm32cube/bsp_uart.h | 3 +- src/hydrabus/commands.c | 16 ++++++++ src/hydrabus/commands.h | 1 + src/hydrabus/hydrabus_bbio_smartcard.c | 15 +++++-- src/hydrabus/hydrabus_bbio_uart.c | 10 +++-- src/hydrabus/hydrabus_mode.c | 18 ++++++--- src/hydrabus/hydrabus_mode.h | 5 ++- src/hydrabus/hydrabus_mode_i2c.c | 4 +- src/hydrabus/hydrabus_mode_jtag.c | 4 +- src/hydrabus/hydrabus_mode_lin.c | 30 +++++++++++--- src/hydrabus/hydrabus_mode_onewire.c | 4 +- src/hydrabus/hydrabus_mode_smartcard.c | 54 +++++++++++++++++++------- src/hydrabus/hydrabus_mode_spi.c | 4 +- src/hydrabus/hydrabus_mode_threewire.c | 4 +- src/hydrabus/hydrabus_mode_twowire.c | 4 +- src/hydrabus/hydrabus_mode_uart.c | 38 +++++++++++++----- src/hydrabus/hydrabus_trigger.c | 5 ++- 21 files changed, 188 insertions(+), 115 deletions(-) diff --git a/src/common/mode_config.h b/src/common/mode_config.h index 0ca04b02..c5141172 100644 --- a/src/common/mode_config.h +++ b/src/common/mode_config.h @@ -175,6 +175,7 @@ typedef struct { #define MODE_CONFIG_PROTO_BUFFER_SIZE (256) typedef struct { uint8_t dev_num; + uint32_t timeout; union { uart_config_t uart; smartcard_config_t smartcard; diff --git a/src/drv/stm32cube/bsp_smartcard.c b/src/drv/stm32cube/bsp_smartcard.c index c618a161..63faa895 100644 --- a/src/drv/stm32cube/bsp_smartcard.c +++ b/src/drv/stm32cube/bsp_smartcard.c @@ -243,49 +243,33 @@ bsp_status_t bsp_smartcard_write_u8(bsp_dev_smartcard_t dev_num, uint8_t* tx_dat * @param dev_num: SMARTCARD dev num. * @param rx_data: Data to receive. * @param nb_data: Number of data to receive. - * @retval status of the transfer. + * @param timeout: Number of miliseconds to wait + * @retval status of the transfer. nb_data will contain the number of read + * bytes */ -bsp_status_t bsp_smartcard_read_u8(bsp_dev_smartcard_t dev_num, uint8_t* rx_data, uint8_t nb_data) +bsp_status_t bsp_smartcard_read_u8(bsp_dev_smartcard_t dev_num, uint8_t* rx_data, uint8_t *nb_data, uint32_t timeout) { SMARTCARD_HandleTypeDef* hsmartcard; hsmartcard = &smartcard_handle[dev_num]; bsp_status_t status; __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard); - status = (bsp_status_t) HAL_SMARTCARD_Receive(hsmartcard, rx_data, nb_data, SMARTCARDx_TIMEOUT_MAX); - - if(status != BSP_OK) { - smartcard_error(dev_num); - } - return status; -} - -/** - * @brief Read bytes in blocking mode, with timeout - * @param dev_num: SMARTCARD dev num. - * @param rx_data: Data to receive. - * @param nb_data: Number of data to receive. - * @param timeout: Number of ticks to wait - * @retval Number of bytes read - */ -bsp_status_t bsp_smartcard_read_u8_timeout(bsp_dev_smartcard_t dev_num, uint8_t* rx_data, - uint8_t nb_data, uint32_t timeout) -{ - SMARTCARD_HandleTypeDef* hsmartcard; - hsmartcard = &smartcard_handle[dev_num]; + status = (bsp_status_t) HAL_SMARTCARD_Receive(hsmartcard, rx_data, *nb_data, timeout); - bsp_status_t status; - __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard); - status = (bsp_status_t) HAL_SMARTCARD_Receive(hsmartcard, rx_data, nb_data, timeout); - switch(status) { + switch(status){ case BSP_OK: + *nb_data = hsmartcard->RxXferSize; + break; case BSP_TIMEOUT: - return (nb_data-(hsmartcard->RxXferCount)-1); + *nb_data = hsmartcard->RxXferSize - hsmartcard->RxXferCount - 1; + break; case BSP_ERROR: default: + *nb_data = 0; smartcard_error(dev_num); - return 0; } + + return status; } /** diff --git a/src/drv/stm32cube/bsp_smartcard.h b/src/drv/stm32cube/bsp_smartcard.h index ab22f8a7..3965b1d1 100644 --- a/src/drv/stm32cube/bsp_smartcard.h +++ b/src/drv/stm32cube/bsp_smartcard.h @@ -27,9 +27,8 @@ bsp_status_t bsp_smartcard_init(bsp_dev_smartcard_t dev_num, mode_config_proto_t bsp_status_t bsp_smartcard_deinit(bsp_dev_smartcard_t dev_num); bsp_status_t bsp_smartcard_write_u8(bsp_dev_smartcard_t dev_num, uint8_t* tx_data, uint8_t nb_data); -bsp_status_t bsp_smartcard_read_u8(bsp_dev_smartcard_t dev_num, uint8_t* rx_data, uint8_t nb_data); +bsp_status_t bsp_smartcard_read_u8(bsp_dev_smartcard_t dev_num, uint8_t* rx_data, uint8_t *nb_data, uint32_t timeout); -bsp_status_t bsp_smartcard_read_u8_timeout(bsp_dev_smartcard_t dev_num, uint8_t* rx_data, uint8_t nb_data, uint32_t timeout); bsp_status_t bsp_smartcard_write_read_u8(bsp_dev_smartcard_t dev_num, uint8_t* tx_data, uint8_t* rx_data, uint8_t nb_data); bsp_status_t bsp_smartcard_rxne(bsp_dev_smartcard_t dev_num); diff --git a/src/drv/stm32cube/bsp_uart.c b/src/drv/stm32cube/bsp_uart.c index 2333d2c1..d1bedf10 100644 --- a/src/drv/stm32cube/bsp_uart.c +++ b/src/drv/stm32cube/bsp_uart.c @@ -258,46 +258,30 @@ bsp_status_t bsp_uart_write_u8(bsp_dev_uart_t dev_num, uint8_t* tx_data, uint8_t * @param dev_num: UART dev num. * @param rx_data: Data to receive. * @param nb_data: Number of data to receive. - * @retval status of the transfer. - */ -bsp_status_t bsp_uart_read_u8(bsp_dev_uart_t dev_num, uint8_t* rx_data, uint8_t nb_data) -{ - UART_HandleTypeDef* huart; - huart = &uart_handle[dev_num]; - - bsp_status_t status; - status = (bsp_status_t) HAL_UART_Receive(huart, rx_data, nb_data, UARTx_TIMEOUT_MAX); - if(status != BSP_OK) { - uart_error(dev_num); - } - return status; -} - -/** - * @brief Read bytes in blocking mode, with timeout - * @param dev_num: UART dev num. - * @param rx_data: Data to receive. - * @param nb_data: Number of data to receive. - * @param timeout: Number of ticks to wait - * @retval Number of bytes read + * @param timeout: Number of miliseconds to wait + * @retval status of the transfer. nb_data will contain the number of read + * bytes */ -bsp_status_t bsp_uart_read_u8_timeout(bsp_dev_uart_t dev_num, uint8_t* rx_data, - uint8_t nb_data, uint32_t timeout) +bsp_status_t bsp_uart_read_u8(bsp_dev_uart_t dev_num, uint8_t* rx_data, uint8_t *nb_data, uint32_t timeout) { UART_HandleTypeDef* huart; huart = &uart_handle[dev_num]; bsp_status_t status; - status = (bsp_status_t) HAL_UART_Receive(huart, rx_data, nb_data, timeout); + status = (bsp_status_t) HAL_UART_Receive(huart, rx_data, *nb_data, timeout); switch(status){ case BSP_OK: + *nb_data = huart->RxXferSize; + break; case BSP_TIMEOUT: - return (nb_data-(huart->RxXferCount)-1); + *nb_data = huart->RxXferSize - huart->RxXferCount - 1; + break; case BSP_ERROR: default: + *nb_data = 0; uart_error(dev_num); - return 0; } + return status; } /** diff --git a/src/drv/stm32cube/bsp_uart.h b/src/drv/stm32cube/bsp_uart.h index 2caf4717..f117431f 100644 --- a/src/drv/stm32cube/bsp_uart.h +++ b/src/drv/stm32cube/bsp_uart.h @@ -33,8 +33,7 @@ bsp_status_t bsp_uart_init(bsp_dev_uart_t dev_num, mode_config_proto_t* mode_con bsp_status_t bsp_uart_deinit(bsp_dev_uart_t dev_num); bsp_status_t bsp_uart_write_u8(bsp_dev_uart_t dev_num, uint8_t* tx_data, uint8_t nb_data); -bsp_status_t bsp_uart_read_u8(bsp_dev_uart_t dev_num, uint8_t* rx_data, uint8_t nb_data); -bsp_status_t bsp_uart_read_u8_timeout(bsp_dev_uart_t dev_num, uint8_t* rx_data, uint8_t nb_data, uint32_t timeout); +bsp_status_t bsp_uart_read_u8(bsp_dev_uart_t dev_num, uint8_t* rx_data, uint8_t *nb_data, uint32_t timeout); bsp_status_t bsp_uart_write_read_u8(bsp_dev_uart_t dev_num, uint8_t* tx_data, uint8_t* rx_data, uint8_t nb_data); bsp_status_t bsp_uart_rxne(bsp_dev_uart_t dev_num); diff --git a/src/hydrabus/commands.c b/src/hydrabus/commands.c index 66396218..8651fff1 100644 --- a/src/hydrabus/commands.c +++ b/src/hydrabus/commands.c @@ -163,6 +163,7 @@ const t_token_dict tl_dict[] = { { T_CONVENTION, "convention" }, { T_DELAY, "delay" }, { T_CLOCK_STRETCH, "clock-stretch" }, + { T_TIMEOUT, "timeout" }, /* Developer warning add new command(s) here */ /* BP-compatible commands */ @@ -475,6 +476,11 @@ t_token tokens_parity[] = { T_STOP_BITS,\ .arg_type = T_ARG_UINT,\ .help = "Stop bits (1/2)"\ + },\ + {\ + T_TIMEOUT,\ + .arg_type = T_ARG_UINT,\ + .help = "Read timeout in msec"\ }, t_token tokens_mode_uart[] = { @@ -604,6 +610,11 @@ t_token tokens_uart[] = { .arg_type = T_ARG_UINT,\ .help = "Communication convention",\ .help_full = "Set communication convention (0=normal, 1=inverse)"\ + },\ + {\ + T_TIMEOUT,\ + .arg_type = T_ARG_UINT,\ + .help = "Read timeout in msec"\ }, t_token tokens_mode_smartcard[] = { @@ -717,6 +728,11 @@ t_token tokens_smartcard[] = { .arg_type = T_ARG_UINT,\ .help = "LIN device (1/2)"\ },\ + {\ + T_TIMEOUT,\ + .arg_type = T_ARG_UINT,\ + .help = "Read timeout in msec"\ + }, t_token tokens_mode_lin[] = { { diff --git a/src/hydrabus/commands.h b/src/hydrabus/commands.h index 99d6cc8a..68844585 100644 --- a/src/hydrabus/commands.h +++ b/src/hydrabus/commands.h @@ -155,6 +155,7 @@ enum { T_CONVENTION, T_DELAY, T_CLOCK_STRETCH, + T_TIMEOUT, /* Developer warning add new command(s) here */ /* BP-compatible commands */ diff --git a/src/hydrabus/hydrabus_bbio_smartcard.c b/src/hydrabus/hydrabus_bbio_smartcard.c index 0cde4e33..fb25055a 100644 --- a/src/hydrabus/hydrabus_bbio_smartcard.c +++ b/src/hydrabus/hydrabus_bbio_smartcard.c @@ -35,6 +35,7 @@ void bbio_smartcard_init_proto_default(t_hydra_console *con) /* Defaults */ proto->dev_num = 0; + proto->timeout = 10000; proto->config.smartcard.dev_speed = 9600; proto->config.smartcard.dev_parity = 0; proto->config.smartcard.dev_stop_bit = 1; @@ -57,7 +58,8 @@ void bbio_mode_smartcard(t_hydra_console *con) uint8_t bbio_subcommand; uint8_t *tx_data = pool_alloc_bytes(0x1000); // 4096 bytes uint8_t *rx_data = pool_alloc_bytes(0x1000); // 4096 bytes - uint8_t data; + uint8_t data, tmp; + uint8_t to_read; uint32_t dev_speed=0; uint32_t final_baudrate; bsp_status_t status; @@ -142,13 +144,17 @@ void bbio_mode_smartcard(t_hydra_console *con) i=0; while(i= 255) { + to_read = 255; bsp_smartcard_read_u8(proto->dev_num, rx_data+i, - 255); + &to_read, + TIME_MS2I(proto->timeout)); } else { + tmp = to_rx-i; bsp_smartcard_read_u8(proto->dev_num, rx_data+i, - to_rx-i); + &tmp, + TIME_MS2I(proto->timeout)); } i+=255; } @@ -185,7 +191,8 @@ void bbio_mode_smartcard(t_hydra_console *con) bsp_smartcard_set_rst(proto->dev_num, 0); DelayMs(1); bsp_smartcard_set_rst(proto->dev_num, 1); - i = bsp_smartcard_read_u8_timeout(proto->dev_num, rx_data, 33, TIME_MS2I(500)); + to_read = 33; + bsp_smartcard_read_u8(proto->dev_num, rx_data, &to_read, TIME_MS2I(500)); cprint(con, (char *)&i, 1); cprint(con, (char *)rx_data, i); break; diff --git a/src/hydrabus/hydrabus_bbio_uart.c b/src/hydrabus/hydrabus_bbio_uart.c index 6bd32dd8..d079c273 100644 --- a/src/hydrabus/hydrabus_bbio_uart.c +++ b/src/hydrabus/hydrabus_bbio_uart.c @@ -34,6 +34,7 @@ void bbio_uart_init_proto_default(t_hydra_console *con) /* Defaults */ proto->dev_num = 0; + proto->timeout = 10000; proto->config.uart.dev_speed = 9600; proto->config.uart.dev_parity = 0; proto->config.uart.dev_stop_bit = 1; @@ -53,10 +54,11 @@ static THD_FUNCTION(uart_reader_thread, arg) if(!chThdShouldTerminateX()) { if(bsp_uart_rxne(proto->dev_num)) { - bytes_read = bsp_uart_read_u8_timeout(proto->dev_num, - proto->buffer_rx, - UART_BRIDGE_BUFF_SIZE, - TIME_US2I(100)); + bytes_read = UART_BRIDGE_BUFF_SIZE; + bsp_uart_read_u8(proto->dev_num, + proto->buffer_rx, + &bytes_read, + TIME_US2I(100)); if(bytes_read > 0) { cprint(con, (char *)proto->buffer_rx, bytes_read); } diff --git a/src/hydrabus/hydrabus_mode.c b/src/hydrabus/hydrabus_mode.c index 2cb6fb8d..ac01d556 100644 --- a/src/hydrabus/hydrabus_mode.c +++ b/src/hydrabus/hydrabus_mode.c @@ -102,6 +102,7 @@ const char hydrabus_mode_str_mul_read[] = "READ: "; const char hydrabus_mode_str_mul_value_u8[] = "0x%02X "; const char hydrabus_mode_str_mul_br[] = "\r\n"; const char hydrabus_mode_str_mdelay[] = "DELAY: %lu ms\r\n"; +const char hydrabus_mode_str_read_timeout[] = "! TIMEOUT: read %lu out of %lu\r\n"; static const char mode_str_write_error[] = "WRITE error:%d\r\n"; static const char mode_str_read_error[] = "READ error:%d\r\n"; @@ -233,7 +234,7 @@ int cmd_mode_exec(t_hydra_console *con, t_tokenline_parsed *p) usec = 1; } DelayUs(usec); - break; + break; case T_PERCENT: factor = 1000; if (p->tokens[t + 1] == T_ARG_TOKEN_SUFFIX_INT) { @@ -454,7 +455,7 @@ static int hydrabus_mode_read(t_hydra_console *con, t_tokenline_parsed *p, if(con->mode->exec->read != NULL) { mode_status = con->mode->exec->read(con, p_proto->buffer_rx, count); } - if (mode_status != HYDRABUS_MODE_STATUS_OK) + if (mode_status == BSP_ERROR) hydrabus_mode_read_error(con, mode_status); return t - token_pos; @@ -494,12 +495,19 @@ static int hydrabus_mode_hexdump(t_hydra_console *con, t_tokenline_parsed *p, } if(con->mode->exec->dump != NULL) { - mode_status = con->mode->exec->dump(con, p_proto->buffer_rx, to_rx); + mode_status = con->mode->exec->dump(con, p_proto->buffer_rx, &to_rx); } - if (mode_status == HYDRABUS_MODE_STATUS_OK) { + switch(mode_status) { + case BSP_OK: print_hex(con, p_proto->buffer_rx, to_rx); - } else { + break; + case BSP_TIMEOUT: + print_hex(con, p_proto->buffer_rx, to_rx); + cprintf(con, hydrabus_mode_str_read_timeout, bytes_read+to_rx, count); + return t - token_pos; + default: hydrabus_mode_read_error(con, mode_status); + return t - token_pos; } bytes_read += to_rx; diff --git a/src/hydrabus/hydrabus_mode.h b/src/hydrabus/hydrabus_mode.h index 90ac1b32..6c04fd65 100644 --- a/src/hydrabus/hydrabus_mode.h +++ b/src/hydrabus/hydrabus_mode.h @@ -52,6 +52,9 @@ extern const char hydrabus_mode_str_mul_value_u8[]; /* "\r\n" */ extern const char hydrabus_mode_str_mul_br[]; +/* "TIMEOUT: read %lu out of %lu\r\n" */ +extern const char hydrabus_mode_str_read_timeout[]; + typedef struct mode_exec_t { /* Initialize mode hardware. */ int (*init)(t_hydra_console *con, t_tokenline_parsed *p); @@ -66,7 +69,7 @@ typedef struct mode_exec_t { /* Read data command 'read' or 'read:n' (return status 0=OK) */ uint32_t (*read)(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data); /* Dump data */ - uint32_t (*dump)(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data); + uint32_t (*dump)(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data); /* Write & Read data (return status 0=OK) */ uint32_t (*write_read)(t_hydra_console *con, uint8_t *tx_data, uint8_t *rx_data, uint8_t nb_data); /* Set CLK High (x-WIRE or other raw mode) command '/' */ diff --git a/src/hydrabus/hydrabus_mode_i2c.c b/src/hydrabus/hydrabus_mode_i2c.c index 8ee8723b..1bd794dd 100644 --- a/src/hydrabus/hydrabus_mode_i2c.c +++ b/src/hydrabus/hydrabus_mode_i2c.c @@ -294,13 +294,13 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) return status; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint32_t status; uint8_t i, tmp; mode_config_proto_t* proto = &con->mode->proto; status = BSP_ERROR; - for(i = 0; i < nb_data; i++) { + for(i = 0; i < *nb_data; i++) { if(proto->config.i2c.ack_pending) { /* Send I2C ACK */ status = bsp_i2c_read_ack(I2C_DEV_NUM, TRUE); diff --git a/src/hydrabus/hydrabus_mode_jtag.c b/src/hydrabus/hydrabus_mode_jtag.c index f639ef45..b68cca1d 100644 --- a/src/hydrabus/hydrabus_mode_jtag.c +++ b/src/hydrabus/hydrabus_mode_jtag.c @@ -959,12 +959,12 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) return BSP_OK; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint8_t i; i = 0; - while(i < nb_data) { + while(i < *nb_data) { rx_data[i] = jtag_read_u8(con); i++; } diff --git a/src/hydrabus/hydrabus_mode_lin.c b/src/hydrabus/hydrabus_mode_lin.c index a680361d..379fa9ac 100644 --- a/src/hydrabus/hydrabus_mode_lin.c +++ b/src/hydrabus/hydrabus_mode_lin.c @@ -22,6 +22,8 @@ #include "hydrabus_trigger.h" #include +#define LIN_DEFAULT_TIMEOUT (2000) + static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos); static int show(t_hydra_console *con, t_tokenline_parsed *p); @@ -42,6 +44,7 @@ static void init_proto_default(t_hydra_console *con) /* Defaults */ proto->dev_num = 0; + proto->timeout = LIN_DEFAULT_TIMEOUT; proto->config.uart.dev_speed = 9600; proto->config.uart.bus_mode = BSP_UART_MODE_LIN; } @@ -52,6 +55,8 @@ static void show_params(t_hydra_console *con) cprintf(con, "Device: LIN%d\r\n", proto->dev_num + 1); + cprintf(con, "Timeout: %d msec\r\n", + proto->timeout); } static int init(t_hydra_console *con, t_tokenline_parsed *p) @@ -107,6 +112,16 @@ static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos) tl_set_prompt(con->tl, (char *)con->mode->exec->get_prompt(con)); cprintf(con, "Note: LIN parameters have been reset to default values.\r\n"); break; + case T_TIMEOUT: + /* Integer parameter. */ + t += 2; + memcpy(&arg_int, p->buf + p->tokens[t], sizeof(int)); + if (arg_int < 1 || arg_int > 30000) { + cprintf(con, "Timeout value must be set between 1 and 30000.\r\n"); + return t; + } + proto->timeout = arg_int; + break; case T_TRIGGER: t++; t += cmd_trigger(con, p, t); @@ -147,9 +162,14 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) int i; uint32_t status; mode_config_proto_t* proto = &con->mode->proto; - - status = bsp_uart_read_u8(proto->dev_num, rx_data, nb_data); - if(status == BSP_OK) { + uint8_t orig_nb_data = nb_data; + + status = bsp_uart_read_u8(proto->dev_num, rx_data, &nb_data, TIME_MS2I(proto->timeout)); + switch(status) { + case BSP_TIMEOUT: + cprintf(con, hydrabus_mode_str_read_timeout, nb_data, orig_nb_data); + __attribute__ ((fallthrough)); // Explicitly fall through + case BSP_OK: if(nb_data == 1) { /* Read 1 data */ cprintf(con, hydrabus_mode_str_read_one_u8, rx_data[0]); @@ -165,12 +185,12 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) return status; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint32_t status; mode_config_proto_t* proto = &con->mode->proto; - status = bsp_uart_read_u8(proto->dev_num, rx_data, nb_data); + status = bsp_uart_read_u8(proto->dev_num, rx_data, nb_data, TIME_MS2I(proto->timeout)); return status; } diff --git a/src/hydrabus/hydrabus_mode_onewire.c b/src/hydrabus/hydrabus_mode_onewire.c index 3f61b129..a9392a5d 100644 --- a/src/hydrabus/hydrabus_mode_onewire.c +++ b/src/hydrabus/hydrabus_mode_onewire.c @@ -472,12 +472,12 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) return BSP_OK; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint8_t i; i = 0; - while(i < nb_data) { + while(i < *nb_data) { rx_data[i] = onewire_read_u8(con); i++; } diff --git a/src/hydrabus/hydrabus_mode_smartcard.c b/src/hydrabus/hydrabus_mode_smartcard.c index dca9fb85..1197ccd4 100644 --- a/src/hydrabus/hydrabus_mode_smartcard.c +++ b/src/hydrabus/hydrabus_mode_smartcard.c @@ -23,6 +23,7 @@ #include #define SMARTCARD_DEFAULT_SPEED (9408) +#define SMARTCARD_DEFAULT_TIMEOUT (1000) static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos); static int show(t_hydra_console *con, t_tokenline_parsed *p); @@ -55,6 +56,7 @@ static void init_proto_default(t_hydra_console *con) /* Defaults */ proto->dev_num = 0; + proto->timeout = SMARTCARD_DEFAULT_TIMEOUT; proto->config.smartcard.dev_speed = SMARTCARD_DEFAULT_SPEED; proto->config.smartcard.dev_parity = 0; proto->config.smartcard.dev_stop_bit = 1; @@ -83,6 +85,8 @@ static void show_params(t_hydra_console *con) proto->config.smartcard.dev_prescaler); print_freq(con, bsp_smartcard_get_clk_frequency(proto->dev_num)); cprint(con, "\r\n", 2); + cprintf(con, "Timeout: %d msec\r\n", + proto->timeout); } static int init(t_hydra_console *con, t_tokenline_parsed *p) @@ -129,6 +133,7 @@ static void smartcard_get_atr(t_hydra_console *con) uint8_t D = 0; uint16_t E = 0; uint8_t max = 0; + uint8_t to_read = 0; /* Defaults */ init_proto_default(con); @@ -138,10 +143,12 @@ static void smartcard_get_atr(t_hydra_console *con) DelayMs(1); // RST low for at least 400 clocks (tb). bsp_smartcard_set_vcc(proto->dev_num, 0); bsp_smartcard_set_rst(proto->dev_num, 1); - bsp_smartcard_read_u8(proto->dev_num, atr, 1); + to_read = 1; + bsp_smartcard_read_u8(proto->dev_num, atr, &to_read, TIME_MS2I(proto->timeout)); if (atr[0] == 0) { - bsp_smartcard_read_u8(proto->dev_num, atr, 1); + to_read = 1; + bsp_smartcard_read_u8(proto->dev_num, atr, &to_read, TIME_MS2I(proto->timeout)); } /* Inverse or Direct convention */ @@ -162,12 +169,14 @@ static void smartcard_get_atr(t_hydra_console *con) /* We don't care about the convention since the TS is not * standard */ - atr_size = bsp_smartcard_read_u8_timeout(proto->dev_num, &atr[1], 8, TIME_MS2I(100)); + atr_size = 8; + atr_size = bsp_smartcard_read_u8(proto->dev_num, &atr[1], &atr_size, TIME_MS2I(100)); print_hex(con, atr, atr_size); return; } - bsp_smartcard_read_u8(proto->dev_num, atr+1, 1); + to_read = 1; + bsp_smartcard_read_u8(proto->dev_num, atr+1, &to_read, TIME_MS2I(proto->timeout)); apply_convention(con, atr+1, 1); while(more_td) { @@ -180,7 +189,8 @@ static void smartcard_get_atr(t_hydra_console *con) checksum |= atr[r]&0x1; r++; for(; r<=atr_size; r++) { - bsp_smartcard_read_u8(proto->dev_num, atr+r, 1); + to_read = 1; + bsp_smartcard_read_u8(proto->dev_num, atr+r, &to_read, TIME_MS2I(proto->timeout)); apply_convention(con, atr+r, 1); // Test if TA1 is present from T0, @@ -211,20 +221,23 @@ static void smartcard_get_atr(t_hydra_console *con) /* Read last Ti */ for(; r<=atr_size; r++) { - bsp_smartcard_read_u8(proto->dev_num, atr+r, 1); + to_read = 1; + bsp_smartcard_read_u8(proto->dev_num, atr+r, &to_read, TIME_MS2I(proto->timeout)); apply_convention(con, atr+r, 1); } /* Read historical data */ for(i=0; i<(atr[1] & 0x0f); i++) { - bsp_smartcard_read_u8(proto->dev_num, atr+(r+i), 1); + to_read = 1; + bsp_smartcard_read_u8(proto->dev_num, atr+(r+i), &to_read, TIME_MS2I(proto->timeout)); apply_convention(con, atr+(r+i), 1); } r+=i; /* Read checksum if present and print ATR */ if(checksum) { - bsp_smartcard_read_u8(proto->dev_num, atr+r, 1); + to_read = 1; + bsp_smartcard_read_u8(proto->dev_num, atr+r, &to_read, TIME_MS2I(proto->timeout)); apply_convention(con, atr+r, 1); print_hex(con, atr, r+1); } else { @@ -424,6 +437,16 @@ static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos) return t; } break; + case T_TIMEOUT: + /* Integer parameter. */ + t += 2; + memcpy(&arg_int, p->buf + p->tokens[t], sizeof(int)); + if (arg_int < 1 || arg_int > 30000) { + cprintf(con, "Timeout value must be set between 1 and 30000.\r\n"); + return t; + } + proto->timeout = arg_int; + break; case T_QUERY: smartcard_get_card_status(con); break; @@ -467,10 +490,15 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) int i; uint32_t status; mode_config_proto_t* proto = &con->mode->proto; + uint8_t orig_nb_data = nb_data; - status = bsp_smartcard_read_u8(proto->dev_num, rx_data, nb_data); + status = bsp_smartcard_read_u8(proto->dev_num, rx_data, &nb_data, TIME_MS2I(proto->timeout)); apply_convention(con, rx_data, nb_data); - if(status == BSP_OK) { + switch(status) { + case BSP_TIMEOUT: + cprintf(con, hydrabus_mode_str_read_timeout, nb_data, orig_nb_data); + __attribute__ ((fallthrough)); // Explicitly fall through + case BSP_OK: if(nb_data == 1) { /* Read 1 data */ cprintf(con, hydrabus_mode_str_read_one_u8, rx_data[0]); @@ -486,13 +514,13 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) return status; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint32_t status; mode_config_proto_t* proto = &con->mode->proto; - status = bsp_smartcard_read_u8(proto->dev_num, rx_data, nb_data); - apply_convention(con, rx_data, nb_data); + status = bsp_smartcard_read_u8(proto->dev_num, rx_data, nb_data, TIME_MS2I(proto->timeout)); + apply_convention(con, rx_data, *nb_data); return status; } diff --git a/src/hydrabus/hydrabus_mode_spi.c b/src/hydrabus/hydrabus_mode_spi.c index bd7022a1..f546ad12 100644 --- a/src/hydrabus/hydrabus_mode_spi.c +++ b/src/hydrabus/hydrabus_mode_spi.c @@ -312,12 +312,12 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) return status; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint32_t status; mode_config_proto_t* proto = &con->mode->proto; - status = bsp_spi_read_u8(proto->dev_num, rx_data, nb_data); + status = bsp_spi_read_u8(proto->dev_num, rx_data, *nb_data); return status; } diff --git a/src/hydrabus/hydrabus_mode_threewire.c b/src/hydrabus/hydrabus_mode_threewire.c index 427362ff..157e391b 100644 --- a/src/hydrabus/hydrabus_mode_threewire.c +++ b/src/hydrabus/hydrabus_mode_threewire.c @@ -403,12 +403,12 @@ static uint32_t write_read(t_hydra_console *con, uint8_t *tx_data, uint8_t *rx_d return BSP_OK; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint8_t i; i = 0; - while(i < nb_data){ + while(i < *nb_data){ rx_data[i] = threewire_read_u8(con); i++; } diff --git a/src/hydrabus/hydrabus_mode_twowire.c b/src/hydrabus/hydrabus_mode_twowire.c index fcbe1278..5af8cedc 100644 --- a/src/hydrabus/hydrabus_mode_twowire.c +++ b/src/hydrabus/hydrabus_mode_twowire.c @@ -488,12 +488,12 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) return BSP_OK; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint8_t i; i = 0; - while(i < nb_data){ + while(i < *nb_data){ rx_data[i] = twowire_read_u8(con); i++; } diff --git a/src/hydrabus/hydrabus_mode_uart.c b/src/hydrabus/hydrabus_mode_uart.c index 03b9479f..4eebd30d 100644 --- a/src/hydrabus/hydrabus_mode_uart.c +++ b/src/hydrabus/hydrabus_mode_uart.c @@ -23,6 +23,7 @@ #include #define UART_DEFAULT_SPEED (9600) +#define UART_DEFAULT_TIMEOUT (2000) static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos); static int show(t_hydra_console *con, t_tokenline_parsed *p); @@ -51,6 +52,7 @@ static void init_proto_default(t_hydra_console *con) /* Defaults */ proto->dev_num = 0; proto->wwr = 0; + proto->timeout = UART_DEFAULT_TIMEOUT; proto->config.uart.dev_speed = UART_DEFAULT_SPEED; proto->config.uart.dev_parity = 0; proto->config.uart.dev_stop_bit = 1; @@ -66,6 +68,8 @@ static void show_params(t_hydra_console *con) cprintf(con, "Parity: %s\r\nStop bits: %d\r\n", str_dev_param_parity[proto->config.uart.dev_parity], proto->config.uart.dev_stop_bit); + cprintf(con, "Timeout: %d msec\r\n", + proto->timeout); } static int init(t_hydra_console *con, t_tokenline_parsed *p) @@ -97,10 +101,11 @@ static THD_FUNCTION(bridge_thread, arg) while (!hydrabus_ubtn()) { if(bsp_uart_rxne(proto->dev_num)) { - bytes_read = bsp_uart_read_u8_timeout(proto->dev_num, - proto->buffer_rx, - UART_BRIDGE_BUFF_SIZE, - TIME_US2I(100)); + bytes_read = UART_BRIDGE_BUFF_SIZE; + bsp_uart_read_u8(proto->dev_num, + proto->buffer_rx, + &bytes_read, + TIME_US2I(100)); if(bytes_read > 0) { cprint(con, (char *)proto->buffer_rx, bytes_read); } @@ -248,6 +253,16 @@ static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos) return t; } break; + case T_TIMEOUT: + /* Integer parameter. */ + t += 2; + memcpy(&arg_int, p->buf + p->tokens[t], sizeof(int)); + if (arg_int < 1 || arg_int > 30000) { + cprintf(con, "Timeout value must be set between 1 and 30000.\r\n"); + return t; + } + proto->timeout = arg_int; + break; case T_BRIDGE: bridge(con); break; @@ -290,9 +305,14 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) int i; uint32_t status; mode_config_proto_t* proto = &con->mode->proto; - - status = bsp_uart_read_u8(proto->dev_num, rx_data, nb_data); - if(status == BSP_OK) { + uint8_t orig_nb_data = nb_data; + + status = bsp_uart_read_u8(proto->dev_num, rx_data, &nb_data, TIME_MS2I(proto->timeout)); + switch(status) { + case BSP_TIMEOUT: + cprintf(con, hydrabus_mode_str_read_timeout, nb_data, orig_nb_data); + __attribute__ ((fallthrough)); // Explicitly fall through + case BSP_OK: if(nb_data == 1) { /* Read 1 data */ cprintf(con, hydrabus_mode_str_read_one_u8, rx_data[0]); @@ -308,12 +328,12 @@ static uint32_t read(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) return status; } -static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t nb_data) +static uint32_t dump(t_hydra_console *con, uint8_t *rx_data, uint8_t *nb_data) { uint32_t status; mode_config_proto_t* proto = &con->mode->proto; - status = bsp_uart_read_u8(proto->dev_num, rx_data, nb_data); + status = bsp_uart_read_u8(proto->dev_num, rx_data, nb_data, TIME_MS2I(proto->timeout)); return status; } diff --git a/src/hydrabus/hydrabus_trigger.c b/src/hydrabus/hydrabus_trigger.c index 3d0db376..86506579 100644 --- a/src/hydrabus/hydrabus_trigger.c +++ b/src/hydrabus/hydrabus_trigger.c @@ -59,11 +59,12 @@ static int show(t_hydra_console *con, t_tokenline_parsed *p, int token_pos) static int trigger_run(t_hydra_console *con) { uint32_t i=0; - uint8_t rx_data; + uint8_t rx_data, to_read; bsp_trigger_init(); while(!hydrabus_ubtn()) { if(con->mode->exec->read) { - con->mode->exec->dump(con,&rx_data,1); + to_read = 1; + con->mode->exec->dump(con,&rx_data,&to_read); } if(rx_data == trigger_data[i]) { i++;