|
@@ -0,0 +1,116 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 2006-2020, RT-Thread Development Team
|
|
|
+ *
|
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
|
+ *
|
|
|
+ * Change Logs:
|
|
|
+ * Date Author Notes
|
|
|
+ * 2020-11-15 xckhmf First Verison
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+#include <rtdevice.h>
|
|
|
+#include <nrfx_twi_twim.h>
|
|
|
+#include <nrfx_twim.h>
|
|
|
+#include <drv_i2c.h>
|
|
|
+#if defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1)
|
|
|
+typedef struct
|
|
|
+{
|
|
|
+ nrf_twim_frequency_t freq;
|
|
|
+ uint32_t scl_pin;
|
|
|
+ uint32_t sda_pin;
|
|
|
+ nrfx_twim_t twi_instance;
|
|
|
+}drv_i2c_cfg_t;
|
|
|
+
|
|
|
+#ifdef BSP_USING_I2C0
|
|
|
+static drv_i2c_cfg_t drv_i2c_0 =
|
|
|
+{
|
|
|
+ .freq = NRF_TWIM_FREQ_400K,
|
|
|
+ .scl_pin = BSP_I2C0_SCL_PIN,
|
|
|
+ .sda_pin = BSP_I2C0_SDA_PIN,
|
|
|
+ .twi_instance = NRFX_TWIM_INSTANCE(0)
|
|
|
+};
|
|
|
+static struct rt_i2c_bus_device i2c0_bus;
|
|
|
+#endif
|
|
|
+#ifdef BSP_USING_I2C1
|
|
|
+static drv_i2c_cfg_t drv_i2c_1 =
|
|
|
+{
|
|
|
+ .freq = NRF_TWIM_FREQ_400K,
|
|
|
+ .scl_pin = BSP_I2C1_SCL_PIN,
|
|
|
+ .sda_pin = BSP_I2C1_SDA_PIN,
|
|
|
+ .twi_instance = NRFX_TWIM_INSTANCE(1)
|
|
|
+};
|
|
|
+static struct rt_i2c_bus_device i2c1_bus;
|
|
|
+#endif
|
|
|
+static int twi_master_init(struct rt_i2c_bus_device *bus)
|
|
|
+{
|
|
|
+ nrfx_err_t rtn;
|
|
|
+ nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG(0,0);
|
|
|
+ drv_i2c_cfg_t *p_cfg = bus->priv;
|
|
|
+ nrfx_twim_t const * p_instance = &p_cfg->twi_instance;
|
|
|
+
|
|
|
+ config.frequency = p_cfg->freq;
|
|
|
+ config.scl = p_cfg->scl_pin;
|
|
|
+ config.sda = p_cfg->sda_pin;
|
|
|
+
|
|
|
+ nrfx_twi_twim_bus_recover(config.scl,config.sda);
|
|
|
+
|
|
|
+ rtn = nrfx_twim_init(p_instance,&config,NULL,NULL);
|
|
|
+ nrfx_twim_enable(p_instance);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static rt_size_t _master_xfer(struct rt_i2c_bus_device *bus,
|
|
|
+ struct rt_i2c_msg msgs[],
|
|
|
+ rt_uint32_t num)
|
|
|
+{
|
|
|
+ nrfx_twim_t const * p_instance = &((drv_i2c_cfg_t *)bus->priv)->twi_instance;
|
|
|
+ nrfx_err_t ret = NRFX_ERROR_INTERNAL;
|
|
|
+ uint32_t no_stop_flag = 0;
|
|
|
+
|
|
|
+ nrfx_twim_xfer_desc_t xfer = NRFX_TWIM_XFER_DESC_TX(msgs->addr,msgs->buf, msgs->len);
|
|
|
+ if((msgs->flags & 0x01) == RT_I2C_WR)
|
|
|
+ {
|
|
|
+ xfer.type = NRFX_TWIM_XFER_TX;
|
|
|
+ if((msgs->flags & 0x40) == RT_I2C_NO_READ_ACK)
|
|
|
+ {
|
|
|
+ no_stop_flag = NRFX_TWIM_FLAG_TX_NO_STOP;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if((msgs->flags & 0x01) == RT_I2C_RD)
|
|
|
+ {
|
|
|
+ xfer.type = NRFX_TWIM_XFER_RX;
|
|
|
+ }
|
|
|
+ ret = nrfx_twim_xfer(p_instance,&xfer,no_stop_flag);
|
|
|
+ return (ret == NRFX_SUCCESS) ? msgs->len : 0;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+static const struct rt_i2c_bus_device_ops _i2c_ops =
|
|
|
+{
|
|
|
+ _master_xfer,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+
|
|
|
+int rt_hw_i2c_init(void)
|
|
|
+{
|
|
|
+#ifdef BSP_USING_I2C0
|
|
|
+ i2c0_bus.ops= &_i2c_ops;
|
|
|
+ i2c0_bus.timeout = 0;
|
|
|
+ i2c0_bus.priv = (void *)&drv_i2c_0;
|
|
|
+ twi_master_init(&i2c0_bus);
|
|
|
+ rt_i2c_bus_device_register(&i2c0_bus, "i2c0");
|
|
|
+#endif
|
|
|
+#ifdef BSP_USING_I2C1
|
|
|
+ i2c1_bus.ops= &_i2c_ops;
|
|
|
+ i2c1_bus.timeout = 0;
|
|
|
+ i2c1_bus.priv = (void *)&drv_i2c_1;
|
|
|
+ twi_master_init(&i2c1_bus);
|
|
|
+ rt_i2c_bus_device_register(&i2c1_bus, "i2c1");
|
|
|
+#endif
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+INIT_BOARD_EXPORT(rt_hw_i2c_init);
|
|
|
+#endif /* defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1) */
|