Closed kattni closed 1 year ago
@ladyada FYI.
what if you use board.SPI()?
I tried board.SPI()
as well yesterday, and still ended in safe mode. I verified again today that the following results in the same safe mode reason.
import digitalio
import board
import adafruit_sdcard
cs = digitalio.DigitalInOut(board.SD_CS)
sdcard = adafruit_sdcard.SDCard(board.SPI(), cs)
I tried running an I2S pin identifying script and ended up in the same safe mode. Running the I2S tone demo does not result in safe mode. I can get the pin script to print 8.5 lines of pin combinations before it resets into safe mode.
I don't know enough about what's going on here to know if it's related, but I'm including it here anyway.
Script below.
import board
import audiobusio
from microcontroller import Pin
def is_hardware_i2s(bit_clock, word_select, data):
try:
p = audiobusio.I2SOut(bit_clock, word_select, data)
p.deinit()
return True
except ValueError:
return False
def get_unique_pins():
exclude = [
getattr(board, p)
for p in [
# This is not an exhaustive list of unexposed pins. Your results
# may include other pins that you cannot easily connect to.
"NEOPIXEL",
"DOTSTAR_CLOCK",
"DOTSTAR_DATA",
"APA102_SCK",
"APA102_MOSI",
"LED",
"SWITCH",
"BUTTON",
]
if p in dir(board)
]
pins = [
pin
for pin in [getattr(board, p) for p in dir(board)]
if isinstance(pin, Pin) and pin not in exclude
]
unique = []
for p in pins:
if p not in unique:
unique.append(p)
return unique
for bit_clock_pin in get_unique_pins():
for word_select_pin in get_unique_pins():
for data_pin in get_unique_pins():
if bit_clock_pin is word_select_pin or bit_clock_pin is data_pin or word_select_pin \
is data_pin:
continue
if is_hardware_i2s(bit_clock_pin, word_select_pin, data_pin):
print("Bit clock pin:", bit_clock_pin, "\t Word select pin:", word_select_pin,
"\t Data pin:", data_pin)
else:
pass
[synthesizing @tannewt's remarks in the meeting as well as some info from the internal meeting]
The 8MB PSRAM uses additional pins because it supports "octal mode", in which 8 bits are transmitted every clock cycle. CircuitPython doesn't correctly protect these pins, which causes the "pin in use check" not to work.
If the check did work, it would not be possible to construct an SPI object using the pre-defined SPI pins because they overlap with the pins used by the PSRAM. (you'd get a "pin in use" exception). We're checking whether it's possible to work around this by using the flash in quad mode rather than octal mode, so making it possible to use the SD card but this slows down RAM access.
As it is, the code switches the pin over to being GPIO, which stops SPI RAM from working anymore. This leads to the watchdog timeout, because CircuitPython stops working properly.
The board has been pulled from the store for the time being, and is likely to undergo a revision before more are sold, so that the Octal mode can be used, by choosing different SD card pins. So if you have one, it's now become a collector's item :) Because the new revision would have a change in the pinout it'd probably become a separate CircuitPython board definition.
What's interesting is how this passed the factory test, which covers all GPIO pins and also the SPI RAM chip: The tester program sets up the SPI RAM first, checks that it works, then does the GPIO checks. But after the GPIO checks it never uses SPI RAM again, so there's no misbehavior noted.
CircuitPython version
Code/REPL
Behavior
On save, the board immediately reboots into safe mode. The code above is the minimal necessary to guarantee safe mode. Safe mode occurs if the code is saved in
code.py
or run from the REPL.Description
No response
Additional information
This is the original demo: