class USBISS_Serial_Interface(wx.Frame): def __init__(self): self._enterKeyPressed = False # Application window super().__init__(parent=None, title="USB ISS Serial", size=(650, 600)) self.panel = wx.Panel(self) # wx.Timer for updating the received data self.updateTimer = wx.Timer(self, wx.ID_ANY) self.Bind(wx.EVT_TIMER, self.updateReadDataWindow, self.updateTimer) # serial port settings self._comspeeds = [ "300", "1200", "2400", "9600", "19200", "38400", "57600", "115200", "250000", "1M" ] self._comboboxSpeed = wx.ComboBox(self.panel, id=wx.ID_ANY, value="speed", choices=list(self._comspeeds)) self._comboboxSpeed.SetSelection(7) #infotext, output and input textboxes self.infotext = wx.StaticText( self.panel, id=wx.ID_ANY, label="No device detected.\nSelect COM port\nand connect.") self.outputtextlabel = wx.StaticText(self.panel, id=wx.ID_ANY, label="User data for sending:") self.outputtext = wx.TextCtrl(self.panel, id=wx.ID_ANY, size=(400, 200), style=wx.TE_MULTILINE) self.inputtext = wx.TextCtrl(self.panel, id=wx.ID_ANY, size=(400, 200), style=wx.TE_MULTILINE) self.inputtextlabel = wx.StaticText(self.panel, id=wx.ID_ANY, label="Received data:") #combobox for selecting the com-port self.comboboxCOMport = wx.ComboBox(self.panel, id=wx.ID_ANY, value="Select port...", choices=self.getComportsList(), size=(130, 35)) self.comboboxCOMport.Bind(wx.EVT_COMBOBOX, self.cmbChanged) #input-field for sending bytes in HEX format self.inputHexLabel = wx.StaticText(self.panel, id=wx.ID_ANY, label="Send data (HEX):") self.inputtextHEX = wx.TextCtrl(self.panel, id=wx.ID_ANY, size=(150, 25), style=wx.TE_CHARWRAP) self.inputHexCheckbox = wx.CheckBox(self.panel, id=wx.ID_ANY, label="Send hex data only") self.inputSendCRCheckBox = wx.CheckBox( self.panel, id=wx.ID_ANY, label="Send Carriage feed/return CR (0x0D)") self.inputSendLFCheckBox = wx.CheckBox( self.panel, id=wx.ID_ANY, label="Send Line feed LF (0x0A)") self.inputtextHEX.Bind(wx.EVT_KEY_UP, self.hexboxtextChanged) self.inputHexCheckbox.Bind(wx.EVT_CHECKBOX, self.sendHexDataChecked) self.inputSendLFCheckBox.SetValue(True) self.inputSendCRCheckBox.SetValue(True) # buttons self.btn_cnct = wx.Button(self.panel, label="Connect") self.btn_cnct.Bind(wx.EVT_BUTTON, self.connectToUSBISS) self.btn_send = wx.Button(self.panel, label="Send") self.btn_send.Bind(wx.EVT_BUTTON, self.sendSerialData) # alignment and positioning wsz = wx.BoxSizer(wx.VERTICAL) # main vertical sizer wsz_hor = wx.BoxSizer(wx.HORIZONTAL) # first row sizer # ----- First row ----- #Port and speed wsz_hor.Add(self.comboboxCOMport, 0, flag=wx.RIGHT | wx.LEFT | wx.ALIGN_TOP, border=10) wsz_hor.Add(self._comboboxSpeed, 0, wx.RIGHT, border=10) #Connect + info wsz_hor.Add(self.btn_cnct, 0, flag=wx.LEFT | wx.ALIGN_TOP, border=0) wsz_hor.Add(self.infotext, 0, wx.LEFT | wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, border=7) wsz.Add(wsz_hor, flag=wx.EXPAND | wx.TOP, border=10, proportion=1) # ----- Second row (receive data) ----- # Received data window wsz.Add(self.inputtextlabel, 0, wx.LEFT | wx.ALIGN_LEFT | wx.ALIGN_BOTTOM, border=10) # add to vertical wsz.Add(self.inputtext, 0, wx.LEFT | wx.BOTTOM | wx.ALIGN_TOP, border=10) # add to vertical # ----- Third Row ----- # Send user data window wsz.Add(self.outputtextlabel, 0, wx.LEFT, border=10) # add to vertical wsz_data_hor = wx.BoxSizer(wx.HORIZONTAL) wsz_data_hor.Add(self.outputtext, 0, wx.LEFT | wx.BOTTOM | wx.ALIGN_TOP, border=10) # -- Right-side containter for the label, input, checkbox and button wsz_data_hor_side = wx.BoxSizer(wx.VERTICAL) wsz_data_hor_side.Add(self.inputHexLabel, 0, wx.LEFT, border=10) wsz_data_hor_side.Add(self.inputtextHEX, 0, wx.LEFT, border=10) wsz_data_hor_side.Add(self.inputHexCheckbox, 0, wx.LEFT | wx.BOTTOM, border=10) wsz_data_hor_side.Add(self.inputSendCRCheckBox, 0, wx.LEFT | wx.BOTTOM, border=10) wsz_data_hor_side.Add(self.inputSendLFCheckBox, 0, wx.LEFT | wx.BOTTOM, border=10) wsz_data_hor_side.Add(self.btn_send, 0, wx.LEFT | wx.RIGHT | wx.ALIGN_LEFT, border=10) wsz_data_hor.Add(wsz_data_hor_side, flag=wx.ALIGN_TOP, border=0) wsz.Add(wsz_data_hor, flag=wx.ALIGN_TOP, border=10, proportion=1) # add to vertical self.btn_cnct.SetMinSize(size=(80, 30)) self.disableControls() ## self.outputtext.Disable() ## self.btn_cnct.Disable() ## self.btn_send.Disable() ## self.inputtextHEX.Disable() ## self.inputHexCheckbox.Disable() #self.panel.SetSizerAndFit(wsz,True) self.panel.SetSizer(wsz) self.Show() def cmbChanged(self, event): p = self.comboboxCOMport.GetValue() self.btn_cnct.Enable() #print(p) def sendHexDataChecked(self, event): if self.inputHexCheckbox.GetValue() == True: self.outputtext.Disable() self.inputtextHEX.Enable() self.inputSendLFCheckBox.Disable() self.inputSendCRCheckBox.Disable() else: self.outputtext.Enable() self.inputtextHEX.Disable() self.inputSendLFCheckBox.Enable() self.inputSendCRCheckBox.Enable() def getComportsList(self): coms = list() i = 0 for port in serial.tools.list_ports.comports(): coms.append(str(port)[0:5]) #print (coms[i]) i += 1 return coms def connectToUSBISS(self, event): if self.btn_cnct.GetLabel() == "Connect": self._iss = UsbIss() p = self.comboboxCOMport.GetValue() self._iss.open(p) try: self._id = self._iss.read_module_id() except UsbIssError as e: wx.MessageBox("Module not identified!", "Module not identified!", wx.OK, self) self._id = 99 if self._id != 7: self.infotext.SetLabel( "Error: Module not identified! Port closed.") self._iss.close() self._iss = None else: self._fwv = self._iss.read_fw_version() self._ser = self._iss.read_serial_number() speed = self.getSelectedPortSpeed( self._comboboxSpeed.GetStringSelection()) self._iss.setup_serial(speed, defs.IOType.DIGITAL_INPUT, defs.IOType.DIGITAL_INPUT) self._currmode = self._iss.read_iss_mode() txt = _infotext.format(self._id, self._fwv, self._ser, self._currmode) self.infotext.SetLabel(txt) self.btn_cnct.SetLabel("Disconnect") self.enableControls() self.panel.Layout() #start receiving in separate thread self.updateTimer.Start(milliseconds=10, oneShot=wx.TIMER_CONTINUOUS) else: self.updateTimer.Stop() self._iss.close() self._iss = None self.infotext.SetLabel("Connection closed...") self.btn_cnct.SetLabel("Connect") self.disableControls() self.btn_cnct.Enable() def disableControls(self): self.outputtext.Disable() self.btn_cnct.Disable() self.btn_send.Disable() self.inputtextHEX.Disable() self.inputHexCheckbox.Disable() self.inputtext.Disable() self.inputSendLFCheckBox.Disable() self.inputSendCRCheckBox.Disable() def enableControls(self): self.outputtext.Enable() self.btn_send.Enable() self.inputtext.Enable() self.inputHexCheckbox.Enable() self.inputtextHEX.Enable() if self.inputHexCheckbox.GetValue() == True: self.inputtextHEX.Enable() self.outputtext.Disable() else: self.outputtext.Enable() self.inputSendLFCheckBox.Enable() self.inputSendCRCheckBox.Enable() self.inputtextHEX.Disable() def handleSerialData(self): mystr = str() try: # Get bytes from the USB ISS serial port r_bytes = self._iss.serial.receive() if r_bytes is not None: if len(r_bytes) > 0: for b in r_bytes: mystr += chr(b) mystr = mystr.rstrip() #print(mystr) return mystr.rstrip() except UsbIssError as e: print("Error: " + str(e)) def updateReadDataWindow(self, event): if self._iss is None: self.updateTimer.Stop() data = self.handleSerialData() if data is not None: self.inputtext.AppendText(data) def hexboxtextChanged(self, event): key = event.GetUnicodeKey() if key == 13: try: inChrs = self.inputtextHEX.GetValue().rstrip().upper() hexStr = bytes.fromhex(inChrs) hexStrConv = binascii.hexlify(hexStr) #print(hexStr) #print(hexStrConv) self._iss.serial.transmit(list(hexStr)) except ValueError as e: #wrongInputMSg(self,e) wx.MessageBox( "Please enter ONLY HEX values (without 0x -prefix) with even count. For example: \"aa55ff\".", "Wrong number of bytes!", wx.OK, self) print(str(e)) def getHexData(self): _hexStr = 0 try: _inChrs = self.inputtextHEX.GetValue().rstrip().upper() _hexStr = bytes.fromhex(_inChrs) except ValueError as e: wx.MessageBox( "Please enter ONLY HEX values (without 0x -prefix) with even count. For example: \"aa55ff\".", "Wrong number of bytes!", wx.OK, self) return _hexStr def sendSerialData(self, event): if self._iss is not None: if self.inputHexCheckbox.GetValue() == True: data = self.getHexData() if data != 0: self._iss.serial.transmit(list(data)) else: data = self.outputtext.GetValue() if self.inputSendLFCheckBox.GetValue() == True: if self.inputSendCRCheckBox.GetValue(): data = data.replace('\n', '\r\n') else: data = data.replace('\n', '') if len(data) > 0: self._iss.serial.transmit(list(bytearray(data, 'utf-8'))) #self._iss.serial.transmit([0x64,0x61,0x74,0x61]) #time.sleep(0.5) #response = self._iss.serial.receive() else: wx.MessageBox("No Connection...", "Cannot send data!", wx.OK, self) def getSelectedPortSpeed(self, comp): sl = self._comspeeds i = 0 #handle the special case 1M here directly if comp == "1M": return 1000000 while i < len(sl): if comp == sl[i]: return int(sl[i]) i += 1 return 115200 #default value
class TestUSbIss(unittest.TestCase): def setUp(self): self.usb_iss = UsbIss() self.driver = Mock() self.usb_iss._drv = self.driver def test_open(self): self.usb_iss.open('PORTNAME') assert_that(self.driver.open, called_once_with('PORTNAME')) def test_close(self): self.usb_iss.open('PORTNAME') self.usb_iss.close() assert_that(self.driver.close, called_once()) def test_setup_i2c(self): test_matrix = [ (20, False, 0x20), (50, False, 0x30), (100, False, 0x40), (400, False, 0x50), (100, True, 0x60), (400, True, 0x70), (1000, True, 0x80), ] for (clk_khz, use_i2c_hardware, i2c_mode) in test_matrix: self.usb_iss.setup_i2c( clock_khz=clk_khz, use_i2c_hardware=use_i2c_hardware, io1_type=defs.IOType.OUTPUT_LOW, io2_type=defs.IOType.OUTPUT_HIGH) assert_that(self.driver.write_cmd, called_with(0x5A, [0x02, i2c_mode, 0x04])) def test_setup_i2c_default_values(self): self.usb_iss.setup_i2c() assert_that(self.driver.write_cmd, called_once_with(0x5A, [ 0x02, defs.Mode.I2C_H_400KHZ.value, defs.IOType.DIGITAL_INPUT.value << 2 | defs.IOType.DIGITAL_INPUT.value])) def test_setup_i2c_failure(self): self.driver.check_ack_error_code.side_effect = UsbIssError assert_that(calling(self.usb_iss.setup_i2c), raises(UsbIssError)) assert_that(self.driver.check_ack_error_code, called_once_with(defs.ModeError)) def test_setup_i2c_invalid_clock_rate(self): assert_that(calling(self.usb_iss.setup_i2c). with_args(clock_khz=942), raises(UsbIssError, "Invalid clk_khz value")) def test_setup_i2c_invalid_hw_clock_rate(self): assert_that(calling(self.usb_iss.setup_i2c). with_args(clock_khz=50, use_i2c_hardware=True), raises(AssertionError, "I2C HW mode doesn't support 50kHz")) def test_setup_i2c_invalid_sw_clock_rate(self): assert_that(calling(self.usb_iss.setup_i2c). with_args(clock_khz=1000, use_i2c_hardware=False), raises(AssertionError, "I2C SW mode doesn't support 1000kHz")) def test_setup_i2c_serial(self): test_matrix = [ (20, False, 0x21), (50, False, 0x31), (100, False, 0x41), (400, False, 0x51), (100, True, 0x61), (400, True, 0x71), (1000, True, 0x81), ] for (clk_khz, use_i2c_hardware, i2c_mode) in test_matrix: self.usb_iss.setup_i2c_serial( clock_khz=clk_khz, use_i2c_hardware=use_i2c_hardware) assert_that(self.driver.write_cmd, called_with(0x5A, [0x02, i2c_mode, 0x01, 0x37])) def test_setup_i2c_serial_baud_rates(self): test_matrix = [ (300, [0x27, 0x0F]), (1200, [0x09, 0xC3]), (2400, [0x04, 0xE1]), (9600, [0x01, 0x37]), (19200, [0x00, 0x9B]), (38400, [0x00, 0x4D]), (57600, [0x00, 0x33]), (115200, [0x00, 0x19]), ] for (baud_rate, divisor) in test_matrix: self.usb_iss.setup_i2c_serial(baud_rate=baud_rate) assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, defs.Mode.I2C_H_400KHZ.value | 0x01] + divisor)) def test_setup_i2c_serial_default_values(self): self.usb_iss.setup_i2c_serial() assert_that(self.driver.write_cmd, called_once_with(0x5A, [ 0x02, defs.Mode.I2C_H_400KHZ.value | 0x01, 0x01, 0x37])) def test_setup_i2c_serial_overflow(self): self.usb_iss.setup_i2c_serial(baud_rate=1) assert_that(self.driver.write_cmd, called_once_with(0x5A, [ 0x02, defs.Mode.I2C_H_400KHZ.value | 0x01, 0xFF, 0xFF])) def test_setup_i2c_serial_failure(self): self.driver.check_ack_error_code.side_effect = UsbIssError assert_that(calling(self.usb_iss.setup_i2c_serial), raises(UsbIssError)) assert_that(self.driver.check_ack_error_code, called_once_with(defs.ModeError)) def test_setup_spi(self): test_matrix = [ (3000, 1), (500, 11), (23, 255), ] for (clk_khz, divisor) in test_matrix: self.usb_iss.setup_spi( spi_mode=defs.SPIMode.TX_IDLE_TO_ACTIVE_IDLE_HIGH, clock_khz=clk_khz) assert_that(self.driver.write_cmd, called_with(0x5A, [0x02, 0x93, divisor])) def test_setup_spi_default_values(self): self.usb_iss.setup_spi() assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x02, 0x90, 11])) def test_setup_spi_overflow(self): self.usb_iss.setup_spi(clock_khz=1) assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x02, 0x90, 0xFF])) def test_setup_spi_failure(self): self.driver.check_ack_error_code.side_effect = UsbIssError assert_that(calling(self.usb_iss.setup_spi), raises(UsbIssError)) assert_that(self.driver.check_ack_error_code, called_once_with(defs.ModeError)) def test_setup_io(self): self.usb_iss.setup_io( io1_type=defs.IOType.OUTPUT_LOW, io2_type=defs.IOType.OUTPUT_HIGH, io3_type=defs.IOType.ANALOGUE_INPUT, io4_type=defs.IOType.DIGITAL_INPUT) assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x02, 0x00, 0xB4])) def test_setup_io_default_values(self): self.usb_iss.setup_io() assert_that(self.driver.write_cmd, called_once_with(0x5A, [ 0x02, 0x00, defs.IOType.DIGITAL_INPUT.value << 6 | defs.IOType.DIGITAL_INPUT.value << 4 | defs.IOType.DIGITAL_INPUT.value << 2 | defs.IOType.DIGITAL_INPUT.value])) def test_setup_io_failure(self): self.driver.check_ack_error_code.side_effect = UsbIssError assert_that(calling(self.usb_iss.setup_io), raises(UsbIssError)) assert_that(self.driver.check_ack_error_code, called_once_with(defs.ModeError)) def test_change_io(self): self.usb_iss.change_io( io1_type=defs.IOType.OUTPUT_LOW, io2_type=defs.IOType.OUTPUT_HIGH, io3_type=defs.IOType.ANALOGUE_INPUT, io4_type=defs.IOType.DIGITAL_INPUT) assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x02, 0x10, 0xB4])) def test_change_io_default_values(self): self.usb_iss.change_io() assert_that(self.driver.write_cmd, called_once_with(0x5A, [ 0x02, 0x10, defs.IOType.DIGITAL_INPUT.value << 6 | defs.IOType.DIGITAL_INPUT.value << 4 | defs.IOType.DIGITAL_INPUT.value << 2 | defs.IOType.DIGITAL_INPUT.value])) def test_change_io_failure(self): self.driver.check_ack_error_code.side_effect = UsbIssError assert_that(calling(self.usb_iss.change_io), raises(UsbIssError)) assert_that(self.driver.check_ack_error_code, called_once_with(defs.ModeError)) def test_setup_serial_baud_rates(self): test_matrix = [ (300, [0x27, 0x0F]), (1200, [0x09, 0xC3]), (2400, [0x04, 0xE1]), (9600, [0x01, 0x37]), (19200, [0x00, 0x9B]), (38400, [0x00, 0x4D]), (57600, [0x00, 0x33]), (115200, [0x00, 0x19]), ] for (baud_rate, divisor) in test_matrix: self.usb_iss.setup_serial(baud_rate=baud_rate, io3_type=defs.IOType.OUTPUT_LOW, io4_type=defs.IOType.OUTPUT_HIGH) assert_that(self.driver.write_cmd, called_with(0x5A, [0x02, 0x01] + divisor + [0x40])) def test_setup_serial_default_values(self): self.usb_iss.setup_serial() assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x02, 0x01, 0x01, 0x37, defs.IOType.DIGITAL_INPUT.value << 6 | defs.IOType.DIGITAL_INPUT.value << 4])) def test_setup_serial_failure(self): self.driver.check_ack_error_code.side_effect = UsbIssError assert_that(calling(self.usb_iss.setup_serial), raises(UsbIssError)) assert_that(self.driver.check_ack_error_code, called_once_with(defs.ModeError)) def test_read_module_id(self): self.driver.read.return_value = [0x07, 0x02, 0x40] result = self.usb_iss.read_module_id() assert_that(result, is_(0x07)) assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x01])) assert_that(self.driver.read, called_once_with(3)) def test_read_fw_version(self): self.driver.read.return_value = [0x07, 0x02, 0x40] result = self.usb_iss.read_fw_version() assert_that(result, is_(0x02)) assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x01])) assert_that(self.driver.read, called_once_with(3)) def test_read_iss_mode(self): self.driver.read.return_value = [0x07, 0x02, 0x40] result = self.usb_iss.read_iss_mode() assert_that(result, is_(defs.Mode.I2C_S_100KHZ)) assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x01])) assert_that(self.driver.read, called_once_with(3)) def test_read_iss_mode_with_serial(self): self.driver.read.return_value = [0x07, 0x02, 0x71] result = self.usb_iss.read_iss_mode() assert_that(result, is_(defs.Mode.SERIAL_I2C_H_400KHZ)) assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x01])) assert_that(self.driver.read, called_once_with(3)) def test_read_serial_number(self): self.driver.read.return_value = [ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31] result = self.usb_iss.read_serial_number() assert_that(result, is_("00000001")) assert_that(self.driver.write_cmd, called_once_with(0x5A, [0x03])) assert_that(self.driver.read, called_once_with(8)) def test_setup_io_then_change_io_defaults(self): self.usb_iss.setup_io( io1_type=defs.IOType.OUTPUT_LOW, io2_type=defs.IOType.OUTPUT_HIGH, io3_type=defs.IOType.ANALOGUE_INPUT, io4_type=defs.IOType.DIGITAL_INPUT) assert_that(self.driver.write_cmd, called_with(0x5A, [0x02, 0x00, 0xB4])) self.usb_iss.change_io() assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, 0x10, defs.IOType.DIGITAL_INPUT.value << 6 | defs.IOType.ANALOGUE_INPUT.value << 4 | defs.IOType.OUTPUT_HIGH.value << 2 | defs.IOType.OUTPUT_LOW.value])) def test_setup_io_then_change_io(self): self.usb_iss.setup_io( io1_type=defs.IOType.OUTPUT_LOW, io2_type=defs.IOType.OUTPUT_HIGH, io3_type=defs.IOType.ANALOGUE_INPUT, io4_type=defs.IOType.DIGITAL_INPUT) assert_that(self.driver.write_cmd, called_with(0x5A, [0x02, 0x00, 0xB4])) self.usb_iss.change_io( io1_type=defs.IOType.DIGITAL_INPUT, io2_type=defs.IOType.ANALOGUE_INPUT, io3_type=defs.IOType.OUTPUT_HIGH, io4_type=defs.IOType.OUTPUT_LOW) assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, 0x10, defs.IOType.OUTPUT_LOW.value << 6 | defs.IOType.OUTPUT_HIGH.value << 4 | defs.IOType.ANALOGUE_INPUT.value << 2 | defs.IOType.DIGITAL_INPUT.value])) def test_setup_io_then_change_io_partial(self): self.usb_iss.setup_io( io1_type=defs.IOType.OUTPUT_LOW, io2_type=defs.IOType.OUTPUT_HIGH, io3_type=defs.IOType.ANALOGUE_INPUT, io4_type=defs.IOType.DIGITAL_INPUT) assert_that(self.driver.write_cmd, called_with(0x5A, [0x02, 0x00, 0xB4])) self.usb_iss.change_io( io1_type=defs.IOType.DIGITAL_INPUT, io3_type=defs.IOType.OUTPUT_HIGH) assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, 0x10, defs.IOType.DIGITAL_INPUT.value << 6 | defs.IOType.OUTPUT_HIGH.value << 4 | defs.IOType.OUTPUT_HIGH.value << 2 | defs.IOType.DIGITAL_INPUT.value])) def test_setup_io_then_setup_i2c_override(self): self.usb_iss.setup_io( io1_type=defs.IOType.OUTPUT_LOW, io2_type=defs.IOType.OUTPUT_HIGH, io3_type=defs.IOType.ANALOGUE_INPUT, io4_type=defs.IOType.DIGITAL_INPUT) assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, 0x00, defs.IOType.DIGITAL_INPUT.value << 6 | defs.IOType.ANALOGUE_INPUT.value << 4 | defs.IOType.OUTPUT_HIGH.value << 2 | defs.IOType.OUTPUT_LOW.value])) self.usb_iss.setup_i2c( io1_type=defs.IOType.DIGITAL_INPUT, io2_type=defs.IOType.ANALOGUE_INPUT) assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, defs.Mode.I2C_H_400KHZ.value, defs.IOType.ANALOGUE_INPUT.value << 2 | defs.IOType.DIGITAL_INPUT.value])) def test_setup_io_then_setup_i2c_defaults(self): self.usb_iss.setup_io( io1_type=defs.IOType.OUTPUT_LOW, io2_type=defs.IOType.OUTPUT_HIGH, io3_type=defs.IOType.ANALOGUE_INPUT, io4_type=defs.IOType.DIGITAL_INPUT) assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, 0x00, defs.IOType.DIGITAL_INPUT.value << 6 | defs.IOType.ANALOGUE_INPUT.value << 4 | defs.IOType.OUTPUT_HIGH.value << 2 | defs.IOType.OUTPUT_LOW.value])) self.usb_iss.setup_i2c() assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, defs.Mode.I2C_H_400KHZ.value, defs.IOType.OUTPUT_HIGH.value << 2 | defs.IOType.OUTPUT_LOW.value])) def test_setup_i2c_defaults_then_change_io_partial(self): self.usb_iss.setup_i2c() assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, defs.Mode.I2C_H_400KHZ.value, defs.IOType.DIGITAL_INPUT.value << 2 | defs.IOType.DIGITAL_INPUT.value])) self.usb_iss.change_io( io1_type=defs.IOType.OUTPUT_LOW, io4_type=defs.IOType.OUTPUT_HIGH) assert_that(self.driver.write_cmd, called_with(0x5A, [ 0x02, 0x10, defs.IOType.OUTPUT_HIGH.value << 6 | defs.IOType.DIGITAL_INPUT.value << 4 | defs.IOType.DIGITAL_INPUT.value << 2 | defs.IOType.OUTPUT_LOW.value]))
class I2C_ISS(object): """ self.port : ex. "COM1"\n self.Slave_Addr : Input slave address(8-bit Address).\n self.print_debug : Print log = 1; Not to print log = 0; \n """ def __init__(self, port, print_debug=0, Slave_Addr=0xA0, speed=400): self.port = port # 7bit Address self.Slave_Addr = (Slave_Addr >> 1) self.print_debug = print_debug self.speed = speed self.iss = UsbIss() self.iss.open(self.port) self.iss.setup_i2c(self.speed) #print ("[Interface] Open ") + self.port + "\n" def ISS_PORT_CLOSE(self): self.iss.close() # Basic Function def I2C_READ(self, address, number): """ USB-ISS Read # byte must be in range(0, 256) """ data = [0] * number start = 0 end = 0 while (number > 0): if number < 60: end += number #if self.print_debug == 1: #print "start = ", start, "end = ", end, "address = ", address, "number = ", number data[start:end] = self.iss.i2c.read(self.Slave_Addr, address, number) break else: end += 60 #if self.print_debug == 1: #print "start = ", start, "end = ", end, "address = ", address, "number = ", number data[start:end] = self.iss.i2c.read(self.Slave_Addr, address, 60) start += 60 address += 60 if ((number - 60) >= 0): number -= 60 if (address >= 256): address -= 128 if self.print_debug == 1: print("Read Value = " + str.join("", ("0x%02X, " % a for a in data[0:end]))) return data def I2C_CURRENT_READ(self, number): data = [0] * number start = 0 end = 0 while (number > 0): if number < 60: end += number #if self.print_debug == 1: #print "start = ", start, "end = ", end, "address = ", address, "number = ", number data[start:end] = self.iss.i2c.read_ad0( self.Slave_Addr, number) break else: end += 60 #if self.print_debug == 1: #print "start = ", start, "end = ", end, "address = ", address, "number = ", number data[start:end] = self.iss.i2c.read_ad0(self.Slave_Addr, 60) start += 60 address += 60 if ((number - 60) >= 0): number -= 60 if (address >= 256): address -= 128 return data def I2C_WRITE(self, byte, data): """ USB-ISS Write """ return_check = 0 byte_shift = 60 count = 0 Start_address = byte number_of_byte = len(data) # Modify by Lance while (1): if number_of_byte > 60: return_check = self.iss.i2c.write( self.Slave_Addr, Start_address, data[(0 + byte_shift * count):(60 + byte_shift * count)]) Start_address += 60 number_of_byte -= 60 count += 1 else: return_check = self.iss.i2c.write( self.Slave_Addr, Start_address, data[(0 + byte_shift * count):(60 + number_of_byte)]) break # Modify by Lance # return_check = self.iss.i2c.write(self.Slave_Addr, byte, data) # write > 60 bytes will error time.sleep(USB_ISS_Write_delay) if self.print_debug == 1: if byte == 0x7F: print("Page select = " + str.join("", ("0x%02X, " % a for a in data))) else: print("Write Value = " + str.join("", ("0x%02X, " % a for a in data))) return return_check # Addictional Function def I2C_PAGE_SELECT(self, page): data = [0xFF] self.I2C_WRITE(0x7F, page) time.sleep(USB_ISS_Write_delay) data = self.I2C_READ(0x7F, 1) if data != page: print("Change Page %s Fail") % hex(data[0]) def MODULE_MODE_CONTROL(self, en): self.I2C_WRITE(0x7F, [0xE6]) time.sleep(0.08) self.I2C_WRITE(0xF0, en) time.sleep(0.08) if self.print_debug == 1: print("Manual Mode = " + en) def I2C_READ_Vendor_Info(self): self.I2C_WRITE(0x7F, [0x00]) time.sleep(USB_ISS_Write_delay) # Vendor PN TEMP_DATA_Vendor_Info = self.I2C_READ(0x94, 16) # Number to ASCII for x in range(len(TEMP_DATA_Vendor_Info)): TEMP_DATA_Vendor_Info[x] = chr(TEMP_DATA_Vendor_Info[x]) print(TEMP_DATA_Vendor_Info) # Vendor SN TEMP_DATA_Vendor_Info = self.I2C_READ(0xA6, 16) # Number to ASCII for x in range(len(TEMP_DATA_Vendor_Info)): TEMP_DATA_Vendor_Info[x] = chr(TEMP_DATA_Vendor_Info[x]) print(TEMP_DATA_Vendor_Info) # For 400G DR4 Only def TWI_DSP_Direct_Read(self, reg, reg_name): self.I2C_PAGE_SELECT(0xB3) self.I2C_WRITE(0xF4, reg) time.sleep(USB_ISS_Write_delay) self.I2C_WRITE(0xF3, [0x01]) time.sleep(0.02) self.reg = reg_name self.data = self.I2C_READ(0xFA, 2) #print ("Read Data = "+ str.join("", ("%02X" % a for a in data))) print(self.reg + " (Read) = 0x" + str.join("", ("%02X" % a for a in self.data))) def TWI_DSP_Direct_Wirte(self, reg, reg_name, Write_data): self.I2C_PAGE_SELECT(0xB3) self.I2C_WRITE(0xF4, reg) time.sleep(USB_ISS_Write_delay) self.I2C_WRITE(0xFA, Write_data) time.sleep(USB_ISS_Write_delay) self.I2C_WRITE(0xF3, [0x00]) time.sleep(0.02) self.reg = reg_name self.data = self.I2C_READ(0xFA, 2) #print ("Write Data", str.join("",("%02x" % a for a in self.data))) print(self.reg + " (Write) = 0x" + str.join("", ("%02X" % a for a in self.data))) def SW_RESET(self, delay): print('Software Reset!') self.I2C_WRITE(26, [0x08]) print('wait ') + str(delay) + 's' time.sleep(delay) def Quick_HPMode(self, delay): print('Quick_HPMode!') self.I2C_WRITE(26, [0x00]) print('wait ') + str(delay) + 's' time.sleep(delay) def Write_Password(self): print('Write_Password!\n') self.I2C_WRITE(0x7A, [0x43, 0x4A, 0x2D, 0x4C]) time.sleep(0.02)
class I2C_Dongle_USBISS(I2C_Dongle): def __init__(self, port): try: self.port = int(port) if port else 0 except ValueError: self.port = 0 self.iss = None def get_port(self): if self.port != 0: return 'COM' + str(self.port) plist = list(serial.tools.list_ports.comports()) for p in plist: if sys.platform.startswith('win32'): if p.vid == 0x04D8 and p.pid == 0xFFEE: return p.device elif sys.platform.startswith('linux'): if 'USB VID:PID=04d8:ffee' in p[2]: return p[0] raise UsbIssError("\nCan't find usb-iss device!\n") def open_device(self, bitrate=400): try: self.iss = UsbIss() self.iss.open(self.get_port()) self.iss.setup_i2c(clock_khz=bitrate) except Exception as ex: print(ex) raise UsbIssError("\ninitial usb-iss device error!\n") def write(self, slave_addr, reg_addr, data, **kwargs): try: data_write = data[:] len_take = 15 if reg_addr is None else 14 end = math.ceil(len(data_write) / len_take) for t in range(int(end)): data_out = data_write[t * len_take:(t + 1) * len_take] if t == 0: if reg_addr is not None: data_out.insert(0, reg_addr) # reg_addr data_out.insert(0, slave_addr) # slave_addr data_out.insert(0, 0x30 + len(data_out) - 1) # write length data_out.insert(0, 0x01) # i2c start else: data_out.insert(0, 0x30 + len(data_out) - 1) # write length if t == end - 1: data_out.append(0x03) # i2c stop self.iss.i2c.direct(data_out) except: return -1 return 0 def read(self, slave_addr, reg_addr, num_bytes, **kwargs): data_in = [] try: read_bytes_per_time = 16 max_loop_num = math.ceil(num_bytes / read_bytes_per_time) num = 0 while num < max_loop_num: if num_bytes - num * read_bytes_per_time < read_bytes_per_time: read_bytes_per_time = num_bytes - num * read_bytes_per_time data_out = [] if num == max_loop_num - 1: data_out.insert(0, defs.I2CDirect.STOP) data_out.insert(0, defs.I2CDirect.READ1) data_out.insert(0, defs.I2CDirect.NACK) if read_bytes_per_time > 1: data_out.insert(0, 0x20 + read_bytes_per_time - 2) else: data_out.insert(0, 0x20 + read_bytes_per_time - 1) if num == 0: data_out.insert(0, slave_addr | 0x01) data_out.insert(0, defs.I2CDirect.WRITE1) if reg_addr is not None: data_out.insert(0, defs.I2CDirect.RESTART) data_out.insert(0, reg_addr) data_out.insert(0, slave_addr) data_out.insert(0, defs.I2CDirect.WRITE2) data_out.insert(0, defs.I2CDirect.START) data_in += self.iss.i2c.direct(data_out) num += 1 except: del data_in[:] return len(data_in), data_in def close_device(self): if self.iss: self.iss.close()