Skip to content

Commit 54b6e3a

Browse files
committed
Add programming procedure for the DAC I2C addresses
1 parent c243fe6 commit 54b6e3a

1 file changed

Lines changed: 86 additions & 1 deletion

File tree

deploy/src/drivers/devices/dac43701.jl

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,89 @@ Return the upper byte of PMBUS_VERSION (98h). The datasheet value is 0x22.
10121012
pmbus_version(dev::DACDevice) =
10131013
UInt8((read_reg(dev, PMBUS_VERSION_ADDR) >> 8) & 0xFF)
10141014

1015+
#=============================================================================
1016+
Bulk slave-address configuration (datasheet §8.5.2.1.1)
1017+
=============================================================================#
1018+
1019+
"""
1020+
set_dac_addresses(bus, pairs) -> Dict{UInt8, DACDevice}
1021+
1022+
Walk through datasheet §8.5.2.1.1 to assign distinct I²C slave addresses to up
1023+
to four DAC43701s sharing a bus, then snapshot each device's registers to NVM
1024+
so the new address survives power cycles.
1025+
1026+
Each entry of `pairs` is `desired_address => gpi_with`, where `desired_address`
1027+
is a 7-bit I²C address in 0x48..0x4B and `gpi_with(callback)` drives that
1028+
device's GPI line high, invokes the zero-arg `callback`, and then drives the
1029+
GPI line back low — for example:
1030+
1031+
0x49 => function (cb)
1032+
set_high(line)
1033+
try; cb(); finally; set_low(line); end
1034+
end
1035+
1036+
Returns a `Dict` mapping each assigned 7-bit address to a freshly-opened
1037+
`DACDevice`. The bulk steps (arming GPI, writing SLAVE_ADDRESS, restoring GPI
1038+
defaults) all go through the broadcast address 0x47, so the function assumes
1039+
every device's GPI pin is held low at entry and that CONFIG2 sits at its reset
1040+
value on every device — a broadcast CONFIG2 write rewrites the whole register,
1041+
so non-default alarm-timing fields would be clobbered.
1042+
"""
1043+
function set_dac_addresses(bus::Integer, pairs)
1044+
for (addr, _) in pairs
1045+
(UInt8(addr) >> 2) == 0x12 || throw(ArgumentError(
1046+
"address 0x$(string(UInt8(addr), base=16, pad=2)) is not a valid " *
1047+
"DAC43701 slave address (must be 0x48..0x4B)"))
1048+
end
1049+
1050+
bcast = DACDevice(I2C.open_device(Int(bus), DAC43701_ADDR_BROADCAST))
1051+
result = Dict{UInt8, DACDevice}()
1052+
try
1053+
# Step 2: route GPI to the slave-address-program function on every
1054+
# device.
1055+
bcast.c2.GPI_CONFIG = UInt8(GPI_SLAVE_ADDR)
1056+
flush_config2(bcast)
1057+
1058+
# Step 3: arm GPI. Broadcast is write-only so we can't RMW TRIGGER;
1059+
# write a fully specified value with every action bit cleared.
1060+
write_reg(bcast, TRIGGER_ADDR,
1061+
as_word(TRIGGER(SW_RESET_NOOP, 0, 0, 0, 0, 0, 0, 1, 0)))
1062+
1063+
# Steps 4-7: caller raises GPI on one device, we broadcast the new
1064+
# SLAVE_ADDRESS (only that device latches it), caller drops GPI again.
1065+
for (desired_addr, gpi_with) in pairs
1066+
gpi_with() do
1067+
bcast.c2.SLAVE_ADDRESS = UInt8(desired_addr) & 0x03
1068+
flush_config2(bcast)
1069+
end
1070+
end
1071+
1072+
# Step 8: GPI_EN back to 0.
1073+
write_reg(bcast, TRIGGER_ADDR,
1074+
as_word(TRIGGER(SW_RESET_NOOP, 0, 0, 0, 0, 0, 0, 0, 0, 0)))
1075+
# Step 9: restore GPI_CONFIG to its reset value.
1076+
bcast.c2.GPI_CONFIG = UInt8(GPI_PD_HIZ)
1077+
flush_config2(bcast)
1078+
1079+
# Step 10: snapshot each device's registers into NVM. Done per-device
1080+
# at its new address so we can poll NVM_BUSY — broadcast can't read.
1081+
# `probe` confirms the address change actually landed before we touch
1082+
# NVM; otherwise a missing/mis-addressed device would silently fall
1083+
# through to the next bus participant.
1084+
for (desired_addr, _) in pairs
1085+
addr = UInt8(desired_addr)
1086+
dev = DACDevice(I2C.open_device(Int(bus), addr))
1087+
probe(dev)
1088+
refresh_cache!(dev)
1089+
program_nvm(dev)
1090+
result[addr] = dev
1091+
end
1092+
finally
1093+
close_dac(bcast)
1094+
end
1095+
return result
1096+
end
1097+
10151098
#=============================================================================
10161099
Cleanup
10171100
=============================================================================#
@@ -1053,6 +1136,8 @@ export
10531136
configure_gpi, enable_gpi, disable_gpi,
10541137
trigger_margin_high, trigger_margin_low,
10551138
# PMBus
1056-
enable_pmbus, pmbus_operation, pmbus_status, clear_pmbus_cml, pmbus_version
1139+
enable_pmbus, pmbus_operation, pmbus_status, clear_pmbus_cml, pmbus_version,
1140+
# Bulk slave-address assignment
1141+
set_dac_addresses
10571142

10581143
end # module DAC43701

0 commit comments

Comments
 (0)