Skip to content

Commit 90e2ed5

Browse files
committed
Round trip working.
This is a complete round trip. At least... for pinMode and digitalWrite. However, I'm now sending a command and getting the correct response. Wrote: ['0xe0', '0x51', '0x2', '0x1', '0xd', '0x1', '0x0', '0xee'] Read: 0xe0 Read: 0xd1 Read: 0x1 Read: 0x1 Parameter #0 length is 1 Read: ['0x1'] Read: 0xee Read 1: [bytearray(b'\x01')] Sending param #0 is 1 bytes long Sending param adafruit#1 is 1 bytes long
1 parent 01d5980 commit 90e2ed5

File tree

1 file changed

+91
-60
lines changed

1 file changed

+91
-60
lines changed

adafruit_esp32i2c/adafruit_esp32.py

Lines changed: 91 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -169,24 +169,38 @@ def _setup_pins(self):
169169
self._cs.direction = Direction.OUTPUT
170170
self._ready.direction = Direction.INPUT
171171
self._spi_device = SPIDevice(spi, cs_pin, baudrate=8000000)
172+
173+
# FIXME
174+
# These can be abstracted further. The Adafruit bus
175+
# devices both have write() and readinto() methods.
172176
def send_buffer(self, buffer, start, end):
173-
spi.write(buffer, start=start, end=end) # pylint: disable=no-member
177+
# FIXME:
178+
# SPI needs to be fixed/reassembled. Currently untested.
179+
with self._spi_device as spi:
180+
spi.write(buffer, start=start, end=end) # pylint: disable=no-member
174181

182+
def readinto(self, buff, start=0, end=1):
183+
with self._spi_device as spi:
184+
spi.readinto(buff)
185+
175186
class I2C(Protocol):
176187
def _setup_pins(self):
177188
if self._debug > 3:
178189
print("I2C Calling super._setup_pins()")
179190
super()._setup_pins()
180-
self._addr = self._params['address']
181-
self._scl = self._params['SCL']
182-
self._sda = self._params['SDA']
183-
self._i2c = busio.I2C(self._scl, self._sda)
184-
self._device = I2CDevice(self._i2c, self._addr)
191+
self._addr = self._params['address']
192+
self._scl = self._params['SCL']
193+
self._sda = self._params['SDA']
194+
self._i2c = busio.I2C(self._scl, self._sda)
195+
self._device = I2CDevice(self._i2c, self._addr)
185196

186197
def send_buffer(self, buffer, start, end):
187-
with self._device:
188-
self._device.write(buffer, start=start, end=end, stop=True)
189-
198+
with self._device as device:
199+
device.write(buffer, start=start, end=end, stop=True)
200+
201+
def readinto(self, buff, start=0, end=1):
202+
with self._device as device:
203+
device.readinto(buff, start=start, end=end)
190204

191205
class ESP_Control: # pylint: disable=too-many-public-methods
192206
"""A class that will talk to an ESP32 module programmed with special firmware
@@ -209,7 +223,6 @@ def __init__(self, proto):
209223
self._ready = proto._ready
210224
self._reset = proto._reset
211225
self._gpio0 = proto._gpio0
212-
213226
# pylint: enable=too-many-arguments
214227

215228
def reset(self):
@@ -229,6 +242,10 @@ def reset(self):
229242

230243
def _wait_for_ready(self):
231244
"""Wait until the ready pin goes low"""
245+
# FIXME HACK
246+
time.sleep(0.05)
247+
return True
248+
232249
if self._debug >= 3:
233250
print("Wait for ESP32 ready", end='')
234251
times = time.monotonic()
@@ -282,85 +299,97 @@ def _send_command(self, cmd, params=None, *, param_len_16=False):
282299

283300
# FIXME mcj
284301
# Add the wait_for_ready back in.
285-
# self._wait_for_ready()
286-
# with self._spi_device as spi:
287-
# with self._device:
288-
times = time.monotonic()
289-
while (time.monotonic() - times) < 1: # wait up to 1000ms
290-
if 1: # FIXME self._ready.value: # ok ready to send!
291-
break
292-
else:
293-
raise RuntimeError("ESP32 timed out on SPI select")
294-
# spi.write(self._sendbuf, start=0, end=packet_len) # pylint: disable=no-member
295-
# self._device.write(self._sendbuf, start = 0, end = packet_len, stop = True)
302+
self._wait_for_ready()
303+
304+
# 20140714 MCJ
305+
# It is unclear why a _wait_for_ready() happens, followed by
306+
# a re-implementation of _wait_for_ready(). I know it says
307+
# that we're waiting for a SPI select... but, we just waited
308+
# for the ready pin to drop. Nothing changes between that call
309+
# and this block of code. I'm removing it for now.
310+
311+
# times = time.monotonic()
312+
# while (time.monotonic() - times) < 1: # wait up to 1000ms
313+
# if 1: # FIXME self._ready.value: # ok ready to send!
314+
# break
315+
# else:
316+
# raise RuntimeError("ESP32 timed out on SPI select")
317+
296318
self._proto.send_buffer(self._sendbuf, start=0, end=packet_len)
297319

298320
if self._debug >= 3:
299321
print("Wrote: ", [hex(b) for b in self._sendbuf[0:packet_len]])
300322
# pylint: disable=too-many-branches
301323

302-
def _read_byte(self, spi):
303-
"""Read one byte from SPI"""
304-
spi.readinto(self._pbuf)
324+
def _read_byte(self):
325+
"""Read one byte from the protocol."""
326+
self._proto.readinto(self._pbuf)
305327
if self._debug >= 3:
306328
print("\t\tRead:", hex(self._pbuf[0]))
307329
return self._pbuf[0]
308-
309-
def _read_bytes(self, spi, buffer, start=0, end=None):
330+
331+
# 20190714 MCJ
332+
# Removed the protocol from the formal parameters.
333+
# Now carried as _proto in the class.
334+
def _read_bytes(self, buffer, start=0, end=None):
310335
"""Read many bytes from SPI"""
311336
if not end:
312337
end = len(buffer)
313-
spi.readinto(buffer, start=start, end=end)
338+
self._proto.readinto(buffer, start=start, end=end)
314339
if self._debug >= 3:
315340
print("\t\tRead:", [hex(i) for i in buffer])
316341

317-
def _wait_spi_char(self, spi, desired):
342+
# 20190714 MCJ
343+
# Was _wait_spi_char. Removed the proto from the formals.
344+
# Now abstracted over the protocol.
345+
def _wait_char(self, desired):
318346
"""Read a byte with a time-out, and if we get it, check that its what we expect"""
319347
times = time.monotonic()
320348
while (time.monotonic() - times) < 0.1:
321-
r = self._read_byte(spi)
349+
r = self._read_byte()
322350
if r == _ERR_CMD:
323351
raise RuntimeError("Error response to command")
324352
if r == desired:
325353
return True
326-
raise RuntimeError("Timed out waiting for SPI char")
354+
raise RuntimeError("Timed out waiting for char")
327355

328-
def _check_data(self, spi, desired):
356+
def _check_data(self, desired):
329357
"""Read a byte and verify its the value we want"""
330-
r = self._read_byte(spi)
358+
r = self._read_byte()
331359
if r != desired:
332360
raise RuntimeError("Expected %02X but got %02X" % (desired, r))
333361

334362
def _wait_response_cmd(self, cmd, num_responses=None, *, param_len_16=False):
335363
"""Wait for ready, then parse the response"""
336364
self._wait_for_ready()
337-
338365
responses = []
339-
with self._spi_device as spi:
340-
times = time.monotonic()
341-
while (time.monotonic() - times) < 1: # wait up to 1000ms
342-
if self._ready.value: # ok ready to send!
343-
break
344-
else:
345-
raise RuntimeError("ESP32 timed out on SPI select")
346-
347-
self._wait_spi_char(spi, _START_CMD)
348-
self._check_data(spi, cmd | _REPLY_FLAG)
349-
if num_responses is not None:
350-
self._check_data(spi, num_responses)
351-
else:
352-
num_responses = self._read_byte(spi)
353-
for num in range(num_responses):
354-
param_len = self._read_byte(spi)
355-
if param_len_16:
356-
param_len <<= 8
357-
param_len |= self._read_byte(spi)
358-
if self._debug >= 2:
359-
print("\tParameter #%d length is %d" % (num, param_len))
360-
response = bytearray(param_len)
361-
self._read_bytes(spi, response)
362-
responses.append(response)
363-
self._check_data(spi, _END_CMD)
366+
367+
# 20190714 MCJ
368+
# This is redundant with the _wait_for_ready() call above.
369+
# times = time.monotonic()
370+
# while (time.monotonic() - times) < 1: # wait up to 1000ms
371+
# if self._ready.value: # ok ready to send!
372+
# break
373+
# else:
374+
# raise RuntimeError("ESP32 timed out on SPI select")
375+
376+
self._wait_char(_START_CMD)
377+
self._check_data(cmd | _REPLY_FLAG)
378+
if num_responses is not None:
379+
self._check_data(num_responses)
380+
else:
381+
num_responses = self._read_byte()
382+
for num in range(num_responses):
383+
param_len = self._read_byte()
384+
if param_len_16:
385+
param_len <<= 8
386+
param_len |= self._read_byte()
387+
if self._debug >= 2:
388+
print("\tParameter #%d length is %d" % (num, param_len))
389+
response = bytearray(param_len)
390+
self._read_bytes(response)
391+
responses.append(response)
392+
self._check_data(_END_CMD)
364393

365394
if self._debug >= 2:
366395
print("Read %d: " % len(responses[0]), responses)
@@ -369,12 +398,14 @@ def _wait_response_cmd(self, cmd, num_responses=None, *, param_len_16=False):
369398
def _send_command_get_response(self, cmd, params=None, *,
370399
reply_params=1, sent_param_len_16=False,
371400
recv_param_len_16=False):
372-
"""Send a high level SPI command, wait and return the response"""
401+
"""Send a high level command, wait and return the response"""
373402
self._send_command(cmd, params, param_len_16=sent_param_len_16)
374403
# FIXME mcj
375404
# Need to implement response.
376405
# Looks like I need a one, doubly nested, to fool the functions.
377-
return [[1]] # self._wait_response_cmd(cmd, reply_params, param_len_16=recv_param_len_16)
406+
# Original return value:
407+
return self._wait_response_cmd(cmd, reply_params, param_len_16=recv_param_len_16)
408+
378409

379410
@property
380411
def status(self):

0 commit comments

Comments
 (0)