or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analog-io.mdbitbangio.mdboard-pins.mdcommunication.mdcore-framework.mddigital-io.mdindex.mdperipherals.mdpwm-pulse.mdutilities.md

bitbangio.mddocs/

0

# Software Bit-banged Protocols

1

2

Software implementations of I2C and SPI communication protocols using bit-banging techniques. These implementations work on platforms without dedicated hardware communication peripherals or when hardware peripherals are already in use.

3

4

## Capabilities

5

6

### Software I2C

7

8

Bit-banged I2C implementation using GPIO pins for clock and data lines. Provides the same interface as hardware I2C but implemented in software.

9

10

```python { .api }

11

class I2C(Lockable):

12

def __init__(self, scl, sda, frequency: int = 400000):

13

"""

14

Initialize software I2C interface.

15

16

Parameters:

17

- scl: Pin to use for I2C clock line

18

- sda: Pin to use for I2C data line

19

- frequency: I2C frequency in Hz (default 400000)

20

21

Raises:

22

- NotImplementedError: On Pyboard or Linux platforms

23

"""

24

25

def scan(self) -> list[int]:

26

"""

27

Scan I2C bus for connected devices.

28

29

Returns:

30

List of device addresses found on the bus

31

"""

32

33

def readfrom_into(self, address: int, buffer: bytearray, start: int = 0, end: int = None) -> None:

34

"""

35

Read data from I2C device into existing buffer.

36

37

Parameters:

38

- address: 7-bit I2C device address

39

- buffer: Buffer to read data into

40

- start: Starting index in buffer (default 0)

41

- end: Ending index in buffer (default None for full buffer)

42

"""

43

44

def writeto(self, address: int, buffer: bytes, start: int = 0, end: int = None, stop: bool = True) -> int:

45

"""

46

Write data to I2C device from buffer.

47

48

Parameters:

49

- address: 7-bit I2C device address

50

- buffer: Data to write

51

- start: Starting index in buffer (default 0)

52

- end: Ending index in buffer (default None for full buffer)

53

- stop: Send I2C stop condition (default True)

54

55

Returns:

56

Number of bytes written

57

"""

58

```

59

60

### Software SPI

61

62

Bit-banged SPI implementation using GPIO pins for clock, MOSI, and MISO lines. Provides SPI communication when hardware SPI is unavailable.

63

64

```python { .api }

65

class SPI(Lockable):

66

def __init__(self, clock, MOSI=None, MISO=None):

67

"""

68

Initialize software SPI interface.

69

70

Parameters:

71

- clock: Pin to use for SPI clock

72

- MOSI: Pin to use for Master Out Slave In (optional)

73

- MISO: Pin to use for Master In Slave Out (optional)

74

75

Raises:

76

- NotImplementedError: On Linux platforms

77

"""

78

79

def configure(self, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8) -> None:

80

"""

81

Configure SPI communication parameters.

82

83

Parameters:

84

- baudrate: SPI clock frequency in Hz (default 100000)

85

- polarity: Clock polarity (0 or 1, default 0)

86

- phase: Clock phase (0 or 1, default 0)

87

- bits: Bits per transfer (default 8)

88

89

Raises:

90

- RuntimeError: If try_lock() has not been called

91

"""

92

93

def write(self, buf: bytes) -> None:

94

"""

95

Write data to SPI device.

96

97

Parameters:

98

- buf: Data buffer to write

99

"""

100

101

def readinto(self, buf: bytearray) -> None:

102

"""

103

Read data from SPI device into buffer.

104

105

Parameters:

106

- buf: Buffer to read data into

107

"""

108

109

def write_readinto(self, buffer_out: bytes, buffer_in: bytearray) -> None:

110

"""

111

Simultaneously write and read data over SPI.

112

113

Parameters:

114

- buffer_out: Data to write

115

- buffer_in: Buffer to read data into

116

"""

117

```

118

119

## Usage Examples

120

121

### Software I2C Example

122

123

```python

124

import bitbangio

125

import board

126

127

# Initialize software I2C

128

i2c = bitbangio.I2C(board.SCL, board.SDA, frequency=100000)

129

130

# Scan for devices

131

devices = i2c.scan()

132

print(f"Found devices: {[hex(d) for d in devices]}")

133

134

# Read from device

135

if devices:

136

data = bytearray(4)

137

i2c.readfrom_into(devices[0], data)

138

print(f"Data: {list(data)}")

139

140

i2c.deinit()

141

```

142

143

### Software SPI Example

144

145

```python

146

import bitbangio

147

import board

148

149

# Initialize software SPI

150

spi = bitbangio.SPI(board.SCLK, MOSI=board.MOSI, MISO=board.MISO)

151

152

# Configure SPI parameters

153

if spi.try_lock():

154

try:

155

spi.configure(baudrate=1000000, polarity=0, phase=0)

156

157

# Write data

158

spi.write(b'\x01\x02\x03\x04')

159

160

# Read data

161

buffer = bytearray(4)

162

spi.readinto(buffer)

163

print(f"Read: {list(buffer)}")

164

165

finally:

166

spi.unlock()

167

168

spi.deinit()

169

```

170

171

## Platform Support

172

173

- **MicroPython platforms**: Full support using machine.I2C and machine.SPI

174

- **Linux platforms**: Not supported - use Adafruit_CircuitPython_BitbangIO instead

175

- **Pyboard**: I2C not supported

176

177

## Notes

178

179

- Software implementations are slower than hardware implementations

180

- CPU usage is higher during communication operations

181

- Timing precision depends on platform and system load

182

- On Linux, use the dedicated Adafruit_CircuitPython_BitbangIO library instead