avr: Allow I2C bus speed to be set by Klipper (#6111)
Allow I2C bus speed to be set by appropriate Klipper commands. Signed-off-by: Matthew Swabey <matthew@swabey.org>
This commit is contained in:
parent
e2d7c59812
commit
2466b7a2c6
|
@ -4508,20 +4508,20 @@ SPI bus.
|
||||||
The following parameters are generally available for devices using an
|
The following parameters are generally available for devices using an
|
||||||
I2C bus.
|
I2C bus.
|
||||||
|
|
||||||
Note that Klipper's current micro-controller support for i2c is
|
Note that Klipper's current micro-controller support for I2C is
|
||||||
generally not tolerant to line noise. Unexpected errors on the i2c
|
generally not tolerant to line noise. Unexpected errors on the I2C
|
||||||
wires may result in Klipper raising a run-time error. Klipper's
|
wires may result in Klipper raising a run-time error. Klipper's
|
||||||
support for error recovery varies between each micro-controller type.
|
support for error recovery varies between each micro-controller type.
|
||||||
It is generally recommended to only use i2c devices that are on the
|
It is generally recommended to only use I2C devices that are on the
|
||||||
same printed circuit board as the micro-controller.
|
same printed circuit board as the micro-controller.
|
||||||
|
|
||||||
Most Klipper micro-controller implementations only support an
|
Most Klipper micro-controller implementations only support an
|
||||||
`i2c_speed` of 100000. The Klipper "linux" micro-controller supports a
|
`i2c_speed` of 100000 (*standard mode*, 100kbit/s). The Klipper "Linux"
|
||||||
400000 speed, but it must be
|
micro-controller supports a 400000 speed (*fast mode*, 400kbit/s), but it must be
|
||||||
[set in the operating system](RPi_microcontroller.md#optional-enabling-i2c)
|
[set in the operating system](RPi_microcontroller.md#optional-enabling-i2c)
|
||||||
and the `i2c_speed` parameter is otherwise ignored. The Klipper
|
and the `i2c_speed` parameter is otherwise ignored. The Klipper
|
||||||
"rp2040" micro-controller supports a rate of 400000 via the
|
"RP2040" micro-controller and ATmega AVR family support a rate of 400000
|
||||||
`i2c_speed` parameter. All other Klipper micro-controllers use a
|
via the `i2c_speed` parameter. All other Klipper micro-controllers use a
|
||||||
100000 rate and ignore the `i2c_speed` parameter.
|
100000 rate and ignore the `i2c_speed` parameter.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -4539,5 +4539,5 @@ and the `i2c_speed` parameter is otherwise ignored. The Klipper
|
||||||
# The I2C speed (in Hz) to use when communicating with the device.
|
# The I2C speed (in Hz) to use when communicating with the device.
|
||||||
# The Klipper implementation on most micro-controllers is hard-coded
|
# The Klipper implementation on most micro-controllers is hard-coded
|
||||||
# to 100000 and changing this value has no effect. The default is
|
# to 100000 and changing this value has no effect. The default is
|
||||||
# 100000.
|
# 100000. Linux, RP2040 and ATmega support 400000.
|
||||||
```
|
```
|
||||||
|
|
|
@ -27,31 +27,27 @@ static const uint8_t SCL = GPIO('D', 0), SDA = GPIO('D', 1);
|
||||||
DECL_CONSTANT_STR("BUS_PINS_twi", "PD0,PD1");
|
DECL_CONSTANT_STR("BUS_PINS_twi", "PD0,PD1");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
|
||||||
i2c_init(void)
|
|
||||||
{
|
|
||||||
if (TWCR & (1<<TWEN))
|
|
||||||
// Already setup
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Setup output pins and enable pullups
|
|
||||||
gpio_out_setup(SDA, 1);
|
|
||||||
gpio_out_setup(SCL, 1);
|
|
||||||
|
|
||||||
// Set 100Khz frequency
|
|
||||||
TWSR = 0;
|
|
||||||
TWBR = ((CONFIG_CLOCK_FREQ / 100000) - 16) / 2;
|
|
||||||
|
|
||||||
// Enable interface
|
|
||||||
TWCR = (1<<TWEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct i2c_config
|
struct i2c_config
|
||||||
i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr)
|
i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr)
|
||||||
{
|
{
|
||||||
if (bus)
|
if (bus)
|
||||||
shutdown("Unsupported i2c bus");
|
shutdown("Unsupported i2c bus");
|
||||||
i2c_init();
|
|
||||||
|
if (!(TWCR & (1<<TWEN))) {
|
||||||
|
// Setup output pins and enable pullups
|
||||||
|
gpio_out_setup(SDA, 1);
|
||||||
|
gpio_out_setup(SCL, 1);
|
||||||
|
|
||||||
|
// Set frequency avoiding pulling in integer divide
|
||||||
|
TWSR = 0;
|
||||||
|
if (rate >= 400000)
|
||||||
|
TWBR = ((CONFIG_CLOCK_FREQ / 400000) - 16) / 2;
|
||||||
|
else
|
||||||
|
TWBR = ((CONFIG_CLOCK_FREQ / 100000) - 16) / 2;
|
||||||
|
|
||||||
|
// Enable interface
|
||||||
|
TWCR = (1<<TWEN);
|
||||||
|
}
|
||||||
return (struct i2c_config){ .addr=addr<<1 };
|
return (struct i2c_config){ .addr=addr<<1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue