I recently picked up a pico development board and I am really enjoying the versatility of MicroPython. In my current project I am trying interface a RPi4 with a high performance ADC, in particular the ADS131M04. However, the non-maskable interrupts are reaking havoc with communication timings. I am experimenting with placing a microcontroller as a intermediate buffer, and as a Python developer by trait the pico with MicroPython seems as the obvious choice.
The ADC requires a 8.192 MHz clock which I generate using the PIO with the following code (working splendid).
Code: Select all
class ClockGenerator:
def __init__(self, pin: int, frequency: float) -> None:
self.clock_out_StateMachine = rp2.StateMachine(
0,
self.square,
freq=int(frequency * 2),
set_base=Pin(pin)
)
@staticmethod
@asm_pio(set_init=PIO.OUT_LOW)
def square() -> None:
wrap_target()
set(pins, 1)
set(pins, 0)
wrap()
def start(self) -> None:
"""Enable clock output"""
self.clock_out_StateMachine.active(1)
def stop(self) -> None:
"""Disable clock output"""
self.clock_out_StateMachine.active(0)
Code: Select all
def READ_ADC(*_):
cs.value(0)
_ = ADC.read(18)
cs.value(1)
sck = Pin(2, Pin.OUT)
mosi = Pin(3, Pin.OUT)
miso = Pin(4, Pin.IN)
cs = Pin(5, Pin.OUT, value=0)
ADC_READY = Pin(14, Pin.IN)
ADC = SPI(0, baudrate=int(12e6), sck=sck, mosi=mosi, miso=miso, polarity=0, phase=1)
ADC.write(bytes([0x00]*18))
ADC_READY.irq(trigger=Pin.IRQ_FALLING, handler=READ_ADC)
The SPI communication seems to drop at periodic intervals. In the picture below the yellow signal is the ADC_READY signal, green SPI CS and blue SPI SCK. In the beginning it is observed that following each yellow falling edge the data is read with a burst of SPI clocks, why the ready signal returns high, untill next availabe data event. However, at periodic intervals the SPI seems to choke up. The ready signal (yellow) goes low indicating new available measurement data, the IRQ rutine is entered and the SPI CS (green) is held low, but no SPI clocks (blue).
The communication dropout seems to be ongoing for approximately 7.4 ms, as seen in the picture below. By the end multiple SPI SCK bursts seems to be issued faster than normal in an attempt to "catch up", before resuming normal operation. This is of course futile as the ADC have a one-deep output buffer.
This phenomenon seems to be periodic happening approximately every second.
I have been trying to fiddle with this for a couple of days but I am at a loss.
Hoping anyone out there can help me figure this out.
Best regards
Jakob W. Funding