or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# smbus2

1

2

A drop-in replacement for smbus-cffi/smbus-python in pure Python. smbus2 provides a complete implementation of the SMBus (System Management Bus) protocol for I2C communication, enabling comprehensive device interaction for embedded systems, IoT devices, and hardware interfacing applications.

3

4

## Package Information

5

6

- **Package Name**: smbus2

7

- **Language**: Python

8

- **Installation**: `pip install smbus2`

9

10

## Core Imports

11

12

```python

13

from smbus2 import SMBus, i2c_msg, I2cFunc

14

```

15

16

Individual component import:

17

18

```python

19

from smbus2 import SMBus # Main SMBus interface

20

from smbus2 import i2c_msg # I2C message class for combined transactions

21

from smbus2 import I2cFunc # I2C functionality flags enum

22

```

23

24

## Basic Usage

25

26

```python

27

from smbus2 import SMBus

28

29

# Basic usage with context manager (recommended)

30

with SMBus(1) as bus:

31

# Read a byte from address 0x50, register 0x00

32

data = bus.read_byte_data(0x50, 0x00)

33

print(f"Read value: {data}")

34

35

# Write a byte to address 0x50, register 0x00

36

bus.write_byte_data(0x50, 0x00, 0xFF)

37

38

# Manual connection management

39

bus = SMBus(1) # Open I2C bus 1

40

try:

41

# Read word data from register

42

word_data = bus.read_word_data(0x50, 0x10)

43

print(f"Word data: {word_data}")

44

finally:

45

bus.close() # Always close the connection

46

47

# Enable Packet Error Checking (PEC)

48

with SMBus(1) as bus:

49

bus.pec = 1 # Enable PEC

50

data = bus.read_byte_data(0x50, 0x00)

51

```

52

53

## Architecture

54

55

smbus2 is built on a layered architecture:

56

57

- **SMBus Class**: High-level interface providing all standard SMBus operations

58

- **i2c_msg System**: Low-level message system for combined I2C transactions beyond SMBus limitations

59

- **ctypes Integration**: Direct interface to Linux I2C subsystem via ioctl calls

60

- **Pure Python Implementation**: No external dependencies, compatible across Python versions

61

62

The library supports both traditional SMBus operations (limited to 32 bytes) and advanced I2C transactions (unlimited size) through the i2c_rdwr interface, making it suitable for both simple sensor communication and complex data transfer scenarios.

63

64

## Capabilities

65

66

### Connection Management

67

68

SMBus connection initialization, opening, and closing with support for context managers and manual resource management.

69

70

```python { .api }

71

class SMBus:

72

def __init__(self, bus=None, force=False):

73

"""

74

Initialize SMBus instance.

75

76

Parameters:

77

- bus: int or str, I2C bus number (e.g. 1) or device path (e.g. '/dev/i2c-1')

78

- force: bool, force using slave address even when driver is already using it

79

"""

80

81

def __enter__(self):

82

"""Context manager entry, returns self."""

83

84

def __exit__(self, exc_type, exc_val, exc_tb):

85

"""Context manager exit, closes connection."""

86

87

def open(self, bus):

88

"""

89

Open I2C bus connection.

90

91

Parameters:

92

- bus: int or str, I2C bus number or device path

93

94

Raises:

95

- TypeError: if bus type is not int or str

96

"""

97

98

def close(self):

99

"""Close I2C connection."""

100

```

101

102

### Basic SMBus Operations

103

104

Fundamental SMBus operations including quick commands and single byte read/write operations.

105

106

```python { .api }

107

def write_quick(self, i2c_addr, force=None):

108

"""

109

Perform SMBus Quick Command.

110

111

Parameters:

112

- i2c_addr: int, I2C slave address

113

- force: bool, optional override for force flag

114

115

Raises:

116

- IOError: if operation fails

117

"""

118

119

def read_byte(self, i2c_addr, force=None):

120

"""

121

Read single byte from I2C device.

122

123

Parameters:

124

- i2c_addr: int, I2C slave address

125

- force: bool, optional override for force flag

126

127

Returns:

128

- int: byte value (0-255)

129

"""

130

131

def write_byte(self, i2c_addr, value, force=None):

132

"""

133

Write single byte to I2C device.

134

135

Parameters:

136

- i2c_addr: int, I2C slave address

137

- value: int, byte value to write (0-255)

138

- force: bool, optional override for force flag

139

"""

140

```

141

142

### Register-Based Operations

143

144

