diff --git a/core/embed/trezorhal/optiga/optiga_transport.c b/core/embed/trezorhal/optiga/optiga_transport.c index b234569bdb..e26076371f 100644 --- a/core/embed/trezorhal/optiga/optiga_transport.c +++ b/core/embed/trezorhal/optiga/optiga_transport.c @@ -281,20 +281,23 @@ static optiga_result optiga_ensure_ready(void) { return ret; } - if ((frame_buffer[0] & I2C_STATE_BYTE1_BUSY) == 0) { + if ((frame_buffer[0] & I2C_STATE_BYTE1_RESP_RDY) != 0) { + // There is a response that needs to be flushed out. break; } + + if ((frame_buffer[0] & I2C_STATE_BYTE1_BUSY) == 0) { + // Not busy and no response that would need to be flushed out. + return OPTIGA_SUCCESS; + } ret = OPTIGA_ERR_BUSY; } if (ret != OPTIGA_SUCCESS) { + // Optiga is busy even after maximum retries at reading the I2C state. return ret; } - if ((frame_buffer[0] & I2C_STATE_BYTE1_RESP_RDY) == 0) { - return OPTIGA_SUCCESS; - } - // Flush out the previous response. uint16_t size = (frame_buffer[2] << 8) + frame_buffer[3]; @@ -404,6 +407,13 @@ static optiga_result optiga_read(void) { return OPTIGA_SUCCESS; } + + if ((frame_buffer[0] & I2C_STATE_BYTE1_BUSY) == 0) { + // Optiga has no response ready and is not busy. This shouldn't happen if + // we are expecting to read a response, but Optiga occasionally fails to + // give any response to a command. + return OPTIGA_ERR_UNEXPECTED; + } } return OPTIGA_ERR_TIMEOUT;