123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245 |
- #ifndef ZEPHYR_INCLUDE_DRIVERS_I2C_H_
- #define ZEPHYR_INCLUDE_DRIVERS_I2C_H_
- #include <zephyr/types.h>
- #include <device.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- #define I2C_SPEED_STANDARD (0x1U)
- #define I2C_SPEED_FAST (0x2U)
- #define I2C_SPEED_FAST_PLUS (0x3U)
- #define I2C_SPEED_HIGH (0x4U)
- #define I2C_SPEED_ULTRA (0x5U)
- #define I2C_SPEED_SHIFT (1U)
- #define I2C_SPEED_SET(speed) (((speed) << I2C_SPEED_SHIFT) \
- & I2C_SPEED_MASK)
- #define I2C_SPEED_MASK (0x7U << I2C_SPEED_SHIFT)
- #define I2C_SPEED_GET(cfg) (((cfg) & I2C_SPEED_MASK) \
- >> I2C_SPEED_SHIFT)
- #define I2C_ADDR_10_BITS BIT(0)
- #define I2C_MODE_MASTER BIT(4)
- struct i2c_dt_spec {
- const struct device *bus;
- uint16_t addr;
- };
- #define I2C_DT_SPEC_GET(node_id) \
- { \
- .bus = DEVICE_DT_GET(DT_BUS(node_id)), \
- .addr = DT_REG_ADDR(node_id) \
- }
- #define I2C_DT_SPEC_INST_GET(inst) \
- I2C_DT_SPEC_GET(DT_DRV_INST(inst))
- #define I2C_MSG_WRITE (0U << 0U)
- #define I2C_MSG_READ BIT(0)
- #define I2C_MSG_RW_MASK BIT(0)
- #define I2C_MSG_STOP BIT(1)
- #define I2C_MSG_RESTART BIT(2)
- #define I2C_MSG_ADDR_10_BITS BIT(3)
- struct i2c_msg {
-
- uint8_t *buf;
-
- uint32_t len;
-
- uint8_t flags;
- };
- struct i2c_slave_config;
- typedef int (*i2c_api_configure_t)(const struct device *dev,
- uint32_t dev_config);
- typedef int (*i2c_api_full_io_t)(const struct device *dev,
- struct i2c_msg *msgs,
- uint8_t num_msgs,
- uint16_t addr);
- typedef int (*i2c_api_slave_register_t)(const struct device *dev,
- struct i2c_slave_config *cfg);
- typedef int (*i2c_api_slave_unregister_t)(const struct device *dev,
- struct i2c_slave_config *cfg);
- typedef int (*i2c_api_recover_bus_t)(const struct device *dev);
- #ifdef CONFIG_I2C_ASYNC
- typedef int (*i2c_async_func_t)(void *cb_data, struct i2c_msg *msgs,
- uint8_t num_msgs, bool is_err);
- #ifdef CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER
- #define I2C_MSG_ASYNC_RX_MAX_BUF (12)
- #define I2C_MSG_ASYNC_TX_MAX_BUF (4)
- #endif
- struct i2c_msg_async {
- struct i2c_msg msg[2];
- uint8_t num_msgs;
- uint16_t addr;
- i2c_async_func_t async_func;
- void *cb_data;
- #ifdef CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER
- uint8_t rx_buf[I2C_MSG_ASYNC_RX_MAX_BUF];
- uint8_t tx_buf[I2C_MSG_ASYNC_TX_MAX_BUF];
- #endif
- };
- typedef int (*i2c_api_full_io_async_t)(const struct device *dev,
- struct i2c_msg_async *msg_async);
- #endif
- __subsystem struct i2c_driver_api {
- i2c_api_configure_t configure;
- i2c_api_full_io_t transfer;
- #ifdef CONFIG_I2C_ASYNC
- i2c_api_full_io_async_t transfer_async;
- #endif
- i2c_api_slave_register_t slave_register;
- i2c_api_slave_unregister_t slave_unregister;
- i2c_api_recover_bus_t recover_bus;
- };
- typedef int (*i2c_slave_api_register_t)(const struct device *dev);
- typedef int (*i2c_slave_api_unregister_t)(const struct device *dev);
- struct i2c_slave_driver_api {
- i2c_slave_api_register_t driver_register;
- i2c_slave_api_unregister_t driver_unregister;
- };
- #define I2C_SLAVE_FLAGS_ADDR_10_BITS BIT(0)
- typedef int (*i2c_slave_write_requested_cb_t)(
- struct i2c_slave_config *config);
- typedef int (*i2c_slave_write_received_cb_t)(
- struct i2c_slave_config *config, uint8_t val);
- typedef int (*i2c_slave_read_requested_cb_t)(
- struct i2c_slave_config *config, uint8_t *val);
- typedef int (*i2c_slave_read_processed_cb_t)(
- struct i2c_slave_config *config, uint8_t *val);
- typedef int (*i2c_slave_stop_cb_t)(struct i2c_slave_config *config);
- struct i2c_slave_callbacks {
- i2c_slave_write_requested_cb_t write_requested;
- i2c_slave_read_requested_cb_t read_requested;
- i2c_slave_write_received_cb_t write_received;
- i2c_slave_read_processed_cb_t read_processed;
- i2c_slave_stop_cb_t stop;
- };
- struct i2c_slave_config {
-
- sys_snode_t node;
-
- uint8_t flags;
-
- uint16_t address;
-
- const struct i2c_slave_callbacks *callbacks;
- };
- __syscall int i2c_configure(const struct device *dev, uint32_t dev_config);
- static inline int z_impl_i2c_configure(const struct device *dev,
- uint32_t dev_config)
- {
- const struct i2c_driver_api *api =
- (const struct i2c_driver_api *)dev->api;
- return api->configure(dev, dev_config);
- }
- __syscall int i2c_transfer(const struct device *dev,
- struct i2c_msg *msgs, uint8_t num_msgs,
- uint16_t addr);
- static inline int z_impl_i2c_transfer(const struct device *dev,
- struct i2c_msg *msgs, uint8_t num_msgs,
- uint16_t addr)
- {
- const struct i2c_driver_api *api =
- (const struct i2c_driver_api *)dev->api;
- return api->transfer(dev, msgs, num_msgs, addr);
- }
- static inline int i2c_transfer_dt(const struct i2c_dt_spec *spec,
- struct i2c_msg *msgs, uint8_t num_msgs)
- {
- return i2c_transfer(spec->bus, msgs, num_msgs, spec->addr);
- }
- __syscall int i2c_recover_bus(const struct device *dev);
- static inline int z_impl_i2c_recover_bus(const struct device *dev)
- {
- const struct i2c_driver_api *api =
- (const struct i2c_driver_api *)dev->api;
- if (api->recover_bus == NULL) {
- return -ENOSYS;
- }
- return api->recover_bus(dev);
- }
- static inline int i2c_slave_register(const struct device *dev,
- struct i2c_slave_config *cfg)
- {
- const struct i2c_driver_api *api =
- (const struct i2c_driver_api *)dev->api;
- if (api->slave_register == NULL) {
- return -ENOSYS;
- }
- return api->slave_register(dev, cfg);
- }
- static inline int i2c_slave_unregister(const struct device *dev,
- struct i2c_slave_config *cfg)
- {
- const struct i2c_driver_api *api =
- (const struct i2c_driver_api *)dev->api;
- if (api->slave_unregister == NULL) {
- return -ENOSYS;
- }
- return api->slave_unregister(dev, cfg);
- }
- __syscall int i2c_slave_driver_register(const struct device *dev);
- static inline int z_impl_i2c_slave_driver_register(const struct device *dev)
- {
- const struct i2c_slave_driver_api *api =
- (const struct i2c_slave_driver_api *)dev->api;
- return api->driver_register(dev);
- }
- __syscall int i2c_slave_driver_unregister(const struct device *dev);
- static inline int z_impl_i2c_slave_driver_unregister(const struct device *dev)
- {
- const struct i2c_slave_driver_api *api =
- (const struct i2c_slave_driver_api *)dev->api;
- return api->driver_unregister(dev);
- }
- static inline int i2c_write(const struct device *dev, const uint8_t *buf,
- uint32_t num_bytes, uint16_t addr)
- {
- struct i2c_msg msg;
- #if defined(CONFIG_I2C_ASYNC) && defined(CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER)
- if ((num_bytes > I2C_MSG_ASYNC_TX_MAX_BUF) || (!num_bytes)) {
- printk("invalid num_bytes:%d max:%d\n",
- num_bytes, I2C_MSG_ASYNC_TX_MAX_BUF);
- return -EINVAL;
- }
- #endif
- msg.buf = (uint8_t *)buf;
- msg.len = num_bytes;
- msg.flags = I2C_MSG_WRITE | I2C_MSG_STOP;
- return i2c_transfer(dev, &msg, 1, addr);
- }
- static inline int i2c_write_dt(const struct i2c_dt_spec *spec,
- const uint8_t *buf, uint32_t num_bytes)
- {
- return i2c_write(spec->bus, buf, num_bytes, spec->addr);
- }
- static inline int i2c_read(const struct device *dev, uint8_t *buf,
- uint32_t num_bytes, uint16_t addr)
- {
- struct i2c_msg msg;
- #if defined(CONFIG_I2C_ASYNC) && defined(CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER)
- if ((num_bytes > I2C_MSG_ASYNC_RX_MAX_BUF) || (!num_bytes)) {
- printk("invalid num_bytes:%d max:%d\n",
- num_bytes, I2C_MSG_ASYNC_RX_MAX_BUF);
- return -EINVAL;
- }
- #endif
- msg.buf = buf;
- msg.len = num_bytes;
- msg.flags = I2C_MSG_READ | I2C_MSG_STOP;
- return i2c_transfer(dev, &msg, 1, addr);
- }
- static inline int i2c_read_dt(const struct i2c_dt_spec *spec,
- uint8_t *buf, uint32_t num_bytes)
- {
- return i2c_read(spec->bus, buf, num_bytes, spec->addr);
- }
- static inline int i2c_write_read(const struct device *dev, uint16_t addr,
- const void *write_buf, size_t num_write,
- void *read_buf, size_t num_read)
- {
- struct i2c_msg msg[2];
- #if defined(CONFIG_I2C_ASYNC) && defined(CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER)
- if ((num_write > I2C_MSG_ASYNC_TX_MAX_BUF) || (!num_write)) {
- printk("invalid num_write:%d max:%d\n",
- num_write, I2C_MSG_ASYNC_TX_MAX_BUF);
- return -EINVAL;
- }
- if ((num_read > I2C_MSG_ASYNC_RX_MAX_BUF) || (!num_read)) {
- printk("invalid num_read:%d max:%d\n",
- num_read, I2C_MSG_ASYNC_RX_MAX_BUF);
- return -EINVAL;
- }
- #endif
- msg[0].buf = (uint8_t *)write_buf;
- msg[0].len = num_write;
- msg[0].flags = I2C_MSG_WRITE;
- msg[1].buf = (uint8_t *)read_buf;
- msg[1].len = num_read;
- msg[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP;
- return i2c_transfer(dev, msg, 2, addr);
- }
- #ifdef CONFIG_I2C_ASYNC
- static inline int i2c_write_async(const struct device *dev, const uint8_t *buf,
- uint32_t num_bytes, uint16_t addr,
- i2c_async_func_t async_func, void *cb_data)
- {
- struct i2c_msg_async msg_async = {0};
- const struct i2c_driver_api *api =
- (const struct i2c_driver_api *)dev->api;
- #ifdef CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER
- if ((num_bytes > I2C_MSG_ASYNC_TX_MAX_BUF) || (!num_bytes)) {
- printk("invalid num_bytes:%d max:%d\n",
- num_bytes, I2C_MSG_ASYNC_TX_MAX_BUF);
- return -EINVAL;
- }
- #endif
- msg_async.msg[0].buf = (uint8_t *)buf;
- msg_async.msg[0].len = num_bytes;
- msg_async.msg[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
- msg_async.addr = addr;
- msg_async.num_msgs = 1;
- msg_async.async_func = async_func;
- msg_async.cb_data = cb_data;
- return api->transfer_async(dev, &msg_async);
- }
- static inline int i2c_read_async(const struct device *dev, uint8_t *buf,
- uint32_t num_bytes, uint16_t addr,
- i2c_async_func_t async_func, void *cb_data)
- {
- struct i2c_msg_async msg_async = {0};
- const struct i2c_driver_api *api =
- (const struct i2c_driver_api *)dev->api;
- #ifdef CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER
- if ((num_bytes > I2C_MSG_ASYNC_RX_MAX_BUF) || (!num_bytes)) {
- printk("invalid num_bytes:%d max:%d\n",
- num_bytes, I2C_MSG_ASYNC_RX_MAX_BUF);
- return -EINVAL;
- }
- #endif
- msg_async.msg[0].buf = buf;
- msg_async.msg[0].len = num_bytes;
- msg_async.msg[0].flags = I2C_MSG_READ | I2C_MSG_STOP;
- msg_async.addr = addr;
- msg_async.num_msgs = 1;
- msg_async.async_func = async_func;
- msg_async.cb_data = cb_data;
- return api->transfer_async(dev, &msg_async);
- }
- static inline int i2c_write_read_async(const struct device *dev, uint16_t addr,
- const void *write_buf, size_t num_write,
- void *read_buf, size_t num_read,
- i2c_async_func_t async_func, void *cb_data)
- {
- struct i2c_msg_async msg_async = {0};
- const struct i2c_driver_api *api =
- (const struct i2c_driver_api *)dev->api;
- #ifdef CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER
- if ((num_write > I2C_MSG_ASYNC_TX_MAX_BUF) || (!num_write)) {
- printk("invalid num_write:%d max:%d\n",
- num_write, I2C_MSG_ASYNC_TX_MAX_BUF);
- return -EINVAL;
- }
- if ((num_read > I2C_MSG_ASYNC_RX_MAX_BUF) || (!num_read)) {
- printk("invalid num_read:%d max:%d\n",
- num_read, I2C_MSG_ASYNC_RX_MAX_BUF);
- return -EINVAL;
- }
- #endif
- msg_async.msg[0].buf = (uint8_t *)write_buf;
- msg_async.msg[0].len = num_write;
- msg_async.msg[0].flags = I2C_MSG_WRITE;
- msg_async.msg[1].buf = (uint8_t *)read_buf;
- msg_async.msg[1].len = num_read;
- msg_async.msg[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP;
- msg_async.addr = addr;
- msg_async.num_msgs = 2;
- msg_async.async_func = async_func;
- msg_async.cb_data = cb_data;
- return api->transfer_async(dev, &msg_async);
- }
- #endif
- static inline int i2c_write_read_dt(const struct i2c_dt_spec *spec,
- const void *write_buf, size_t num_write,
- void *read_buf, size_t num_read)
- {
- return i2c_write_read(spec->bus, spec->addr,
- write_buf, num_write,
- read_buf, num_read);
- }
- static inline int i2c_burst_read(const struct device *dev,
- uint16_t dev_addr,
- uint8_t start_addr,
- uint8_t *buf,
- uint32_t num_bytes)
- {
- return i2c_write_read(dev, dev_addr,
- &start_addr, sizeof(start_addr),
- buf, num_bytes);
- }
- static inline int i2c_burst_read_dt(const struct i2c_dt_spec *spec,
- uint8_t start_addr,
- uint8_t *buf,
- uint32_t num_bytes)
- {
- return i2c_burst_read(spec->bus, spec->addr,
- start_addr, buf, num_bytes);
- }
- static inline int i2c_burst_write(const struct device *dev,
- uint16_t dev_addr,
- uint8_t start_addr,
- const uint8_t *buf,
- uint32_t num_bytes)
- {
- struct i2c_msg msg[2];
- msg[0].buf = &start_addr;
- msg[0].len = 1U;
- msg[0].flags = I2C_MSG_WRITE;
- msg[1].buf = (uint8_t *)buf;
- msg[1].len = num_bytes;
- msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
- return i2c_transfer(dev, msg, 2, dev_addr);
- }
- static inline int i2c_burst_write_dt(const struct i2c_dt_spec *spec,
- uint8_t start_addr,
- const uint8_t *buf,
- uint32_t num_bytes)
- {
- return i2c_burst_write(spec->bus, spec->addr,
- start_addr, buf, num_bytes);
- }
- static inline int i2c_reg_read_byte(const struct device *dev,
- uint16_t dev_addr,
- uint8_t reg_addr, uint8_t *value)
- {
- return i2c_write_read(dev, dev_addr,
- ®_addr, sizeof(reg_addr),
- value, sizeof(*value));
- }
- static inline int i2c_reg_read_byte_dt(const struct i2c_dt_spec *spec,
- uint8_t reg_addr, uint8_t *value)
- {
- return i2c_reg_read_byte(spec->bus, spec->addr, reg_addr, value);
- }
- static inline int i2c_reg_write_byte(const struct device *dev,
- uint16_t dev_addr,
- uint8_t reg_addr, uint8_t value)
- {
- uint8_t tx_buf[2] = {reg_addr, value};
- return i2c_write(dev, tx_buf, 2, dev_addr);
- }
- static inline int i2c_reg_write_byte_dt(const struct i2c_dt_spec *spec,
- uint8_t reg_addr, uint8_t value)
- {
- return i2c_reg_write_byte(spec->bus, spec->addr, reg_addr, value);
- }
- static inline int i2c_reg_update_byte(const struct device *dev,
- uint8_t dev_addr,
- uint8_t reg_addr, uint8_t mask,
- uint8_t value)
- {
- uint8_t old_value, new_value;
- int rc;
- rc = i2c_reg_read_byte(dev, dev_addr, reg_addr, &old_value);
- if (rc != 0) {
- return rc;
- }
- new_value = (old_value & ~mask) | (value & mask);
- if (new_value == old_value) {
- return 0;
- }
- return i2c_reg_write_byte(dev, dev_addr, reg_addr, new_value);
- }
- static inline int i2c_reg_update_byte_dt(const struct i2c_dt_spec *spec,
- uint8_t reg_addr, uint8_t mask,
- uint8_t value)
- {
- return i2c_reg_update_byte(spec->bus, spec->addr,
- reg_addr, mask, value);
- }
- void i2c_dump_msgs(const char *name, const struct i2c_msg *msgs,
- uint8_t num_msgs, uint16_t addr);
- struct i2c_client_config {
- char *i2c_master;
- uint16_t i2c_addr;
- };
- #define I2C_DECLARE_CLIENT_CONFIG struct i2c_client_config i2c_client
- #define I2C_CLIENT(_master, _addr) \
- .i2c_client = { \
- .i2c_master = (_master), \
- .i2c_addr = (_addr), \
- }
- #define I2C_GET_MASTER(_conf) ((_conf)->i2c_client.i2c_master)
- #define I2C_GET_ADDR(_conf) ((_conf)->i2c_client.i2c_addr)
- #ifdef __cplusplus
- }
- #endif
- #include <syscalls/i2c.h>
- #endif
|