doceme / py-spidev

MIT License
461 stars 203 forks source link

Adding writebytes2 method #77

Closed dimas closed 6 years ago

dimas commented 6 years ago

Just like xfer3 it can accept lists of arbitrary size. In addition to that, it understands buffer protocol if passed object supports it. This greatly saves time when working with numpy arrays because we do not need to iterate over them.

dimas commented 6 years ago

Some background here - I am interfacing with SSD1351 OLED display driver and trying to write frames to it as quickly as possible. Each frame is 48K

The work here is kind of continuation of https://github.com/doceme/py-spidev/pull/75 - I just realised I am not really using proper "transfer" because I am not expecting anything back from the display and only need to write the data. So writebytes has some benefit over xfer that it does not have to manage receive buffer etc. But the writebytes still requires you to slice your data block into 4K chunks

So this patch adds writebytes2 that is different in the following ways:

  1. you can send lists of arbitrary size there, if slicing is required, it will be done internally
  2. for really small writes, avoid doing malloc/free and use a small on-stack local buffer instead.
  3. most importantly, if the object passed supports buffer protocol, just directly get its data.

In my case OLED frame is stored as numpy.array(..., dtype=numpy.uint8) and in order to pass it towritebytes before had to call tolist() on it. This tolist() plus the iteration loop performed by writebytes to build the txbuffer together cost about 14-17ms on my Raspberry Pi. Which is a lot of time when you try to achieve a decent framerate. By passing the same numpy array and letting writebytes2 gets its buffer, these 14-17ms are eliminated.