|
42 | 42 |
|
43 | 43 | /* Espressif */ |
44 | 44 | #include "sdkconfig.h" |
| 45 | +#include <driver/gpio.h> |
| 46 | +#include <driver/spi_master.h> |
45 | 47 |
|
46 | 48 | #define TAG "TPM_IO" |
47 | 49 |
|
|
165 | 167 | #define TPM_I2C_TRIES 10 |
166 | 168 | #endif |
167 | 169 |
|
168 | | -static int _is_initialized_i2c = FALSE; |
| 170 | +static int _is_initialized_i2c = 0; |
169 | 171 |
|
170 | 172 | #ifdef DEBUG_WOLFSSL_VERBOSE |
171 | 173 | static esp_err_t show_binary(byte* theVar, size_t dataSz) { |
@@ -238,7 +240,7 @@ static esp_err_t i2c_master_delete(void) |
238 | 240 | { |
239 | 241 | ESP_LOGI(TAG, "i2c_master_delete"); |
240 | 242 | ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM)); |
241 | | - _is_initialized_i2c = FALSE; |
| 243 | + _is_initialized_i2c = 0; |
242 | 244 | return ESP_OK; |
243 | 245 | } |
244 | 246 |
|
@@ -438,20 +440,209 @@ int TPM2_IoCb_Espressif_I2C(TPM2_CTX* ctx, int isRead, word32 addr, |
438 | 440 | /* end WOLFTPM_I2C */ |
439 | 441 |
|
440 | 442 | #else /* If not I2C, it must be SPI */ |
441 | | - /* TODO implement SPI */ |
| 443 | +/*---------------------------------------------------------------------------*/ |
442 | 444 |
|
443 | | - #ifndef TPM2_SPI_HZ |
444 | | - /* Use the max speed by default |
445 | | - * See tpm2_types.h for chip specific max values */ |
446 | | - #define TPM2_SPI_HZ TPM2_SPI_MAX_HZ |
| 445 | +/* Note: If an error is encountered during SPI transfer: |
| 446 | + * TPM2_StartAuthSession failed 0x903: TPM_RC_SESSION_MEMORY |
| 447 | + * Try hardware reset of the TPM device. */ |
| 448 | + |
| 449 | +#define SPI_CLOCK_MHZ (10 * 1000 * 1000) /* 10MHz, but tested up to 22MHz */ |
| 450 | + |
| 451 | +/* If failures are encountered, try hardware reset of TPM device. */ |
| 452 | +#if defined(CONFIG_IDF_TARGET_ESP32S3) |
| 453 | + #ifndef ESP_SPI_MAX_TRANSFER |
| 454 | + #define ESP_SPI_MAX_TRANSFER_SIZE MAX_SPI_FRAMESIZE + 4 |
| 455 | + #endif |
| 456 | + /* FSPI (HOST_SPI2) on esp32-s3-wroom */ |
| 457 | + #ifndef PIN_NUM_MISO |
| 458 | + #define PIN_NUM_MISO 13 |
| 459 | + #endif |
| 460 | + #ifndef PIN_NUM_MOSI |
| 461 | + #define PIN_NUM_MOSI 11 |
| 462 | + #endif |
| 463 | + #ifndef PIN_NUM_CLK |
| 464 | + #define PIN_NUM_CLK 12 |
| 465 | + #endif |
| 466 | + #ifndef PIN_NUM_CS |
| 467 | + #define PIN_NUM_CS 10 |
| 468 | + #endif |
| 469 | +#elif defined(CONFIG_IDF_TARGET_ESP32C6) |
| 470 | + #ifndef ESP_SPI_MAX_TRANSFER |
| 471 | + #define ESP_SPI_MAX_TRANSFER_SIZE 1024 |
| 472 | + #endif |
| 473 | + #ifndef PIN_NUM_MISO |
| 474 | + #define PIN_NUM_MISO 2 |
| 475 | + #endif |
| 476 | + #ifndef PIN_NUM_MOSI |
| 477 | + #define PIN_NUM_MOSI 7 |
| 478 | + #endif |
| 479 | + #ifndef PIN_NUM_CLK |
| 480 | + #define PIN_NUM_CLK 6 |
| 481 | + #endif |
| 482 | + #ifndef PIN_NUM_CS |
| 483 | + /* Set to 10 on ESP32-C6 despite documentation that states 16 |
| 484 | + * Tested on ESP32-C6-DevKitC-1 */ |
| 485 | + #define PIN_NUM_CS 10 |
| 486 | + /* Allow software control */ |
| 487 | + #define PIN_NUM_SPICS_IO -1 |
| 488 | + #endif |
| 489 | +#else |
| 490 | + #ifndef ESP_SPI_MAX_TRANSFER |
| 491 | + #define ESP_SPI_MAX_TRANSFER_SIZE MAX_SPI_FRAMESIZE |
| 492 | + #endif |
| 493 | + #ifndef PIN_NUM_MISO |
| 494 | + #error PIN_NUM_MISO undefined |
447 | 495 | #endif |
448 | | - #ifdef WOLFTPM_CHECK_WAIT_STATE |
449 | | - #error SPI check wait state logic not supported |
| 496 | + #ifndef PIN_NUM_MOSI |
| 497 | + #error PIN_NUM_MOSI undefined |
450 | 498 | #endif |
| 499 | + #ifndef PIN_NUM_CLK |
| 500 | + #error PIN_NUM_CLK undefined |
| 501 | + #endif |
| 502 | + #ifndef PIN_NUM_CS |
| 503 | + #error PIN_NUM_CS undefined |
| 504 | + #endif |
| 505 | +#endif |
451 | 506 |
|
452 | | - #error TPM2 SPI support on this platform not supported yet |
| 507 | +/* Set spi_device_interface_config_t.spics_io_num = PIN_NUM_SPICS_IO |
| 508 | + * to -1 to let software control. |
| 509 | + * to CS Pin = PIN_NUM_CS for hardware control. |
| 510 | + * See tpm_spi_acquire() and tpm_spi_release() |
| 511 | + * Software control still requires CS pin */ |
| 512 | +#ifndef PIN_NUM_SPICS_IO |
| 513 | + #define PIN_NUM_SPICS_IO PIN_NUM_CS |
453 | 514 | #endif |
454 | 515 |
|
| 516 | +/* TPM data storing SPI handles & timeouts */ |
| 517 | +static struct TPM_DATA { |
| 518 | + spi_device_handle_t spi; |
| 519 | + gpio_num_t cs_pin; |
| 520 | + int64_t timeout_expiry; |
| 521 | +} *tpm_data; |
| 522 | + |
| 523 | +static int _is_initialized_spi = 0; |
| 524 | + |
| 525 | +static int esp_spi_master_init(void) |
| 526 | +{ |
| 527 | + /* SPI bus & device configuration */ |
| 528 | + const spi_bus_config_t bus_cfg = { |
| 529 | + .miso_io_num = PIN_NUM_MISO, |
| 530 | + .mosi_io_num = PIN_NUM_MOSI, |
| 531 | + .sclk_io_num = PIN_NUM_CLK, |
| 532 | + .quadwp_io_num = -1, |
| 533 | + .quadhd_io_num = -1, |
| 534 | + .max_transfer_sz = ESP_SPI_MAX_TRANSFER_SIZE |
| 535 | + }; |
| 536 | + const spi_device_interface_config_t dev_cfg = { |
| 537 | + .clock_speed_hz = SPI_CLOCK_MHZ, |
| 538 | + .mode = 0, |
| 539 | + .spics_io_num = PIN_NUM_SPICS_IO, /* -1 for SW or PIN_NUM_CS */ |
| 540 | + .queue_size = 1, |
| 541 | + .pre_cb = NULL, |
| 542 | + .post_cb = NULL, |
| 543 | + }; |
| 544 | + esp_err_t ret; |
| 545 | + |
| 546 | + /* Initializing CS pin */ |
| 547 | + esp_rom_gpio_pad_select_gpio(PIN_NUM_CS); |
| 548 | + gpio_set_direction(PIN_NUM_CS, GPIO_MODE_OUTPUT); |
| 549 | + gpio_set_level(PIN_NUM_CS, 1); |
| 550 | + |
| 551 | + /* Initialize the SPI bus and device */ |
| 552 | + ret = spi_bus_initialize(SPI2_HOST, &bus_cfg, 0); |
| 553 | + ESP_ERROR_CHECK(ret); |
| 554 | + |
| 555 | + /* Attach the device to the SPI bus */ |
| 556 | + spi_device_handle_t spi; |
| 557 | + ret = spi_bus_add_device(SPI2_HOST, &dev_cfg, &spi); |
| 558 | + ESP_ERROR_CHECK(ret); |
| 559 | + |
| 560 | + tpm_data = malloc(sizeof(struct TPM_DATA)); |
| 561 | + tpm_data->spi = spi; |
| 562 | + tpm_data->cs_pin = PIN_NUM_CS; |
| 563 | + tpm_data->timeout_expiry = 0; |
| 564 | + |
| 565 | + _is_initialized_spi = TRUE; |
| 566 | + return 0; |
| 567 | +} |
| 568 | + |
| 569 | +/* Aquire SPI bus and keep pulling CS */ |
| 570 | +static int tpm_spi_acquire(void) |
| 571 | +{ |
| 572 | + int ret; |
| 573 | + gpio_set_level(tpm_data->cs_pin, 0); |
| 574 | + ret = spi_device_acquire_bus(tpm_data->spi, portMAX_DELAY); |
| 575 | + return ret; |
| 576 | +} |
| 577 | + |
| 578 | +/* Release SPI bus and CS */ |
| 579 | +int tpm_spi_release (void) |
| 580 | +{ |
| 581 | + gpio_set_level(tpm_data->cs_pin, 1); |
| 582 | + spi_device_release_bus(tpm_data->spi); |
| 583 | + return 0; |
| 584 | +} |
| 585 | + |
| 586 | +int tpm_spi_raw_transfer (const byte *data_out, byte *data_in, size_t cnt) |
| 587 | +{ |
| 588 | + spi_transaction_t t; |
| 589 | + esp_err_t ret; |
| 590 | + |
| 591 | + /* Maximum transfer size is 64 byte because we don't use DMA. */ |
| 592 | + if (cnt > MAX_SPI_FRAMESIZE + ESP_SPI_ADDITIONAL_FRAME_BUFFER) { |
| 593 | + ESP_LOGE(TAG, "tpm_io_espressif: cnt %d larger than framesize\n", cnt); |
| 594 | + return -1; |
| 595 | + } |
| 596 | + |
| 597 | + /* At least one of the buffers has to be set. */ |
| 598 | + if (data_out == NULL && data_in == NULL) { |
| 599 | + return -1; |
| 600 | + } |
| 601 | + |
| 602 | + /* Setup transaction */ |
| 603 | + memset(&t, 0, sizeof(t)); |
| 604 | + t.length = cnt*8; |
| 605 | + t.tx_buffer = data_out; |
| 606 | + t.rx_buffer = data_in; |
| 607 | + |
| 608 | + /* Transmit */ |
| 609 | + ret = spi_device_polling_transmit(tpm_data->spi, &t); |
| 610 | + if (ret != ESP_OK) { |
| 611 | + ESP_LOGE(TAG, "spi_transmit returned error %d\n", ret); |
| 612 | + return -1; |
| 613 | + } |
| 614 | + |
| 615 | + return 0; |
| 616 | +} /* tpm_spi_raw_transfer */ |
| 617 | + |
| 618 | +int TPM2_IoCb_Espressif_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, |
| 619 | + word16 xferSz, void* userCtx) |
| 620 | +{ |
| 621 | + (void)ctx; |
| 622 | + int ret = TPM_RC_FAILURE; |
| 623 | + |
| 624 | + if (_is_initialized_spi) { |
| 625 | + ret = ESP_OK; |
| 626 | + } |
| 627 | + else { |
| 628 | + ret = esp_spi_master_init(); /* ESP return code, not TPM */ |
| 629 | + ESP_LOGV(TAG, "HAL: Initializing SPI %d", ret); |
| 630 | + } |
| 631 | + |
| 632 | + if (ret == ESP_OK) { |
| 633 | + tpm_spi_acquire(); |
| 634 | + ret = tpm_spi_raw_transfer(txBuf, rxBuf, xferSz); |
| 635 | + tpm_spi_release(); |
| 636 | + } |
| 637 | + else { |
| 638 | + ESP_LOGE(TAG, "SPI Failed to initialize. Error: %d", ret); |
| 639 | + ret = TPM_RC_FAILURE; |
| 640 | + } |
| 641 | + |
| 642 | + return ret; |
| 643 | +} /* TPM2_IoCb_Espressif_SPI */ |
| 644 | + |
| 645 | +#endif /* Espressif SPI */ |
455 | 646 | #endif /* WOLFSSL_ESPIDF */ |
456 | 647 | #endif /* WOLFTPM_INCLUDE_IO_FILE */ |
457 | 648 |
|
|
0 commit comments