Files
2024-01-09 17:33:02 +08:00

302 lines
13 KiB
Python

# Support for i2c based temperature sensors
#
# Copyright (C) 2020 Eric Callahan <arksine.code@gmail.com>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
import struct
from . import bus
BL24C16F_CHIP_ADDR_0 = 0x50
BL24C16F_CHIP_ADDR_1 = 0x51
BL24C16F_CHIP_ADDR_2 = 0x52
BL24C16F_CHIP_ADDR_3 = 0x53
BL24C16F_CHIP_ADDR_4 = 0x54
BL24C16F_CHIP_ADDR_5 = 0x55
BL24C16F_CHIP_ADDR_6 = 0x56
BL24C16F_CHIP_ADDR_7 = 0x57
class EEPROMCommandHelper:
def __init__(self, config, chip):
self.printer = config.get_printer()
self.chip = chip
name_parts = config.get_name().split()
self.base_name = name_parts[0]
self.name = name_parts[-1]
self.register_commands(self.name)
if len(name_parts) == 1:
if self.name == "bl24c16f" or not config.has_section("bl24c16f"):
self.register_commands(None)
def register_commands(self, name):
gcode = self.printer.lookup_object('gcode')
gcode.register_mux_command("EEPROM_DEBUG_READ", "CHIP", name,
self.cmd_EEPROM_DEBUG_READ,
desc=self.cmd_EEPROM_DEBUG_READ_help)
gcode.register_mux_command("EEPROM_DEBUG_WRITE_BYTE", "CHIP", name,
self.cmd_EEPROM_DEBUG_WRITE_BYTE,
desc=self.cmd_EEPROM_DEBUG_WRITE_BYTE_help)
gcode.register_mux_command("EEPROM_DEBUG_WRITE_INT", "CHIP", name,
self.cmd_EEPROM_DEBUG_WRITE_INT,
desc=self.cmd_EEPROM_DEBUG_WRITE_INT_help)
gcode.register_mux_command("EEPROM_DEBUG_WRITE_FLOAT", "CHIP", name,
self.cmd_EEPROM_DEBUG_WRITE_FLOAT,
desc=self.cmd_EEPROM_DEBUG_WRITE_FLOAT_help)
gcode.register_mux_command("EEPROM_READ", "CHIP", name,
self.cmd_EEPROM_READ,
desc=self.cmd_EEPROM_READ_help)
gcode.register_mux_command("EEPROM_WRITE_BYTE", "CHIP", name,
self.cmd_EEPROM_WRITE_BYTE,
desc=self.cmd_EEPROM_WRITE_BYTE_help)
gcode.register_mux_command("EEPROM_WRITE_INT", "CHIP", name,
self.cmd_EEPROM_WRITE_INT,
desc=self.cmd_EEPROM_WRITE_INT_help)
gcode.register_mux_command("EEPROM_WRITE_FLOAT", "CHIP", name,
self.cmd_EEPROM_WRITE_FLOAT,
desc=self.cmd_EEPROM_WRITE_FLOAT_help)
gcode.register_mux_command("EEPROM_IS_FIRST_USED", "CHIP", name,
self.cmd_EEPROM_IS_FIRST_USED)
gcode.register_mux_command("EEPROM_POS", "CHIP", name,
self.cmd_EEPROM_POS)
gcode.register_mux_command("EEPROM_PRINTER_INFO", "CHIP", name,
self.cmd_EEPROM_PRINTER_INFO)
def cmd_EEPROM_IS_FIRST_USED(self, gcmd):
val = self.chip.read_reg(1, 1)
state = False if int.from_bytes(val, 'little') != 255 else True
gcmd.respond_info("EEPROM_IS_USED val:%s state:%s" % (int.from_bytes(val, 'little'), state))
if int.from_bytes(val, 'little') != 255:
return False
else:
return True
def cmd_EEPROM_POS(self, gcmd):
pos = self.chip.read_reg(0, 1)
gcmd.respond_info("EEPROM_POS int_pos:%s, pos:%s" % (int.from_bytes(pos, 'little'), pos))
def cmd_EEPROM_PRINTER_INFO(self, gcmd):
pos = int.from_bytes(self.chip.read_reg(0, 1), 'little')
file_position = self.chip.read_reg(pos*8, 4)
base_position_e = self.chip.read_reg(pos*8+4, 4)
ret = {"file_position": int.from_bytes(file_position, 'little'), "base_position_e": struct.unpack('f', base_position_e)[0]}
gcmd.respond_info("EEPROM_PRINTER_INFO ret:%s" % str(ret))
def cmd_EEPROM_DEBUG_READ(self, gcmd):
addr = gcmd.get("ADDR", minval=0, maxval=2047, parser=lambda x: int(x, 0))
size = gcmd.get("SIZE", minval=0, maxval=56, parser=lambda x: int(x, 0))
vals = self.chip.read_reg(addr, size)
gcmd.respond_info("EEPROM_DEBUG_READ size: 0x%x" % size)
reg_vals = 'read vals: '
for i in range(size):
if i % 16 == 0:
reg_vals += '\n'
reg_vals += '0x%x ' % vals[i]
gcmd.respond_info(reg_vals)
cmd_EEPROM_DEBUG_READ_help = "Read data bytes from eeprom"
def cmd_EEPROM_DEBUG_WRITE_BYTE(self, gcmd):
addr = gcmd.get("ADDR", minval=0, maxval=2047, parser=lambda x: int(x, 0))
val = gcmd.get("VAL", minval=0, maxval=255, parser=lambda x: int(x, 0))
gcmd.respond_info("EEPROM_DEBUG_WRITE_BYTE : ADDR[0x%x] = 0x%x" % (addr, val))
self.chip.write_reg(addr, val)
cmd_EEPROM_DEBUG_WRITE_BYTE_help = "Write byte data to eeprom"
def cmd_EEPROM_DEBUG_WRITE_INT(self, gcmd):
pos = self.chip.read_reg(0, 1)
gcmd.respond_info("EEPROM_POS int_pos:%s" % int.from_bytes(pos, 'little'))
addr = gcmd.get("ADDR", minval=0, maxval=2047, parser=lambda x: int(x, 0))
val = gcmd.get("VAL", minval=0, maxval=4294967296, parser=lambda x: int(x, 0))
gcmd.respond_info("EEPROM_DEBUG_WRITE_INT : val = %d" % val)
vals = [val & 0xFF]
vals += [ (val >> 8) & 0xFF,
(val >> 16) & 0xFF,
(val >> 24) & 0xFF,
]
gcmd.respond_info("EEPROM_DEBUG_WRITE_INT : ADDR[0x%x] = 0x%02x 0x%02x 0x%02x 0x%02x"
% (addr, vals[0], vals[1], vals[2], vals[3]))
self.chip.write_reg(addr, vals)
cmd_EEPROM_DEBUG_WRITE_INT_help = "Write int (4 byte) data to eeprom"
def cmd_EEPROM_DEBUG_WRITE_FLOAT(self, gcmd):
addr = gcmd.get("ADDR", minval=0, maxval=2047, parser=lambda x: int(x, 0))
val = gcmd.get_float("VAL", 0.)
gcmd.respond_info("EEPROM_DEBUG_WRITE_FLOAT : val = %f" % val)
bs = struct.pack("f", val)
data = int.from_bytes(bs, byteorder="little")
vals = [data & 0xFF]
vals += [ (data >> 8) & 0xFF,
(data >> 16) & 0xFF,
(data >> 24) & 0xFF
]
gcmd.respond_info("EEPROM_DEBUG_WRITE_FLOAT : ADDR[0x%x] = 0x%02x 0x%02x 0x%02x 0x%02x"
% (addr, vals[0], vals[1], vals[2], vals[3]))
self.chip.write_reg(addr, vals)
cmd_EEPROM_DEBUG_WRITE_FLOAT_help = "Write float (4 byte) data to eeprom"
def cmd_EEPROM_READ(self, gcmd):
addr = gcmd.get("ADDR", minval=0, maxval=2047, parser=lambda x: int(x, 0))
size = gcmd.get("SIZE", minval=0, maxval=56, parser=lambda x: int(x, 0))
vals = self.chip.read_reg(addr, size)
# gcmd.respond_info("EEPROM_READ size: 0x%x" % size)
reg_vals = 'read vals: '
for i in range(size):
if i % 16 == 0:
reg_vals += '\n'
reg_vals += '0x%x ' % vals[i]
# gcmd.respond_info(reg_vals)
cmd_EEPROM_READ_help = "Read data bytes from eeprom"
def cmd_EEPROM_WRITE_BYTE(self, gcmd):
addr = gcmd.get("ADDR", minval=0, maxval=2047, parser=lambda x: int(x, 0))
val = gcmd.get("VAL", minval=0, maxval=255, parser=lambda x: int(x, 0))
# gcmd.respond_info("EEPROM_WRITE_BYTE : ADDR[0x%x] = 0x%x" % (addr, val))
self.chip.write_reg(addr, val)
cmd_EEPROM_WRITE_BYTE_help = "Write byte data to eeprom"
def cmd_EEPROM_WRITE_INT(self, gcmd):
# pos = self.chip.read_reg(0, 1)
# gcmd.respond_info("EEPROM_POS int_pos:%s" % int.from_bytes(pos, 'little'))
addr = gcmd.get("ADDR", minval=0, maxval=2047, parser=lambda x: int(x, 0))
val = gcmd.get("VAL", minval=0, maxval=4294967296, parser=lambda x: int(x, 0))
# gcmd.respond_info("EEPROM_WRITE_INT : val = %d" % val)
vals = [val & 0xFF]
vals += [ (val >> 8) & 0xFF,
(val >> 16) & 0xFF,
(val >> 24) & 0xFF,
]
# gcmd.respond_info("EEPROM_WRITE_INT : ADDR[0x%x] = 0x%02x 0x%02x 0x%02x 0x%02x"
# % (addr, vals[0], vals[1], vals[2], vals[3]))
self.chip.write_reg(addr, vals)
cmd_EEPROM_WRITE_INT_help = "Write int (4 byte) data to eeprom"
def cmd_EEPROM_WRITE_FLOAT(self, gcmd):
addr = gcmd.get("ADDR", minval=0, maxval=2047, parser=lambda x: int(x, 0))
val = gcmd.get_float("VAL", 0.)
# gcmd.respond_info("EEPROM_WRITE_FLOAT : val = %f" % val)
bs = struct.pack("f", val)
data = int.from_bytes(bs, byteorder="little")
vals = [data & 0xFF]
vals += [ (data >> 8) & 0xFF,
(data >> 16) & 0xFF,
(data >> 24) & 0xFF
]
# gcmd.respond_info("EEPROM_WRITE_FLOAT : ADDR[0x%x] = 0x%02x 0x%02x 0x%02x 0x%02x"
# % (addr, vals[0], vals[1], vals[2], vals[3]))
self.chip.write_reg(addr, vals)
cmd_EEPROM_WRITE_FLOAT_help = "Write float (4 byte) data to eeprom"
class BL24C16F:
def __init__(self, config):
self.printer = config.get_printer()
EEPROMCommandHelper(config, self)
self.name = config.get_name().split()[-1]
self.reactor = self.printer.get_reactor()
self.i2c0 = bus.MCU_I2C_from_config(
config, default_addr=BL24C16F_CHIP_ADDR_0, default_speed=400000)
self.i2c1 = bus.MCU_I2C_from_config(
config, default_addr=BL24C16F_CHIP_ADDR_1, default_speed=400000)
self.i2c2 = bus.MCU_I2C_from_config(
config, default_addr=BL24C16F_CHIP_ADDR_2, default_speed=400000)
self.i2c3 = bus.MCU_I2C_from_config(
config, default_addr=BL24C16F_CHIP_ADDR_3, default_speed=400000)
self.i2c4 = bus.MCU_I2C_from_config(
config, default_addr=BL24C16F_CHIP_ADDR_4, default_speed=400000)
self.i2c5 = bus.MCU_I2C_from_config(
config, default_addr=BL24C16F_CHIP_ADDR_5, default_speed=400000)
self.i2c6 = bus.MCU_I2C_from_config(
config, default_addr=BL24C16F_CHIP_ADDR_6, default_speed=400000)
self.i2c7 = bus.MCU_I2C_from_config(
config, default_addr=BL24C16F_CHIP_ADDR_7, default_speed=400000)
self.mcu = self.i2c0.get_mcu()
self.printer.add_object("bl24c16f " + self.name, self)
self.printer.register_event_handler("klippy:connect",
self.handle_connect)
def handle_connect(self):
self._init_bl24c16f()
def _init_bl24c16f(self):
logging.info("bl24c16f init...")
def read_reg(self, addr, read_len):
index = addr // 256
offset = addr % 256
reg = [offset]
if index == 0 :
params = self.i2c0.i2c_read(reg, read_len)
elif index == 1 :
params = self.i2c1.i2c_read(reg, read_len)
elif index == 2 :
params = self.i2c2.i2c_read(reg, read_len)
elif index == 3 :
params = self.i2c3.i2c_read(reg, read_len)
elif index == 4 :
params = self.i2c4.i2c_read(reg, read_len)
elif index == 5 :
params = self.i2c5.i2c_read(reg, read_len)
elif index == 6 :
params = self.i2c6.i2c_read(reg, read_len)
elif index == 7 :
params = self.i2c7.i2c_read(reg, read_len)
return bytearray(params['response'])
def write_reg(self, addr, data):
if type(data) is not list:
data = [data]
index = addr // 256
offset = addr % 256
data.insert(0, offset)
if index == 0 :
self.i2c0.i2c_write(data)
if index == 1 :
self.i2c1.i2c_write(data)
if index == 2 :
self.i2c2.i2c_write(data)
if index == 3 :
self.i2c3.i2c_write(data)
if index == 4 :
self.i2c4.i2c_write(data)
if index == 5 :
self.i2c5.i2c_write(data)
if index == 6 :
self.i2c6.i2c_write(data)
if index == 7 :
self.i2c7.i2c_write(data)
def setEepromDisable(self):
self.write_reg(1, 255)
def checkEepromFirstEnable(self):
val = self.read_reg(1, 1)
if int.from_bytes(val, 'little') != 255:
return False
else:
return True
def eepromReadHeader(self):
pos = self.read_reg(0, 1)
return int.from_bytes(pos, 'little')
def eepromReadBody(self, pos):
file_position = self.read_reg(pos*8, 4)
base_position_e = self.read_reg(pos*8+4, 4)
return {"file_position": int.from_bytes(file_position, 'little'), "base_position_e": struct.unpack('f', base_position_e)[0]}
def load_config(config):
return BL24C16F(config)
def load_config_prefix(config):
return BL24C16F(config)