клас SPI – протокол шини Serial Peripheral Interface (з боку контролера)

SPI – це синхронний послідовний протокол, яким керує контролер. На фізичному рівні шина складається з 3 ліній: SCK, MOSI, MISO. На одній шині можуть бути кілька пристроїв. Кожен пристрій повинен мати окремий четвертий сигнал CS (Chip Select) для вибору конкретного пристрою на шині, з яким відбувається обмін. Управління сигналом CS повинно здійснюватися у користувацькому коді (через клас machine.Pin).

Існують апаратні та програмні реалізації SPI через класи SPI і SoftSPI. Апаратний SPI використовує підтримку апаратного забезпечення системи для виконання читання/запису і зазвичай є ефективним і швидким, але може мати обмеження щодо того, які виводи можна використовувати. Програмний SPI реалізовано методом побітового маніпулювання і може використовуватися на будь-якому виводі, але є менш ефективним. Ці класи мають однакові доступні методи і відрізняються переважно способом конструювання.

Приклад використання:

from machine import SPI, Pin

spi = SPI(0, baudrate=400000)           # Create SPI peripheral 0 at frequency of 400kHz.
                                        # Depending on the use case, extra parameters may be required
                                        # to select the bus characteristics and/or pins to use.
cs = Pin(4, mode=Pin.OUT, value=1)      # Create chip-select on pin 4.

try:
    cs(0)                               # Select peripheral.
    spi.write(b"12345678")              # Write 8 bytes, and don't care about received data.
finally:
    cs(1)                               # Deselect peripheral.

try:
    cs(0)                               # Select peripheral.
    rxdata = spi.read(8, 0x42)          # Read 8 bytes while writing 0x42 for each byte.
finally:
    cs(1)                               # Deselect peripheral.

rxdata = bytearray(8)
try:
    cs(0)                               # Select peripheral.
    spi.readinto(rxdata, 0x42)          # Read 8 bytes inplace while writing 0x42 for each byte.
finally:
    cs(1)                               # Deselect peripheral.

txdata = b"12345678"
rxdata = bytearray(len(txdata))
try:
    cs(0)                               # Select peripheral.
    spi.write_readinto(txdata, rxdata)  # Simultaneously write and read bytes.
finally:
    cs(1)                               # Deselect peripheral.

Конструктори

class machine.SPI(id: int, baudrate: int = 1000000, *, polarity: int = 0, phase: int = 0, bits: int = 8, firstbit: int = MSB, sck: Pin | None = None, mosi: Pin | None = None, miso: Pin | None = None)

Створює об’єкт SPI на заданій шині id. Значення id залежать від конкретного порту та його апаратного забезпечення. Значення 0, 1 тощо зазвичай використовуються для вибору апаратного блоку SPI №0, №1 тощо.

Без додаткових параметрів об’єкт SPI створюється, але не ініціалізується (він має налаштування з останньої ініціалізації шини, якщо вона була). Якщо вказані додаткові аргументи, шина ініціалізується. Параметри ініціалізації описані в init.

Методи

init(baudrate: int = 1000000, *, polarity: int = 0, phase: int = 0, bits: int = 8, firstbit: int = SPI.MSB, sck: Pin | None = None, mosi: Pin | None = None, miso: Pin | None = None) None

Ініціалізує шину SPI із заданими параметрами:

  • baudrate – це частота тактового сигналу SCK.

  • polarity може бути 0 або 1 і задає рівень, на якому перебуває лінія тактового сигналу у стані спокою.

  • phase може бути 0 або 1 для вибірки даних на першому або другому фронті тактового сигналу відповідно.

  • bits – ширина кожної передачі у бітах. Тільки значення 8 гарантовано підтримується всім апаратним забезпеченням.

  • firstbit може бути SPI.MSB або SPI.LSB.

  • sck, mosi, miso – об’єкти виводів (machine.Pin) для сигналів шини. Для більшості апаратних блоків SPI (що вибираються параметром id конструктора) виводи фіксовані і не можуть бути змінені. У деяких випадках апаратні блоки допускають 2-3 альтернативні набори виводів для апаратного блоку SPI. Довільне призначення виводів можливе лише для драйвера побітового маніпулювання SPI (id = -1).

