175 lines
6.1 KiB
C
175 lines
6.1 KiB
C
/*----------------------------------------------------------------------------
|
||
* Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved.
|
||
*
|
||
* Description: common_i2c.c
|
||
*
|
||
* Author: luziquan@ss-tjd.com
|
||
*
|
||
* Create: 2024-05-29
|
||
*--------------------------------------------------------------------------*/
|
||
|
||
#include "common_i2c.h"
|
||
#include "i2c.h"
|
||
#include "osal_atomic.h"
|
||
#include "string.h"
|
||
#include "sys_config.h"
|
||
|
||
// clang-format off
|
||
#define ENABLE_PRINT_INFO 1
|
||
#if ENABLE_PRINT_INFO
|
||
#define static_print_info(...) sys_pm_log_i(__VA_ARGS__) // 一般信息打印宏控制
|
||
#define static_print_warn(...) sys_pm_log_w(__VA_ARGS__) // 警告信息打印一般常开
|
||
#define static_print_error(...) sys_pm_log_e(__VA_ARGS__) // 错误信息打印一般常开
|
||
#else
|
||
#define static_print_info(...)
|
||
#define static_print_warn(...)
|
||
#define static_print_error(...)
|
||
#endif
|
||
// clang-format on
|
||
|
||
#ifndef ARRAY_SIZE
|
||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||
#endif
|
||
|
||
typedef struct
|
||
{
|
||
i2c_bus_t bus;
|
||
uint16_t dev_addr;
|
||
uint32_t baudrate;
|
||
bool inited : 1;
|
||
} i2c_device_info_t;
|
||
|
||
static i2c_device_info_t g_i2c_devices[I2C_MODEL_MAX_ID];
|
||
|
||
static uint32_t g_last_baudrate[I2C_BUS_MAX_NUMBER];
|
||
|
||
static uint32_t common_i2c_init(i2c_model_id_t model_id, i2c_bus_t bus, uint16_t dev_addr, uint32_t baudrate)
|
||
{
|
||
uint32_t ret = 0;
|
||
if (model_id >= I2C_MODEL_MAX_ID) {
|
||
return ERRCODE_I2C_INVALID_PARAMETER;
|
||
}
|
||
if (g_i2c_devices[model_id].inited) {
|
||
static_print_error("Model %d I2C[%d] has been initialized", model_id, bus);
|
||
return ERRCODE_I2C_ALREADY_INIT;
|
||
}
|
||
/* uapi_i2c_master_init里面会检测i2c是否初始化,不需要手动管理 */
|
||
ret = uapi_i2c_master_init(bus, baudrate, 0);
|
||
if (ret != ERRCODE_SUCC && ret != ERRCODE_I2C_ALREADY_INIT) {
|
||
static_print_error("Model %d I2C[%d] init failed, ret=0x%x", model_id, bus, ret);
|
||
return ret;
|
||
}
|
||
|
||
g_i2c_devices[model_id].bus = bus;
|
||
g_i2c_devices[model_id].dev_addr = dev_addr;
|
||
g_i2c_devices[model_id].baudrate = baudrate;
|
||
g_i2c_devices[model_id].inited = true;
|
||
|
||
static_print_info("Model %d I2C[%d] Device[0x%x] init success", model_id, bus, dev_addr);
|
||
return ERRCODE_SUCC;
|
||
}
|
||
|
||
static uint32_t common_i2c_deinit(i2c_model_id_t model_id)
|
||
{
|
||
uint32_t ret = 0;
|
||
if (model_id >= I2C_MODEL_MAX_ID) {
|
||
return ERRCODE_I2C_INVALID_PARAMETER;
|
||
}
|
||
if (!g_i2c_devices[model_id].inited) {
|
||
static_print_error("Model %d I2C has not been initialized", model_id);
|
||
return ERRCODE_I2C_NOT_INIT;
|
||
}
|
||
|
||
/* 保证全部同总线i2c设备deinit */
|
||
for (int i = 0; i < I2C_MODEL_MAX_ID; i++) {
|
||
if (i == model_id) {
|
||
continue;
|
||
}
|
||
if (g_i2c_devices[i].bus == g_i2c_devices[model_id].bus && g_i2c_devices[i].inited) {
|
||
g_i2c_devices[model_id].inited = false;
|
||
return ERRCODE_FAIL;
|
||
}
|
||
}
|
||
ret = uapi_i2c_deinit(g_i2c_devices[model_id].bus);
|
||
if (ret != ERRCODE_SUCC && ret != ERRCODE_I2C_NOT_INIT) {
|
||
static_print_error("Model %d deinit failed, ret=0x%x", model_id, ret);
|
||
return ret;
|
||
}
|
||
static_print_info("Model %d I2C device %d deinit success", model_id, g_i2c_devices[model_id].bus);
|
||
memset(&g_i2c_devices[model_id], 0, sizeof(i2c_device_info_t));
|
||
return ERRCODE_SUCC;
|
||
}
|
||
|
||
static uint32_t common_i2c_master_read(i2c_model_id_t model_id, i2c_data_t *data)
|
||
{
|
||
if (model_id >= I2C_MODEL_MAX_ID) {
|
||
return ERRCODE_I2C_INVALID_PARAMETER;
|
||
}
|
||
const i2c_device_info_t *device = &g_i2c_devices[model_id];
|
||
if (device->inited == false) {
|
||
static_print_error("Model %d has not been initialized", model_id);
|
||
return ERRCODE_I2C_NOT_INIT;
|
||
}
|
||
if (g_last_baudrate[device->bus] != device->baudrate) {
|
||
static_print_info("Model %d I2C[%d] set baudrate %d", model_id, device->bus, device->baudrate);
|
||
uapi_i2c_set_baudrate(device->bus, device->baudrate);
|
||
}
|
||
g_last_baudrate[device->bus] = device->baudrate;
|
||
return uapi_i2c_master_read(device->bus, device->dev_addr, data);
|
||
}
|
||
|
||
static uint32_t common_i2c_master_write(i2c_model_id_t model_id, i2c_data_t *data)
|
||
{
|
||
if (model_id >= I2C_MODEL_MAX_ID) {
|
||
return ERRCODE_I2C_INVALID_PARAMETER;
|
||
}
|
||
const i2c_device_info_t *device = &g_i2c_devices[model_id];
|
||
if (device->inited == false) {
|
||
static_print_error("Model %d has not been initialized", model_id);
|
||
return ERRCODE_I2C_NOT_INIT;
|
||
}
|
||
if (g_last_baudrate[device->bus] != device->baudrate) {
|
||
static_print_info("Model %d I2C[%d] set baudrate %d", model_id, device->bus, device->baudrate);
|
||
uapi_i2c_set_baudrate(device->bus, device->baudrate);
|
||
}
|
||
g_last_baudrate[device->bus] = device->baudrate;
|
||
return uapi_i2c_master_write(device->bus, device->dev_addr, data);
|
||
}
|
||
|
||
static uint32_t common_i2c_master_writeread(i2c_model_id_t model_id, i2c_data_t *data)
|
||
{
|
||
if (model_id >= I2C_MODEL_MAX_ID) {
|
||
return ERRCODE_I2C_INVALID_PARAMETER;
|
||
}
|
||
const i2c_device_info_t *device = &g_i2c_devices[model_id];
|
||
if (device->inited == false) {
|
||
static_print_error("Model %d has not been initialized", model_id);
|
||
return ERRCODE_I2C_NOT_INIT;
|
||
}
|
||
if (g_last_baudrate[device->bus] != device->baudrate) {
|
||
static_print_info("Model %d I2C[%d] set baudrate %d", model_id, device->bus, device->baudrate);
|
||
uapi_i2c_set_baudrate(device->bus, device->baudrate);
|
||
}
|
||
g_last_baudrate[device->bus] = device->baudrate;
|
||
return uapi_i2c_master_writeread(device->bus, device->dev_addr, data);
|
||
}
|
||
|
||
static uint32_t common_i2c_master_set_dev_addr(i2c_model_id_t model_id, uint16_t dev_addr)
|
||
{
|
||
if (model_id >= I2C_MODEL_MAX_ID) {
|
||
return ERRCODE_I2C_INVALID_PARAMETER;
|
||
}
|
||
g_i2c_devices[model_id].dev_addr = dev_addr;
|
||
return ERRCODE_SUCC;
|
||
}
|
||
|
||
static struct common_i2c_class_ops g_common_i2c_ops = {
|
||
.open = common_i2c_init,
|
||
.close = common_i2c_deinit,
|
||
.read = common_i2c_master_read,
|
||
.write = common_i2c_master_write,
|
||
.writeread = common_i2c_master_writeread,
|
||
.set_dev_addr = common_i2c_master_set_dev_addr,
|
||
};
|
||
|
||
const struct common_i2c_class_ops *tjd_driver_common_i2c_get_ops(void) { return &g_common_i2c_ops; } |