diff --git a/hal/tpm_io.c b/hal/tpm_io.c index 8944805d..a5e7ff98 100644 --- a/hal/tpm_io.c +++ b/hal/tpm_io.c @@ -97,6 +97,8 @@ static int TPM2_IoCb_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, ret = TPM2_IoCb_Infineon_TriCore_SPI(ctx, txBuf, rxBuf, xferSz, userCtx); #elif defined(WOLFTPM_MICROCHIP_HARMONY) ret = TPM2_IoCb_Microchip_SPI(ctx, txBuf, rxBuf, xferSz, userCtx); +#elif defined(WOLFSSL_ESPIDF) + ret = TPM2_IoCb_Espressif_SPI(ctx, txBuf, rxBuf, xferSz, userCtx); #else /* TODO: Add your platform here for HW SPI interface */ diff --git a/hal/tpm_io_espressif.c b/hal/tpm_io_espressif.c index 8a003a45..7d01adf8 100644 --- a/hal/tpm_io_espressif.c +++ b/hal/tpm_io_espressif.c @@ -42,6 +42,8 @@ /* Espressif */ #include "sdkconfig.h" +#include +#include #define TAG "TPM_IO" @@ -438,20 +440,141 @@ int TPM2_IoCb_Espressif_I2C(TPM2_CTX* ctx, int isRead, word32 addr, /* end WOLFTPM_I2C */ #else /* If not I2C, it must be SPI */ - /* TODO implement SPI */ - - #ifndef TPM2_SPI_HZ - /* Use the max speed by default - * See tpm2_types.h for chip specific max values */ - #define TPM2_SPI_HZ TPM2_SPI_MAX_HZ - #endif - #ifdef WOLFTPM_CHECK_WAIT_STATE - #error SPI check wait state logic not supported - #endif - - #error TPM2 SPI support on this platform not supported yet -#endif +// FSPI (HOST_SPI2) on esp32-s3-wroom +#define PIN_NUM_MISO 13 +#define PIN_NUM_MOSI 11 +#define PIN_NUM_CLK 12 +#define PIN_NUM_CS 10 + +// NOTE: on esp, 64 byte limit includes data and header!!! +#define SPI_MAX_TRANSFER 64 + +// TPM data storing SPI handles & timeouts +static struct TPM_DATA { + spi_device_handle_t spi; + gpio_num_t cs_pin; + int64_t timeout_expiry; +} *tpm_data; + +static int _is_initialized_spi = FALSE; + +int esp_spi_master_init() { + // SPI bus & device configuration + spi_bus_config_t bus_cfg = { + .miso_io_num = PIN_NUM_MISO, + .mosi_io_num = PIN_NUM_MOSI, + .sclk_io_num = PIN_NUM_CLK, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = 64 + }; + spi_device_interface_config_t dev_cfg = { + .clock_speed_hz = 10*1000*1000, // 10MHz, but tested up to 22MHz + .mode = 0, + .spics_io_num = PIN_NUM_CS, + .queue_size = 1, + .pre_cb = NULL, + .post_cb = NULL, + }; + + // Initializing CS pin + esp_rom_gpio_pad_select_gpio(PIN_NUM_CS); + gpio_set_direction(PIN_NUM_CS, GPIO_MODE_OUTPUT); + gpio_set_level(PIN_NUM_CS, 1); + + // Initialize the SPI bus and device + esp_err_t ret; + ret = spi_bus_initialize(SPI2_HOST, &bus_cfg, 0); + ESP_ERROR_CHECK(ret); + + // Attach the device to the SPI bus + spi_device_handle_t spi; + ret = spi_bus_add_device(SPI2_HOST, &dev_cfg, &spi); + ESP_ERROR_CHECK(ret); + + tpm_data = malloc(sizeof(struct TPM_DATA)); + tpm_data->spi = spi; + tpm_data->cs_pin = PIN_NUM_CS; + tpm_data->timeout_expiry = 0; + + _is_initialized_spi = TRUE; + return 0; +} + +/* Aquire SPI bus and keep pulling CS */ +int tpm_spi_acquire() +{ + int ret; + gpio_set_level(tpm_data->cs_pin, 0); + ret = spi_device_acquire_bus(tpm_data->spi, portMAX_DELAY); + return ret; +} + +/* Release SPI bus and CS */ +int tpm_spi_release () +{ + gpio_set_level(tpm_data->cs_pin, 1); + spi_device_release_bus(tpm_data->spi); + return 0; +} + +int tpm_spi_raw_transfer (const byte *data_out, byte *data_in, size_t cnt) { + + /* Maximum transfer size is 64 byte because we don't use DMA. */ + if (cnt > SPI_MAX_TRANSFER) { + printf("tpm_io_espressif: cnt %d\n", cnt); + return -1; + } + + /* At least one of the buffers has to be set. */ + if (data_out == NULL && data_in == NULL) { + return -1; + } + + /* Setup transaction */ + spi_transaction_t t; + memset(&t, 0, sizeof(t)); + t.length = cnt*8; + t.tx_buffer = data_out; + t.rx_buffer = data_in; + + /* Transmit */ + esp_err_t ret = spi_device_polling_transmit(tpm_data->spi, &t); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "spi_transmit returned error %d\n", ret); + return -1; + } + + return 0; +} /* tpm_spi_raw_transfer */ + +int TPM2_IoCb_Espressif_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, + word16 xferSz, void* userCtx) { + int ret = TPM_RC_FAILURE; + + if (_is_initialized_spi) + ret = ESP_OK; + else { + ret = esp_spi_master_init(); /* ESP return code, not TPM */ + ESP_LOGV(TAG, "HAL: Initializing SPI %d", ret); + } + + if (ret == ESP_OK) { + tpm_spi_acquire(); + ret = tpm_spi_raw_transfer(txBuf, rxBuf, xferSz); + tpm_spi_release(); + } + else { + ESP_LOGE(TAG, "SPI Failed to initialize. Error: %d", ret); + ret = TPM_RC_FAILURE; + } + + (void)ctx; + return ret; +} /* TPM2_IoCb_Espressif_SPI */ + +#endif /* Espressif SPI */ #endif /* WOLFSSL_ESPIDF */ #endif /* WOLFTPM_INCLUDE_IO_FILE */