У випадку апаратного SPI фактична частота тактового сигналу може бути нижчою за запитувану швидкість передачі. Це залежить від апаратного забезпечення платформи. Фактична швидкість може бути визначена шляхом виведення об’єкта SPI.

deinit() None

Вимикає шину SPI.

read(nbytes: int, write: int = 0x00) bytes

Читає кількість байт, вказану в nbytes, одночасно безперервно записуючи єдиний байт, заданий write. Повертає об’єкт bytes із прочитаними даними.

readinto(buf: bytearray, write: int = 0x00) None

Читає у буфер, вказаний у buf, одночасно безперервно записуючи єдиний байт, заданий write. Повертає None.

write(buf: bytes) None

Записує байти, що містяться у buf. Повертає None.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Записує байти з write_buf, одночасно читаючи у read_buf. Буфери можуть бути однаковими або різними, але обидва буфери повинні мати однакову довжину. Повертає None.

Константи

MSB: int

Передається до firstbit для передачі/прийому найзначущого біту першим (найпоширеніший порядок).

LSB: int

Передається до firstbit для передачі/прийому найменш значущого біту першим.

клас SoftSPI – шина SPI з програмною емуляцією

Клас SoftSPI реалізує SPI методом побітового маніпулювання довільними виводами GPIO. Він надає ту саму поверхню методів, що й SPI, тому існуючий код, орієнтований на апаратний SPI, може перейти на програмний лише зі зміною конструктора. Використовуйте його, коли потрібні виводи не підключені до апаратного блоку SPI, коли потрібно більше, ніж є доступних апаратних шин, або коли периферійний пристрій вимагає нестандартної фазування тактового сигналу, яку апаратне забезпечення не може забезпечити.

Конструктори

class machine.SoftSPI(baudrate: int = 500000, *, polarity: int = 0, phase: int = 0, bits: int = 8, firstbit: int = MSB, sck: Pin | None = None, mosi: Pin | None = None, miso: Pin | None = None)

Створює об’єкт програмного SPI. sck, mosi і miso обов’язкові – неявного вибору виводів немає. Значення інших параметрів описані в SPI.init(). baudrate за замовчуванням нижча, ніж для апаратного SPI, оскільки цикл побітового маніпулювання має більші накладні витрати.

Методи

init(baudrate: int = 500000, *, polarity: int = 0, phase: int = 0, bits: int = 8, firstbit: int = SoftSPI.MSB, sck: Pin | None = None, mosi: Pin | None = None, miso: Pin | None = None) None

Повторно ініціалізує програмну шину SPI із заданими параметрами. Оновлюються лише передані аргументи; інші зберігають попередні значення. Значення кожного аргументу описані в SPI.init().

deinit() None

Звільняє виводи GPIO, зайняті драйвером побітового маніпулювання, і припиняє керування шиною.

read(nbytes: int, write: int = 0x00) bytes

Читає nbytes байт, одночасно безперервно записуючи єдиний байт write. Повертає об’єкт bytes із отриманими даними.

readinto(buf: bytearray, write: int = 0x00) None

Читає у buf, одночасно безперервно записуючи єдиний байт write. Повертає None.

write(buf: bytes) None

Записує buf на шину. Отримані байти відкидаються.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Одночасно записує write_buf і читає у read_buf. Обидва буфери повинні мати однакову довжину; вони можуть збігатися.

Константи

MSB: int

Передається до firstbit для передачі/прийому найзначущого біту першим.

LSB: int

Передається до firstbit для передачі/прийому найменш значущого біту першим.