Code: Select all
"""This module creates an abstraction for an ADC sampling program
running concurrently on the ESP32 ULP coprocessor"""
from esp32 import ULP
from machine import mem32, ADC, Pin
from esp32_ulp.__main__ import src_to_binary
class ULP_ADC:
SOURCE = """\
data: .long 0
entry: move r3, data # load data address into r3
adc r2, 0, 4 # measure voltage with ADC1 pad 3 and store result in r2
st r2, r3, 0 # store r2 in data [r3 + 0]
halt # halt ULP co-processor until woken up again
"""
ULP_MEM_BASE = 0x50000000
ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits
LOAD_ADDR = 0
ENTRY_ADDR = 4
def __init__(self, gpio):
self.binary = src_to_binary(ULP_ADC.SOURCE)
# we only use this object to configure the ADC.
# we don't actually need it for sampling
self.ulp = ULP()
self.gpio = gpio
def start(self, wakeup_period_cyc, atten, width):
self.ulp.set_wakeup_period(0, wakeup_period_cyc) # use timer 0
self.ulp.load_binary(ULP_ADC.LOAD_ADDR, self.binary)
mem32[ULP_ADC.ULP_MEM_BASE + ULP_ADC.LOAD_ADDR] = 0x1000
self.ulp.run(ULP_ADC.ENTRY_ADDR)
self.adc = ADC(Pin(self.gpio))
self.adc.atten(atten)
self.adc.width(width)
def get_reading(self):
return mem32[ULP_ADC.ULP_MEM_BASE + ULP_ADC.LOAD_ADDR] & ULP_ADC.ULP_DATA_MASK
I know a small amount about the ESP32 low level operations, but I'm starting to get lost trying to solve this problem. I would appreciate a second set of eyes to point out obvious mistake, or someone who know the granularity of working with the ESP32. I'm also curious if there is a way to call the ad1_ulp_enable() function.