Skip to content

Commit 4513cf8

Browse files
Merge pull request #22 from sparkfun/feature/add_no_addr_reads
Feature/add no addr reads
2 parents 4b62c38 + b691b2c commit 4513cf8

File tree

4 files changed

+112
-14
lines changed

4 files changed

+112
-14
lines changed

qwiic_i2c/circuitpy_i2c.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ def readWord(self, address, commandCode):
162162
buffer = bytearray(2)
163163

164164
try:
165-
self._i2cbus.writeto_then_readfrom(address, bytes([commandCode]), buffer)
165+
if (commandCode == None):
166+
self._i2cbus.readfrom_into(address, buffer)
167+
else:
168+
self._i2cbus.writeto_then_readfrom(address, bytes([commandCode]), buffer)
166169
except Exception as e:
167170
self._i2cbus.unlock()
168171
raise e
@@ -176,14 +179,17 @@ def read_word(self, address, commandCode):
176179
return self.readWord(address, commandCode)
177180

178181
#----------------------------------------------------------
179-
def readByte(self, address, commandCode):
182+
def readByte(self, address, commandCode = None):
180183
if not self._i2cbus.try_lock():
181184
raise Exception("Unable to lock I2C bus")
182185

183186
buffer = bytearray(1)
184187

185188
try:
186-
self._i2cbus.writeto_then_readfrom(address, bytes([commandCode]), buffer)
189+
if (commandCode == None):
190+
self._i2cbus.readfrom_into(address, buffer)
191+
else:
192+
self._i2cbus.writeto_then_readfrom(address, bytes([commandCode]), buffer)
187193
except Exception as e:
188194
self._i2cbus.unlock()
189195
raise e
@@ -203,7 +209,10 @@ def readBlock(self, address, commandCode, nBytes):
203209
buffer = bytearray(nBytes)
204210

205211
try:
206-
self._i2cbus.writeto_then_readfrom(address, bytes([commandCode]), buffer)
212+
if (commandCode == None):
213+
self._i2cbus.readfrom_into(address, buffer)
214+
else:
215+
self._i2cbus.writeto_then_readfrom(address, bytes([commandCode]), buffer)
207216
except Exception as e:
208217
self._i2cbus.unlock()
209218
raise e
@@ -290,6 +299,26 @@ def writeBlock(self, address, commandCode, value):
290299
def write_block(self, address, commandCode, value):
291300
return self.writeBlock(address, commandCode, value)
292301

302+
def writeReadBlock(self, address, writeBytes, readNBytes):
303+
read_buffer = bytearray(readNBytes)
304+
305+
if not self._i2cbus.try_lock():
306+
raise Exception("Unable to lock I2C bus")
307+
308+
try:
309+
self._i2cbus.writeto_then_readfrom(address, bytes(writeBytes), read_buffer)
310+
except Exception as e:
311+
self._i2cbus.unlock()
312+
raise e
313+
else:
314+
self._i2cbus.unlock()
315+
316+
return list(read_buffer)
317+
318+
319+
def write_read_block(self, address, writeBytes, readNBytes):
320+
return self.writeReadBlock(address, writeBytes, readNBytes)
321+
293322
def isDeviceConnected(self, devAddress):
294323
if not self._i2cbus.try_lock():
295324
raise Exception("Unable to lock I2C bus")
@@ -332,3 +361,4 @@ def scan(self):
332361
self._i2cbus.unlock()
333362

334363
return devices
364+

qwiic_i2c/i2c_driver.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def readWord(self, address, commandCode):
126126
Called to read a word (16 bits) from a specific device.
127127
128128
:param address: The I2C address of the device to read from
129-
:param commandCode: The "command" or register to read from
129+
:param commandCode: The "command" or register to read from, or `None` for no command
130130
131131
:return: Returns the read data
132132
:rtype: integer - first 16 bits contain the read data.
@@ -139,7 +139,7 @@ def read_word(self, address, commandCode):
139139
Called to read a word (16 bits) from a specific device.
140140
141141
:param address: The I2C address of the device to read from
142-
:param commandCode: The "command" or register to read from
142+
:param commandCode: The "command" or register to read from, or `None` for no command
143143
144144
:return: Returns the read data
145145
:rtype: integer - first 16 bits contain the read data.
@@ -152,7 +152,7 @@ def readByte(self, address, commandCode):
152152
Called to read a byte (8 bits) from a specific device.
153153
154154
:param address: The I2C address of the device to read from
155-
:param commandCode: The "command" or register to read from
155+
:param commandCode: The "command" or register to read from, or `None` for no command
156156
157157
:return: Returns the read data
158158
:rtype: integer - first 8 bits contain the read data.
@@ -165,7 +165,7 @@ def read_byte(self, address, commandCode):
165165
Called to read a byte (8 bits) from a specific device.
166166
167167
:param address: The I2C address of the device to read from
168-
:param commandCode: The "command" or register to read from
168+
:param commandCode: The "command" or register to read from, or `None` for no command
169169
170170
:return: Returns the read data
171171
:rtype: integer - first 8 bits contain the read data.
@@ -178,7 +178,7 @@ def readBlock(self, address, commandCode, nBytes):
178178
Called to read a block of bytesfrom a specific device.
179179
180180
:param address: The I2C address of the device to read from
181-
:param commandCode: The "command" or register to read from
181+
:param commandCode: The "command" or register to read from, or `None` for no command
182182
:param nBytes: The number of bytes to read from the device
183183
184184
:return: Returns the read data as a list of integers.
@@ -192,7 +192,7 @@ def read_block(self, address, commandCode, nBytes):
192192
Called to read a block of bytesfrom a specific device.
193193
194194
:param address: The I2C address of the device to read from
195-
:param commandCode: The "command" or register to read from
195+
:param commandCode: The "command" or register to read from, or `None` for no command
196196
:param nBytes: The number of bytes to read from the device
197197
198198
:return: Returns the read data as a list of integers.
@@ -312,6 +312,35 @@ def write_block(self, address, commandCode, value):
312312
313313
"""
314314
return None
315+
316+
def writeReadBlock(self, address, writeBytes, readNBytes):
317+
"""
318+
Called to write a block of bytes to a device, send no stop bit, and then read a block of bytes.
319+
320+
:param address: The I2C address of the device to read from
321+
:param writeBytes: A list of bytes (ints) to write on the I2C bus.
322+
:param readNBytes: The number of bytes to read from the device
323+
324+
:return: A list of bytes read from the device.
325+
:rtype: list
326+
327+
"""
328+
return None
329+
330+
def write_read_block(self, address, writeBytes, readNBytes):
331+
"""
332+
Called to write a block of bytes to a device, send no stop bit, and then read a block of bytes.
333+
334+
:param address: The I2C address of the device to read from
335+
:param writeBytes: A list of bytes (ints) to write on the I2C bus.
336+
:param readNBytes: The number of bytes to read from the device
337+
338+
:return: A list of bytes read from the device.
339+
:rtype: list
340+
341+
"""
342+
return None
343+
315344

316345
def isDeviceConnected(self, devAddress):
317346
"""

