Loading...
Searching...
No Matches
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_HARDWARE_I2C, Enable/disable assertions in the hardware_i2c module, type=bool, default=0, group=hardware_i2c
16#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_I2C
17#ifdef PARAM_ASSERTIONS_ENABLED_I2C // backwards compatibility with SDK < 2.0.0
18#define PARAM_ASSERTIONS_ENABLED_HARDWARE_I2C PARAM_ASSERTIONS_ENABLED_I2C
19#else
20#define PARAM_ASSERTIONS_ENABLED_HARDWARE_I2C 0
21#endif
22#endif
23#ifdef __cplusplus
24extern "C" {
25#endif
26
54
55typedef struct i2c_inst i2c_inst_t;
56
57// PICO_CONFIG: PICO_DEFAULT_I2C, Define the default I2C for a board, min=0, max=1, default=Usually provided via board header, group=hardware_i2c
58// PICO_CONFIG: PICO_DEFAULT_I2C_SDA_PIN, Define the default I2C SDA pin, min=0, max=47 on RP2350B, 29 otherwise, default=Usually provided via board header, group=hardware_i2c
59// PICO_CONFIG: PICO_DEFAULT_I2C_SCL_PIN, Define the default I2C SCL pin, min=0, max=47 on RP2350B, 29 otherwise, default=Usually provided via board header, group=hardware_i2c
60
68extern i2c_inst_t i2c0_inst;
69extern i2c_inst_t i2c1_inst;
70
71#define i2c0 (&i2c0_inst)
72#define i2c1 (&i2c1_inst)
73
74#if !defined(PICO_DEFAULT_I2C_INSTANCE) && defined(PICO_DEFAULT_I2C)
75#define PICO_DEFAULT_I2C_INSTANCE() (__CONCAT(i2c,PICO_DEFAULT_I2C))
76#endif
77
84
91#ifdef PICO_DEFAULT_I2C_INSTANCE
92#define i2c_default PICO_DEFAULT_I2C_INSTANCE()
93#endif
94
96
97// ----------------------------------------------------------------------------
98// Setup
99
114uint i2c_init(i2c_inst_t *i2c, uint baudrate);
115
124void i2c_deinit(i2c_inst_t *i2c);
125
137uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate);
138
146void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr);
147
148// ----------------------------------------------------------------------------
149// Generic input/output
150
161
170#ifndef I2C_NUM
171static_assert(NUM_I2CS == 2, "");
172#define I2C_NUM(i2c) ((i2c) == i2c1)
173#endif
174
183#ifndef I2C_INSTANCE
184static_assert(NUM_I2CS == 2, "");
185#define I2C_INSTANCE(num) ((num) ? i2c1 : i2c0)
186#endif
187
196#ifndef I2C_IS_INSTANCE
197static_assert(NUM_I2CS == 2, "");
198#define I2C_IS_INSTANCE(i2c) ((i2c) == i2c0 || (i2c) == i2c1)
199#endif
200
210#ifndef I2C_DREQ_NUM
211static_assert(DREQ_I2C0_RX == DREQ_I2C0_TX + 1, "");
212static_assert(DREQ_I2C1_RX == DREQ_I2C1_TX + 1, "");
213static_assert(DREQ_I2C1_TX == DREQ_I2C0_TX + 2, "");
214#define I2C_DREQ_NUM(i2c,is_tx) (DREQ_I2C0_TX + I2C_NUM(i2c) * 2 + !(is_tx))
215#endif
216
225#ifndef I2C_RESET_NUM
226#include "hardware/resets.h"
227#define I2C_RESET_NUM(i2c) (i2c_get_index(i2c) ? RESET_I2C1 : RESET_I2C0)
228#endif
229
236static inline uint i2c_get_index(i2c_inst_t *i2c) {
237 valid_params_if(HARDWARE_I2C, I2C_IS_INSTANCE(i2c));
238 return I2C_NUM(i2c);
239}
240
241// backward compatibility
242#define i2c_hw_index(i2c) i2c_get_index(i2c)
243
250static inline i2c_hw_t *i2c_get_hw(i2c_inst_t *i2c) {
251 i2c_hw_index(i2c); // check it is a hw i2c
252 return i2c->hw;
253}
254
261static inline i2c_inst_t *i2c_get_instance(uint num) {
262 invalid_params_if(HARDWARE_I2C, num >= NUM_I2CS);
263 return I2C_INSTANCE(num);
264}
265
281int i2c_write_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, absolute_time_t until);
282
295int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until);
296
312static 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) {
314 return i2c_write_blocking_until(i2c, addr, src, len, nostop, t);
315}
316
317int 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);
318
331static inline int i2c_read_timeout_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, uint timeout_us) {
333 return i2c_read_blocking_until(i2c, addr, dst, len, nostop, t);
334}
335
336int 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);
337
349int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop);
350
364int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len);
365
377int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop);
378
392int i2c_read_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len);
393
401static inline size_t i2c_get_write_available(i2c_inst_t *i2c) {
402 const size_t IC_TX_BUFFER_DEPTH = 16;
403 return IC_TX_BUFFER_DEPTH - i2c_get_hw(i2c)->txflr;
404}
405
413static inline size_t i2c_get_read_available(i2c_inst_t *i2c) {
414 return i2c_get_hw(i2c)->rxflr;
415}
416
427static inline void i2c_write_raw_blocking(i2c_inst_t *i2c, const uint8_t *src, size_t len) {
428 for (size_t i = 0; i < len; ++i) {
429 // TODO NACK or STOP on end?
430 while (!i2c_get_write_available(i2c))
432 i2c_get_hw(i2c)->data_cmd = *src++;
433 }
434}
435
446static inline void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t len) {
447 for (size_t i = 0; i < len; ++i) {
448 while (!i2c_get_read_available(i2c))
450 *dst++ = (uint8_t)i2c_get_hw(i2c)->data_cmd;
451 }
452}
453
463static inline uint8_t i2c_read_byte_raw(i2c_inst_t *i2c) {
464 i2c_hw_t *hw = i2c_get_hw(i2c);
465 assert(hw->status & I2C_IC_STATUS_RFNE_BITS); // Rx FIFO must not be empty
466 return (uint8_t)hw->data_cmd;
467}
468
478static inline void i2c_write_byte_raw(i2c_inst_t *i2c, uint8_t value) {
479 i2c_hw_t *hw = i2c_get_hw(i2c);
480 assert(hw->status & I2C_IC_STATUS_TFNF_BITS); // Tx FIFO must not be full
481 hw->data_cmd = value;
482}
483
490static inline uint i2c_get_dreq(i2c_inst_t *i2c, bool is_tx) {
491 return I2C_DREQ_NUM(i2c, is_tx);
492}
493
494#ifdef __cplusplus
495}
496#endif
497
498#endif
@ DREQ_I2C1_RX
Select I2C1's RX FIFO as DREQ.
Definition dreq.h:129
@ DREQ_I2C0_RX
Select I2C0's RX FIFO as DREQ.
Definition dreq.h:127
@ DREQ_I2C1_TX
Select I2C1's TX FIFO as DREQ.
Definition dreq.h:128
@ DREQ_I2C0_TX
Select I2C0's TX FIFO as DREQ.
Definition dreq.h:126
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:312
#define I2C_NUM(i2c)
Returns the I2C number for a I2C instance.
Definition i2c.h:172
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:342
static i2c_inst_t * i2c_get_instance(uint num)
Convert I2C hardware instance number to I2C instance.
Definition i2c.h:261
void i2c_deinit(i2c_inst_t *i2c)
Disable the I2C HW block.
Definition i2c.c:58
void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr)
Set I2C port to slave mode.
Definition i2c.c:112
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:245
int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len)
Attempt to write specified number of bytes to address, blocking in burst mode.
Definition i2c.c:262
i2c_inst_t i2c0_inst
Definition i2c.c:15
static size_t i2c_get_read_available(i2c_inst_t *i2c)
Determine number of bytes received.
Definition i2c.h:413
uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate)
Set I2C baudrate.
Definition i2c.c:62
#define I2C_DREQ_NUM(i2c, is_tx)
Returns the dreq_num_t used for pacing DMA transfers to or from this I2C instance....
Definition i2c.h:214
#define I2C_IS_INSTANCE(i2c)
Returns true if the I2C instance is one of the h/w I2C instances.
Definition i2c.h:198
static size_t i2c_get_write_available(i2c_inst_t *i2c)
Determine non-blocking write space available.
Definition i2c.h:401
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:331
static void i2c_write_byte_raw(i2c_inst_t *i2c, uint8_t value)
Push a byte into I2C Tx FIFO.
Definition i2c.h:478
#define I2C_INSTANCE(num)
Returns the I2C instance with the given I2C number.
Definition i2c.h:185
static uint i2c_get_index(i2c_inst_t *i2c)
Convert I2C instance to hardware instance number.
Definition i2c.h:236
static uint8_t i2c_read_byte_raw(i2c_inst_t *i2c)
Pop a byte from I2C Rx FIFO.
Definition i2c.h:463
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:338
static void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t len)
Read direct from RX FIFO.
Definition i2c.h:446
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:490
uint i2c_init(i2c_inst_t *i2c, uint baudrate)
Initialise the I2C HW block.
Definition i2c.c:32
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:427
int i2c_read_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len)
Attempt to read specified number of bytes from address, blocking in burst mode.
Definition i2c.c:354
static i2c_hw_t * i2c_get_hw(i2c_inst_t *i2c)
Return pointer to structure containing i2c hardware registers.
Definition i2c.h:250
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:249
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition common.h:79
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:148
uint64_t absolute_time_t
An opaque 64 bit timestamp in microseconds.
Definition types.h:43
Definition i2c.h:26
I2C controller instance.
Definition i2c.h:157
i2c_hw_t * hw
Pointer to the I2C hardware registers.
Definition i2c.h:158
bool restart_on_next
If true, the next transfer will begin with a Restart rather than a Start.
Definition i2c.h:159