Skip to content

esp8266: SPI writes appear to be buffered and can finish after write call returns #62

Description

@tdicola

I noticed an interesting thing with ESP8266 SPI, given a simple function to test writing bytes like:

import nativeio
import board

spi = nativeio.SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)
while not spi.try_lock():
    pass
spi.configure(baudrate=1000000)

cs = nativeio.DigitalInOut(board.GPIO0)
cs.switch_to_output(value=True)

def test_spi(spi, cs):
    cs.value = False
    spi.write(bytearray([255, 128, 64, 32]))
    cs.value = True

I notice if I setup a Saleae and look at the pin output the CS pin toggles back up to true before the entire SPI write has finished going out the clock and MOSI lines. See below:
screen shot 2016-12-05 at 11 40 39 pm

The top line is the clock, middle line is MOSI, and bottom line is CS. Notice how 255, 128, 64 come through correctly but the last byte 32 isn't interpreted because the CS line (bottom row) jumps back up to a high value before the last byte finishes writing out the SPI lines.

It seems like perhaps the SPI data is buffered and we're not waiting for the buffer to finish draining before returning. It becomes problematic though in this case where you toggle CS and other lines around SPI transactions since you need to wait for the data to finish sending/receiving before changing those lines.

If I put in an explicit sleep before toggling CS low I do see the byte received as expected:
screen shot 2016-12-05 at 11 49 15 pm

Let's see if there's a bit to tell if the SPI buffer is drained and perhaps busy wait on that before returning from SPI.write.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions