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