summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYilin Sun <[email protected]>2024-09-04 15:56:47 +0800
committerRbb666 <[email protected]>2024-09-04 23:34:40 +0800
commitb76fd6ba0af6a99e47cff21c36cbcb4dcb54f700 (patch)
tree9b93c7087d7882ca11638b0b5ef41e70707b9f06
parentd2160d352c34c46015eb916f12c23cf16b2b9a66 (diff)
bsp: nxp/mcx/mcxc: Add I2C driver support.
-rw-r--r--bsp/nxp/mcx/mcxc/Libraries/drivers/drv_i2c.c152
1 files changed, 152 insertions, 0 deletions
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 <rtdevice.h>
+
+#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