Class Target

extends Object
An ESP32 SPI target that handles one transaction at a time with a controller.
The transfer method arms the peripheral before suspending the calling Toit task.
SPI does not define a standard register protocol. Protocols that interpret the first received bytes as commands or addresses should be built on top of this transaction API.
The ordinary ESP32 SPI target peripheral does not provide progress watermarks within one transaction. Large continuously clocked streams therefore need a separate chunked protocol in which the controller pauses between chunks or observes a ready signal.

Class summary


constructor --mosi/int= --miso/int= --clock/int --cs/int --mode/int= --transmit-lsb-first/bool= --receive-lsb-first/bool= --max-transfer-size/int= --dma/bool=
Constructs an SPI target.

Constructors

constructor --mosi/int=null --miso/int=null --clock/int --cs/int --mode/int=0 --transmit-lsb-first/bool=false --receive-lsb-first/bool=false --max-transfer-size/int=DEFAULT-TARGET-MAX-TRANSFER-SIZE --dma/bool=true
Constructs an SPI target.
The clock and cs GPIOs are required. At least one of mosi and miso must be provided; pass null for an unused data direction. All pins are reserved until close is called.
mode selects clock polarity and phase in the range 0 through 3.
transmit-lsb-first and receive-lsb-first independently select the bit order used on MISO and MOSI, respectively.
With dma enabled, transactions use preallocated DMA-capable buffers and can be as large as max-transfer-size. Without DMA, the ESP32 peripheral limits transactions to TARGET-NON-DMA-MAX-TRANSFER-SIZE bytes.
On the classic ESP32, target DMA cannot reliably receive and transmit at the same time. DMA reception is also unavailable in modes 1 and 3. Use non-DMA transactions of at most TARGET-NON-DMA-MAX-TRANSFER-SIZE bytes, or configure only one data direction. These restrictions do not apply to newer ESP32 variants.
Classic ESP32 target DMA commits received MOSI data in complete four-byte words. If the controller ends a transaction at another byte boundary, the trailing one to three bytes are discarded and are not returned by transfer.

Methods

close -> none
Closes the target and releases its peripheral, pins, and native buffers.
A transfer running in another task is aborted and throws CLOSED. Calling this method from that transfer's when-armed block is invalid.

operator == other/any -> bool
Whether this object is equal to the other.
By default, identical is used for equality.
Inheritance
Classes overwrite this operator to get an equality specific to their needs. Equality operators often compare the type and field contents. For example:

class Pin:
  number/int

  constructor .number:

  operator == other:
    if other is not Pin: return false
    return number == other.number
A class doesn't have to follow the above format, but it must keep the operator in sync with any hash-code method. That is, if a class has a hash-code member, then the equality and hash-code must agree. If two instances are equal (a == b), then their hash codes must also be equal (a.hash-code == b.hash-code).

Stringifies this object.
Inheritance
Objects that need a human-friendly string representation should overwrite this method. The default string is based on the internal class-ID.

transfer transmit/ByteArray=#[ ] --receive-size/int=transmit.size --fill-byte/int=0xff -> ByteArray
Arms and waits for one full-duplex SPI transaction.
Up to receive-size bytes received on MOSI are returned. If the controller deasserts CS before clocking all requested bytes, the returned array is correspondingly shorter. The target sends transmit on MISO and uses fill-byte for any remaining clocks. The maximum of the transmit and receive sizes is the maximum number of bytes accepted for this transaction.
If the task is interrupted or reaches its deadline after the peripheral is armed, the transaction is aborted and its native buffers are released before the exception is propagated.

transfer transmit/ByteArray=#[ ] --receive-size/int=transmit.size --fill-byte/int=0xff [--when-armed] -> ByteArray
Variant of transfer transmit that calls when-armed once the peripheral is armed.
The when-armed block runs before this method starts waiting for the controller. It can assert an application-level ready signal to tell the controller that it may start generating clocks. It must not call close or recursively call transfer; doing so throws INVALID_STATE.