I am essentially brand new to MicroPython and am hoping to get some feedback on how to best implement a register interface.
I took a first pass attempt using bit-fields in ctypes. Here is some sample code for the ADC registers on the RPI Pico:
Code: Select all
import ctypes
from machine import mem32
ADC_BASE = 0x4004c000
# Struct layout for the ADC on the RP2040 IC
ADC_BITS = {
"CS": (0x00,{
"EN": 0 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"TS_EN": 1 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"START_ONCE": 2 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"START_MANY": 3 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"READY": 8 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"ERR": 9 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"ERR_STICKY": 10 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"AINSEL": 12 << ctypes.BF_POS | 3 << ctypes.BF_LEN | ctypes.BFUINT32,
"RROBIN": 16 << ctypes.BF_POS | 5 << ctypes.BF_LEN | ctypes.BFUINT32,
}),
"RESULT": (0x04,{ "VAL" : 12 << ctypes.BF_LEN | ctypes.BFUINT32, }),
"FCS": (0x08,{
"EN": 0 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"SHIFT": 1 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"ERR": 2 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"DREQ_EN": 3 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"EMPTY": 8 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"FULL": 9 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"UNDER": 10 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"OVER": 11 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
"LEVEL": 16 << ctypes.BF_POS | 4 << ctypes.BF_LEN | ctypes.BFUINT32,
"THRESH": 24 << ctypes.BF_POS | 4 << ctypes.BF_LEN | ctypes.BFUINT32,
}),
"FIFO": (0x0C,{
"VAL": 0 << ctypes.BF_POS | 12 << ctypes.BF_LEN | ctypes.BFUINT32,
"ERR": 15 << ctypes.BF_POS | 1 << ctypes.BF_LEN | ctypes.BFUINT32,
}),
"DIV": (0x10,{
"FRAC": 0 << ctypes.BF_POS | 8 << ctypes.BF_LEN | ctypes.BFUINT32,
"INT": 8 << ctypes.BF_POS | 16 << ctypes.BF_LEN | ctypes.BFUINT32,
}),
}
ADC = ctypes.struct(ADC_BASE,ADC_BITS)
# Some basic bit field settings
print('Set ADC DIV Reg to 0')
ADC.DIV.INT = 0
ADC.DIV.FRAC = 0
print("ADC DIV REG: 0x{:08X}".format(mem32[ADC_BASE+0x10]))
print('The fraction bit field is bits 0:7')
print('Set DIV.FRAC to 0x35')
ADC.DIV.FRAC = 0x35
print("ADC DIV REG: 0x{:08X}".format(mem32[ADC_BASE+0x10]))
print('The integer bit field is bits 8:23')
print('Set DIV.INT to 0x4321')
ADC.DIV.INT = 0x4321
print("ADC DIV REG: 0x{:08X}".format(mem32[ADC_BASE+0x10]))
I don't know if I am doing something wrong or if this is the expected behavior, but I get an error trying to dir(ADC)
I suppose because there is no dir function for the struct the autocomplete fails in Thonny?>>> type(ADC)
<class 'struct'>
>>> print(ADC)
<struct STRUCT 4004c000>
>>> dir(ADC)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: __dir__
>>>
Thank you for your help>>> ADC.**press tab**
NB! Thonny could not execute 'shell_autocomplete'.
SCRIPT:
__thonny_helper.print_mgmt_value(dir(ADC) if 'ADC' in locals() or 'ADC' in globals() else [])
STDOUT:
STDERR:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: __dir__
You may need to reconnect, Stop/Restart or hard-reset your device.