rt-thread-official/bsp/nrf5x/libraries/drivers/drv_i2c.c

176 lines
4.2 KiB
C
Raw Permalink Normal View History

2020-11-24 00:49:27 +08:00
/*
2023-01-28 17:38:36 +08:00
* Copyright (c) 2006-2023, RT-Thread Development Team
2020-11-24 00:49:27 +08:00
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-11-15 xckhmf First Verison
2021-11-27 19:04:23 +08:00
* 2021-11-27 chenyingchun fix _master_xfer bug
2023-01-28 17:38:36 +08:00
* 2023-01-28 Andrew add Nrf5340 support
2020-11-24 00:49:27 +08:00
*/
2021-03-14 15:18:33 +08:00
2020-11-24 00:49:27 +08:00
#include <rtdevice.h>
#include <nrfx_twi_twim.h>
#include <nrfx_twim.h>
#include <drv_i2c.h>
2023-01-28 17:38:36 +08:00
#if defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3)
2020-11-24 00:49:27 +08:00
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
2021-03-14 15:18:33 +08:00
static drv_i2c_cfg_t drv_i2c_0 =
2020-11-24 00:49:27 +08:00
{
.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
2021-03-14 15:18:33 +08:00
static drv_i2c_cfg_t drv_i2c_1 =
2020-11-24 00:49:27 +08:00
{
.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
2023-01-28 17:38:36 +08:00
#ifdef BSP_USING_I2C2
static drv_i2c_cfg_t drv_i2c_2 =
{
.freq = NRF_TWIM_FREQ_400K,
.scl_pin = BSP_I2C2_SCL_PIN,
.sda_pin = BSP_I2C2_SDA_PIN,
.twi_instance = NRFX_TWIM_INSTANCE(2)
};
static struct rt_i2c_bus_device i2c2_bus;
#endif
#ifdef BSP_USING_I2C3
static drv_i2c_cfg_t drv_i2c_3 =
{
.freq = NRF_TWIM_FREQ_400K,
.scl_pin = BSP_I2C3_SCL_PIN,
.sda_pin = BSP_I2C3_SDA_PIN,
.twi_instance = NRFX_TWIM_INSTANCE(3)
};
static struct rt_i2c_bus_device i2c3_bus;
#endif
2021-03-14 15:18:33 +08:00
static int twi_master_init(struct rt_i2c_bus_device *bus)
2020-11-24 00:49:27 +08:00
{
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;
2021-03-14 15:18:33 +08:00
2020-11-24 00:49:27 +08:00
config.frequency = p_cfg->freq;
config.scl = p_cfg->scl_pin;
config.sda = p_cfg->sda_pin;
2021-03-14 15:18:33 +08:00
2020-11-24 00:49:27 +08:00
nrfx_twi_twim_bus_recover(config.scl,config.sda);
rtn = nrfx_twim_init(p_instance,&config,NULL,NULL);
2021-11-27 19:04:23 +08:00
if (rtn != NRFX_SUCCESS)
{
return rtn;
}
2020-11-24 00:49:27 +08:00
nrfx_twim_enable(p_instance);
return 0;
}
static rt_ssize_t _master_xfer(struct rt_i2c_bus_device *bus,
2021-11-27 19:04:23 +08:00
struct rt_i2c_msg msgs[],
rt_uint32_t num)
2020-11-24 00:49:27 +08:00
{
2021-11-27 19:04:23 +08:00
struct rt_i2c_msg *msg;
nrfx_twim_t const *p_instance = &((drv_i2c_cfg_t *)bus->priv)->twi_instance;
2020-11-24 00:49:27 +08:00
nrfx_err_t ret = NRFX_ERROR_INTERNAL;
uint32_t no_stop_flag = 0;
2021-11-27 19:04:23 +08:00
rt_int32_t i = 0;
2021-03-14 15:18:33 +08:00
2021-11-27 19:04:23 +08:00
for (i = 0; i < num; i++)
2020-11-24 00:49:27 +08:00
{
2021-11-27 19:04:23 +08:00
msg = &msgs[i];
nrfx_twim_xfer_desc_t xfer = NRFX_TWIM_XFER_DESC_TX(msg->addr, msg->buf, msg->len);
if (msg->flags & RT_I2C_RD)
2020-11-24 00:49:27 +08:00
{
2021-11-27 19:04:23 +08:00
xfer.type = NRFX_TWIM_XFER_RX;
}
else
{
xfer.type = NRFX_TWIM_XFER_TX;
if (msg->flags & RT_I2C_NO_READ_ACK)
{
no_stop_flag = NRFX_TWIM_FLAG_TX_NO_STOP;
}
}
ret = nrfx_twim_xfer(p_instance, &xfer, no_stop_flag);
if (ret != NRFX_SUCCESS)
{
goto out;
2020-11-24 00:49:27 +08:00
}
}
2021-03-14 15:18:33 +08:00
2021-11-27 19:04:23 +08:00
out:
return i;
2020-11-24 00:49:27 +08:00
}
2021-11-27 19:04:23 +08:00
2020-11-24 00:49:27 +08:00
static const struct rt_i2c_bus_device_ops _i2c_ops =
{
_master_xfer,
NULL,
NULL,
};
int rt_hw_i2c_init(void)
2021-03-14 15:18:33 +08:00
{
2020-11-24 00:49:27 +08:00
#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);
2021-03-14 15:18:33 +08:00
rt_i2c_bus_device_register(&i2c0_bus, "i2c0");
2020-11-24 00:49:27 +08:00
#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);
2021-03-14 15:18:33 +08:00
rt_i2c_bus_device_register(&i2c1_bus, "i2c1");
2020-11-24 00:49:27 +08:00
#endif
2023-01-28 17:38:36 +08:00
#ifdef BSP_USING_I2C2
i2c2_bus.ops= &_i2c_ops;
i2c2_bus.timeout = 0;
i2c2_bus.priv = (void *)&drv_i2c_2;
twi_master_init(&i2c2_bus);
rt_i2c_bus_device_register(&i2c2_bus, "i2c2");
#endif
#ifdef BSP_USING_I2C3
i2c3_bus.ops= &_i2c_ops;
i2c3_bus.timeout = 0;
i2c3_bus.priv = (void *)&drv_i2c_3;
twi_master_init(&i2c3_bus);
rt_i2c_bus_device_register(&i2c3_bus, "i2c3");
#endif
2020-11-24 00:49:27 +08:00
return 0;
}
2021-03-14 15:18:33 +08:00
INIT_BOARD_EXPORT(rt_hw_i2c_init);
2020-11-24 00:49:27 +08:00
#endif /* defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1) */