Created
May 23, 2024 23:53
-
-
Save mattytrentini/689dd83810a58e78170382fc754fc54d to your computer and use it in GitHub Desktop.
Example MicroPython code to interact with an AD5592r chip
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The microcontroller used was a SeeedStudio XIAO RP2040. | |
# Modify `spi` and `cs` appropriately to work on any other micro. | |
from machine import Pin, SPI | |
spi = SPI(0, baudrate=20_000_000) # Initialise SPI at 20MHz. Note that on RP2040 due to clock configurations this is closer to 15MHz. | |
cs = Pin.board.CSn | |
cs.init(Pin.OUT, value=1) # Initialise CS high, ie no transmission | |
def send(spi, cs, reg): | |
""" Send reg as two-byte data """ | |
buf = bytearray(2) | |
buf[0] = (reg & 0xff00) >> 8 | |
buf[1] = reg & 0x00ff | |
cs.off() | |
spi.write(buf) | |
cs.on() | |
def get_register(spi, cs, reg): | |
""" Send a CONFIG_READ_AND_LDAC with the appropriate register details, read back the value of the register. """ | |
buf = bytearray(2) | |
regdata = bytearray(2) | |
# 0b0_0111_0000_1_1000_00 # Retrieve GPIO register | |
buf[0] = 0b0_0111_000 # Read, Read register, Reserved | |
buf[1] = 0b0_1_0000_00 # Reserved continued, Read enabled, register, LDAC | |
buf[1] |= (reg & 0xf) << 2 | |
cs.off() | |
spi.write(buf) | |
cs.on() | |
cs.off() | |
spi.readinto(regdata) | |
cs.on() | |
return (regdata[0] << 8) + regdata[1] | |
def read_data(spi, cs, send=0): | |
""" Read 16-bit ADC response, return the ADC channel and data """ | |
data = bytearray(2) | |
buf = bytearray(2) | |
buf[0] = (send & 0xff00) >> 8 | |
buf[1] = send & 0x00ff | |
cs.off() | |
spi.write_readinto(buf, data) | |
cs.on() | |
adc_addr = data[0] >> 4 | |
adc_data = ((data[0] & 0xf) << 8) + data[1] | |
return adc_addr, adc_data | |
def get_adc_values(spi, cs, channels): | |
""" Send ADC_SEQ (not repeating) to initialise ADC reads. Read the ADC data for each channel requested. | |
Return a list of tuples where each tuple is a pair of ADC channel ID's and the corresponding ADC data. | |
""" | |
seq = (0b0_0010_0_0_0 << 8) + (channels & 0xff) | |
print(bin(seq)) | |
send(spi, cs, seq) | |
# Datasheet suggests this next spi operation is necessary but data was inconsistent when it was added. | |
# Working theory is that CS toggling was slow enough (10's of us) in MicroPython that the ADC conversion | |
# would occur before the toggle. | |
# Could approach native speeds by toggling with register access but seems adequate as-is for now. | |
#send(spi, cs, 0) | |
num_reads = bin(channels).count("1") | |
data = [read_data(spi, cs) for _ in range(num_reads)] | |
return data | |
def print_all_registers(spi, cs): | |
""" Print all of the registers in a neat table. | |
Skips over CONFIG_READ_AND_LDAC since it's the register used to read each register and is modified during the read! | |
""" | |
reg_names = ["NOP", "DAC_RD", "ADC_SEQ", "GEN_CTRL_REG", "ADC_CONFIG", | |
"DAC_CONFIG", "PULLDWN_CONFIG", #"CONFIG_READ_AND_LDAC", | |
"GPIO_CONFIG", "GPIO_OUTPUT", "GPIO_INPUT", "PD_REF_CTRL", | |
"GPIO_OPENDRAIN_CONFIG", "IO_TS_CONFIG"] | |
longest_len = len(max(reg_names, key = len)) | |
for reg_id in range(0xd): | |
print(f"{reg_names[reg_id]:<{longest_len}} {reg_id:#06b} {get_register(spi, cs, reg_id):#018b}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment