def transfer(self, data, assert_ss=True, deassert_ss=True):
if self._mosi is None:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT>if self._miso is None:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT>if assert_ss and self._ss is not None:<EOL><INDENT>self._gpio.set_low(self._ss)<EOL><DEDENT>result = bytearray(len(data))<EOL>for i in range(len(data)):<EOL><INDENT>for j in range(<NUM_LIT:8>):<EOL><INDENT>if self._write_shift(data[i], j) & self._mask:<EOL><INDENT>self._gpio.set_high(self._mosi)<EOL><DEDENT>else:<EOL><INDENT>self._gpio.set_low(self._mosi)<EOL><DEDENT>self._gpio.output(self._sclk, not self._clock_base)<EOL>if self._read_leading:<EOL><INDENT>if self._gpio.is_high(self._miso):<EOL><INDENT>result[i] |= self._read_shift(self._mask, j)<EOL><DEDENT>else:<EOL><INDENT>result[i] &= ~self._read_shift(self._mask, j)<EOL><DEDENT><DEDENT>self._gpio.output(self._sclk, self._clock_base)<EOL>if not self._read_leading:<EOL><INDENT>if self._gpio.is_high(self._miso):<EOL><INDENT>result[i] |= self._read_shift(self._mask, j)<EOL><DEDENT>else:<EOL><INDENT>result[i] &= ~self._read_shift(self._mask, j)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if deassert_ss and self._ss is not None:<EOL><INDENT>self._gpio.set_high(self._ss)<EOL><DEDENT>return result<EOL>
Full-duplex SPI read and write.  If assert_ss is true, the SS line
        will be asserted low, the specified bytes will be clocked out the MOSI
        line while bytes will also be read from the MISO line, and if
        deassert_ss is true the SS line will be put back high.  Bytes which are
        read will be returned as a bytearray object.