qwiic_i2c/linux_i2c.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,26 @@ def __setattr__(self, name, value):
151151
#-------------------------------------------------------------------------
152152
# read Data Command
153153

154+
# Performs a general read of <nBytes> from the device at <address> without a command/register code
155+
# Linux doesn't support this directly like CircuitPython and MicroPython, so we have to read byte by byte
156+
def _read_no_command(self, address, nBytes):
157+
data = [0] * nBytes
158+
for i in range(nBytes):
159+
data = self._i2cbus.read_byte(address)
160+
data[i] = data
161+
return data
162+
154163
def readWord(self, address, commandCode):
155164

156165
data = 0
157166

158167
# add some error handling and recovery....
159168
for i in range(_retry_count):
160169
try:
161-
data = self._i2cbus.read_word_data(address, commandCode)
170+
if commandCode == None:
171+
data = self._read_no_command(address, 2) # TODO: Check this, we may need to switch endianess
172+
else:
173+
data = self._i2cbus.read_word_data(address, commandCode)
162174

163175
break # break if try succeeds
164176

@@ -199,7 +211,10 @@ def readBlock(self, address, commandCode, nBytes):
199211
data = 0
200212
for i in range(_retry_count):
201213
try:
202-
data = self._i2cbus.read_i2c_block_data(address, commandCode, nBytes)
214+
if commandCode == None:
215+
data = self._read_no_command(address, nBytes)
216+
else:
217+
data = self._i2cbus.read_i2c_block_data(address, commandCode, nBytes)
203218

204219
break # break if try succeeds
205220

@@ -253,6 +268,12 @@ def writeBlock(self, address, commandCode, value):
253268
def write_block(self, address, commandCode, value):
254269
return self.writeBlock(address, commandCode, value)
255270

271+
def writeReadBlock(self, address, writeBytes, readNBytes):
272+
return self.__i2c_rdwr__(address, writeBytes, readNBytes)
273+
274+
def write_read_block(self, address, writeBytes, readNBytes):
275+
return self.writeReadBlock(address, writeBytes, readNBytes)
276+
256277
def isDeviceConnected(self, devAddress):
257278
isConnected = False
258279
try:

qwiic_i2c/micropython_i2c.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,29 @@ def __setattr__(self, name, value):
117117

118118
# read commands ----------------------------------------------------------
119119
def readWord(self, address, commandCode):
120-
buffer = self._i2cbus.readfrom_mem(address, commandCode, 2)
120+
if (commandCode == None):
121+
buffer = self._i2cbus.readfrom(address, 2)
122+
else:
123+
buffer = self._i2cbus.readfrom_mem(address, commandCode, 2)
124+
121125
return (buffer[1] << 8 ) | buffer[0]
122126

123127
def read_word(self, address, commandCode):
124128
return self.readWord(address, commandCode)
125129

126-
def readByte(self, address, commandCode):
130+
def readByte(self, address, commandCode = None):
131+
if (commandCode == None):
132+
return self._i2cbus.readfrom(address, 1)[0]
133+
127134
return self._i2cbus.readfrom_mem(address, commandCode, 1)[0]
128135

129136
def read_byte(self, address, commandCode = None):
130137
return self.readByte(address, commandCode)
131138

132139
def readBlock(self, address, commandCode, nBytes):
140+
if (commandCode == None):
141+
return self._i2cbus.readfrom(address, nBytes)
142+
133143
return self._i2cbus.readfrom_mem(address, commandCode, nBytes)
134144

135145
def read_block(self, address, commandCode, nBytes):
@@ -160,6 +170,14 @@ def writeBlock(self, address, commandCode, value):
160170
def write_block(self, address, commandCode, value):
161171
return self.writeBlock(address, commandCode, value)
162172

173+
def writeReadBlock(self, address, writeBytes, readNBytes):
174+
# micropython I2C doesn't have a corresponding "i2c_rdwr" function like smbus2, so we will make our own by passing stop=False to not send stop bits between repeated transfers
175+
self._i2cbus.writeto(address, bytes(writeBytes), False)
176+
return self._i2cbus.readfrom(address, readNBytes)
177+
178+
def write_read_block(self, address, writeBytes, readNBytes):
179+
return self.writeReadBlock(address, writeBytes, readNBytes)
180+
163181
def isDeviceConnected(self, devAddress):
164182
isConnected = False
165183
try:

0 commit comments

Comments
 (0)