#
# driver for the MCP42xxx family of digital potentiometers
#
# on instatiation expects an SPI object and a chip select pin
# the MCP42xxx family does only support write command + data,no read
#
# function write expects:
#        a wiper value (0...255)
#        a potentiometer number [0 , 1, both]
#        option kwarg nop = true, default false
#
# function shutdown executes a SW-shutdown for the given Pot(s)
#
#
# by wolf2018
# initial rev 23-Aug2023
#

# set debug to 0 for no printout, 1 for debug output
debug = 0

# definition of command values

SW_shutdown = 0x20
NOP = 0x30

# byte array for spi write
cmd_data = bytearray(2)


#
class MCP42xxx:

    def __init__(self, spi_if, cs_pin):

        self.spi = spi_if
        self.cs = cs_pin

    def write(self, wiper_value, pot, nop=False):
        # sends wiper value to the given Pot or both Pots
        # executes a no operation if nop is set to true

        # set command byte for given potentiometer
        if pot == 0:            # write to potentiometer 0
            command = 0x11
        elif pot == 1:          # write to potentiometer 1
            command = 0x12
        elif pot == 2:     # write to both potentiometers
            command = 0x13
        else:
            # raise ("invalid potentiometer number")
            print("invalid potentiometer number")

        # check for no operation command and set if true
        if nop is True:
            command = command | NOP    # logical OR to set bits for nop command

        # check for invalid wiper_value
        if wiper_value < 0 or wiper_value > 255:
            # raise ("invalid wiper_value")
            print("invalid wiper_value")

        # load command and data byte to byte array and send

        cmd_data[0] = command
        cmd_data[1] = wiper_value

        if debug:
            print("command byte is ", '{:02X}'.format(cmd_data[0]), "h", "   wiper_value is ", '{:02X}'.format(cmd_data[1]), "h")

        # set CS Pin low, write two bytes, set CS Pin high
        self.cs.value(0)
        self.spi.write(cmd_data)
        self.cs.value(1)

    def shut_down(self, pot):
        # sends a shut down command to the  given Pot or both Pots

        # determine which potentiometer to disable
        if pot == 0:            # disable potentiometer 0
            _pot = 0x01
        elif pot == 1:          # wdisable potentiometer 1
            _pot = 0x02
        elif pot == 2:     # disable both potentiometers
            _pot = 0x03
        else:
            # raise ("invalid potentiometer number")
            print("invalid potentiometer number")

        # load command and data byte to byte array and send

        cmd_data[0] = SW_shutdown | _pot
        cmd_data[1] = 0x00        # data is don't care

        if debug:
            print("command byte is ", '{:02X}'.format(cmd_data[0]), "h", "   wiper_value is ", '{:02X}'.format(cmd_data[1]), "h")
            print("shutting down potentiometer(s) ", int(pot))

        # set CS Pin low, write two bytes, set CS Pin high
        self.cs.value(0)
        self.spi.write(cmd_data)
        self.cs.value(1)
