imrishabh18/rp2040-motor-controller

This circuit module provides a microcontroller-based NEMA17 stepper motor driver with integrated USB-C Power Delivery, temperature sensing, and safety interlocks.

Version
1.0.16
License
unset
Stars
0

firmware/tmp102.py

"""TMP102 at 0x48: TI SBOS397I, normal 12-bit mode, active-low comparator."""

WARN_C = 65.0
TRIP_C = 75.0
RESTART_C = 60.0
CONFIG = 0x60C0  # continuous, 8 Hz, one fault, active-low comparator, EM=0
CONFIG_MASK = 0x7FD0  # exclude OS and read-only ALERT status


def encode_temperature(celsius):
    raw = (int(round(celsius * 16)) & 0xFFF) << 4
    return bytes((raw >> 8, raw & 0xFF))


def decode_temperature(data):
    if len(data) != 2 or data[1] & 0x0F:
        raise ValueError("Invalid TMP102 normal-mode temperature")
    raw = ((data[0] << 8) | data[1]) >> 4
    if raw & 0x800:
        raw -= 0x1000
    result = raw / 16.0
    if not -40 <= result <= 125:
        raise ValueError("Temperature outside sensor operating range")
    return result


class TMP102:
    def __init__(self, i2c, address=0x48):
        self.i2c = i2c
        self.address = address

    def read_register(self, register):
        data = self.i2c.readfrom_mem(self.address, register, 2)
        if len(data) != 2:
            raise OSError("Short TMP102 register read")
        return (data[0] << 8) | data[1]

    def configure(self):
        # Caller must hold GPIO22 LOW throughout configuration and settling.
        self.i2c.writeto_mem(self.address, 1, bytes((CONFIG >> 8, CONFIG & 255)))
        self.i2c.writeto_mem(self.address, 2, encode_temperature(RESTART_C))
        self.i2c.writeto_mem(self.address, 3, encode_temperature(TRIP_C))
        self.verify()

    def verify(self):
        # Detect sensor reset or changed polarity/mode/limits during operation.
        if self.read_register(1) & CONFIG_MASK != CONFIG & CONFIG_MASK:
            raise OSError("TMP102 protection configuration changed")
        for register, value in ((2, RESTART_C), (3, TRIP_C)):
            encoded = encode_temperature(value)
            if self.read_register(register) != (encoded[0] << 8) | encoded[1]:
                raise OSError("TMP102 protection threshold changed")

    def temperature(self):
        self.verify()
        return decode_temperature(self.i2c.readfrom_mem(self.address, 0, 2))