mirror of https://github.com/wolfSSL/wolfTPM.git
Implementation for TPM2_IoCb_MicrochipHarmony_I2C.
parent
6e1205b1e1
commit
eb079ee22a
|
@ -148,6 +148,9 @@ int TPM2_IoCb(TPM2_CTX* ctx, INT32 isRead, UINT32 addr,
|
||||||
ret = TPM2_IoCb_Infineon_I2C(ctx, isRead, addr, buf, size, userCtx);
|
ret = TPM2_IoCb_Infineon_I2C(ctx, isRead, addr, buf, size, userCtx);
|
||||||
#elif defined(WOLFSSL_ESPIDF)
|
#elif defined(WOLFSSL_ESPIDF)
|
||||||
ret = TPM2_IoCb_Espressif_I2C(ctx, isRead, addr, buf, size, userCtx);
|
ret = TPM2_IoCb_Espressif_I2C(ctx, isRead, addr, buf, size, userCtx);
|
||||||
|
#elif defined(WOLFTPM_MICROCHIP_HARMONY)
|
||||||
|
/* Use MicrochipHarmony I2C */
|
||||||
|
ret = TPM2_IoCb_MicrochipHarmony_I2C(ctx, isRead, addr, buf, size, userCtx);
|
||||||
#else
|
#else
|
||||||
/* TODO: Add your platform here for HW I2C interface */
|
/* TODO: Add your platform here for HW I2C interface */
|
||||||
printf("Add your platform here for HW I2C interface\n");
|
printf("Add your platform here for HW I2C interface\n");
|
||||||
|
|
|
@ -88,6 +88,9 @@ WOLFTPM_LOCAL int TPM2_IoCb_Infineon_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
|
||||||
#elif defined(WOLFSSL_ESPIDF)
|
#elif defined(WOLFSSL_ESPIDF)
|
||||||
WOLFTPM_LOCAL int TPM2_IoCb_Espressif_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
|
WOLFTPM_LOCAL int TPM2_IoCb_Espressif_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
|
||||||
byte* buf, word16 size, void* userCtx);
|
byte* buf, word16 size, void* userCtx);
|
||||||
|
#elif defined(WOLFTPM_MICROCHIP_HARMONY)
|
||||||
|
WOLFTPM_LOCAL int TPM2_IoCb_MicrochipHarmony_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
|
||||||
|
byte* buf, word16 size, void* userCtx);
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|
||||||
#else /* SPI */
|
#else /* SPI */
|
||||||
|
|
|
@ -49,13 +49,232 @@
|
||||||
|
|
||||||
#if defined(WOLFTPM_MICROCHIP_HARMONY)
|
#if defined(WOLFTPM_MICROCHIP_HARMONY)
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
|
||||||
|
#ifdef WOLFTPM_I2C /* Microchip Harmony Hal I2C */
|
||||||
|
/* We are using the I2C bitbang library. */
|
||||||
|
#include <i2cbb/i2c_bb.h>
|
||||||
|
/* Use sys_time to implement delay. */
|
||||||
|
#include "system/time/sys_time.h"
|
||||||
|
|
||||||
|
#ifndef TPM_I2C_TRIES
|
||||||
|
#define TPM_I2C_TRIES 10
|
||||||
|
#endif
|
||||||
|
#ifndef TPM2_I2C_ADDR
|
||||||
|
#define TPM2_I2C_ADDR 0x2e
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uintptr_t dummy_context;
|
||||||
|
|
||||||
|
static void dummy_callback(uintptr_t context)
|
||||||
|
{
|
||||||
|
(void) context;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for time_ms using Micochip Harmony SYS_TIME API. */
|
||||||
|
static void microchip_wait(uint32_t time_ms)
|
||||||
|
{
|
||||||
|
/* Microchip Harmony example from documentation.
|
||||||
|
* SYS_TIME_DelayMS will internally create the timer,
|
||||||
|
* and SYS_TIME_DelayIsComplete will delete it when
|
||||||
|
* the delay has completed. */
|
||||||
|
SYS_TIME_HANDLE timer = SYS_TIME_HANDLE_INVALID;
|
||||||
|
|
||||||
|
if (SYS_TIME_DelayMS(time_ms, &timer) != SYS_TIME_SUCCESS) {
|
||||||
|
printf("error: microchip_wait: SYS_TIME_DelayMS failed\n");
|
||||||
|
}
|
||||||
|
else if(SYS_TIME_DelayIsComplete(timer) != true) {
|
||||||
|
/* Loop until delay is complete. */
|
||||||
|
while (SYS_TIME_DelayIsComplete(timer) == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Microchip Harmony I2C */
|
||||||
|
static int i2c_read(void* userCtx, word32 reg, byte* data, int len)
|
||||||
|
{
|
||||||
|
int ret = TPM_RC_FAILURE;
|
||||||
|
I2CBB_ERROR status = I2CBB_ERROR_NONE;
|
||||||
|
bool queued = false;
|
||||||
|
int timeout = TPM_I2C_TRIES;
|
||||||
|
int busy_retry = TPM_I2C_TRIES;
|
||||||
|
byte buf[1];
|
||||||
|
|
||||||
|
if (I2C_BB_IsBusy()) {
|
||||||
|
printf("error: i2c_read: already busy\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TIS layer should never provide a buffer larger than this,
|
||||||
|
but double check for good coding practice */
|
||||||
|
if (len > MAX_SPI_FRAMESIZE) {
|
||||||
|
printf("error: i2c_read: len too large: %d\n", len);
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = (reg & 0xFF); /* convert to simple 8-bit address for I2C */
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Queue the write with I2C_BB. */
|
||||||
|
queued = I2C_BB_Write(TPM2_I2C_ADDR, buf, sizeof(buf));
|
||||||
|
|
||||||
|
if (!queued) {
|
||||||
|
printf("error: i2c_read: I2C_BB_Write failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
busy_retry = TPM_I2C_TRIES;
|
||||||
|
|
||||||
|
while (I2C_BB_IsBusy() && --busy_retry > 0) {
|
||||||
|
microchip_wait(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (I2C_BB_IsBusy()) {
|
||||||
|
printf("error: i2c_read: busy wait timed out\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = I2C_BB_ErrorGet();
|
||||||
|
if (status == I2CBB_ERROR_NAK) {
|
||||||
|
microchip_wait(250);
|
||||||
|
}
|
||||||
|
} while (status == I2CBB_ERROR_NAK && --timeout > 0);
|
||||||
|
|
||||||
|
if (status != I2CBB_ERROR_NONE) {
|
||||||
|
if (status == I2CBB_ERROR_NAK) {
|
||||||
|
printf("error: i2c_read: I2C_BB_Write failed with NAK: %d\n",
|
||||||
|
status);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("error: i2c_read: I2C_BB_Write failed: %d\n", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout = TPM_I2C_TRIES;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Queue the read with I2C_BB. */
|
||||||
|
queued = I2C_BB_Read(TPM2_I2C_ADDR, data, len);
|
||||||
|
|
||||||
|
if (!queued) {
|
||||||
|
printf("error: i2c_read: I2C_BB_Read failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
busy_retry = TPM_I2C_TRIES;
|
||||||
|
|
||||||
|
while (I2C_BB_IsBusy() && --busy_retry > 0) {
|
||||||
|
microchip_wait(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = I2C_BB_ErrorGet();
|
||||||
|
if (status == I2CBB_ERROR_NAK) {
|
||||||
|
microchip_wait(250);
|
||||||
|
}
|
||||||
|
} while (status == I2CBB_ERROR_NAK && --timeout > 0);
|
||||||
|
|
||||||
|
if (status == I2CBB_ERROR_NONE) {
|
||||||
|
ret = TPM_RC_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("error: I2C Read failure %d (tries %d)\n",
|
||||||
|
status, TPM_I2C_TRIES - timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int i2c_write(void* userCtx, word32 reg, byte* data, int len)
|
||||||
|
{
|
||||||
|
int ret = TPM_RC_FAILURE;
|
||||||
|
I2CBB_ERROR status = I2CBB_ERROR_NONE;
|
||||||
|
bool queued = false;
|
||||||
|
int timeout = TPM_I2C_TRIES;
|
||||||
|
int busy_retry = TPM_I2C_TRIES;
|
||||||
|
byte buf[MAX_SPI_FRAMESIZE+1];
|
||||||
|
|
||||||
|
/* TIS layer should never provide a buffer larger than this,
|
||||||
|
but double check for good coding practice */
|
||||||
|
if (len > MAX_SPI_FRAMESIZE) {
|
||||||
|
printf("error: i2c_write: len too large: %d\n", len);
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (I2C_BB_IsBusy()) {
|
||||||
|
printf("error: i2c_write: already busy\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build packet with TPM register and data */
|
||||||
|
buf[0] = (reg & 0xFF); /* convert to simple 8-bit address for I2C */
|
||||||
|
XMEMCPY(buf + 1, data, len);
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Queue the write with I2C_BB. */
|
||||||
|
queued = I2C_BB_Write(TPM2_I2C_ADDR, buf, len + 1);
|
||||||
|
|
||||||
|
if (!queued) {
|
||||||
|
printf("error: i2c_write: I2C_BB_Write failed: %d\n", status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (I2C_BB_IsBusy() && --busy_retry > 0) {
|
||||||
|
microchip_wait(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = I2C_BB_ErrorGet();
|
||||||
|
|
||||||
|
if (status == I2CBB_ERROR_NAK) {
|
||||||
|
microchip_wait(250);
|
||||||
|
}
|
||||||
|
} while (status == I2CBB_ERROR_NAK && --timeout > 0);
|
||||||
|
|
||||||
|
if (status == I2CBB_ERROR_NONE) {
|
||||||
|
ret = TPM_RC_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("I2C Write failure %d\n", status);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TPM2_IoCb_MicrochipHarmony_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
|
||||||
|
byte* buf, word16 size, void* userCtx)
|
||||||
|
{
|
||||||
|
int ret = TPM_RC_FAILURE;
|
||||||
|
|
||||||
|
/* Set callback to null to do time based polling of
|
||||||
|
* I2C_BB_IsBusy instead.
|
||||||
|
*
|
||||||
|
* Note: Apparently a callback is actually required,
|
||||||
|
* even if not used.
|
||||||
|
* */
|
||||||
|
I2C_BB_Initialize();
|
||||||
|
I2C_BB_CallbackRegister(dummy_callback, dummy_context);
|
||||||
|
|
||||||
|
if (isRead) {
|
||||||
|
ret = i2c_read(userCtx, addr, buf, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = i2c_write(userCtx, addr, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)userCtx;
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else /* Microchip Harmony Hal SPI */
|
||||||
|
|
||||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||||
#error This driver does not support check wait state yet
|
#error This driver does not support check wait state yet
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "configuration.h"
|
|
||||||
#include "definitions.h"
|
|
||||||
|
|
||||||
/* TPM Chip Select Pin (default PC5) */
|
/* TPM Chip Select Pin (default PC5) */
|
||||||
#ifndef TPM_SPI_PIN
|
#ifndef TPM_SPI_PIN
|
||||||
#define SYS_PORT_PIN_PC5
|
#define SYS_PORT_PIN_PC5
|
||||||
|
@ -98,6 +317,7 @@ int TPM2_IoCb_Microchip_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* WOLFTPM_I2C */
|
||||||
#endif /* WOLFTPM_MICROCHIP_HARMONY */
|
#endif /* WOLFTPM_MICROCHIP_HARMONY */
|
||||||
#endif /* !(WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI) */
|
#endif /* !(WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI) */
|
||||||
#endif /* WOLFTPM_INCLUDE_IO_FILE */
|
#endif /* WOLFTPM_INCLUDE_IO_FILE */
|
||||||
|
|
Loading…
Reference in New Issue