SMBus byte and word data operations for reading from and writing to specific device registers.

145

146

```python { .api }

147

def read_byte_data(self, i2c_addr, register, force=None):

148

"""

149

Read byte from specified register.

150

151

Parameters:

152

- i2c_addr: int, I2C slave address

153

- register: int, register address (0-255)

154

- force: bool, optional override for force flag

155

156

Returns:

157

- int: byte value from register

158

"""

159

160

def write_byte_data(self, i2c_addr, register, value, force=None):

161

"""

162

Write byte to specified register.

163

164

Parameters:

165

- i2c_addr: int, I2C slave address

166

- register: int, register address (0-255)

167

- value: int, byte value to write (0-255)

168

- force: bool, optional override for force flag

169

"""

170

171

def read_word_data(self, i2c_addr, register, force=None):

172

"""

173

Read 16-bit word from specified register.

174

175

Parameters:

176

- i2c_addr: int, I2C slave address

177

- register: int, register address (0-255)

178

- force: bool, optional override for force flag

179

180

Returns:

181

- int: 16-bit word value from register

182

"""

183

184

def write_word_data(self, i2c_addr, register, value, force=None):

185

"""

186

Write 16-bit word to specified register.

187

188

Parameters:

189

- i2c_addr: int, I2C slave address

190

- register: int, register address (0-255)

191

- value: int, 16-bit word value to write (0-65535)

192

- force: bool, optional override for force flag

193

"""

194

```

195

196

### Process Call Operations

197

198

SMBus Process Call operations for atomic write-then-read transactions.

199

200

```python { .api }

201

def process_call(self, i2c_addr, register, value, force=None):

202

"""

203

Execute SMBus Process Call (write 16-bit value, read 16-bit response).

204

205

Parameters:

206

- i2c_addr: int, I2C slave address

207

- register: int, register address

208

- value: int, 16-bit value to send

209

- force: bool, optional override for force flag

210

211

Returns:

212

- int: 16-bit response value

213

"""

214

215

def block_process_call(self, i2c_addr, register, data, force=None):

216

"""

217

Execute SMBus Block Process Call (write block, read block response).

218

219

Parameters:

220

- i2c_addr: int, I2C slave address

221

- register: int, register address

222

- data: list of int, data bytes to send (max 32 bytes)

223

- force: bool, optional override for force flag

224

225

Returns:

226

- list of int: response data bytes

227

228

Raises:

229

- ValueError: if data length exceeds 32 bytes

230

"""

231

```

232

233

### Block Data Operations

234

235

SMBus block data operations for reading and writing multiple bytes in a single transaction.

236

237

```python { .api }

238

def read_block_data(self, i2c_addr, register, force=None):

239

"""

240

Read block of data from register (up to 32 bytes).

241

242

Parameters:

243

- i2c_addr: int, I2C slave address

244

- register: int, start register address

245

- force: bool, optional override for force flag

246

247

Returns:

248

- list of int: data bytes read

249

"""

250

251

def write_block_data(self, i2c_addr, register, data, force=None):

252

"""

253

Write block of data to register (up to 32 bytes).

254

255

Parameters:

256

- i2c_addr: int, I2C slave address

257

- register: int, start register address

258

- data: list of int, data bytes to write (max 32 bytes)

259

- force: bool, optional override for force flag

260

261

Raises:

262

- ValueError: if data length exceeds 32 bytes

263

"""

264

265

def read_i2c_block_data(self, i2c_addr, register, length, force=None):

266

"""

267

Read I2C block data with specified length.

268

269

Parameters:

270

- i2c_addr: int, I2C slave address

271

- register: int, start register address

272

- length: int, number of bytes to read (max 32)

273

- force: bool, optional override for force flag

274

275

Returns:

276

- list of int: data bytes read

277

278

Raises:

279

- ValueError: if length exceeds 32 bytes

280

"""

281

282

def write_i2c_block_data(self, i2c_addr, register, data, force=None):

283

"""

284

Write I2C block data.

285

286

Parameters:

287

- i2c_addr: int, I2C slave address

288

- register: int, start register address

289

- data: list of int, data bytes to write (max 32 bytes)

290

- force: bool, optional override for force flag

291

292

Raises:

293

- ValueError: if data length exceeds 32 bytes

294

"""

295

```

296

297

### Advanced I2C Operations

298

299

Combined I2C read/write operations using i2c_msg for transactions beyond SMBus limitations.

300

301

