i2c_dev.c 3.6 KB
Newer Older
1
/*
2
 * Copyright (c) 2006-2018, RT-Thread Development Team
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
5 6 7 8
 *
 * Change Logs:
 * Date           Author        Notes
 * 2012-04-25     weety         first version
B
bernard 已提交
9
 * 2014-08-03     bernard       fix some compiling warning
10 11 12 13
 */

#include <rtdevice.h>

14 15 16 17 18 19 20 21
#define DBG_TAG               "I2C"
#ifdef RT_I2C_DEBUG
#define DBG_LVL               DBG_LOG
#else
#define DBG_LVL               DBG_INFO
#endif
#include <rtdbg.h>

22 23 24 25 26 27 28 29 30 31 32 33
static rt_size_t i2c_bus_device_read(rt_device_t dev,
                                     rt_off_t    pos,
                                     void       *buffer,
                                     rt_size_t   count)
{
    rt_uint16_t addr;
    rt_uint16_t flags;
    struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data;

    RT_ASSERT(bus != RT_NULL);
    RT_ASSERT(buffer != RT_NULL);

34
    LOG_D("I2C bus dev [%s] reading %u bytes.", dev->parent.name, count);
35 36 37 38

    addr = pos & 0xffff;
    flags = (pos >> 16) & 0xffff;

39
    return rt_i2c_master_recv(bus, addr, flags, (rt_uint8_t *)buffer, count);
40 41 42 43 44 45 46 47 48 49 50 51 52 53
}

static rt_size_t i2c_bus_device_write(rt_device_t dev,
                                      rt_off_t    pos,
                                      const void *buffer,
                                      rt_size_t   count)
{
    rt_uint16_t addr;
    rt_uint16_t flags;
    struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data;

    RT_ASSERT(bus != RT_NULL);
    RT_ASSERT(buffer != RT_NULL);

54
    LOG_D("I2C bus dev [%s] writing %u bytes.", dev->parent.name, count);
55 56 57 58

    addr = pos & 0xffff;
    flags = (pos >> 16) & 0xffff;

59
    return rt_i2c_master_send(bus, addr, flags, (const rt_uint8_t *)buffer, count);
60 61 62
}

static rt_err_t i2c_bus_device_control(rt_device_t dev,
B
bernard 已提交
63
                                       int         cmd,
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
                                       void       *args)
{
    rt_err_t ret;
    struct rt_i2c_priv_data *priv_data;
    struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data;

    RT_ASSERT(bus != RT_NULL);

    switch (cmd)
    {
    /* set 10-bit addr mode */
    case RT_I2C_DEV_CTRL_10BIT:
        bus->flags |= RT_I2C_ADDR_10BIT;
        break;
    case RT_I2C_DEV_CTRL_ADDR:
        bus->addr = *(rt_uint16_t *)args;
        break;
    case RT_I2C_DEV_CTRL_TIMEOUT:
        bus->timeout = *(rt_uint32_t *)args;
        break;
    case RT_I2C_DEV_CTRL_RW:
        priv_data = (struct rt_i2c_priv_data *)args;
        ret = rt_i2c_transfer(bus, priv_data->msgs, priv_data->number);
        if (ret < 0)
        {
            return -RT_EIO;
        }
        break;
    default:
        break;
    }

    return RT_EOK;
}

B
Bernard Xiong 已提交
99 100 101 102 103 104 105 106 107 108 109 110
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops i2c_ops = 
{
    RT_NULL, 
    RT_NULL,
    RT_NULL,
    i2c_bus_device_read,
    i2c_bus_device_write,
    i2c_bus_device_control
};
#endif

111 112 113 114 115 116 117 118 119 120 121 122 123
rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus,
                                       const char               *name)
{
    struct rt_device *device;
    RT_ASSERT(bus != RT_NULL);

    device = &bus->parent;

    device->user_data = bus;

    /* set device type */
    device->type    = RT_Device_Class_I2CBUS;
    /* initialize device interface */
B
Bernard Xiong 已提交
124 125 126
#ifdef RT_USING_DEVICE_OPS
    device->ops     = &i2c_ops;
#else
B
bernard 已提交
127
    device->init    = RT_NULL;
128 129 130 131 132
    device->open    = RT_NULL;
    device->close   = RT_NULL;
    device->read    = i2c_bus_device_read;
    device->write   = i2c_bus_device_write;
    device->control = i2c_bus_device_control;
B
Bernard Xiong 已提交
133
#endif
134 135 136 137 138 139

    /* register to device manager */
    rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);

    return RT_EOK;
}