Перейти к содержанию
Материалы раздела

SPI

SPI — синхронный последовательный интерфейс для связи микроконтроллера с периферийными устройствами. Lua RTOS работает ведущим и использует четыре сигнала:

  • SCK (CLK) — тактовый сигнал;
  • MOSI — данные от ведущего к ведомому;
  • MISO — данные от ведомого к ведущему;
  • CS — выбор ведомого устройства, обычно активный низким уровнем.

Несколько устройств могут совместно использовать SCK, MOSI и MISO, если у каждого есть отдельный CS. Параметры частоты и режима хранятся в экземпляре устройства и применяются при его выборе.

local device = spi.attach(
    spi.SPI2,
    spi.MASTER,
    pio.GPIO5,
    1000000,
    8,
    0
)

device:select()
device:write("Hello, Lua RTOS!")
device:deselect()

spi.pins([as_table])

Показать текущие назначения MISO, MOSI и CLK для доступных шин SPI.

Если as_table равен true, функция возвращает массив записей с полями id, miso, mosi и clk. В остальных случаях она выводит назначения в консоль и ничего не возвращает.

local buses = spi.pins(true)
for _, bus in ipairs(buses) do
    print(bus.id, bus.miso, bus.mosi, bus.clk)
end

spi.setpins(id, miso, mosi, clk)

Изменить назначение выводов шины до её первого подключения.

Аргументы:

  • id: идентификатор шины, например spi.SPI2;
  • miso: GPIO с поддержкой ввода;
  • mosi: GPIO с поддержкой вывода;
  • clk: GPIO с поддержкой вывода.

Значение -1 сохраняет текущее назначение соответствующего сигнала. MISO, MOSI и CLK должны использовать разные GPIO. Функция ничего не возвращает или вызывает исключение.

spi.setpins(spi.SPI2, pio.GPIO12, pio.GPIO13, pio.GPIO14)

device = spi.attach(id, mode, cs, speed, data_bits, spi_mode [, flags])

Подключить устройство SPI.

Аргументы:

  • id: идентификатор шины, например spi.SPI2;
  • mode: только spi.MASTER; ведомый режим spi.SLAVE не поддерживается;
  • cs: GPIO выбора устройства с поддержкой вывода. Он должен отличаться от MISO, MOSI и CLK. Значение -1 использует настроенный для шины вывод CS по умолчанию и вызывает исключение, если такой вывод не задан;
  • speed: частота SPI от 1 до 80 000 000 Гц. При ненативном назначении выводов драйвер ограничивает фактическую частоту значением 26 000 000 Гц;
  • data_bits: только 8; передачи по 16 и 32 бита не поддерживаются;
  • spi_mode: режим от 0 до 3;
  • flags (необязательно): spi.READ, spi.WRITE или их комбинация. По умолчанию используется spi.READ | spi.WRITE.
spi_modeCPOLCPHA
000
101
210
311

Возвращает экземпляр устройства или вызывает исключение. Один вывод CS нельзя одновременно подключить к двум экземплярам или повторно подключить, пока первый экземпляр не отключён через detach().

device:select()

Захватить шину, применить параметры устройства и активировать CS. Перед write() или readwrite() устройство должно быть выбрано. Повторный вызов без deselect() вызывает исключение. Завершить транзакцию через deselect() или detach() должна та же задача FreeRTOS, которая вызвала select().

device:deselect()

Передать оставшиеся в буфере данные, деактивировать CS и освободить шину. Если устройство не выбрано, функция ничего не делает.

device:write(data1 [, data2, ...])

Добавить данные в буфер передачи. Каждый аргумент может быть целым числом или бинарной строкой; у целого передаётся младший байт. Данные отправляются при заполнении внутреннего буфера, перед readwrite() или при вызове deselect().

device:select()
device:write(0x02, 0x00, 0x10, "data")
device:deselect()

bytes = device:readwrite(data1 [, data2, ...])

Выполнить полнодуплексную передачу. Аргументы кодируются так же, как в write(). Функция возвращает таблицу принятых байтов той же длины. Чтобы только прочитать данные, передайте нужное число фиктивных байтов, например 0x00.

Если до вызова в буфере оставались данные от write(), функция сначала передаёт их без сохранения одновременно принятых байтов, а затем выполняет полнодуплексный обмен для собственных аргументов.

device:select()
local response = device:readwrite(0x9f, 0x00, 0x00, 0x00)
device:deselect()

print(string.format(
    "JEDEC ID: %02X %02X %02X",
    response[2],
    response[3],
    response[4]
))

device:detach()

Отключить устройство и освободить его ресурсы. Если устройство выбрано, detach() сначала завершает транзакцию. После отключения остальные методы экземпляра вызывают исключение; повторный вызов detach() безопасен.