Command controller to write arbitrary TDI and TMS data to the
        physical scan chain. Optionally return TDO bits sent back
        from the scan chain.

        Args:
            tmsdata - bits to send over TMS line of scan chain (bitarray)
                      must be the same length ad tdidata
            tdidata - bits to send over TDI line of scan chain (bitarray)
                      must be the same length ad tmsdata
            return_tdo (bool) - return the devices bitarray response

        Returns:
            None by default or the (bitarray) response of the device
            after receiving data, if return_tdo is True.

        Usage:
            >>> from proteusisc import getAttachedControllers, bitarray
            >>> c = getAttachedControllers()[0]
            >>> c.jtag_enable()
            >>> c.write_tms_tdi_bits(bitarray("00001"),
                                     bitarray("11111"), return_tdo=True)
            >>> c.jtag_disable()

def write_tms_tdi_bits(self, tmsdata, tdidata, return_tdo=False):
        """
        Command controller to write arbitrary TDI and TMS data to the
        physical scan chain. Optionally return TDO bits sent back
        from the scan chain.

        Args:
            tmsdata - bits to send over TMS line of scan chain (bitarray)
                      must be the same length ad tdidata
            tdidata - bits to send over TDI line of scan chain (bitarray)
                      must be the same length ad tmsdata
            return_tdo (bool) - return the devices bitarray response

        Returns:
            None by default or the (bitarray) response of the device
            after receiving data, if return_tdo is True.

        Usage:
            >>> from proteusisc import getAttachedControllers, bitarray
            >>> c = getAttachedControllers()[0]
            >>> c.jtag_enable()
            >>> c.write_tms_tdi_bits(bitarray("00001"),
                                     bitarray("11111"), return_tdo=True)
            >>> c.jtag_disable()
        """
        self._check_jtag()
        if len(tmsdata) != len(tdidata):
            raise Exception("TMSdata and TDIData must be the same length")
        self._update_scanchain(tmsdata)
        count = len(tmsdata)

        t = time()
        outdata = bitarray([val for pair in zip(tmsdata, tdidata)
                            for val in pair])
        outdata = build_byte_align_buff(outdata).tobytes()[::-1]

        if self._scanchain and self._scanchain._print_statistics:
            print("TDI/TDI DATA PREP TIME", time()-t)#pragma: no cover
            t = time()

        self.bulkCommandDefault(_BMSG_WRITE_TMS_TDI % \
                  (return_tdo, count.to_bytes(4, 'little')))
        self.bulkWriteData(outdata)

        if self._scanchain and self._scanchain._print_statistics:
            print("TRANSFER TIME", time()-t)
            t = time()

        tdo_bits = self._read_tdo(count) if return_tdo else None

        if self._scanchain and self._scanchain._print_statistics:
            print("TDO READ TIME", time()-t)#pragma: no cover

        self._get_adv_trans_stats(0x0A, return_tdo)
        return tdo_bits