mcp4018: Remove support for manual i2c - use standard mcu software i2c instead

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2025-07-14 13:27:17 -04:00
parent 354b1e666b
commit a209d4db5b
5 changed files with 38 additions and 94 deletions

View file

@ -89,32 +89,32 @@ max_z_velocity: 5
max_z_accel: 100
[mcp4018 x_axis_pot]
scl_pin: PJ5
sda_pin: PF3
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PF3
wiper: 0.50
scale: 0.773
[mcp4018 y_axis_pot]
scl_pin: PJ5
sda_pin: PF7
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PF7
wiper: 0.50
scale: 0.773
[mcp4018 z_axis_pot]
scl_pin: PJ5
sda_pin: PK3
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PK3
wiper: 0.50
scale: 0.773
[mcp4018 a_axis_pot]
scl_pin: PJ5
sda_pin: PA5
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PA5
wiper: 0.50
scale: 0.773
[mcp4018 b_axis_pot]
scl_pin: PJ5
sda_pin: PJ6
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PJ6
wiper: 0.50
scale: 0.773

View file

@ -127,32 +127,32 @@ max_z_velocity: 5
max_z_accel: 100
[mcp4018 x_axis_pot]
scl_pin: PJ5
sda_pin: PF3
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PF3
wiper: 118
scale: 127
[mcp4018 y_axis_pot]
scl_pin: PJ5
sda_pin: PF7
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PF7
wiper: 118
scale: 127
[mcp4018 z_axis_pot]
scl_pin: PJ5
sda_pin: PK3
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PK3
wiper: 40
scale: 127
[mcp4018 a_axis_pot]
scl_pin: PJ5
sda_pin: PA5
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PA5
wiper: 118
scale: 127
[mcp4018 b_axis_pot]
scl_pin: PJ5
sda_pin: PJ6
i2c_software_scl_pin: PJ5
i2c_software_sda_pin: PJ6
wiper: 118
scale: 127

View file

@ -8,8 +8,8 @@ All dates in this document are approximate.
## Changes
20250721: The `[pca9632]` module no longer accepts the `scl_pin` and
`sda_pin` options. Use `i2c_software_scl_pin` and
20250721: The `[pca9632]` and `[mcp4018]` modules no longer accept the
`scl_pin` and `sda_pin` options. Use `i2c_software_scl_pin` and
`i2c_software_sda_pin` instead.
20250428: The maximum `cycle_time` for pwm `[output_pin]`,

View file

@ -4392,16 +4392,21 @@ prefix).
### [mcp4018]
Statically configured MCP4018 digipot connected via two gpio "bit
banging" pins (one may define any number of sections with an "mcp4018"
prefix).
Statically configured MCP4018 digipot connected via i2c (one may
define any number of sections with an "mcp4018" prefix).
```
[mcp4018 my_digipot]
scl_pin:
# The SCL "clock" pin. This parameter must be provided.
sda_pin:
# The SDA "data" pin. This parameter must be provided.
#i2c_address: 47
# The i2c address that the chip is using on the i2c bus. The default
# is 47.
#i2c_mcu:
#i2c_bus:
#i2c_software_scl_pin:
#i2c_software_sda_pin:
#i2c_speed:
# See the "common I2C settings" section for a description of the
# above parameters.
wiper:
# The value to statically set the given MCP4018 "wiper" to. This is
# typically set to a number between 0.0 and 1.0 with 1.0 being the

View file

@ -1,75 +1,14 @@
# MCP4018 digipot support (via bit-banging)
# MCP4018 digipot support
#
# Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
# Copyright (C) 2019-2025 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
class SoftwareI2C:
def __init__(self, config, addr):
self.addr = addr << 1
self.update_pin_cmd = None
# Lookup pins
ppins = config.get_printer().lookup_object('pins')
scl_pin = config.get('scl_pin')
scl_params = ppins.lookup_pin(scl_pin, share_type='sw_scl')
self.mcu = scl_params['chip']
self.scl_pin = scl_params['pin']
self.scl_main = scl_params.get('class')
if self.scl_main is None:
self.scl_main = scl_params['class'] = self
self.scl_oid = self.mcu.create_oid()
self.cmd_queue = self.mcu.alloc_command_queue()
self.mcu.register_config_callback(self.build_config)
else:
self.scl_oid = self.scl_main.scl_oid
self.cmd_queue = self.scl_main.cmd_queue
sda_params = ppins.lookup_pin(config.get('sda_pin'))
self.sda_oid = self.mcu.create_oid()
if sda_params['chip'] != self.mcu:
raise ppins.error("%s: scl_pin and sda_pin must be on same mcu" % (
config.get_name(),))
self.mcu.add_config_cmd("config_digital_out oid=%d pin=%s"
" value=%d default_value=%d max_duration=%d" % (
self.sda_oid, sda_params['pin'], 1, 1, 0))
def get_mcu(self):
return self.mcu
def build_config(self):
self.mcu.add_config_cmd("config_digital_out oid=%d pin=%s value=%d"
" default_value=%d max_duration=%d" % (
self.scl_oid, self.scl_pin, 1, 1, 0))
self.update_pin_cmd = self.mcu.lookup_command(
"update_digital_out oid=%c value=%c", cq=self.cmd_queue)
def i2c_write(self, msg, minclock=0, reqclock=0):
msg = [self.addr] + msg
send = self.scl_main.update_pin_cmd.send
# Send ack
send([self.sda_oid, 0], minclock=minclock, reqclock=reqclock)
send([self.scl_oid, 0], minclock=minclock, reqclock=reqclock)
# Send bytes
sda_last = 0
for data in msg:
# Transmit 8 data bits
for i in range(8):
sda_next = not not (data & (0x80 >> i))
if sda_last != sda_next:
sda_last = sda_next
send([self.sda_oid, sda_last],
minclock=minclock, reqclock=reqclock)
send([self.scl_oid, 1], minclock=minclock, reqclock=reqclock)
send([self.scl_oid, 0], minclock=minclock, reqclock=reqclock)
# Transmit clock for ack
send([self.scl_oid, 1], minclock=minclock, reqclock=reqclock)
send([self.scl_oid, 0], minclock=minclock, reqclock=reqclock)
# Send stop
if sda_last:
send([self.sda_oid, 0], minclock=minclock, reqclock=reqclock)
send([self.scl_oid, 1], minclock=minclock, reqclock=reqclock)
send([self.sda_oid, 1], minclock=minclock, reqclock=reqclock)
from . import bus
class mcp4018:
def __init__(self, config):
self.printer = config.get_printer()
self.i2c = SoftwareI2C(config, 0x2f)
self.i2c = bus.MCU_I2C_from_config(config, default_addr=0x2f)
self.scale = config.getfloat('scale', 1., above=0.)
self.start_value = config.getfloat('wiper',
minval=0., maxval=self.scale)