Update SCP03 tests with PlatformSCP03 integration tests and documentation
- Add PlatformSCP03 integration test cases (test_scp03_platform_integration, test_scp03_platform_key_file) - Update test helpers with mock session creation - Update README with PlatformSCP03 configuration guide - Add references to NXP AN12413 and AN12436 - Fix test assertions to work with opaque session type
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
* @file se050_i2c_hal.c
|
||||
* @brief SE050 I2C HAL Implementation
|
||||
*
|
||||
* Clean-room I2C hardware abstraction layer for SE050.
|
||||
*
|
||||
* License: MIT (Clean-room implementation)
|
||||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "se050_wireguard.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __linux__
|
||||
/* Linux-specific I2C IOCTL definitions */
|
||||
#ifndef I2C_SLAVE
|
||||
#define I2C_SLAVE 0x0703
|
||||
#endif
|
||||
#ifndef I2C_SMBUS
|
||||
#define I2C_SMBUS 0x0720
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* SE050 default I2C address */
|
||||
#define SE050_I2C_ADDR_DEFAULT 0x90
|
||||
|
||||
/* I2C timeout in milliseconds */
|
||||
#define SE050_I2C_TIMEOUT_MS 1000
|
||||
|
||||
/* Maximum retry count for I2C operations */
|
||||
#define SE050_I2C_MAX_RETRY 3
|
||||
|
||||
/* SE050 wakeup delay in milliseconds */
|
||||
#define SE050_WAKEUP_DELAY_MS 5
|
||||
|
||||
/**
|
||||
* @brief Sleep for specified milliseconds
|
||||
*/
|
||||
static void se050_sleep_ms(unsigned int ms)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct timespec ts;
|
||||
ts.tv_sec = ms / 1000;
|
||||
ts.tv_nsec = (ms % 1000) * 1000000L;
|
||||
nanosleep(&ts, NULL);
|
||||
#else
|
||||
/* Fallback for non-Linux platforms */
|
||||
volatile int i;
|
||||
for (i = 0; i < ms * 1000; i++);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open I2C device
|
||||
*/
|
||||
static void *i2c_open(const char *dev_path)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (!dev_path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = open(dev_path, O_RDWR);
|
||||
if (fd < 0) {
|
||||
perror("I2C open failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)(intptr_t)fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close I2C device
|
||||
*/
|
||||
static void i2c_close(void *handle)
|
||||
{
|
||||
int fd = (int)(intptr_t)handle;
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set I2C slave address
|
||||
*/
|
||||
static se050_status_t i2c_set_slave_addr(void *handle, uint8_t addr)
|
||||
{
|
||||
int fd = (int)(intptr_t)handle;
|
||||
int ret;
|
||||
|
||||
ret = ioctl(fd, I2C_SLAVE, addr >> 1);
|
||||
if (ret < 0) {
|
||||
perror("I2C set slave address failed");
|
||||
return SE050_ERR_I2C;
|
||||
}
|
||||
|
||||
return SE050_OK;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Public API Implementation
|
||||
* ============================================================================ */
|
||||
|
||||
se050_status_t se050_i2c_init(se050_i2c_hal_t *hal, const char *dev_path, uint8_t slave_addr)
|
||||
{
|
||||
void *handle;
|
||||
|
||||
if (!hal || !dev_path) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
memset(hal, 0, sizeof(*hal));
|
||||
|
||||
/* Open I2C device */
|
||||
handle = i2c_open(dev_path);
|
||||
if (!handle) {
|
||||
return SE050_ERR_I2C;
|
||||
}
|
||||
|
||||
/* Set slave address */
|
||||
if (i2c_set_slave_addr(handle, slave_addr) != SE050_OK) {
|
||||
i2c_close(handle);
|
||||
return SE050_ERR_I2C;
|
||||
}
|
||||
|
||||
hal->handle = handle;
|
||||
hal->slave_addr = slave_addr;
|
||||
hal->dev_path = strdup(dev_path);
|
||||
|
||||
return SE050_OK;
|
||||
}
|
||||
|
||||
void se050_i2c_close(se050_i2c_hal_t *hal)
|
||||
{
|
||||
if (!hal) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hal->handle) {
|
||||
i2c_close(hal->handle);
|
||||
hal->handle = NULL;
|
||||
}
|
||||
|
||||
if (hal->dev_path) {
|
||||
free((void *)hal->dev_path);
|
||||
hal->dev_path = NULL;
|
||||
}
|
||||
|
||||
hal->slave_addr = 0;
|
||||
}
|
||||
|
||||
int se050_i2c_read(se050_i2c_hal_t *hal, uint8_t *buffer, int length)
|
||||
{
|
||||
int fd;
|
||||
int retry;
|
||||
int bytes_read;
|
||||
|
||||
if (!hal || !buffer || length <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = (int)(intptr_t)hal->handle;
|
||||
|
||||
for (retry = 0; retry < SE050_I2C_MAX_RETRY; retry++) {
|
||||
bytes_read = read(fd, buffer, length);
|
||||
if (bytes_read > 0) {
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
if (errno != EAGAIN && errno != ETIMEDOUT) {
|
||||
/* Permanent error */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Retry with delay */
|
||||
se050_sleep_ms(SE050_WAKEUP_DELAY_MS);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int se050_i2c_write(se050_i2c_hal_t *hal, const uint8_t *buffer, int length)
|
||||
{
|
||||
int fd;
|
||||
int retry;
|
||||
int bytes_written;
|
||||
|
||||
if (!hal || !buffer || length <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = (int)(intptr_t)hal->handle;
|
||||
|
||||
for (retry = 0; retry < SE050_I2C_MAX_RETRY; retry++) {
|
||||
bytes_written = write(fd, buffer, length);
|
||||
if (bytes_written > 0) {
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
if (errno != EAGAIN && errno != ETIMEDOUT) {
|
||||
/* Permanent error */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Retry with delay */
|
||||
se050_sleep_ms(SE050_WAKEUP_DELAY_MS);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
se050_status_t se050_i2c_wakeup(se050_i2c_hal_t *hal)
|
||||
{
|
||||
uint8_t wakeup_cmd = 0x00;
|
||||
int ret;
|
||||
|
||||
if (!hal) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Send wakeup command (dummy write) */
|
||||
ret = se050_i2c_write(hal, &wakeup_cmd, 1);
|
||||
if (ret < 0) {
|
||||
return SE050_ERR_I2C;
|
||||
}
|
||||
|
||||
/* Wait for SE050 to respond */
|
||||
se050_sleep_ms(SE050_WAKEUP_DELAY_MS);
|
||||
|
||||
return SE050_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user