#!/usr/bin/env python3 from machine import ADC from array import array from time import ticks_us, ticks_diff import micropython class FastADC: # _ADC_BASE = const(0x4004c000) # rp2040 _ADC_BASE = const(0x400a0000) # rp2350 _ADC_CS = const(0x00 >> 2) _ADC_FCS = const(0x08 >> 2) _ADC_FIFO = const(0x0c >> 2) def __init__(self, adc_pin): self.adc = ADC(adc_pin) @micropython.viper def adc_on(self): ADC: ptr32 = ptr32(_ADC_BASE) #ADC[FastADC._ADC_FCS] = (1<<0) # EN write result to the FIFO after each conversion. ADC[_ADC_FCS] = (1<<0) ADC[_ADC_CS] = ( (1<<3) # START_MANY Continuously perform conversions. | (1<<0) ) # EN Power on ADC and enable its clock. @micropython.viper def adc_off(self): ADC: ptr32 = ptr32(_ADC_BASE) ADC[_ADC_FCS] = 0 ADC[_ADC_CS] = 0 @micropython.viper def get_samples(self, values: ptr16, length: int): FIFOEMPTY: int = (1<<8) # prepare mask ADC: ptr32 = ptr32(_ADC_BASE) self.adc_on() index: int = 0 start: int = ticks_us() while (ADC[_ADC_FCS] & FIFOEMPTY) == 0: ADC[_ADC_FIFO] while index < length: while ADC[_ADC_FCS] & FIFOEMPTY: pass values[index] = ADC[_ADC_FIFO] index += 1 stop: int = ticks_us() self.adc_off() samplingTime_us=float(ticks_diff(stop, start)) / float(length) return values,samplingTime_us @staticmethod def show_results(dt): print(f'sampling time: {dt:10} µs') print(f'sampling frequency: {1e6/dt:10} Hz') # Usage example: if __name__ == "__main__": fast_adc = FastADC(0) # Initialize with ADC pin 0 length = 1000 values = array('H', (0 for _ in range(length))) for n in range(0,10): values,dt = fast_adc.get_samples(values, length) FastADC.show_results(dt)