diff options
| author | [email protected] <[email protected]> | 2012-11-22 08:43:40 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2012-11-22 08:43:40 +0000 |
| commit | 68b7e7c4812bc3203120c925f8fc92ec4d3ecf46 (patch) | |
| tree | 1001d7dc1bc8822e953bb1e6759c5b2c2b4a6c9d /components/drivers/i2c | |
| parent | 871951930bedf2a4e1d6bbf860acceb89b6f7c20 (diff) | |
fixed the coding style in the components/drivers
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2431 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/drivers/i2c')
| -rw-r--r-- | components/drivers/i2c/i2c-bit-ops.c | 894 | ||||
| -rw-r--r-- | components/drivers/i2c/i2c_core.c | 266 | ||||
| -rw-r--r-- | components/drivers/i2c/i2c_dev.c | 239 |
3 files changed, 707 insertions, 692 deletions
diff --git a/components/drivers/i2c/i2c-bit-ops.c b/components/drivers/i2c/i2c-bit-ops.c index bfd4512f1e..e41422a023 100644 --- a/components/drivers/i2c/i2c-bit-ops.c +++ b/components/drivers/i2c/i2c-bit-ops.c @@ -1,444 +1,450 @@ -/*
- * File : i2c-bit-ops.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2012-04-25 weety first version
- */
-
-#include <rtdevice.h>
-
-#ifdef RT_I2C_BIT_DEBUG
-#define bit_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
-#else
-#define bit_dbg(fmt, ...)
-#endif
-
-
-#define SET_SDA(ops, val) ops->set_sda(ops->data, val)
-#define SET_SCL(ops, val) ops->set_scl(ops->data, val)
-#define GET_SDA(ops) ops->get_sda(ops->data)
-#define GET_SCL(ops) ops->get_scl(ops->data)
-
-rt_inline void i2c_delay(struct rt_i2c_bit_ops *ops)
-{
- ops->udelay((ops->delay_us + 1) >> 1);
-}
-
-rt_inline void i2c_delay2(struct rt_i2c_bit_ops *ops)
-{
- ops->udelay(ops->delay_us);
-}
-
-#define SDA_L(ops) SET_SDA(ops, 0)
-#define SDA_H(ops) SET_SDA(ops, 1)
-#define SCL_L(ops) SET_SCL(ops, 0)
-
-/*
- * release scl line, and wait scl line to high.
- */
-static rt_err_t SCL_H(struct rt_i2c_bit_ops *ops)
-{
- rt_tick_t start;
-
- SET_SCL(ops, 1);
-
- if (!ops->get_scl)
- goto done;
-
- start = rt_tick_get();
- while (!GET_SCL(ops))
- {
- if ((rt_tick_get() - start) > ops->timeout)
- return -RT_ETIMEOUT;
- rt_thread_delay((ops->timeout + 1) >> 1);
- }
-#ifdef RT_I2C_BIT_DEBUG
- if (rt_tick_get() != start)
- {
- bit_dbg("wait %ld tick for SCL line to go high\n",
- rt_tick_get() - start);
- }
-#endif
-
-done:
- i2c_delay(ops);
-
- return RT_EOK;
-}
-
-
-static void i2c_start(struct rt_i2c_bit_ops *ops)
-{
-#ifdef RT_I2C_BIT_DEBUG
- if (ops->get_scl && !GET_SCL(ops))
- {
- bit_dbg("I2C bus error, SCL line low\n");
- }
- if (ops->get_sda && !GET_SDA(ops))
- {
- bit_dbg("I2C bus error, SDA line low\n");
- }
-#endif
- SDA_L(ops);
- i2c_delay(ops);
- SCL_L(ops);
-}
-
-static void i2c_restart(struct rt_i2c_bit_ops *ops)
-{
- SDA_H(ops);
- SCL_H(ops);
- i2c_delay(ops);
- SDA_L(ops);
- i2c_delay(ops);
- SCL_L(ops);
-}
-
-
-static void i2c_stop(struct rt_i2c_bit_ops *ops)
-{
- SDA_L(ops);
- i2c_delay(ops);
- SCL_H(ops);
- i2c_delay(ops);
- SDA_H(ops);
- i2c_delay2(ops);
-}
-
-rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops)
-{
- rt_bool_t ack;
-
- SDA_H(ops);
- i2c_delay(ops);
-
- if (SCL_H(ops) < 0)
- {
- bit_dbg("wait ack timeout\n");
- return -RT_ETIMEOUT;
- }
-
- ack = !GET_SDA(ops); /* ACK : SDA pin is pulled low */
- bit_dbg("%s\n", ack ? "ACK" : "NACK");
-
- SCL_L(ops);
-
- return ack;
-}
-
-
-static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data)
-{
- rt_int32_t i;
- rt_uint8_t bit;
-
- struct rt_i2c_bit_ops *ops = bus->priv;
-
- for (i = 7; i >= 0; i--)
- {
- SCL_L(ops);
- bit = (data >> i) & 1;
- SET_SDA(ops, bit);
- i2c_delay(ops);
- if (SCL_H(ops) < 0)
- {
- bit_dbg("i2c_writeb: 0x%02x, "
- "wait scl pin high timeout at bit %d\n",
- data, i);
- return -RT_ETIMEOUT;
- }
-
- }
- SCL_L(ops);
- i2c_delay(ops);
-
- return i2c_waitack(ops);
-}
-
-
-static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus)
-{
- rt_uint8_t i;
- rt_uint8_t data = 0;
- struct rt_i2c_bit_ops *ops = bus->priv;
-
- SDA_H(ops);
- i2c_delay(ops);
- for (i = 0; i < 8; i++)
- {
- data <<= 1;
-
- if (SCL_H(ops) < 0)
- {
- bit_dbg("i2c_readb: wait scl pin high "
- "timeout at bit %d\n", 7 - i);
- return -RT_ETIMEOUT;
- }
-
- if (GET_SDA(ops))
- data |= 1;
- SCL_L(ops);
- i2c_delay2(ops);
- }
-
- return data;
-}
-
-
-static rt_size_t i2c_send_bytes(struct rt_i2c_bus_device *bus, struct rt_i2c_msg *msg)
-{
- rt_int32_t ret;
- rt_size_t bytes = 0;
- const rt_uint8_t *ptr = msg->buf;
- rt_int32_t count = msg->len;
- rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
-
- while (count > 0)
- {
- ret = i2c_writeb(bus, *ptr);
-
- if ((ret > 0) || (ignore_nack && (ret == 0)))
- {
- count--;
- ptr++;
- bytes++;
- }
- else if (ret == 0)
- {
- i2c_dbg("send bytes: NACK.\n");
- return 0;
- }
- else
- {
- i2c_dbg("send bytes: error %d\n", ret);
- return ret;
- }
- }
- return bytes;
-}
-
-static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus_device *bus, int ack)
-{
- struct rt_i2c_bit_ops *ops = bus->priv;
-
- if (ack)
- SET_SDA(ops, 0);
- i2c_delay(ops);
- if (SCL_H(ops) < 0)
- {
- bit_dbg("ACK or NACK timeout\n");
- return -RT_ETIMEOUT;
- }
- SCL_L(ops);
- return RT_EOK;
-}
-
-static rt_size_t i2c_recv_bytes(struct rt_i2c_bus_device *bus, struct rt_i2c_msg *msg)
-{
- rt_int32_t val;
- rt_int32_t bytes = 0; /* actual bytes */
- rt_uint8_t *ptr = msg->buf;
- rt_int32_t count = msg->len;
- const rt_uint32_t flags = msg->flags;
-
- while (count > 0)
- {
- val = i2c_readb(bus);
- if (val >= 0)
- {
- *ptr = val;
- bytes++;
- }
- else
- {
- break;
- }
-
- ptr++;
- count--;
-
- bit_dbg("recieve bytes: 0x%02x, %s\n",
- val, (flags & RT_I2C_NO_READ_ACK) ?
- "(No ACK/NACK)" : (count ? "ACK" : "NACK"));
-
- if (!(flags & RT_I2C_NO_READ_ACK))
- {
- val = i2c_send_ack_or_nack(bus, count);
- if (val < 0)
- return val;
- }
- }
- return bytes;
-}
-
-static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus,
- rt_uint8_t addr, rt_int32_t retries)
-{
- struct rt_i2c_bit_ops *ops = bus->priv;
- rt_int32_t i;
- rt_err_t ret = 0;
-
- for (i = 0; i <= retries; i++)
- {
- ret = i2c_writeb(bus, addr);
- if (ret == 1 || i == retries)
- break;
- bit_dbg("send stop condition\n");
- i2c_stop(ops);
- i2c_delay2(ops);
- bit_dbg("send start condition\n");
- i2c_start(ops);
- }
-
- return ret;
-}
-
-static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus, struct rt_i2c_msg *msg)
-{
- rt_uint16_t flags = msg->flags;
- rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
- struct rt_i2c_bit_ops *ops = bus->priv;
-
- rt_uint8_t addr1, addr2;
- rt_int32_t retries;
- rt_err_t ret;
-
- retries = ignore_nack ? 0 : bus->retries;
-
- if (flags & RT_I2C_ADDR_10BIT)
- {
- addr1 = 0xf0 | ((msg->addr >> 7) & 0x06);
- addr2 = msg->addr & 0xff;
-
- bit_dbg("addr1: %d, addr2: %d\n", addr1, addr2);
-
- ret = i2c_send_address(bus, addr1, retries);
- if ((ret != 1) && !ignore_nack)
- {
- bit_dbg("NACK: sending first addr\n");
- return -RT_EIO;
- }
-
- ret = i2c_writeb(bus, addr2);
- if ((ret != 1) && !ignore_nack)
- {
- bit_dbg("NACK: sending second addr\n");
- return -RT_EIO;
- }
- if (flags & RT_I2C_RD)
- {
- bit_dbg("send repeated start condition\n");
- i2c_restart(ops);
- addr1 |= 0x01;
- ret = i2c_send_address(bus, addr1, retries);
- if ((ret != 1) && !ignore_nack)
- {
- bit_dbg("NACK: sending repeated addr\n");
- return -RT_EIO;
- }
- }
- }
- else
- {
- /* 7-bit addr */
- addr1 = msg->addr << 1;
- if (flags & RT_I2C_RD)
- addr1 |= 1;
- ret = i2c_send_address(bus, addr1, retries);
- if ((ret != 1) && !ignore_nack)
- return -RT_EIO;
- }
-
- return RT_EOK;
-}
-
-
-static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
- struct rt_i2c_msg msgs[], rt_uint32_t num)
-{
- struct rt_i2c_msg *msg;
- struct rt_i2c_bit_ops *ops = bus->priv;
- rt_int32_t i, ret;
- rt_uint16_t ignore_nack;
-
- bit_dbg("send start condition\n");
- i2c_start(ops);
- for (i = 0; i < num; i++)
- {
- msg = &msgs[i];
- ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
- if (!(msg->flags & RT_I2C_NO_START))
- {
- if (i)
- {
- i2c_restart(ops);
- }
- ret = i2c_bit_send_address(bus, msg);
- if ((ret != RT_EOK) && !ignore_nack)
- {
- bit_dbg("receive NACK from device addr 0x%02x msg %d\n",
- msgs[i].addr, i);
- goto out;
- }
- }
- if (msg->flags & RT_I2C_RD)
- {
- ret = i2c_recv_bytes(bus, msg);
- if (ret >= 1)
- bit_dbg("read %d byte%s\n",
- ret, ret == 1 ? "" : "s");
- if (ret < msg->len)
- {
- if (ret >= 0)
- ret = -RT_EIO;
- goto out;
- }
- }
- else
- {
- ret = i2c_send_bytes(bus, msg);
- if (ret >= 1)
- bit_dbg("write %d byte%s\n",
- ret, ret == 1 ? "" : "s");
- if (ret < msg->len)
- {
- if (ret >= 0)
- ret = -RT_ERROR;
- goto out;
- }
- }
- }
- ret = i;
-
-out:
- bit_dbg("send stop condition\n");
- i2c_stop(ops);
-
- return ret;
-}
-
-
-static const struct rt_i2c_bus_device_ops i2c_bit_bus_ops =
-{
- i2c_bit_xfer,
- RT_NULL,
- RT_NULL
-};
-
-
-rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus_device *bus, const char *bus_name)
-{
- struct rt_i2c_bit_ops *bit_ops = bus->priv;
- RT_ASSERT(bit_ops != RT_NULL);
-
- bus->ops = &i2c_bit_bus_ops;
-
- return rt_i2c_bus_device_register(bus, bus_name);
-}
+/* + * File : i2c-bit-ops.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-04-25 weety first version + */ + +#include <rtdevice.h> + +#ifdef RT_I2C_BIT_DEBUG +#define bit_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__) +#else +#define bit_dbg(fmt, ...) +#endif + +#define SET_SDA(ops, val) ops->set_sda(ops->data, val) +#define SET_SCL(ops, val) ops->set_scl(ops->data, val) +#define GET_SDA(ops) ops->get_sda(ops->data) +#define GET_SCL(ops) ops->get_scl(ops->data) + +rt_inline void i2c_delay(struct rt_i2c_bit_ops *ops) +{ + ops->udelay((ops->delay_us + 1) >> 1); +} + +rt_inline void i2c_delay2(struct rt_i2c_bit_ops *ops) +{ + ops->udelay(ops->delay_us); +} + +#define SDA_L(ops) SET_SDA(ops, 0) +#define SDA_H(ops) SET_SDA(ops, 1) +#define SCL_L(ops) SET_SCL(ops, 0) + +/** + * release scl line, and wait scl line to high. + */ +static rt_err_t SCL_H(struct rt_i2c_bit_ops *ops) +{ + rt_tick_t start; + + SET_SCL(ops, 1); + + if (!ops->get_scl) + goto done; + + start = rt_tick_get(); + while (!GET_SCL(ops)) + { + if ((rt_tick_get() - start) > ops->timeout) + return -RT_ETIMEOUT; + rt_thread_delay((ops->timeout + 1) >> 1); + } +#ifdef RT_I2C_BIT_DEBUG + if (rt_tick_get() != start) + { + bit_dbg("wait %ld tick for SCL line to go high\n", + rt_tick_get() - start); + } +#endif + +done: + i2c_delay(ops); + + return RT_EOK; +} + +static void i2c_start(struct rt_i2c_bit_ops *ops) +{ +#ifdef RT_I2C_BIT_DEBUG + if (ops->get_scl && !GET_SCL(ops)) + { + bit_dbg("I2C bus error, SCL line low\n"); + } + if (ops->get_sda && !GET_SDA(ops)) + { + bit_dbg("I2C bus error, SDA line low\n"); + } +#endif + SDA_L(ops); + i2c_delay(ops); + SCL_L(ops); +} + +static void i2c_restart(struct rt_i2c_bit_ops *ops) +{ + SDA_H(ops); + SCL_H(ops); + i2c_delay(ops); + SDA_L(ops); + i2c_delay(ops); + SCL_L(ops); +} + +static void i2c_stop(struct rt_i2c_bit_ops *ops) +{ + SDA_L(ops); + i2c_delay(ops); + SCL_H(ops); + i2c_delay(ops); + SDA_H(ops); + i2c_delay2(ops); +} + +rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops) +{ + rt_bool_t ack; + + SDA_H(ops); + i2c_delay(ops); + + if (SCL_H(ops) < 0) + { + bit_dbg("wait ack timeout\n"); + + return -RT_ETIMEOUT; + } + + ack = !GET_SDA(ops); /* ACK : SDA pin is pulled low */ + bit_dbg("%s\n", ack ? "ACK" : "NACK"); + + SCL_L(ops); + + return ack; +} + +static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data) +{ + rt_int32_t i; + rt_uint8_t bit; + + struct rt_i2c_bit_ops *ops = bus->priv; + + for (i = 7; i >= 0; i--) + { + SCL_L(ops); + bit = (data >> i) & 1; + SET_SDA(ops, bit); + i2c_delay(ops); + if (SCL_H(ops) < 0) + { + bit_dbg("i2c_writeb: 0x%02x, " + "wait scl pin high timeout at bit %d\n", + data, i); + + return -RT_ETIMEOUT; + } + } + SCL_L(ops); + i2c_delay(ops); + + return i2c_waitack(ops); +} + +static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus) +{ + rt_uint8_t i; + rt_uint8_t data = 0; + struct rt_i2c_bit_ops *ops = bus->priv; + + SDA_H(ops); + i2c_delay(ops); + for (i = 0; i < 8; i++) + { + data <<= 1; + + if (SCL_H(ops) < 0) + { + bit_dbg("i2c_readb: wait scl pin high " + "timeout at bit %d\n", 7 - i); + + return -RT_ETIMEOUT; + } + + if (GET_SDA(ops)) + data |= 1; + SCL_L(ops); + i2c_delay2(ops); + } + + return data; +} + +static rt_size_t i2c_send_bytes(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg *msg) +{ + rt_int32_t ret; + rt_size_t bytes = 0; + const rt_uint8_t *ptr = msg->buf; + rt_int32_t count = msg->len; + rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; + + while (count > 0) + { + ret = i2c_writeb(bus, *ptr); + + if ((ret > 0) || (ignore_nack && (ret == 0))) + { + count --; + ptr ++; + bytes ++; + } + else if (ret == 0) + { + i2c_dbg("send bytes: NACK.\n"); + + return 0; + } + else + { + i2c_dbg("send bytes: error %d\n", ret); + + return ret; + } + } + + return bytes; +} + +static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus_device *bus, int ack) +{ + struct rt_i2c_bit_ops *ops = bus->priv; + + if (ack) + SET_SDA(ops, 0); + i2c_delay(ops); + if (SCL_H(ops) < 0) + { + bit_dbg("ACK or NACK timeout\n"); + + return -RT_ETIMEOUT; + } + SCL_L(ops); + + return RT_EOK; +} + +static rt_size_t i2c_recv_bytes(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg *msg) +{ + rt_int32_t val; + rt_int32_t bytes = 0; /* actual bytes */ + rt_uint8_t *ptr = msg->buf; + rt_int32_t count = msg->len; + const rt_uint32_t flags = msg->flags; + + while (count > 0) + { + val = i2c_readb(bus); + if (val >= 0) + { + *ptr = val; + bytes ++; + } + else + { + break; + } + + ptr ++; + count --; + + bit_dbg("recieve bytes: 0x%02x, %s\n", + val, (flags & RT_I2C_NO_READ_ACK) ? + "(No ACK/NACK)" : (count ? "ACK" : "NACK")); + + if (!(flags & RT_I2C_NO_READ_ACK)) + { + val = i2c_send_ack_or_nack(bus, count); + if (val < 0) + return val; + } + } + + return bytes; +} + +static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus, + rt_uint8_t addr, + rt_int32_t retries) +{ + struct rt_i2c_bit_ops *ops = bus->priv; + rt_int32_t i; + rt_err_t ret = 0; + + for (i = 0; i <= retries; i++) + { + ret = i2c_writeb(bus, addr); + if (ret == 1 || i == retries) + break; + bit_dbg("send stop condition\n"); + i2c_stop(ops); + i2c_delay2(ops); + bit_dbg("send start condition\n"); + i2c_start(ops); + } + + return ret; +} + +static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg *msg) +{ + rt_uint16_t flags = msg->flags; + rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; + struct rt_i2c_bit_ops *ops = bus->priv; + + rt_uint8_t addr1, addr2; + rt_int32_t retries; + rt_err_t ret; + + retries = ignore_nack ? 0 : bus->retries; + + if (flags & RT_I2C_ADDR_10BIT) + { + addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); + addr2 = msg->addr & 0xff; + + bit_dbg("addr1: %d, addr2: %d\n", addr1, addr2); + + ret = i2c_send_address(bus, addr1, retries); + if ((ret != 1) && !ignore_nack) + { + bit_dbg("NACK: sending first addr\n"); + + return -RT_EIO; + } + + ret = i2c_writeb(bus, addr2); + if ((ret != 1) && !ignore_nack) + { + bit_dbg("NACK: sending second addr\n"); + + return -RT_EIO; + } + if (flags & RT_I2C_RD) + { + bit_dbg("send repeated start condition\n"); + i2c_restart(ops); + addr1 |= 0x01; + ret = i2c_send_address(bus, addr1, retries); + if ((ret != 1) && !ignore_nack) + { + bit_dbg("NACK: sending repeated addr\n"); + + return -RT_EIO; + } + } + } + else + { + /* 7-bit addr */ + addr1 = msg->addr << 1; + if (flags & RT_I2C_RD) + addr1 |= 1; + ret = i2c_send_address(bus, addr1, retries); + if ((ret != 1) && !ignore_nack) + return -RT_EIO; + } + + return RT_EOK; +} + +static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + struct rt_i2c_msg *msg; + struct rt_i2c_bit_ops *ops = bus->priv; + rt_int32_t i, ret; + rt_uint16_t ignore_nack; + + bit_dbg("send start condition\n"); + i2c_start(ops); + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; + if (!(msg->flags & RT_I2C_NO_START)) + { + if (i) + { + i2c_restart(ops); + } + ret = i2c_bit_send_address(bus, msg); + if ((ret != RT_EOK) && !ignore_nack) + { + bit_dbg("receive NACK from device addr 0x%02x msg %d\n", + msgs[i].addr, i); + goto out; + } + } + if (msg->flags & RT_I2C_RD) + { + ret = i2c_recv_bytes(bus, msg); + if (ret >= 1) + bit_dbg("read %d byte%s\n", ret, ret == 1 ? "" : "s"); + if (ret < msg->len) + { + if (ret >= 0) + ret = -RT_EIO; + goto out; + } + } + else + { + ret = i2c_send_bytes(bus, msg); + if (ret >= 1) + bit_dbg("write %d byte%s\n", ret, ret == 1 ? "" : "s"); + if (ret < msg->len) + { + if (ret >= 0) + ret = -RT_ERROR; + goto out; + } + } + } + ret = i; + +out: + bit_dbg("send stop condition\n"); + i2c_stop(ops); + + return ret; +} + +static const struct rt_i2c_bus_device_ops i2c_bit_bus_ops = +{ + i2c_bit_xfer, + RT_NULL, + RT_NULL +}; + +rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus_device *bus, + const char *bus_name) +{ + struct rt_i2c_bit_ops *bit_ops = bus->priv; + RT_ASSERT(bit_ops != RT_NULL); + + bus->ops = &i2c_bit_bus_ops; + + return rt_i2c_bus_device_register(bus, bus_name); +} diff --git a/components/drivers/i2c/i2c_core.c b/components/drivers/i2c/i2c_core.c index 6fa3fcc887..598b63cc93 100644 --- a/components/drivers/i2c/i2c_core.c +++ b/components/drivers/i2c/i2c_core.c @@ -1,135 +1,131 @@ -/*
- * File : i2c_core.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2012-04-25 weety first version
- */
-
-#include <rtdevice.h>
-
-static struct rt_mutex i2c_core_lock;
-
-rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
- const char *bus_name)
-{
- rt_err_t res = RT_EOK;
-
- rt_mutex_init(&bus->lock, "i2c_bus_lock", RT_IPC_FLAG_FIFO);
-
- rt_mutex_take(&i2c_core_lock, RT_WAITING_FOREVER);
-
- if (bus->timeout == 0)
- bus->timeout = RT_TICK_PER_SECOND;
-
- res = rt_i2c_bus_device_device_init(bus, bus_name);
-
- i2c_dbg("I2C bus [%s] registered\n", bus_name);
-
- rt_mutex_release(&i2c_core_lock);
- return res;
-}
-
-
-struct rt_i2c_bus_device* rt_i2c_bus_device_find(const char *bus_name)
-{
- struct rt_i2c_bus_device *bus;
- rt_device_t dev = rt_device_find(bus_name);
- if (dev == RT_NULL || dev->type != RT_Device_Class_I2CBUS)
- {
- i2c_dbg("I2C bus %s not exist\n", bus_name);
- return RT_NULL;
- }
-
- bus = (struct rt_i2c_bus_device *)dev->user_data;
-
- return bus;
-}
-
-
-rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
- struct rt_i2c_msg msgs[],
- rt_uint32_t num)
-{
- rt_size_t ret;
-
- if (bus->ops->master_xfer)
- {
-#ifdef RT_I2C_DEBUG
- for (ret = 0; ret < num; ret++)
- {
- i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d%s\n", ret,
- (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W',
- msgs[ret].addr, msgs[ret].len);
- }
-#endif
-
- rt_mutex_take(&bus->lock, RT_WAITING_FOREVER);
- ret = bus->ops->master_xfer(bus, msgs, num);
- rt_mutex_release(&bus->lock);
-
- return ret;
- }
- else
- {
- i2c_dbg("I2C bus operation not supported\n");
- return 0;
- }
-}
-
-
-rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus,
- rt_uint16_t addr,
- rt_uint16_t flags,
- const rt_uint8_t *buf,
- rt_uint32_t count)
-{
- rt_size_t ret;
- struct rt_i2c_msg msg;
-
- msg.addr = addr;
- msg.flags = flags & RT_I2C_ADDR_10BIT;
- msg.len = count;
- msg.buf = (rt_uint8_t *)buf;
-
- ret = rt_i2c_transfer(bus, &msg, 1);
-
- return (ret > 0) ? count : ret;
-}
-
-
-
-rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus,
- rt_uint16_t addr,
- rt_uint16_t flags,
- rt_uint8_t *buf,
- rt_uint32_t count)
-{
- rt_size_t ret;
- struct rt_i2c_msg msg;
- RT_ASSERT(bus != RT_NULL);
-
- msg.addr = addr;
- msg.flags = flags & RT_I2C_ADDR_10BIT;
- msg.flags |= RT_I2C_RD;
- msg.len = count;
- msg.buf = buf;
-
- ret = rt_i2c_transfer(bus, &msg, 1);
-
- return (ret > 0) ? count : ret;
-}
-
-
-rt_err_t rt_i2c_core_init(void)
-{
-
- return rt_mutex_init (&i2c_core_lock, "i2c_core_lock", RT_IPC_FLAG_FIFO);
-}
-
+/* + * File : i2c_core.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-04-25 weety first version + */ + +#include <rtdevice.h> + +static struct rt_mutex i2c_core_lock; + +rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus, + const char *bus_name) +{ + rt_err_t res = RT_EOK; + + rt_mutex_init(&bus->lock, "i2c_bus_lock", RT_IPC_FLAG_FIFO); + + rt_mutex_take(&i2c_core_lock, RT_WAITING_FOREVER); + + if (bus->timeout == 0) + bus->timeout = RT_TICK_PER_SECOND; + + res = rt_i2c_bus_device_device_init(bus, bus_name); + + i2c_dbg("I2C bus [%s] registered\n", bus_name); + + rt_mutex_release(&i2c_core_lock); + + return res; +} + +struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name) +{ + struct rt_i2c_bus_device *bus; + rt_device_t dev = rt_device_find(bus_name); + if (dev == RT_NULL || dev->type != RT_Device_Class_I2CBUS) + { + i2c_dbg("I2C bus %s not exist\n", bus_name); + + return RT_NULL; + } + + bus = (struct rt_i2c_bus_device *)dev->user_data; + + return bus; +} + +rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + rt_size_t ret; + + if (bus->ops->master_xfer) + { +#ifdef RT_I2C_DEBUG + for (ret = 0; ret < num; ret++) + { + i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d%s\n", ret, + (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W', + msgs[ret].addr, msgs[ret].len); + } +#endif + + rt_mutex_take(&bus->lock, RT_WAITING_FOREVER); + ret = bus->ops->master_xfer(bus, msgs, num); + rt_mutex_release(&bus->lock); + + return ret; + } + else + { + i2c_dbg("I2C bus operation not supported\n"); + + return 0; + } +} + +rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus, + rt_uint16_t addr, + rt_uint16_t flags, + const rt_uint8_t *buf, + rt_uint32_t count) +{ + rt_size_t ret; + struct rt_i2c_msg msg; + + msg.addr = addr; + msg.flags = flags & RT_I2C_ADDR_10BIT; + msg.len = count; + msg.buf = (rt_uint8_t *)buf; + + ret = rt_i2c_transfer(bus, &msg, 1); + + return (ret > 0) ? count : ret; +} + +rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus, + rt_uint16_t addr, + rt_uint16_t flags, + rt_uint8_t *buf, + rt_uint32_t count) +{ + rt_size_t ret; + struct rt_i2c_msg msg; + RT_ASSERT(bus != RT_NULL); + + msg.addr = addr; + msg.flags = flags & RT_I2C_ADDR_10BIT; + msg.flags |= RT_I2C_RD; + msg.len = count; + msg.buf = buf; + + ret = rt_i2c_transfer(bus, &msg, 1); + + return (ret > 0) ? count : ret; +} + +rt_err_t rt_i2c_core_init(void) +{ + return rt_mutex_init(&i2c_core_lock, "i2c_core_lock", RT_IPC_FLAG_FIFO); +} + diff --git a/components/drivers/i2c/i2c_dev.c b/components/drivers/i2c/i2c_dev.c index d1fc55567b..dff21d8e67 100644 --- a/components/drivers/i2c/i2c_dev.c +++ b/components/drivers/i2c/i2c_dev.c @@ -1,113 +1,126 @@ -#include <rtdevice.h>
-
-static rt_err_t i2c_bus_device_init(rt_device_t dev)
-{
- struct rt_i2c_bus_device* bus = (struct rt_i2c_bus_device *)dev->user_data;
- RT_ASSERT(bus != RT_NULL);
-
- return RT_EOK;
-}
-
-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);
-
- i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", dev->parent.name, count);
-
- addr = pos & 0xffff;
- flags = (pos >> 16) & 0xffff;
-
- return rt_i2c_master_recv(bus, addr, flags, buffer, count);
-}
-
-
-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);
-
- i2c_dbg("I2C bus dev writing %u bytes.\n", dev->parent.name, count);
-
- addr = pos & 0xffff;
- flags = (pos >> 16) & 0xffff;
-
- return rt_i2c_master_send(bus, addr, flags, buffer, count);
-}
-
-static rt_err_t i2c_bus_device_control(rt_device_t dev,
- rt_uint8_t cmd,
- 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)
- {
- case RT_I2C_DEV_CTRL_10BIT: /* set 10-bit addr mode */
- 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;
-}
-
-
-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 */
- device->init = i2c_bus_device_init;
- 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;
-
- /* register to device manager */
- rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
-
- return RT_EOK;
-}
+/* + * File : i2c_dev.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-04-25 weety first version + */ + +#include <rtdevice.h> + +static rt_err_t i2c_bus_device_init(rt_device_t dev) +{ + struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; + RT_ASSERT(bus != RT_NULL); + + return RT_EOK; +} + +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); + + i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", dev->parent.name, count); + + addr = pos & 0xffff; + flags = (pos >> 16) & 0xffff; + + return rt_i2c_master_recv(bus, addr, flags, buffer, count); +} + +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); + + i2c_dbg("I2C bus dev writing %u bytes.\n", dev->parent.name, count); + + addr = pos & 0xffff; + flags = (pos >> 16) & 0xffff; + + return rt_i2c_master_send(bus, addr, flags, buffer, count); +} + +static rt_err_t i2c_bus_device_control(rt_device_t dev, + rt_uint8_t cmd, + 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; +} + +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 */ + device->init = i2c_bus_device_init; + 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; + + /* register to device manager */ + rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); + + return RT_EOK; +} |
