Skip to content

Hardware crash involving sdcardio and analogbufio #8020

@gpeyton

Description

@gpeyton

CircuitPython version

Adafruit CircuitPython 8.1.0-alpha.2-132-g3ab9920927

Running on ESP32-S2 (custom board).

Code/REPL

import board
import analogbufio
import array
import supervisor
import gc
import busio
import sdcardio, storage, os
from digitalio import DigitalInOut, Direction, Pull, DriveMode

# Mount file system
sd_spi = busio.SPI(clock=board.SCLK, MOSI=board.SD_DIN, MISO=board.SD_DOUT)
sdcard = sdcardio.SDCard(sd_spi, cs=board.CS)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")

SAMPLE_RATE = const(20000)
CAPTURE_TIME_SECONDS = const(4)
ADC_PIN = board.MIC_OUT
SAMPLE_SIZE_IN_BYTES = 2

MAX_ADC_RANGE = 65535

_TICKS_PERIOD = const(1<<29)
_TICKS_MAX = const(_TICKS_PERIOD-1)
_TICKS_HALFPERIOD = const(_TICKS_PERIOD//2)

# Setup audio pins
aud_en = DigitalInOut(board.AUD_PWR)
aud_en.direction = Direction.OUTPUT
aud_en.value = True
mic_en = DigitalInOut(board.MIC_PWR)
mic_en.direction = Direction.OUTPUT
mic_en.value = True

i2s_bclk = board.MAX_BCLK
i2s_lrc = board.MAX_LRCLK
i2s_data = board.MAX_DIN

def ticks_diff(ticks1, ticks2):
    "Compute the signed difference between two ticks values, assuming that they are within 2**28 ticks"
    diff = (ticks1 - ticks2) & _TICKS_MAX
    diff = ((diff + _TICKS_HALFPERIOD) & _TICKS_MAX) - _TICKS_HALFPERIOD
    return diff

def ram_available(sample_rate, capture_time_seconds, sample_size_in_bytes):
    ram_required = sample_rate*capture_time_seconds*sample_size_in_bytes
    gc.collect()
    ram_available = gc.mem_free()
    return (ram_required < ram_available)

def collect_samples(adc_pin, sample_rate, capture_time_seconds, sample_size_in_bytes):
    try:
        numSamples = sample_rate*capture_time_seconds
        print("Reading",numSamples,"samples from",adc_pin,"pin")
        mybuffer = array.array('H', [0]) * numSamples
        adcbuf = analogbufio.BufferedIn(adc_pin, sample_rate=sample_rate)
        start_time = supervisor.ticks_ms()
        numCapturedSamples = adcbuf.readinto(mybuffer)
        end_time = supervisor.ticks_ms()
        adcbuf.deinit()
        if(numCapturedSamples == numSamples):
            timetaken = ticks_diff(end_time,start_time)
            print("Number of samples read:",numCapturedSamples)
            print("Time required",timetaken,"ms")
            print("Desired sampling rate:",sample_rate,"/s")
            print("Computed sampling rate:",(numCapturedSamples*1000)/timetaken,"/s")
        else:
            print("Unable to capture all samples")
        return mybuffer
    except (ValueError, RuntimeError) as e:
        print("Exception", e)

def main():
    print("\n=================")
    if ram_available(SAMPLE_RATE,CAPTURE_TIME_SECONDS,SAMPLE_SIZE_IN_BYTES):
        print("recording audio")
        buffer = collect_samples(ADC_PIN,SAMPLE_RATE,CAPTURE_TIME_SECONDS,SAMPLE_SIZE_IN_BYTES)
    else:
        print("Not enough RAM available to collect required samples")
    print("playing audio recording")

main()

Behavior

Mounting causes an instant hardware crash. Note that the SD card works in all other situations (i.e. when not using adcbuf.readinto(mybuffer)), so sdcardio is not the root cause.

Commenting out the "mount file system" code causes the code to run fine. Likewise, commenting all analogbufio code allows SD to mount successfully. So combining them breaks something.

Description

I have also tried unmounting and deinit the drive, but issue persists

####################################################### 
# SD CARD
####################################################### 
sd_spi = busio.SPI(clock=board.SCLK, MOSI=board.SD_DIN, MISO=board.SD_DOUT)
sdcard = sdcardio.SDCard(sd_spi, cs=board.CS)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
storage.umount(vfs)
sdcard.deinit()

Additional information

Pinouts are:

{ MP_ROM_QSTR(MP_QSTR_MIC_OUT), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_SD_DOUT), MP_ROM_PTR(&pin_GPIO15) },
{ MP_ROM_QSTR(MP_QSTR_SCLK), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_SD_DIN), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO18) },

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions