i2c.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_I2C_H
8#define _HARDWARE_I2C_H
9
10#include "pico.h"
11#include "pico/time.h"
12#include "hardware/structs/i2c.h"
13#include "hardware/regs/dreq.h"
14
15// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_I2C, Enable/disable assertions in the I2C module, type=bool, default=0, group=hardware_i2c
16#ifndef PARAM_ASSERTIONS_ENABLED_I2C
17#define PARAM_ASSERTIONS_ENABLED_I2C 0
18#endif
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
52typedef struct i2c_inst i2c_inst_t;
53
54// PICO_CONFIG: PICO_DEFAULT_I2C, Define the default I2C for a board, min=0, max=1, group=hardware_i2c
55// PICO_CONFIG: PICO_DEFAULT_I2C_SDA_PIN, Define the default I2C SDA pin, min=0, max=29, group=hardware_i2c
56// PICO_CONFIG: PICO_DEFAULT_I2C_SCL_PIN, Define the default I2C SCL pin, min=0, max=29, group=hardware_i2c
57
66extern i2c_inst_t i2c1_inst;
67
68#define i2c0 (&i2c0_inst)
69#define i2c1 (&i2c1_inst)
70
71#if !defined(PICO_DEFAULT_I2C_INSTANCE) && defined(PICO_DEFAULT_I2C)
72#define PICO_DEFAULT_I2C_INSTANCE (__CONCAT(i2c,PICO_DEFAULT_I2C))
73#endif
74
75#ifdef PICO_DEFAULT_I2C_INSTANCE
76#define i2c_default PICO_DEFAULT_I2C_INSTANCE
77#endif
78
81// ----------------------------------------------------------------------------
82// Setup
83
98uint i2c_init(i2c_inst_t *i2c, uint baudrate);
99
108void i2c_deinit(i2c_inst_t *i2c);
109
121uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate);
122
130void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr);
131
132// ----------------------------------------------------------------------------
133// Generic input/output
134
135struct i2c_inst {
136 i2c_hw_t *hw;
137 bool restart_on_next;
138};
139
146static inline uint i2c_hw_index(i2c_inst_t *i2c) {
147 invalid_params_if(I2C, i2c != i2c0 && i2c != i2c1);
148 return i2c == i2c1 ? 1 : 0;
149}
150
151static inline i2c_hw_t *i2c_get_hw(i2c_inst_t *i2c) {
152 i2c_hw_index(i2c); // check it is a hw i2c
153 return i2c->hw;
154}
155
171int i2c_write_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, absolute_time_t until);
172
185int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until);
186
202static inline int i2c_write_timeout_us(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, uint timeout_us) {
204 return i2c_write_blocking_until(i2c, addr, src, len, nostop, t);
205}
206
207int i2c_write_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, uint timeout_per_char_us);
208
221static inline int i2c_read_timeout_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, uint timeout_us) {
223 return i2c_read_blocking_until(i2c, addr, dst, len, nostop, t);
224}
225
226int i2c_read_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, uint timeout_per_char_us);
227
239int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop);
240
252int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop);
253
254
262static inline size_t i2c_get_write_available(i2c_inst_t *i2c) {
263 const size_t IC_TX_BUFFER_DEPTH = 16;
264 return IC_TX_BUFFER_DEPTH - i2c_get_hw(i2c)->txflr;
265}
266
274static inline size_t i2c_get_read_available(i2c_inst_t *i2c) {
275 return i2c_get_hw(i2c)->rxflr;
276}
277
288static inline void i2c_write_raw_blocking(i2c_inst_t *i2c, const uint8_t *src, size_t len) {
289 for (size_t i = 0; i < len; ++i) {
290 // TODO NACK or STOP on end?
291 while (!i2c_get_write_available(i2c))
293 i2c_get_hw(i2c)->data_cmd = *src++;
294 }
295}
296
307static inline void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t len) {
308 for (size_t i = 0; i < len; ++i) {
309 while (!i2c_get_read_available(i2c))
311 *dst++ = (uint8_t)i2c_get_hw(i2c)->data_cmd;
312 }
313}
314
321static inline uint i2c_get_dreq(i2c_inst_t *i2c, bool is_tx) {
322 static_assert(DREQ_I2C0_RX == DREQ_I2C0_TX + 1, "");
323 static_assert(DREQ_I2C1_RX == DREQ_I2C1_TX + 1, "");
324 static_assert(DREQ_I2C1_TX == DREQ_I2C0_TX + 2, "");
325 return DREQ_I2C0_TX + i2c_hw_index(i2c) * 2 + !is_tx;
326}
327
328#ifdef __cplusplus
329}
330#endif
331
332#endif
static int i2c_write_timeout_us(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, uint timeout_us)
Attempt to write specified number of bytes to address, with timeout.
Definition: i2c.h:202
int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until)
Attempt to read specified number of bytes from address, blocking until the specified absolute time is...
Definition: i2c.c:327
void i2c_deinit(i2c_inst_t *i2c)
Disable the I2C HW block.
Definition: i2c.c:60
void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr)
Set I2C port to slave mode.
Definition: i2c.c:114
static uint i2c_hw_index(i2c_inst_t *i2c)
Convert I2C instance to hardware instance number.
Definition: i2c.h:146
int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop)
Attempt to write specified number of bytes to address, blocking.
Definition: i2c.c:243
i2c_inst_t i2c0_inst
The I2C identifiers for use in I2C functions.
Definition: i2c.c:15
static size_t i2c_get_read_available(i2c_inst_t *i2c)
Determine number of bytes received.
Definition: i2c.h:274
uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate)
Set I2C baudrate.
Definition: i2c.c:64
static size_t i2c_get_write_available(i2c_inst_t *i2c)
Determine non-blocking write space available.
Definition: i2c.h:262
static int i2c_read_timeout_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, uint timeout_us)
Attempt to read specified number of bytes from address, with timeout.
Definition: i2c.h:221
int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop)
Attempt to read specified number of bytes from address, blocking.
Definition: i2c.c:323
static void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t len)
Read direct from RX FIFO.
Definition: i2c.h:307
static uint i2c_get_dreq(i2c_inst_t *i2c, bool is_tx)
Return the DREQ to use for pacing transfers to/from a particular I2C instance.
Definition: i2c.h:321
uint i2c_init(i2c_inst_t *i2c, uint baudrate)
Initialise the I2C HW block.
Definition: i2c.c:34
static void i2c_write_raw_blocking(i2c_inst_t *i2c, const uint8_t *src, size_t len)
Write direct to TX FIFO.
Definition: i2c.h:288
int i2c_write_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, absolute_time_t until)
Attempt to write specified number of bytes to address, blocking until the specified absolute time is ...
Definition: i2c.c:247
static __always_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:347
static absolute_time_t make_timeout_time_us(uint64_t us)
Convenience method to get the timestamp a number of microseconds from the current time.
Definition: time.h:129
#define i2c0
Identifier for I2C HW Block 0.
Definition: i2c.h:68
#define i2c1
Identifier for I2C HW Block 1.
Definition: i2c.h:69
Definition: types.h:33
Definition: i2c.h:23
Definition: i2c.h:135