diff --git a/MCP2221/MCP2221.py b/MCP2221/MCP2221.py index d89d8fc..f85c650 100644 --- a/MCP2221/MCP2221.py +++ b/MCP2221/MCP2221.py @@ -165,81 +165,102 @@ def SetInterruptDetection(self): # TODO raise Exception("Not yet implemented") - def InitGP(self, pin: int, type: TYPE, value: int = 0): + def InitGP(self, pin: int, type: TYPE, value: bool = False): """ Init GPIO """ buf = self._getConfig() buf[7 + 1] = 0b10000000 # alter GPIO - if pin == 0: - buf[8 + 1] = 0 - - if type == TYPE.INPUT: - buf[8 + 1] |= 1 << 3 - elif type == TYPE.OUTPUT: - buf[8 + 1] |= (value & 1) << 4 - elif type == TYPE.SSPND: - buf[8 + 1] |= 1 - elif type == TYPE.LED_RX: - buf[8 + 1] |= 2 - else: - raise TypeError("Invalid type on pin GP0") - - elif pin == 1: - buf[9 + 1] = 0 - - if type == TYPE.INPUT: - buf[9 + 1] |= 1 << 3 - elif type == TYPE.OUTPUT: - buf[9 + 1] |= (value & 1) << 4 - elif type == TYPE.CLOCK_OUT: - buf[9 + 1] |= 1 - elif type == TYPE.ADC: - buf[9 + 1] |= 2 - elif type == TYPE.LED_TX: - buf[9 + 1] |= 3 - elif type == TYPE.INTERRUPT: - buf[9 + 1] |= 4 - else: - raise TypeError("Invalid type on pin GP1") - - elif pin == 2: - buf[10 + 1] = 0 - - if type == TYPE.INPUT: - buf[10 + 1] |= 1 << 3 - elif type == TYPE.OUTPUT: - buf[10 + 1] |= (value & 1) << 4 - elif type == TYPE.USBCFG: - buf[10 + 1] |= 1 - elif type == TYPE.ADC: - buf[10 + 1] |= 2 - elif type == TYPE.DAC: - buf[10 + 1] |= 3 - else: - raise TypeError("Invalid type on pin GP2") - - elif pin == 3: - buf[11 + 1] = 0 - - if type == TYPE.INPUT: - buf[11 + 1] |= 1 << 3 - elif type == TYPE.OUTPUT: - buf[11 + 1] |= (value & 1) << 4 - elif type == TYPE.LED_I2C: - buf[11 + 1] |= 1 - elif type == TYPE.ADC: - buf[11 + 1] |= 2 - elif type == TYPE.DAC: - buf[11 + 1] |= 3 - else: - raise TypeError("Invalid type on pin GP3") + pin_index = { + 0: 9, # 8 + 1 + 1: 10, # 9 + 1 + 2: 11, # 10 + 1 + 3: 12, # 11 + 1 + } - else: + if pin not in pin_index: raise ValueError("Invalid pin number") + buf_offset = pin_index[pin] + buf[buf_offset] = 0 + + if type == TYPE.INPUT: + buf[buf_offset] = 1 << 3 + elif type == TYPE.OUTPUT: + buf[buf_offset] = (int(value) & 1) << 4 + elif type == TYPE.SSPND and pin == 0: + buf[buf_offset] = 1 + elif type == TYPE.LED_RX and pin == 0: + buf[buf_offset] = 2 + elif type == TYPE.CLOCK_OUT and pin == 1: + buf[buf_offset] = 1 + elif type == TYPE.ADC and (pin == 1 or pin == 2 or pin == 3): + buf[buf_offset] = 2 + elif type == TYPE.LED_TX and pin == 1: + buf[buf_offset] = 3 + elif type == TYPE.INTERRUPT and pin == 1: + buf[buf_offset] = 4 + elif type == TYPE.USBCFG and pin == 2: + buf[buf_offset] = 1 + elif type == TYPE.DAC and (pin == 2 or pin == 3): + buf[buf_offset] = 3 + elif type == TYPE.LED_I2C and pin == 3: + buf[buf_offset] = 1 + else: + raise TypeError(f"Invalid type on pin GP{pin}") + self._send(buf) + def GetGPType(self, pin: int) -> TYPE: + pin_index = { + 0: 9, # 8 + 1 + 1: 10, # 9 + 1 + 2: 11, # 10 + 1 + 3: 12, # 11 + 1 + } + + if pin not in pin_index: + raise ValueError("Invalid pin number") + + buf = self._getConfig() + + buf_offset = pin_index.get(pin) + fn = buf[buf_offset] & 0b111 + + # shared functions + if buf[buf_offset] & (1 << 3): + return TYPE.INPUT + elif (pin == 1 or pin == 2 or pin == 3) and fn == 2: + return TYPE.ADC + elif (pin == 2 or pin == 3) and fn == 3: + return TYPE.DAC + + # GP0 + elif pin == 0 and fn == 1: + return TYPE.SSPND + elif pin == 0 and fn == 2: + return TYPE.LED_RX + + # GP1 + elif pin == 1 and fn == 1: + return TYPE.CLOCK_OUT + elif pin == 1 and fn == 3: + return TYPE.LED_TX + elif pin == 1 and fn == 4: + return TYPE.INTERRUPT + + # GP2 + elif pin == 2 and fn == 1: + return TYPE.USBCFG + + # GP3 + elif pin == 3 and fn == 1: + return TYPE.LED_I2C + + # check for output + elif buf[buf_offset] & 0b1111 == 0: + return TYPE.OUTPUT + def ReadAllGP(self): """ Read GPIOs in bulk (when set as input or output) """ diff --git a/tests/test_gpio.py b/tests/test_gpio.py index 20b2d19..fd9c1cf 100644 --- a/tests/test_gpio.py +++ b/tests/test_gpio.py @@ -55,24 +55,43 @@ def testInitInput(pin): assert (gp_type, direction) == (0, 1) -@pytest.mark.parametrize("pin,type,value", [ - (0, MCP2221.TYPE.SSPND, 0b001), - (0, MCP2221.TYPE.LED_RX, 0b010), - (1, MCP2221.TYPE.LED_TX, 0b011), - (2, MCP2221.TYPE.USBCFG, 0b001), - (3, MCP2221.TYPE.LED_I2C, 0b001)]) -def testValidType(pin, type, value): +@pytest.mark.parametrize("pin,type", [ + (0, MCP2221.TYPE.INPUT), + (0, MCP2221.TYPE.OUTPUT), + (0, MCP2221.TYPE.SSPND), + (0, MCP2221.TYPE.LED_RX), + + (1, MCP2221.TYPE.INPUT), + (1, MCP2221.TYPE.OUTPUT), + (1, MCP2221.TYPE.CLOCK_OUT), + (1, MCP2221.TYPE.ADC), + (1, MCP2221.TYPE.LED_TX), + (1, MCP2221.TYPE.INTERRUPT), + + (2, MCP2221.TYPE.INPUT), + (2, MCP2221.TYPE.OUTPUT), + (2, MCP2221.TYPE.USBCFG), + (2, MCP2221.TYPE.ADC), + (2, MCP2221.TYPE.DAC), + + (3, MCP2221.TYPE.INPUT), + (3, MCP2221.TYPE.OUTPUT), + (3, MCP2221.TYPE.LED_I2C), + (3, MCP2221.TYPE.ADC), + (3, MCP2221.TYPE.DAC)]) +def testValidType(pin, type): mcp2221 = MCP2221.MCP2221() mcp2221.InitGP(pin, type) - buf = [0] * 65 - buf[1] = 0x61 # get SRAM settings - buf = mcp2221._send(buf) + gp_type = mcp2221.GetGPType(pin) - gp_type = buf[pin + 22] & 0b111 + assert gp_type == type - assert gp_type == value +def testGetType(): + mcp2221 = MCP2221.MCP2221() + with pytest.raises(ValueError): + mcp2221.GetGPType(5) @pytest.mark.parametrize("pin,type", [ (0, MCP2221.TYPE.LED_I2C),