@web-font-path: "roboto-debian.css";
v2.2.0 (RP2040)
Loading...
Searching...
No Matches
i2c.h
Go to the documentation of this file.
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _HARDWARE_I2C_H
#define _HARDWARE_I2C_H
#include "pico.h"
#include "pico/time.h"
#include "hardware/structs/i2c.h"
#include "hardware/regs/dreq.h"
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_I2C, Enable/disable assertions in the hardware_i2c module, type=bool, default=0, group=hardware_i2c
#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_I2C
#ifdef PARAM_ASSERTIONS_ENABLED_I2C // backwards compatibility with SDK < 2.0.0
#define PARAM_ASSERTIONS_ENABLED_HARDWARE_I2C PARAM_ASSERTIONS_ENABLED_I2C
#else
#define PARAM_ASSERTIONS_ENABLED_HARDWARE_I2C 0
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct i2c_inst i2c_inst_t;
// 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
// 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
// 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
extern i2c_inst_t i2c0_inst;
extern i2c_inst_t i2c1_inst;
#define i2c0 (&i2c0_inst)
#define i2c1 (&i2c1_inst)
#if !defined(PICO_DEFAULT_I2C_INSTANCE) && defined(PICO_DEFAULT_I2C)
#define PICO_DEFAULT_I2C_INSTANCE() (__CONCAT(i2c,PICO_DEFAULT_I2C))
#endif
#ifdef PICO_DEFAULT_I2C_INSTANCE
#define i2c_default PICO_DEFAULT_I2C_INSTANCE()
#endif
// ----------------------------------------------------------------------------
// Setup
uint i2c_init(i2c_inst_t *i2c, uint baudrate);
void i2c_deinit(i2c_inst_t *i2c);
uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate);
void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr);
// ----------------------------------------------------------------------------
// Generic input/output
struct i2c_inst {
i2c_hw_t *hw;
bool restart_on_next;
};
#ifndef I2C_NUM
static_assert(NUM_I2CS == 2, "");
#define I2C_NUM(i2c) ((i2c) == i2c1)
#endif
#ifndef I2C_INSTANCE
static_assert(NUM_I2CS == 2, "");
#define I2C_INSTANCE(num) ((num) ? i2c1 : i2c0)
#endif
#ifndef I2C_DREQ_NUM
static_assert(DREQ_I2C0_RX == DREQ_I2C0_TX + 1, "");
static_assert(DREQ_I2C1_RX == DREQ_I2C1_TX + 1, "");
static_assert(DREQ_I2C1_TX == DREQ_I2C0_TX + 2, "");
#define I2C_DREQ_NUM(i2c,is_tx) (DREQ_I2C0_TX + I2C_NUM(i2c) * 2 + !(is_tx))
#endif
static inline uint i2c_get_index(i2c_inst_t *i2c) {
invalid_params_if(HARDWARE_I2C, i2c != i2c0 && i2c != i2c1);
return I2C_NUM(i2c);
}
// backward compatibility
#define i2c_hw_index(i2c) i2c_get_index(i2c)
static inline i2c_hw_t *i2c_get_hw(i2c_inst_t *i2c) {
i2c_hw_index(i2c); // check it is a hw i2c
return i2c->hw;
}
static inline i2c_inst_t *i2c_get_instance(uint num) {
invalid_params_if(HARDWARE_I2C, num >= NUM_I2CS);
return I2C_INSTANCE(num);
}
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);
int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until);
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) {
absolute_time_t t = make_timeout_time_us(timeout_us);
return i2c_write_blocking_until(i2c, addr, src, len, nostop, t);
}
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);
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) {
absolute_time_t t = make_timeout_time_us(timeout_us);
return i2c_read_blocking_until(i2c, addr, dst, len, nostop, t);
}
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);
int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop);
int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len);
int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop);
int i2c_read_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len);
static inline size_t i2c_get_write_available(i2c_inst_t *i2c) {
const size_t IC_TX_BUFFER_DEPTH = 16;
return IC_TX_BUFFER_DEPTH - i2c_get_hw(i2c)->txflr;
}
static inline size_t i2c_get_read_available(i2c_inst_t *i2c) {
return i2c_get_hw(i2c)->rxflr;
}
static inline void i2c_write_raw_blocking(i2c_inst_t *i2c, const uint8_t *src, size_t len) {
for (size_t i = 0; i < len; ++i) {
// TODO NACK or STOP on end?
while (!i2c_get_write_available(i2c))
tight_loop_contents();
i2c_get_hw(i2c)->data_cmd = *src++;
}
}
static inline void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t len) {
for (size_t i = 0; i < len; ++i) {
while (!i2c_get_read_available(i2c))
tight_loop_contents();
*dst++ = (uint8_t)i2c_get_hw(i2c)->data_cmd;
}
}
static inline uint8_t i2c_read_byte_raw(i2c_inst_t *i2c) {
i2c_hw_t *hw = i2c_get_hw(i2c);
assert(hw->status & I2C_IC_STATUS_RFNE_BITS); // Rx FIFO must not be empty
return (uint8_t)hw->data_cmd;
}
static inline void i2c_write_byte_raw(i2c_inst_t *i2c, uint8_t value) {
i2c_hw_t *hw = i2c_get_hw(i2c);
assert(hw->status & I2C_IC_STATUS_TFNF_BITS); // Tx FIFO must not be full
hw->data_cmd = value;
}
static inline uint i2c_get_dreq(i2c_inst_t *i2c, bool is_tx) {
return I2C_DREQ_NUM(i2c, is_tx);
}
#ifdef __cplusplus
}
#endif
#endif
time.h
DREQ_I2C1_RX
@ DREQ_I2C1_RX
Select I2C1's RX FIFO as DREQ.
Definition dreq.h:102
DREQ_I2C0_RX
@ DREQ_I2C0_RX
Select I2C0's RX FIFO as DREQ.
Definition dreq.h:100
DREQ_I2C1_TX
@ DREQ_I2C1_TX
Select I2C1's TX FIFO as DREQ.
Definition dreq.h:101
DREQ_I2C0_TX
@ DREQ_I2C0_TX
Select I2C0's TX FIFO as DREQ.
Definition dreq.h:99
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:280
I2C_NUM
#define I2C_NUM(i2c)
Returns the I2C number for a I2C instance.
Definition i2c.h:166
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:342
i2c_get_instance
static i2c_inst_t * i2c_get_instance(uint num)
Convert I2C hardware instance number to I2C instance.
Definition i2c.h:229
i2c_deinit
void i2c_deinit(i2c_inst_t *i2c)
Disable the I2C HW block.
Definition i2c.c:58
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:112
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:245
i2c_write_burst_blocking
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
i2c0_inst
i2c_inst_t i2c0_inst
Definition i2c.c:15
i2c_get_read_available
static size_t i2c_get_read_available(i2c_inst_t *i2c)
Determine number of bytes received.
Definition i2c.h:381
i2c_set_baudrate
uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate)
Set I2C baudrate.
Definition i2c.c:62
I2C_DREQ_NUM
#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:195
i2c_get_write_available
static size_t i2c_get_write_available(i2c_inst_t *i2c)
Determine non-blocking write space available.
Definition i2c.h:369
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:299
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:446
I2C_INSTANCE
#define I2C_INSTANCE(num)
Returns the I2C instance with the given I2C number.
Definition i2c.h:179
i2c_get_index
static uint i2c_get_index(i2c_inst_t *i2c)
Convert I2C instance to hardware instance number.
Definition i2c.h:204
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:431
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:338
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:414
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:458
i2c_init
uint i2c_init(i2c_inst_t *i2c, uint baudrate)
Initialise the I2C HW block.
Definition i2c.c:32
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:395
i2c_read_burst_blocking
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
i2c_get_hw
static i2c_hw_t * i2c_get_hw(i2c_inst_t *i2c)
Return pointer to structure containing i2c hardware registers.
Definition i2c.h:218
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:249
tight_loop_contents
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition common.h:74
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:136
absolute_time_t
uint64_t absolute_time_t
An opaque 64 bit timestamp in microseconds.
Definition types.h:43
pico.h
i2c0
#define i2c0
Identifier for I2C HW Block 0.
Definition i2c.h:71
i2c1
#define i2c1
Identifier for I2C HW Block 1.
Definition i2c.h:72
i2c_hw_t
Definition i2c.h:26
i2c_inst
Definition i2c.h:151