```python { .api }

302

def i2c_rdwr(self, *i2c_msgs):

303

"""

304

Execute combined I2C read/write operations with repeated start.

305

306

Parameters:

307

- i2c_msgs: i2c_msg instances created with i2c_msg.read() or i2c_msg.write()

308

309

Note: Allows bulk transfers beyond SMBus 32-byte limit

310

"""

311

312

class i2c_msg:

313

"""I2C message for combined transactions."""

314

315

@staticmethod

316

def read(address, length):

317

"""

318

Create I2C read message.

319

320

Parameters:

321

- address: int, I2C slave address

322

- length: int, number of bytes to read

323

324

Returns:

325

- i2c_msg: configured for read operation

326

"""

327

328

@staticmethod

329

def write(address, buf):

330

"""

331

Create I2C write message.

332

333

Parameters:

334

- address: int, I2C slave address

335

- buf: list of int or str, data to write

336

337

Returns:

338

- i2c_msg: configured for write operation

339

"""

340

341

def __iter__(self):

342

"""Iterate over message data bytes."""

343

344

def __len__(self):

345

"""Get message length."""

346

347

def __bytes__(self):

348

"""Get message data as bytes."""

349

350

def __repr__(self):

351

"""String representation of message."""

352

353

def __str__(self):

354

"""Decoded string representation of message data."""

355

356

# Properties

357

addr: int # I2C slave address

358

flags: int # Message flags (e.g., I2C_M_RD for read)

359

len: int # Message length in bytes

360

buf: pointer # Message data buffer

361

```

362

363

### Configuration and Capabilities

364

365

Device capability detection and configuration management including Packet Error Checking.

366

367

```python { .api }

368

def enable_pec(self, enable=True):

369

"""

370

Enable or disable Packet Error Checking (SMBus 1.1+).

371

372

Parameters:

373

- enable: bool, True to enable PEC, False to disable

374

375

Raises:

376

- IOError: if device doesn't support PEC

377

"""

378

379

# Properties

380

pec: int # PEC setting (0=disabled, 1=enabled)

381

funcs: I2cFunc # Device capability flags

382

fd: int # File descriptor for I2C device

383

address: int # Current I2C slave address

384

force: bool # Force flag setting

385

386

class I2cFunc:

387

"""IntFlag enum for I2C/SMBus capability flags."""

388

389

# Basic I2C capabilities

390

I2C = 0x00000001

391

ADDR_10BIT = 0x00000002

392

PROTOCOL_MANGLING = 0x00000004

393

SMBUS_PEC = 0x00000008

394

NOSTART = 0x00000010

395

SLAVE = 0x00000020

396

397

# SMBus operation capabilities

398

SMBUS_QUICK = 0x00010000

399

SMBUS_READ_BYTE = 0x00020000

400

SMBUS_WRITE_BYTE = 0x00040000

401

SMBUS_READ_BYTE_DATA = 0x00080000

402

SMBUS_WRITE_BYTE_DATA = 0x00100000

403

SMBUS_READ_WORD_DATA = 0x00200000

404

SMBUS_WRITE_WORD_DATA = 0x00400000

405

SMBUS_PROC_CALL = 0x00800000

406

SMBUS_READ_BLOCK_DATA = 0x01000000

407

SMBUS_WRITE_BLOCK_DATA = 0x02000000

408

SMBUS_READ_I2C_BLOCK = 0x04000000

409

SMBUS_WRITE_I2C_BLOCK = 0x08000000

410

SMBUS_BLOCK_PROC_CALL = 0x00008000

411

SMBUS_HOST_NOTIFY = 0x10000000

412

413

# Combined capability flags

414

SMBUS_BYTE = 0x00060000

415

SMBUS_BYTE_DATA = 0x00180000

416

SMBUS_WORD_DATA = 0x00600000

417

SMBUS_BLOCK_DATA = 0x03000000

418

SMBUS_I2C_BLOCK = 0x0c000000

419

SMBUS_EMUL = 0x0eff0008

420

```

421

422

## Usage Examples

423

424

### Basic Sensor Reading

425

426

```python

427

from smbus2 import SMBus

428

429

# Read temperature from sensor at address 0x48

430

with SMBus(1) as bus:

431

# Read 2-byte temperature value

432

temp_raw = bus.read_word_data(0x48, 0x00)

433

# Convert to Celsius (example conversion for specific sensor)

434

temperature = (temp_raw >> 8) * 0.5

435

print(f"Temperature: {temperature}°C")

436

```

437

438

### Block Data Transfer

439

440

