mcu_hi3321_watch/tjd/driver/common/common_i2c.c
2025-05-26 20:15:20 +08:00

175 lines
6.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* 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; }