From b76fd6ba0af6a99e47cff21c36cbcb4dcb54f700 Mon Sep 17 00:00:00 2001 From: Yilin Sun Date: Wed, 4 Sep 2024 15:56:47 +0800 Subject: [PATCH] bsp: nxp/mcx/mcxc: Add I2C driver support. --- bsp/nxp/mcx/mcxc/Libraries/drivers/drv_i2c.c | 152 +++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 bsp/nxp/mcx/mcxc/Libraries/drivers/drv_i2c.c diff --git a/bsp/nxp/mcx/mcxc/Libraries/drivers/drv_i2c.c b/bsp/nxp/mcx/mcxc/Libraries/drivers/drv_i2c.c new file mode 100644 index 0000000000..0c1b75cc55 --- /dev/null +++ b/bsp/nxp/mcx/mcxc/Libraries/drivers/drv_i2c.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-09-03 Yilin Sun Initial version + */ + +#include + +#include "fsl_i2c.h" + +#ifdef RT_USING_I2C + +#define BSP_DEFAULT_I2C_FREQ (100000) + +typedef struct +{ + struct rt_i2c_bus_device parent; + I2C_Type *instance; + uint32_t input_frequency; +} mcx_i2c_obj_t; + +typedef struct +{ + I2C_Type *instance; + uint8_t id; +} mcx_i2c_instance_t; + +static const mcx_i2c_instance_t mcx_i2c_instances[] = +{ +#ifdef BSP_USING_I2C0 + {I2C0, 0}, +#endif + +#ifdef BSP_USING_I2C1 + {I2C1, 1}, +#endif +}; + +static mcx_i2c_obj_t mcx_i2c_list[ARRAY_SIZE(mcx_i2c_instances)]; + +static int mcx_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) +{ + struct rt_i2c_msg *msg; + i2c_master_transfer_t xfer = {0}; + rt_uint32_t i; + rt_ssize_t ret = 0; + + mcx_i2c_obj_t *i2c = (mcx_i2c_obj_t *)bus; + + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + + if (msg->flags & RT_I2C_RD) + { + xfer.slaveAddress = msg->addr; + xfer.direction = kI2C_Read; + xfer.subaddress = 0; + xfer.subaddressSize = 0; + xfer.data = msg->buf; + xfer.dataSize = msg->len; + + xfer.flags = kI2C_TransferDefaultFlag; + + if (i != 0) + { + xfer.flags |= kI2C_TransferRepeatedStartFlag; + } + + if (i != num - 1) + { + xfer.flags |= kI2C_TransferNoStopFlag; + } + + + if (I2C_MasterTransferBlocking(i2c->instance, &xfer) != kStatus_Success) + { + return i; + } + } + else + { + xfer.slaveAddress = msg->addr; + xfer.direction = kI2C_Write; + xfer.subaddress = 0; + xfer.subaddressSize = 0; + xfer.data = msg->buf; + xfer.dataSize = msg->len; + + xfer.flags = kI2C_TransferDefaultFlag; + + if (i != 0) + { + xfer.flags |= kI2C_TransferRepeatedStartFlag; + } + + if (i != num - 1) + { + xfer.flags |= kI2C_TransferNoStopFlag; + } + + if (I2C_MasterTransferBlocking(i2c->instance, &xfer) != kStatus_Success) + { + return i; + } + } + } + + ret = num; + + return ret; +} + +static const struct rt_i2c_bus_device_ops mcx_i2c_ops = +{ + mcx_i2c_master_xfer, + RT_NULL, + RT_NULL, +}; + +static int rt_hw_i2c_init(void) +{ + i2c_master_config_t master_cfg; + char name_buf[16]; + + for (size_t i = 0; i < ARRAY_SIZE(mcx_i2c_instances); i++) + { + mcx_i2c_list[i].input_frequency = CLOCK_GetCoreSysClkFreq(); + mcx_i2c_list[i].instance = mcx_i2c_instances[i].instance; + mcx_i2c_list[i].parent.ops = &mcx_i2c_ops; + + I2C_MasterGetDefaultConfig(&master_cfg); + + master_cfg.baudRate_Bps = BSP_DEFAULT_I2C_FREQ; + + I2C_MasterInit(mcx_i2c_list[i].instance, &master_cfg, mcx_i2c_list[i].input_frequency); + + rt_snprintf(name_buf, 16, "i2c%d", mcx_i2c_instances[i].id); + + rt_i2c_bus_device_register(&mcx_i2c_list[i].parent, name_buf); + } + + return RT_EOK; +} + +INIT_DEVICE_EXPORT(rt_hw_i2c_init); + +#endif