```python

441

from smbus2 import SMBus

442

443

# Read configuration block from EEPROM

444

with SMBus(1) as bus:

445

# Read 16 bytes starting from address 0x00

446

config_data = bus.read_i2c_block_data(0x50, 0x00, 16)

447

print(f"Config: {[hex(b) for b in config_data]}")

448

449

# Write new configuration

450

new_config = [0x01, 0x02, 0x03, 0x04, 0x05]

451

bus.write_i2c_block_data(0x50, 0x00, new_config)

452

```

453

454

### Combined I2C Transactions

455

456

```python

457

from smbus2 import SMBus, i2c_msg

458

459

# Advanced I2C operations beyond SMBus limits

460

with SMBus(1) as bus:

461

# Write command and read large response in single transaction

462

write_cmd = i2c_msg.write(0x40, [0x01, 0x02])

463

read_response = i2c_msg.read(0x40, 64) # Read 64 bytes

464

465

bus.i2c_rdwr(write_cmd, read_response)

466

467

# Access response data

468

response_data = list(read_response)

469

print(f"Response: {response_data}")

470

```

471

472

### Capability Detection

473

474

```python

475

from smbus2 import SMBus, I2cFunc

476

477

with SMBus(1) as bus:

478

# Check device capabilities

479

if bus.funcs & I2cFunc.SMBUS_PEC:

480

print("Device supports Packet Error Checking")

481

bus.pec = 1 # Enable PEC

482

483

if bus.funcs & I2cFunc.SMBUS_BLOCK_DATA:

484

print("Device supports SMBus block operations")

485

486

if bus.funcs & I2cFunc.I2C:

487

print("Device supports I2C operations")

488

```

489

490

## Constants

491

492

```python { .api }

493

# I2C device control constants

494

I2C_SLAVE = 0x0703 # Use this slave address

495

I2C_SLAVE_FORCE = 0x0706 # Use this slave address, even if already in use by a driver

496

I2C_FUNCS = 0x0705 # Get the adapter functionality mask

497

I2C_RDWR = 0x0707 # Combined R/W transfer (one STOP only)

498

I2C_SMBUS = 0x0720 # SMBus transfer. Takes pointer to i2c_smbus_ioctl_data

499

I2C_PEC = 0x0708 # != 0 to use PEC with SMBus

500

501

# SMBus transfer direction markers

502

I2C_SMBUS_WRITE = 0

503

I2C_SMBUS_READ = 1

504

505

# SMBus operation size identifiers

506

I2C_SMBUS_QUICK = 0

507

I2C_SMBUS_BYTE = 1

508

I2C_SMBUS_BYTE_DATA = 2

509

I2C_SMBUS_WORD_DATA = 3

510

I2C_SMBUS_PROC_CALL = 4

511

I2C_SMBUS_BLOCK_DATA = 5 # Not supported by Pure-I2C drivers with SMBUS emulation

512

I2C_SMBUS_BLOCK_PROC_CALL = 7 # Not supported by Pure-I2C drivers either

513

I2C_SMBUS_I2C_BLOCK_DATA = 8

514

I2C_SMBUS_BLOCK_MAX = 32

515

516

# I2C message flags

517

I2C_M_RD = 0x0001

518

```

519

520

## Error Handling

521

522

Common exceptions that may be raised:

523

524

- **IOError**: I2C operation failed (device not responding, bus error, insufficient permissions, PEC not supported)

525

- **ValueError**: Invalid parameter values (data length exceeds I2C_SMBUS_BLOCK_MAX (32 bytes), invalid length specification)

526

- **TypeError**: Incorrect parameter types (bus must be int or str)

527

528

Specific error conditions:

529

- Block operations raise `ValueError` if data length > 32 bytes

530

- `enable_pec()` raises `IOError` if device doesn't support SMBUS_PEC functionality

531

- `open()` raises `TypeError` if bus parameter is not int or str

532

533

Always use try-except blocks for robust error handling:

534

535

```python

536

from smbus2 import SMBus, I2cFunc

537

538

try:

539

with SMBus(1) as bus:

540

# Check PEC support before enabling

541

if bus.funcs & I2cFunc.SMBUS_PEC:

542

bus.pec = 1

543

data = bus.read_byte_data(0x50, 0x00)

544

except IOError as e:

545

print(f"I2C communication error: {e}")

546

except ValueError as e:

547

print(f"Invalid parameter: {e}")

548

except TypeError as e:

549

print(f"Invalid type: {e}")

550

```