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
21 extern "C" {
22 #endif
23 
52 typedef 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 
65 extern i2c_inst_t i2c0_inst;
66 extern 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 
98 uint i2c_init(i2c_inst_t *i2c, uint baudrate);
99 
108 void i2c_deinit(i2c_inst_t *i2c);
109 
121 uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate);
122 
130 void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr);
131 
132 // ----------------------------------------------------------------------------
133 // Generic input/output
134 
135 struct i2c_inst {
136  i2c_hw_t *hw;
137  bool restart_on_next;
138 };
139 
146 static 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 
151 static 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 
156 static inline i2c_inst_t *i2c_get_instance(uint instance) {
157  static_assert(NUM_I2CS == 2, "");
158  invalid_params_if(I2C, instance >= NUM_I2CS);
159  return instance ? i2c1 : i2c0;
160 }
161 
177 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);
178 
191 int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until);
192 
208 static 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) {
209  absolute_time_t t = make_timeout_time_us(timeout_us);
210  return i2c_write_blocking_until(i2c, addr, src, len, nostop, t);
211 }
212 
213 int 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);
214 
227 static inline int i2c_read_timeout_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, uint timeout_us) {
228  absolute_time_t t = make_timeout_time_us(timeout_us);
229  return i2c_read_blocking_until(i2c, addr, dst, len, nostop, t);
230 }
231 
232 int 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);
233 
245 int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop);
246 
258 int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop);
259 
260 
268 static inline size_t i2c_get_write_available(i2c_inst_t *i2c) {
269  const size_t IC_TX_BUFFER_DEPTH = 16;
270  return IC_TX_BUFFER_DEPTH - i2c_get_hw(i2c)->txflr;
271 }
272 
280 static inline size_t i2c_get_read_available(i2c_inst_t *i2c) {
281  return i2c_get_hw(i2c)->rxflr;
282 }
283 
294 static inline void i2c_write_raw_blocking(i2c_inst_t *i2c, const uint8_t *src, size_t len) {
295  for (size_t i = 0; i < len; ++i) {
296  // TODO NACK or STOP on end?
297  while (!i2c_get_write_available(i2c))
299  i2c_get_hw(i2c)->data_cmd = *src++;
300  }
301 }
302 
313 static inline void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t len) {
314  for (size_t i = 0; i < len; ++i) {
315  while (!i2c_get_read_available(i2c))
317  *dst++ = (uint8_t)i2c_get_hw(i2c)->data_cmd;
318  }
319 }
320 
330 static inline uint8_t i2c_read_byte_raw(i2c_inst_t *i2c) {
331  i2c_hw_t *hw = i2c_get_hw(i2c);
332  assert(hw->status & I2C_IC_STATUS_RFNE_BITS); // Rx FIFO must not be empty
333  return (uint8_t)hw->data_cmd;
334 }
335 
345 static inline void i2c_write_byte_raw(i2c_inst_t *i2c, uint8_t value) {
346  i2c_hw_t *hw = i2c_get_hw(i2c);
347  assert(hw->status & I2C_IC_STATUS_TFNF_BITS); // Tx FIFO must not be full
348  hw->data_cmd = value;
349 }
350 
351 
358 static inline uint i2c_get_dreq(i2c_inst_t *i2c, bool is_tx) {
359  static_assert(DREQ_I2C0_RX == DREQ_I2C0_TX + 1, "");
360  static_assert(DREQ_I2C1_RX == DREQ_I2C1_TX + 1, "");
361  static_assert(DREQ_I2C1_TX == DREQ_I2C0_TX + 2, "");
362  return DREQ_I2C0_TX + i2c_hw_index(i2c) * 2 + !is_tx;
363 }
364 
365 #ifdef __cplusplus
366 }
367 #endif
368 
369 #endif
i2c_write_byte_raw
static void i2c_write_byte_raw(i2c_inst_t *i2c, uint8_t value)
Push a byte into I2C Tx FIFO.
Definition: i2c.h:345
i2c_hw_t
Definition: i2c.h:23
make_timeout_time_us
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:131
i2c1
#define i2c1
Identifier for I2C HW Block 1.
Definition: i2c.h:69
absolute_time_t
Definition: types.h:33
i2c_write_raw_blocking
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:294
i2c_write_blocking_until
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
i2c_write_blocking
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_get_write_available
static size_t i2c_get_write_available(i2c_inst_t *i2c)
Determine non-blocking write space available.
Definition: i2c.h:268
time.h
i2c_set_baudrate
uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate)
Set I2C baudrate.
Definition: i2c.c:64
i2c_set_slave_mode
void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr)
Set I2C port to slave mode.
Definition: i2c.c:114
i2c_get_read_available
static size_t i2c_get_read_available(i2c_inst_t *i2c)
Determine number of bytes received.
Definition: i2c.h:280
i2c0
#define i2c0
Identifier for I2C HW Block 0.
Definition: i2c.h:68
tight_loop_contents
static __always_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:358
i2c_deinit
void i2c_deinit(i2c_inst_t *i2c)
Disable the I2C HW block.
Definition: i2c.c:60
i2c0_inst
i2c_inst_t i2c0_inst
Definition: i2c.c:15
i2c_get_dreq
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:358
pico.h
i2c_hw_index
static uint i2c_hw_index(i2c_inst_t *i2c)
Convert I2C instance to hardware instance number.
Definition: i2c.h:146
i2c_read_raw_blocking
static void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t len)
Read direct from RX FIFO.
Definition: i2c.h:313
i2c_write_timeout_us
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:208
i2c_read_blocking_until
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
i2c_read_timeout_us
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:227
i2c_read_byte_raw
static uint8_t i2c_read_byte_raw(i2c_inst_t *i2c)
Pop a byte from I2C Rx FIFO.
Definition: i2c.h:330
i2c_inst
Definition: i2c.h:135
i2c_read_blocking
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
i2c_init
uint i2c_init(i2c_inst_t *i2c, uint baudrate)
Initialise the I2C HW block.
Definition: i2c.c:34