/* * 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 #include #include #include #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) */