У процессора ADSP-BF538 Blackfin есть 3 штуки SPI-совместимых интерфейса (что такое SPI см. [2]). Обычно у SPI используется 4 сигнальных вывода: 2 для приема и передачи, 1 для тактов, и еще один для подачи сигнала выборки подчиненному устройству (иногда используются 3 сигнала, когда не нужно давать сигнал выборки, или даже 2 сигнала, если требуется передавать данные только в одном направлении). В такой конфигурации можно организовать достаточно быстрый дуплексный канал связи. SPI процессора BF538 поддерживает работу в режиме master, slave, а также режим с несколькими устройствами master. Можно менять скорость передачи и полярность/фазу сигнала тактов. Использование драйвера с открытым стоком позволяет поддерживать сценарий использования с несколькими устройствами master без опасности сквозных токов между несколькими выходами.
Примечание: там, где в тексте будет указано ADSP-BF538 или просто BF538, имеется в виду две модели процессора ADSP-BF538 и ADSP-BF538F. Непонятные термины и сокращения см. в разделе "Словарик" статьи [5].
Вот типичные примеры применения интерфейса SPI в электронике:
• Обмен данными с другими CPU или микроконтроллерами. • Подключение аппаратных кодеков. • Микросхемы аналого-цифровых преобразователей (ADC). • Микросхемы цифро-аналоговых преобразователей (DAC). • Преобразователи частот дискретизации. • Цифровые передатчики и приемники аудио-стандартов SP/DIF или AES/EBU. • Дисплеи LCD, OLED. • Регистры сдвига, расширители портов ввода/вывода. • Кристаллы FPGA с эмуляцией интерфейса SPI. • Программирование микросхем памяти и микроконтроллеров. • Подключение микросхем памяти, в том числе и FLASH-карт SD/miniSD/microSD.
На рис. 10-1 показана блок-схема SPI процессора Blackfin. Здесь MOSIx это сигнал передачи данных выход master вход slave, MISOx сигнал передачи данных вход master выход slave, SCKx это сигнал тактов, ~SPIxSS это сигнал выборки для подчиненного устройства (вместо x может быть подставлена цифра 0, 1 или 2). Обратите внимание, что на диаграмме сигналы MOSIx, MISOx, SCKx показаны двунаправленными потому, что направление передачи зависит от режима работы SPI - это может быть режим master (главное устройство на шине) или режим slave (подчиненное устройство). Но на самом деле в любой момент времени порт SPI может быть настроен либо как master, либо как slave, поэтому все сигналы будут исключительно однонаправленными.
Рис. 10-1. Блок-диаграмма SPI.
Вывод
Описание
MOSIx
Master Output Slave Input: выход данных главного устройства и вход данных подчиненного.
MISOx
Master Input Slave Output: вход данных главного устройства и выход данных подчиненного.
SCKx
Тактовый сигнал, который генерирует главное устройство. Для подчиненного устройства этот сигнал является входом.
~SPIxSS
Сигнал активации для подчиненного устройства, выставляемый главным устройством. Активный уровень лог. 0. Для процессора Blackfin этот сигнал всегда является входом, но его функция различается для режимов master и slave. Когда Blackfin работает как подчиненное устройство SPI (slave), то это сигнал выборки для него. Когда Blackfin работает как главное устройство SPI (master), то этот вход работает как сигнал ошибки.
~SPIxSELn
Сигнал активации для подчиненного устройства, выставляемый главным устройством. Активный уровень лог. 0. Для процессора Blackfin этот сигнал является выходом.
Примечание: вместо буквы x может быть подставлена цифра 0, 1 или 2, обозначающая номер интерфейса SPI. Вместо буквы n может быть подставлена цифра 1 для интерфейсов SPI1 и SPI2, или цифра 1..7 для интерфейса SPI0.
Интерфейс SPI в сущности построен на основе регистра сдвига, который последовательно передает и принимает биты данных, по одному биту за такт сигнала SCKx - таким способом происходит обмен с другими устройствами SPI. Данные SPI передаются и принимаются одновременно - когда происходит передача, данные последовательно выдвигаются из регистра сдвига через выходной сигнал данных и в это же время через вход данных вдвигаются в тот же самый регистр сдвига, но с другого его конца. Синхросигнал SCKx управляет сдвигом и выборкой данных.
Во время передач данных SPI одно из устройств на шине работает как главное (master), где оно управляет потоком данных генерацией сигнала тактов и сигнала выборки для подчиненного устройства (~SPIxSS). Другое устройство на шине работает как подчиненное (slave), и принимает новые данные от master в свой регистр сдвига через сигнал приема (MOSI), и одновременно передает данные из регистра сдвига через свой сигнал передачи (MISO).
Иногда система обмена построена так, что к шине подключено несколько устройств SPI. Тогда главное устройство (обычно это процессор или микроконтроллер) может передавать данные всем устройствам на шине одновременно (этот режим еще называется широковещанием, broadcast mode). Однако передавать данные на шину может только одно подчиненное устройство. Этого можно добиться в broadcast mode для SPI0, где несколько устройств могут быть выбраны для получения данных от master, но только одно slave-устройство может отправлять данные обратно к master. В условиях работы с несколькими master на шине (multimaster) или с несколькими устройствами на шине (multislave), когда несколько процессоров соединены друг с другом через свои порты SPI, все выводы MOSIx соединяются друг с другом, как и выводы MISOx и SCKx.
Для ситуации multislave процессор может использовать 7 выводов GPIO порта F, PF1–PF7, которые предназначены для подачи сигналов выборки для подчиненных устройств порта SPI0. Для SPI1 и SPI2 процессор использует один вывод GPIO для каждого сигнала выборки подчиненного устройства: SPI1 использует PD4, и SPI2 использует PD9.
Примечание: подробнее про GPIO порта F см. [3].
После сброса все блоки SPI процессора запрещены, и по умолчанию сконфигурированы в режим slave.
В таблицах приведена цоколевка ножек 316-выводного корпуса CSP BGA микроконтроллера Blackfin ADSP-BF538, подключенных к SPI0, SPI1, SPI2.
[SPI0]
Вывод
Ножка CSP BGA
MOSI0
G2
MISO0
F2
SCK0
G1
~SPI0SS/PF0
F1
~SPI0SEL1/PF1
E1
~SPI0SEL2/PF2
E2
~SPI0SEL3/PF3
B4
~SPI0SEL4/PF4
D1
~SPI0SEL5/PF5
D2
~SPI0SEL6/PF6
C1
~SPI0SEL7/PF7
C2
[SPI1]
Вывод
Ножка CSP BGA
MOSI1/PD0
C16
MISO1/PD1
C14
SCK1/PD2
C17
~SPI1SS/PD3
C15
~SPI1SEL1/PD4
C13
[SPI2]
Вывод
Ножка CSP BGA
MOSI2/PD5
C9
MISO2/PD6
C10
SCK2/PD7
C11
~SPI2SS/PD8
C8
~SPI2SEL1/PD9
C7
[Сигнал тактирования SCKx]
SCKx это сигнал тактирования SPI. Он генерируется master-устройством на шине, и управляет скоростью передачи данных в обоих направлениях. Устройство master может передавать данные с разными скоростями. За один передаваемый бит сигнал SCKx проходит 1 период своего сигнала. Когда устройство сконфигурировано как master, этот сигнал у него становится выходом, а когда как slave, то входом.
Такты SCKx вырабатываются не постоянно, а только во время активной передачи, и количество импульсов тактов соответствует битовой длине передаваемого слова (фрейма). Количество активных тактовых перепадов равно количеству бит данных, появляющихся друг за другом на сигналах MISOx и MOSIx. Подчиненные устройства игнорируют тактовый сигнал, если вход выборки подчиненного устройства (сигнал ~SPIxSS, который генерирует master) находится в неактивном состоянии (лог. 1).
SCKx используется для выдвигания наружу и вдвигания внутрь данных через выводы MOSIx и MISOx соответственно. Полярность и фаза тактов по отношению к сигналу данных программируется с помощью регистра управления SPI (SPI control register, SPIx_CTL), и определяют формат передачи (см. раздел "Форматы передачи SPI").
Сигнал SCK0 выделен для исключительного использования под такты SPI. Сигналы SCK1 и SCK2 являются выводами GPIO, соответственно PD2 и PD7. Убедитесь, что регистр PORTDIO_FER настроен для работы этих выводов как сигналов периферийного устройства (подробнее см. [4]).
[Вход: сигнал выборки периферийного устройства ~SPIxSS]
Это сигнал выборки для подчиненного устройства шины SPI, который вырабатывает главное устройство. Сигнал активен при лог. 0, и этим уровнем разрешается работа блока SPI процессора, когда SPI сконфигурирован как подчиненное устройство. Сигнал ~SPIxSS работает только как вход, и ведет себя как сигнал chip-select. Когда SPI процессора сконфигурирован как устройство master, сигнал ~SPIxSS может действовать как входной сигнал ошибки, когда используется обмен данными на шине с несколькими устройствами master (режим multimaster). В режиме multimaster, если выставлен сигнал ~SPIxSS для master (переведен в лог. 0), и разрешен бит PSSE в регистре SPIx_CTL, то произошла ошибка. Это означает, что другое устройство пытается стать master-ом шины SPI.
Примечание: бит PSSE в регистре SPIx_CTL разрешает функцию реагирования на внешний сигнал ошибки. Когда PSSE = 1, вход ~SPIxSS становится входом ошибки в режиме master. Иначе ~SPIxSS игнорируется.
Сигнал ~SPI0SS использует тот же самый вывод, что и PF0. Убедитесь, что не используете PF0 как выход, когда хотите его задействовать в качестве сигнала ~SPI0SS. Сигналы ~SPI1SS и ~SPI2SS это выводы GPIO (PD3 и PD8, соответственно). Убедитесь, что регистр PORTDIO_FER правильно настроил эти выводы для работы совместно с периферийным устройством (подробнее см. [4]).
[Master Out Slave In (MOSIx)]
Вывод MOSI0 выделен для исключительного использования под данные SPI0, а выводы MOSI1 и MOSI2 несут также общую функцию GPIO (PD0 и PD5 соответственно). Убедитесь, что в регистре PORTDIO_FER биты 0 и 5 настроены под периферийное устройство (подробнее см. [4]).
Вывод MOSIx работает как выход главного и вход подчиненного устройства (master-out-slave-in, сокращенно MOSI). Если процессор сконфигурирован как master, вывод MOSIx становится сигналом передачи (выходом), через который передаются данные к подчиненному устройству. Если процессор сконфигурирован как slave (подчиненное устройство), то вывод MOSIx становится сигналом приема (вход), через который поступают входные данные от главного устройства. При взаимодействии по шине SPI данные выдвигаются наружу из вывода MOSIx главного устройства и вдвигаются внутрь через MOSIx подчиненного устройства.
[Master In Slave Out (MISOx)]
Вывод MISOx работает как вход главного и выход подчиненного устройства (master-in-slave-out, сокращенно MISO). Если процессор сконфигурирован как master, вывод MISOx становится сигналом приема (вход), на который поступают данные от главного устройства. Если процессор сконфигурирован как slave, вывод MISOx становится сигналом передачи (выход), который передает данные к главному устройству. При взаимодействии по шине SPI данные выдвигаются наружу из вывода MISOx подчиненного устройства и вдвигаются внутрь через MISOx главного устройства. Здесь следует сделать несколько важных замечаний.
• Вывод MISO0 выделен для исключительного использования в периферийном устройстве SPI0, а выводы MISO1 и MISO2 несут также общую функцию GPIO (PD1 и PD6 соответственно). Убедитесь, что в регистре PORTDIO_FER биты 1 и 6 настроены под периферийное устройство (подробнее см. [4]). • При работе в системе multislave только одному устройству slave разрешено передавать данные. • Процессор может быть загружен через свой интерфейс SPI0, что позволяет загрузить и запустить исполняемый код приложения пользователя.
Пример конфигурации SPI показан на рис. 10-2, здесь процессор используется как подчиненное устройство SPI (slave). 8-разрядный микроконтроллер работает как главное устройство (SPI master).
Рис. 10-2. Процессор BF538 в качестве подчиненного устройства SPI.
[Выходы прерывания]
Каждый модуль SPI имеет 2 выходных сигнала прерывания: прерывание данных и прерывание ошибки.
Поведение сигнала прерывания данных (SPI data interrupt) зависит от битового поля инициации TIMOD в регистре управления SPI (SPIx_CTL). В режиме DMA (TIMOD = 1X), прерывание данных действует как запрос DMA, и генерируется, когда DMA FIFO готово к записи (TIMOD = 11) или к чтению (TIMOD = 10). В режиме без DMA (TIMOD = 0X), прерывание данных генерируется, когда регистр SPIx_TDBR готов к записи (TIMOD = 01), или когда регистр SPIx_RDBR готов к чтению (TIMOD = 00).
Прерывание ошибки SPI генерируется в режиме master, когда возникает ошибка режима (mode fault error), как с использованием DMA, так и без DMA. Прерывание ошибки может быть также сгенерировано в режиме DMA, когда была недогрузка данных, underflow (TXE при TIMOD = 11) или переполнение данных, overflow (RBSY при TIMOD = 10). Без использования DMA биты события underflow и overflow соответственно устанавливают биты TXE и RBSY в регистре SPIx_STAT, но прерывание при этом не генерируется.
Подробнее про эти выходы прерывания см. врезку "Регистр SPIx_CTL".
[Регистры SPI]
У периферийных устройств SPI есть несколько регистров, доступных из приложения пользователя. Некоторые из этих регистров также доступны через шину DMA. 4 регистра содержат информацию управления и состояния: SPIx_BAUD, SPIx_CTL, SPIx_FLG и SPIx_STAT. 2 регистра используются для буферизации данных приема и передачи: SPIx_RDBR и SPIx_TDBR. Подробнее про регистры DMA см. [6]. Регистр сдвига SFDR является внутренним для модуля SPI, и к нему нет прямого доступа.
Регистры состояния используются для определения разных событий, в том числе и ошибок, подробнее про это см. раздел "Сигналы ошибок и флаги". Обзор функций регистров см. в таблице 10-3.
Регистр скорости (SPI baud rate register, SPIx_BAUD) используется для установки скорости передачи в устройстве master. Когда устройство сконфигурировано как slave, записанное значение в этом регистре игнорируется. Тактовая частота, определяющая скорость, вычисляется по формуле:
Частота SCKx = SCLK/(2 x SPIx_BAUD)
Здесь SCLK это тактовая частота системной шины процессора, используемая для тактирования периферийных устройств. Запись значений 0 или 1 в этот регистр запрещает генерацию тактов SPI. Таким образом, максимально возможная тактовая частота данных может быть 1/4 от тактовой частоты системной шины.
Рис. 10-3. SPI Baud Rate Register (SPIx_BAUD).
В таблице 10-1 перечислено несколько примеров тактовых частот главного устройства SPI.
Регистр управления (SPI control register, SPIx_CTL) используется для конфигурирования и разрешения работы модуля SPI. Этот регистр используется для разрешения интерфейса SPI, выбора режима master или slave и определения формата передачи данных и размера передаваемого слова в битах (размер фрейма).
Под термином "слово" подразумевается минимальный блок бит, который может быть либо 8, либо 16 бит, в зависимости от бита длины слова (SIZE) в регистре SPIx_CTL. Здесь есть также 2 специальных бита, которые могут быть модифицированы аппаратно: SPE и MSTR.
Рис. 10-4. SPI Control Register (SPIx_CTL).
SPE (SPI Enable). Этот бит разрешает работу аппаратуры SPI. 0: SPI запрещен, 1: разрешен.
WOM (Write Open Drain Master). Определяет тип буферов выходов в режиме master. 0: обычные (двухтактные) выходные буферы, 1: буфер с открытым коллектором, требующим на сигнальной шине наличия подтягивающего верхнего резистора (pull-up).
MSTR (Master). 0: подчиненное (slave) устройство, 1: главное (master) устройство на шине SPI.
CPHA (Clock Phase). Фаза тактового сигнала SCKx, также определяет режим работы. 0: SCKx начинает переключаться посередине бита данных, выводы управления подчиненными устройствами управляются аппаратно. 1: SCKx начинает переключаться в момент появления первого бита, выводы управления подчиненными устройствами должны переключаться программно.
Биты CPOL и CPHA определяют формат фрейма SPI.
LSBF (LSB First). 0: старший бит (Most Significant Bit, MSB) данных передается первым, 1: младший бит (Least Significant Bit, LSB) передается первым.
SIZE (Size of Words). Определяет количество бит в передаваемом слове. 0: 8 бит, 1: 16 бит.
EMISO (Enable MISOx). Бит EMISO разрешает вывод MISOx для работы в качестве выхода. Это нужно в системах multislave, когда master хочет передать данные нескольким устройствам сразу (broadcast). В этом случае только одному устройству slave можно передавать данные обратно к master. За исключением того slave, от которого master хочет принять данные, все другие slave-устройства должны очистить этот бит.
PSSE (Slave Select Enable). Бит PSSE используется для разрешения работы входа ~SPIxSS в режиме master. Когда вход не используется, ~SPIxSS можно запретить, оставив этот вывод свободным для использования в качестве вывода порта GPIO. 0: вход запрещен (можно использовать как GPIO), 1: вход разрешен.
GM (Get More Data). Определяет получение или отбрасывание данных, когда SPIx_RDBR заполнен. 0: приходящие данные отбрасываются, 1: продолжение приема данных, который затрет предыдущие данные.
SZ (Send Zero). Что посылать, когда SPIx_TDBR пуст. 0: передавать последнее слово, 1: передавать нули.
TIMOD. Поле TIMOD используется для указания действия, которое начинает передачи в/из буферов приема/передачи.
Биты TIMOD
Описание
00
Если поле TIMOD установлено в 00, то транзакция порта SPI начнется, когда прочитан буфер приема SPIx_RDBR. Данные от первого чтения должны быть отброшены, потому что чтение должно инициировать первую транзакцию порта SPI. Прерывание генерируется, когда регистр SPIx_RDBR будет заполнен.
01
Когда поле TIMOD установлено в 01, транзакция инициируется при записи буфера передачи SPIx_TDBR. Прерывание генерируется, когда SPIx_TDBR пуст.
10
Значение 10 для поля TIMOD выбирает режим приема DMA, и первая транзакция начинается путем разрешения приема SPI с использованием DMA. Последующие индивидуальные транзакции (передачи блоков слов) инициируются автоматическими DMA-чтениями регистра SPIx_RDBR, как только буфер SPI DMA FIFO окажется не заполненным.
11
Значение 11 для поля TIMOD выбирает режим передачи DMA, и в этом случае транзакция начинается путем DMA-записи регистра SPIx_TDBR. Первая DMA-запись запускается разрешением SPI в режиме DMA, после чего начинается передаваться первый блок данных без участия процессора, под управлением DMA. Последующие автоматические DMA-записи начинаются, как только SPI DMA FIFO окажется не пуст.
Биты SPE и MSTR могут быть модифицированы аппаратурой, когда установлен бит MODF в регистре состояния. Подробнее см. врезку "Mode Fault Error (MODF)".
Если SPI разрешен как master, то SPI использует регистр флагов (SPI flag register, SPIx_FLG) для разрешения до 7 выводов GPIO порта F для использования в качестве индивидуальных сигналов выборки slave-устройств. В режиме slave биты SPIx_FLG не имеют никакого значения, и каждый SPI использует вход SPIxSS в качестве сигнала выборки подчиненного устройства.
Ниже на рисунке показано распределение бит для порта SPI0. Для портов SPI1 и SPI2 имеют значение только биты FLG1 и FLS1, остальные биты не используются. Подробнее про отличия в управлении подчиненными устройствами для разных модулей SPI см. раздел "Особенности управления подчиненными устройствами SPI1 и SPI2".
Рис. 10-5. SPIx Flag Register (SPIx_FLG).
Примечание: серым цветом помечены биты, которые не используются.
Регистр SPI0_FLG содержит 2 набора бит, которые работают следующим образом.
• Slave select enable (FLSx).
Каждый из бит FLSx соответствует выводам GPIO порта F (PFx). Когда бит FLSx установлен, соответствующий вывод PFx управляется как сигнал выборки подчиненного устройства (slave select). Например, если FLS1 установлен в SPI0_FLG, то PF1 управляется как slave select (SPI0SEL1). В таблице 10-2 показана связь битов FLSx и соответствующих выводов PFx.
Если бит FLSx не установлен, то регистры GPIO порта F (PORTFIO_DIR и другие) конфигурируют соответствующий вывод PFx и управляют его поведением для SPI0.
• Slave select value (FLGx).
Когда вывод PFx сконфигурирован как выход сигнала slave select для SPI0, биты FLGx могут определять значение, которое передается на выход.
Если CPHA = 1 в регистре SPI0_CTL, то выходное значение определяется программным управлением битами FLGx. Протокол SPI позволяет сигналу slave select оставаться активным (в лог. 0), либо неактивным между передачами слов. Пользователь должен программно установить или сбросить соответствующие биты FLGx. Например, чтобы управлять PF3 в качестве сигнала slave select, должен быть установлен бит FLS3 в регистре SPI0_FLG. Очистка FLG3 переведет выход PF3 в состояние лог. 0, установка FLG3 переведет PF3 в лог. 1. Таким образом, PF3 может переключаться в лог. 1 и лог. 0 между передачами путем установки и сброса бита FLG3. Иначе PF3 должен оставаться активным (лог. 0) между передачами, чтобы подчиненное устройство, для которого предназначен сигнал выборки, могло получить (и отправить, если это необходимо) данные.
Если CPHA = 0 в регистре SPI0_CTL, то аппаратура SPI устанавливает выходное значение сигнала выборки, и биты FLGx игнорируются. Протокол SPI требует, чтобы сигнал slave select было неактивным между передачами слов. В этом случае аппаратура SPI управляет выводами. Например, для использования PF3 в качестве сигнала slave select, нужно только установить бит FLS3 в регистре SPIx_FLG. Нет никакой необходимости также управлять значением бита FLG3, потому что аппаратура SPI будет автоматически сама управлять выводом PF3 как сигналом выборки для подчиненного устройства.
Таблица 10-2. Привязка битов регистра SPI0_FLG к выводам PFx.
Бит
Имя
Функция
Вывод PFx
По умолчанию
0
зарезервировано
0
1
FLS1
Разрешение SPI0SEL1
PF1
0
2
FLS2
Разрешение SPI0SEL2
PF2
0
3
FLS3
Разрешение SPI0SEL3
PF3
0
4
FLS4
Разрешение SPI0SEL4
PF4
0
5
FLS5
Разрешение SPI0SEL5
PF5
0
6
FLS6
Разрешение SPI0SEL6
PF6
0
7
FLS7
Разрешение SPI0SEL7
PF7
0
8
зарезервировано
1
9
FLG1
Значение SPI0SEL1
PF1
1
10
FLG2
Значение SPI0SEL2
PF2
1
11
FLG3
Значение SPI0SEL3
PF3
1
12
FLG4
Значение SPI0SEL4
PF4
1
13
FLG5
Значение SPI0SEL5
PF5
1
14
FLG6
Значение SPI0SEL6
PF6
1
15
FLG7
Значение SPI0SEL7
PF7
1
[Выходы управления подчиненными устройствами ~SPI0SEL7..SPI0SEL1. Использование битов FLS регистра SPI0_FLG для SPI multislave]
Биты FLSx в регистре SPI0_FLG используются в рабочем окружении с несколькими подчиненными устройствами на шине SPI (multislave). Например, если на шине есть 8 устройств SPI, включая устройство master, то процессор master может поддерживать транзакции SPI с другими 7 slave-устройствами. Эта конфигурация требует наличия только одного master-устройства. Например, предположим, что SPI0 работает как master. 7 выводов порта GPIO F (PF1–PF7) процессора подключен каждый к выводам ~SPIxSS подчиненных устройств SPI. В такой конфигурации биты FLSx в регистре SPI0_FLG могут использоваться тремя разными способами.
Для вариантов 1 и 2 процессор является master, и 7 микроконтроллеров / внешних периферийных устройств работают через SPI как slave-устройства. Процессор может:
1. Передать данные для всех семи устройств SPI в режиме broadcast. В этом случае все биты FLSx установлены.
2. Передать и принять данные от каждого slave-устройства SPI по отдельности. В этом случае требуется избирательное управление битами FLSx.
Для варианта 3 все 8 устройств подключенные через порты SPI могут быть также другими процессорами.
3. Если все подчиненные устройства также являются процессорами, то запрашивающий может принять данные только от одного процессора (что можно организовать, очистив бит EMISO в остальных шести slave-процессорах) за один раз, и может передать данные сразу всем slave-процессорам одновременно (broadcast). Эта функция EMISO может быть также доступна и в других микроконтроллерах. Таким образом, можно использовать функцию EMISO в любым другим устройством SPI, которое поддерживает такую функцию.
На рис. 10-6 показан один процессор в качестве master с тремя другими процессорами (или это могут быть другие SPI-совместимые устройства) в режиме slave.
Рис. 10-6. Сценарий, где один Master и несколько устройств Slave.
[Особенности управления подчиненными устройствами SPI1 и SPI2]
Весь функционал, описанный выше для SPI0 для управления выходами выборки slave-select, также справедлив и для SPI1 и SPI2. Однако, поскольку SPI1 и SPI2 могут управлять каждый только одним выходным сигналом slave-select, то реальным функционалом в регистрах SPIx_FLG обладают только биты FLS1/FLG1. Остальные биты в регистрах SPIx_FLG для SPI1 и SPI2 зарезервированы. Для SPI1 изменение состояния этих битов влияет на вывод PD4 pin. Для SPI2 изменение состояния этих битов влияет на вывод PD9. Удостоверьтесь, что регистр PORTDIO_FER правильно сконфигурирован для настройки этих выводов под использование периферийным устройством. Подробнее см. рис. 15-8 и 15-10 в статье [4].
Регистр состояния (SPI status register, SPIx_STAT) используется для детектирования момента, когда передача SPI завершилась, или когда произошла ошибка передачи/приема. Регистр SPIx_STAT может быть прочитан в любое время. Некоторые биты в SPIx_STAT предназначены только для чтения (RO, Read Only) - это биты, которые предназначены для получения информации (биты RXS, TXS, SPIF). Эти биты устанавливаются и очищаются аппаратно.
Некоторые биты можно сбросить (только сбросить, устанавливаются они аппаратно), если записать в них лог. 1 (так называемая технология W1C, т. е. Write-1-Clear, записать лог. 1 для очистки). Это биты TXCOL, RBSY, TXE, MODF - они устанавливаются аппаратно, если происходит ошибка. Будучи установленными, они должны быть сброшены программно. Например, если установлен бит TXE, то в регистр SPIx_STAT нужно записать число 0x0004 (лог. 1 в позиции бита TXE), тогда TXE сбросится.
Биты TXCOL, RBSY, TXE, MODF сбрасываются при сбросе процессора, но не сбрасываются, если запретить SPI.
Рис. 10-7. SPI Status Register (SPIx_STAT).
TXCOL (Transmit Collision Error). Бит типа W1C, устанавливается аппаратно, должен быть сброшен программно записью лог. 1. Когда установлен, это означает, что могли быть переданы испорченные данные.
RXS (RX Data Buffer register). Бит типа RO, только для чтения. 0 означает, что буфер приема пуст, 1 что буфер приема заполнен принятыми данными.
RBSY (Receive Error). Бит типа W1C, устанавливается аппаратно, должен быть сброшен программно записью лог. 1. Когда установлен, это означает, что были приняты данные, когда буфер приема был заполнен (не прочитан вовремя, т. е. произошло переполнение на приеме, RX overflow).
TXS (SPIx_TDBR Data Buffer register). Бит типа RO, только для чтения. 0 означает, что буфер передачи пуст, 1 что буфер передачи заполнен данными, которые еще не отправлены.
TXE (Transmission Error). Бит типа W1C, устанавливается аппаратно, должен быть сброшен программно записью лог. 1. Когда установлен, это означает, что произошла передача, когда в регистре SPIx_TDBR не было новых данных (регистр не был заполнен вовремя, т. е. произошла недогрузка на передаче, TX underflow).
MODF (Mode Fault Error). Бит типа W1C, устанавливается аппаратно, должен быть сброшен программно записью лог. 1. Устанавливается в устройстве master, когда другое устройство пытается стать master.
SPIF (SPI Finished). Бит типа RO, только для чтения. Устанавливается, когда завершена передача одного слова (фрейма).
Буфер передачи становится заполненным, когда в него (т. е. в регистр SPIx_TDBR) записаны данные, и становится пустым, когда начинается передача, и значение буфера загружено в регистр сдвига. Буфер приема становится заполненным по окончании передачи, когда значение из регистра сдвига загружено в буфер приема (т. е. в регистр SPIx_RDBR). Буфер приема опустошается, когда SPIx_RDBR прочитан программным обеспечением.
Бит SPIF по умолчанию (т. е. после сброса) установлен. Он также устанавливается, когда запрещается порт SPI.
При входе в режим DMA буфер передачи и буфер приема становятся пустыми. Таким образом, биты TXS и RXS изначально очищены после входа в режим DMA. Когда для передачи используется DMA, то прерывание DMA_DONE сигнализирует от том, что DMA FIFO пуст. Однако в этот момент все еще могут быть данные в SPI DMA FIFO, ожидающие своей передачи. Таким образом, программному обеспечению требуется опрашивать бит TXS в регистре SPIx_STAT, пока он не станет лог. 0 для двух последовательных чтений, и только тогда можно считать буфер SPI DMA FIFO опустошенным (т. е. только тогда его можно заполнять новыми данными). Когда затем бит SPIF переходит в лог. 1, это означает, что было передано последнее слово.
Регистр буфера передачи (SPI transmit data buffer register, SPIx_TDBR) является 16-битным регистром, доступным на чтение и запись. Перед передачей данные загружаются в этот регистр. Сразу перед началом передачи данных данные в SPIx_TDBR загружаются в регистр сдвига данных (shift data register, SFDR). Чтение SPIx_TDBR может произойти в любое время, что никак не влияет на инициирование передач SPI или на саму передачу.
Когда для передачи разрешен DMA, подсистема DMA загружает данные в этот регистр для передачи сразу перед началом передачи. В этом режиме не следует записывать программно данные в SPIx_TDBR, потому что это перезапишет те данные, которые были записаны DMA.
Когда DMA разрешен для приема, содержимое SPIx_TDBR постоянно повторно передается (передача через SPI всегда дуплексная). В этом режиме запись в SPIx_TDBR разрешена, и записанные данные будут переданы.
Если бит управления передачей нулей (send zeros control bit, SZ в регистре SPIx_CTL) установлен, то при определенных обстоятельствах регистр SPIx_TDBR может быть сброшен в 0.
Если в SPIx_TDBR будет выполнено несколько записей во время выполняющейся передачи, то будут переданы только те данные, что были записаны в последний раз. Предыдущие значения, которые были записаны в SPIx_TDBR до завершения передачи, не будут переданы. Таким образом, множественная запись в SPIx_TDBR возможна, но это не рекомендуется.
Рис. 10-8. SPI Transmit Data Buffer Register (SPIx_TDBR).
Регистр буфера приема (SPI receive data buffer register, SPIx_RDBR) является 16-битным регистром, предназначенным только для чтения. По окончании передачи данные из регистра сдвига загружаются в SPIx_RDBR. При использовании DMA на приеме данные в SPIx_RDBR автоматически вычитываются подсистемой DMA. Когда SPIx_RDBR читается программно, бит RXS очищается, и может быть инициирована новая передача SPI (если TIMOD = 00).
Рис. 10-9. SPI Receive Data Buffer Register (SPIx_RDBR).
Теневой регистр буфера приема (SPI RDBR shadow register, SPIx_SHADOW) предоставлен для использования в отладке программного обеспечения. Этот регистр имеет адрес, отличающийся от адреса буфера приема SPIx_RDBR, но содержимое SPIx_SHADOW идентично содержимому SPIx_RDBR. Когда программное обеспечение читает SPIx_RDBR, бит RXS в регистре SPIx_STAT очищается, и может быть инициирована передача SPI (если TIMOD = 00 в SPIx_CTL). При чтении регистра SPIx_SHADOW не происходит никаких аппаратных действий. Регистр SPIx_SHADOW предназначен только для чтения.
Биты SPE и MSTR в этом регистре также могут быть изменены аппаратурой (когда установлен MODF).
SPIx_FLG
Флаги порта SPI
Биты 0 и 8 в регистре SPI0_FLG зарезервированы. В регистрах SPI1_FLG и SPI2_FLG зарезервированы все биты, за исключением FLS1 и FLG1.
SPIx_STAT
Состояние порта SPI
Бит SPIF может быть установлен очисткой бита SPE в регистре SPIx_CTL.
SPIx_TDBR
Буфер передачи порта SPI
Содержимое этого регистра также может быть изменено аппаратно (блоком DMA, и/или когда бит SZ=1 в регистре SPIx_CTL).
SPIx_RDBR
Буфер приема порта SPI
Когда этот регистр читается программным обеспечением, срабатывает аппаратное событие.
SPIx_BAUD
Управление скоростью порта SPI
Значения 0 и 1 в этом регистре запрещают генерацию тактов SCKx.
SPIx_SHADOW
Данные порта SPI
В регистре появляется то же самое содержимое, что и в регистре SPIx_RDBR, однако при чтении регистра SPIx_SHADOW не происходит никаких действий.
[Форматы передачи SPI]
SPI поддерживает 4 разных комбинации фазы и полярности тактов бит (SPI режимы 0-3). Эти комбинации выбираются битами CPOL и CPHA в регистре SPIx_CTL, как это показано на рис. 10-11.
Рис. 10-11. Режимы работы SPI.
Примечание: перепад выборки - это изменение логического уровня тактов в момент считывания значения бита данных. Перепад переключения - момент вывода следующего бита данных.
Рисунки 10-12 и 10-13 демонстрируют два базовых формата передачи, заданные битом CPHA. Показаны на каждом рисунке показано 2 формы сигнала для SCKx - один для CPOL = 0, другой для CPOL = 1. Диаграммы могут быть интерпретированы как диаграммы устройства master или slave, поскольку сигналы SCKx, MISOx и MOSIx напрямую соединены между устройствами master и slave. Сигнал MISOx является выходом slave-устройства (передача от подчиненного устройства), и сигнал MOSIx является выходом master (передача от главного устройства). Сигнал SCKx генерируется устройством master, и сигнал ~SPIxSS является входом выборки подчиненного устройства (slave device select input), на который приходит выборка от устройства master. На диаграммах показана 8-битная передача (SIZE = 0), при передаче первым самого значимого бита, most significant bit, MSB (LSBF = 0). Разрешена любая комбинация бит SIZE и LSBF в регистре SPIx_CTL. Например, другой возможной конфигурацией может быть 16-битная передача, когда самый менее значимый бит (least significant bit, LSB) передается первым.
Полярность и фаза тактов должна быть настроена идентично для устройств master и slave, которые вовлечены в обмен друг с другом. Формат передачи от master может быть изменен между передачами, чтобы удовлетворить требованиям slave-устройства.
Когда CPHA = 0, линия выборки подчиненного устройства должна быть не активна (в состоянии лог. 1) между каждой передачей фрейма. Это управляется автоматически аппаратной логикой периферийного устройства SPI. Когда CPHA = 1, линия выборки подчиненного устройства ~SPIxSS может либо оставаться активной (все время оставаться в лог. 0) между следующими друг за другом передачами фрейма, либо становиться неактивной между передачами (переходить в лог. 1). Это должно управляться программно, путем манипуляции содержимым регистра SPIx_FLG.
На рис. 10-12 показан протокол передачи SPI для CPHA = 0. Обратите внимание, что SCKx начинает переключение посередине передачи данных, SIZE = 0 и LSBF = 0.
Рис. 10-12. Протокол передачи SPI (формат фрейма) для CPHA = 0.
На рис. 10-13 показан протокол передачи SPI для CPHA = 1. Обратите внимание, что SCKx начинает переключение в момент начала передачи, SIZE = 0 и LSBF = 0.
Рис. 10-13. Протокол передачи SPI (формат фрейма) для CPHA = 1.
[Основное описание работы SPI]
Интерфейс SPI может использоваться в обмене с одним устройство master на шине, и в ситуациях, когда устройством master могут становиться несколько устройств (рабочее окружение multimaster). В любом случае одноименные сигналы MOSIx, MISOx и SCKx соединяются друг с другом напрямую. Передача и прием между двумя устройствами SPI всегда начинаются немедленно (т. е. передача информации дуплексная), за исключением выбора режима широковещания (broadcast), когда на шине присутствуют несколько подчиненных устройств. В режиме broadcast несколько slave-устройств могут быть разрешены на прием, но только одному из них должна быть разрешена передача, иначе несколько выходов могут породить на сигнале MISO сквозные токи. Если передача или прием не требуется, то это можно просто игнорировать. В этом разделе описываются сигналы тактирования, работа SPI в качестве master и в качестве slave, и генерация ошибок.
Должны быть предприняты меры предосторожности, чтобы не допустить порчи данных, когда меняется конфигурация модуля SPI. Конфигурация не должна меняться при передаче данных. Полярность тактов должна меняться только тогда, когда нет выбранных slave-устройств. Исключением из этого может быть ситуация, когда на шине SPI есть только один master и только одно устройство slave, CPHA = 1, и вход slave-устройства уже переведен в активное состояние (лог. 0). В этом случае slave всегда выбран, и ситуации порчи данных можно избежать путем разрешения slave-устройства только после того, как сконфигурированы оба устройства, и master, и slave.
В системах multimaster (когда на шине SPI в разные моменты времени могут становиться главными разные устройства) или в системах multislave (когда на шине SPI есть несколько подчиненных устройств), выводы выхода данных (MOSIx и MISOx) могут быть сконфигурированы для работы как выходы с открытыми стоками, что позволяет предотвратить появление сквозных токов, когда на выходах появляются противоположные уровни (сквозные токи могут привести к повышенному потреблению тока и даже к выходу из строя выходных буферов порта). В такой конфигурации требуется подключение внешнего верхнего нагрузочного резистора (pull-up) между шиной питания VDDEXT и сигналом данных, работающем на открытых стоках (MOSIx и/или MISOx).
Опцией открытого стока управляет бит WOM. Когда бит WOM установлен, и SPI сконфигурирован как master, вывод MOSIx становится выходом с тремя состояниями, когда на нем устанавливается лог. 1 (т. е. открытый сток перестает замыкать линию MOSIx на GND). Но когда на выход MOSIx выводится лог. 0, то выход перестает быть в третьем состоянии (потому что открытый сток притягивает сигнал MOSIx к GND). Аналогично, когда WOM установлен, и SPI сконфигурирован в режиме slave, вывод MISOx становится с открытым стоком, и может переходить в третье состояние, когда на него выводится лог. 1.
[Тактирование SPI]
Тактовый сигнал SCKx выдается на шину не постоянно, а только когда активна передача фрейма, т. е. когда биты слова данных передаются по шине SPI. Количество активных перепадов тактов точно равно количеству бит, передаваемых по сигналам данных MISO и MOSI. Максимальная частота тактов может быть 1/4 от тактовой частоты SCLK. Для устройств master тактовая частота определяется 16-битным значением в регистре SPIx_BAUD. Для slave-устройств значение SPIx_BAUD игнорируется. Когда устройство SPI является master, сигнал SCKx становится выходом. Когда устройство SPI работает как slave, сигнал SCKx становится входом. Slave-устройства игнорируют сигнал SCKx, если их сигнал выборки становится неактивным (high).
Сигнал SCKx используется для вдвигания данных в регистр сдвига и выталкивания их наружу из регистра сдвига через сигналы данных MISOx и MOSIx соответственно. Данные всегда выдвигаются по одному биту на один перепад тактов (0 -> 1 или 1 -> 0, в зависимости от конфигурации), и выборка данных происходит на противоположном перепаде (1 -> 0 или 0 -> 1). Полярность и фаза тактов программируется в регистре SPIx_CTL и определяет формат фрейма (рис. 10-11).
[Работа в режиме главного устройства (Master)]
Между портами SPI0 и SPI1/SPI2 есть отличия, связанные с инициализацией ножек и с сигналами выборки подчиненных устройств.
SPI0. Когда SPI0 сконфигурирован как master (и не выбран режим DMA), интерфейс работает по следующему алгоритму.
1. Ядро записывает регистр SPI0_FLG, чем устанавливает один или большее количество флагов выборки (SPI flag select bits, FLSx). Это гарантирует, что не будут выбраны никакие подчиненные устройства на шине, пока master не будет сконфигурирован.
2. Ядро записывает регистры SPI0_BAUD и SPI0_CTL, чем разрешает работу устройства в режиме master, и конфигурирует систему SPI, задавая длину слова, формат передачи, скорость и другие необходимые параметры.
3. Если CPHA = 1, ядро активирует нужное подчиненное устройство (или несколько подчиненных устройств) путем очистки одного (или большего количества) битов FLGx в регистре SPI0_FLG.
4. Биты TIMOD в SPI0_CTL определяют режим инициации передачи SPI. Передача на шине SPI начинается либо при записи данных ядром в буфер передачи (SPI0_TDBR), либо при чтении данных из буфера приема (SPI0_RDBR).
5. Затем SPI генерирует импульсы тактов на выводе SCK0, и одновременно выдвигает данные наружу через свой выход MOSI0, и вдвигает данные внутрь через свой вход MISO0. Перед сдвигом регистр сдвига автоматически загружается содержимым регистра SPI0_TDBR. По окончании передачи содержимое регистра сдвига загружается в SPI0_RDBR (буфер приема).
6. С каждым новым инициированием передачи SPI продолжит передавать и принимать слова данных, в соответствии с настроенным режимом инициации (см. биты TIMOD регистре SPIx_CTL).
SPI1 и SPI2. Для SPI1 и SPI2 используется та же самая последовательность, отличие только в том, что ядро должно сначала проверить, что выводы GPIO, используемые для портов SPIx, не работают как порты GPIO. По умолчанию выводы предназначены для использования периферийными устройствами SPI1 и SPI2 (дополнительную информацию про настройку портов GPIO см. в статье [4]). Если буфер передачи остается пустым или буфер приема остается заполненным, то устройство работает в соответствии с состояниями битов SZ и GM в регистре SPIx_CTL. Если SZ = 1, и буфер передачи пуст, то устройство постоянно передает нули через вывод MOSIx. Одно слово передается для каждой новой команды инициации передачи. Если SZ = 0, и буфер передачи пуст, устройство постоянно передает последнее слово, которое было передано последний раз ранее, до того как буфер передачи опустошился. Если GM = 1, и буфер приема полон, устройство продолжит принимать новые данные из вывода MISOx, перезаписывая старые данные в буфере приема SPIx_RDBR. Если GM = 0, и буфер приема полон, то приходящие данные будут отброшены, и буфер приема SPIx_RDBR не будет обновляться.
[Режимы передачи. Инициация передачи от главного устройства]
Когда устройство сконфигурировано как master, инициация определяется полем TIMOD - двумя битами в регистре SPIx_CTL. На основе этих двух бит и состояния интерфейса новая передача начнется либо при чтении SPIx_RDBR, либо при записи SPIx_TDBR. Эта информация сведена в таблице 10-4.
Если порт SPI разрешен с TIMOD = 01 или TIMOD = 11, аппаратура немедленно выдает первое прерывание или запрос DMA.
Таблица 10-4. Инициация передачи по шине SPI.
TIMOD
Функция
Когда инициируется передача
Действие, прерывание
00
Передача и прием.
Инициируется новая одиночная передача слова при чтении SPIx_RDBR и завершении предыдущей передачи.
Прерывание активно, когда буфер приема заполнен.
Чтение SPIx_RDBR очищает прерывание.
01
Передача и прием.
Инициируется новая одиночная передача слова при записи SPIx_TDBR и завершении предыдущей передачи.
Прерывание активно, когда буфер передачи пуст.
Запись в SPIx_TDBR очищает прерывание.
10
Прием под управлением DMA
Инициируется передача нового блока слов при разрешении SPI для режима DMA. Передача отдельного слова начинается с чтения блоком DMA регистра SPIx_RDBR и завершения последней передачи.
Запрашивает чтения DMA, как только SPI DMA FIFO не пуст.
11
Передача под управлением DMA
Инициируется передача нового блока слов при разрешении SPI для режима DMA. Передача отдельного слова начинается с записи блоком DMA регистра SPIx_TDBR и завершения последней передачи.
Запрашивает записи DMA, как только SPI DMA FIFO не заполнен.
[Работа в режиме подчиненного устройства]
Когда устройство настроено как подчиненное (и не выбран режим DMA), начало передачи срабатывает при переходе сигнала ~SPIxSS в активное состояние (лог. 0), или по первому активному перепаду тактов (SCKx) - в зависимости от состояния бита CPHA в регистре SPIx_CTL.
Вот шаги, иллюстрирующие работу SPI в режиме slave:
1. Ядро записывает регистр SPIx_CTL, чтобы настроить режим последовательного соединения так, чтобы быть совместимым с форматом передачи, настроенным на стороне SPI master.
2. Чтобы подготовить передачу данных, ядро записывает эти данные в буфер передачи SPIx_TDBR.
3. Как только на входе ~SPIxSS появился спад уровня (переход от лог. 1 к лог. 0), устройство slave начинает выдвигать данные наружу через свой выход MISO, и вдвигать данные внутрь через свой вход MOSI по перепадам сигнала SCKx, в зависимости от настроек бит CPHA и CPOL регистра SPIx_CTL.
4. Прием/передача происходит до того момента, как станет неактивным сигнал ~SPIxSS, или пока slave не получит нужное количество тактовых импульсов SCKx.
Для SPI1 и SPI2 выводы периферийного устройства SPI не должны быть сконфигурированы как выводы портов GPIO, подробнее про конфигурирование портов GPIO см. [4].
Если буфер передачи остается пустым, или буфер приема остается заполненным, то устройство работает в соответствии с настройкой бит SZ и GM регистра SPIx_CTL. Если SZ = 1 и буфер передачи пуст, устройство постоянно передает нули на выводе MISOx. Если SZ = 0, и буфер передачи пуст, то устройство постоянно передает последнее слово данных, которое было передано последний раз перед тем, как буфер передачи опустошился. Если GM = 1, и буфер приема полон, устройство продолжит принимать новые данные с вывода MOSIx, перезаписывая старые данные в регистре SPIx_RDBR. Если GM = 0, и буфер приема полон, то приходящие данные отбрасываются, и регистр SPIx_RDBR не обновляется.
Готовность подчиненного устройства к передаче. Когда устройство сконфигурировано как slave, необходимо выполнить действия, показанные в таблице 10-5, чтобы подготовить устройство к новой передаче.
Таблица 10-5. Подготовка передачи.
TIMOD
Функция
Действие, прерывание
00
Передача и прием.
Прерывание активно, когда буфер приема заполнен.
Чтение SPIx_RDBR очищает прерывание.
01
Передача и прием.
Прерывание активно, когда буфер передачи пуст.
Запись в SPIx_TDBR очищает прерывание.
10
Прием под управлением DMA
Запрашивает чтения DMA, как только SPI DMA FIFO не пуст.
11
Передача под управлением DMA
Запрашивает записи DMA, как только SPI DMA FIFO не заполнен.
Бит MODF в регистре SPIx_STAT установится, когда вход ~SPIxSS устройства, работающего как master, переводится в лог. 0 каким-то другим устройством в системе. Это происходит в системах multimaster, где другое устройство также пытается перейти в режим master. Чтобы разрешить эту функцию, должен быть установлен бит PSSE в регистре SPIx_CTL. Конкуренция друг с другом нескольких выходов может привести к повреждению выходных буферов. Как только обнаружена эта ошибка, происходят следующие действия:
• Очищается управляющий бит MSTR в регистре SPIx_CTL, что конфигурирует интерфейс SPI как slave. • Очищается управляющий бит SPE в регистре SPIx_CTL, чем запрещается работа системы SPI. • Устанавливается бит состояния MODF в регистре SPIx_STAT. • Генерируется прерывание ошибки SPI.
Эти 4 условия сохраняются, пока бит MODF не будет очищен программно. Пока бит MODF не будет очищен, SPI не может быть заново разрешен, даже в качестве slave-устройства. Аппаратура не дает пользователю установить ни бит SPE, ни бит MSTR, пока установлен бит MODF.
Когда MODF очищен, прерывание ошибки SPI деактивируется. Перед попыткой повторно разрешить SPI как master, должно быть проверено состояние входа ~SPIxSS, чтобы убедиться, что не нем лог. 1. Иначе сразу, как только SPE и MSTR будут установлены, возникнет снова ошибка режима (mode fault error).
Когда SPE и MSTR очищены, драйверы данных и тактов SPI (MOSIx, MISOx и SCKx) запрещены. Однако выходные выводы управления подчиненными устройствами возвращаются под управление регистров GPIO порта F. Это может привести к конкуренции на сигналах выборки подчиненных устройств, если они все еще управляются процессором. Чтобы гарантировать, что драйверы выхода управления подчиненными устройствами были запрещены, когда произошла ошибка MODF, программа должна сконфигурировать соответствующим образом регистры GPIO порта F (подробнее про конфигурирование GPIO порта F см. [3]).
Когда разрешается функция MODF, программа должна сконфигурировать все выводы PFx, используемые для выборки подчиненных устройств, как входы GPIO. Программа должна сделать это путем конфигурирования направления выводов выборки slave до конфигурирования SPI. Это будет гарантировать, что при возникновении ошибки MODF выходы выборки подчиненных устройств автоматически перепрограммируются как GPIO, и выходные драйверы при этом будут запрещены.
Бит TXE установиться в регистре SPIx_STAT, когда все условия для передачи выполнены, однако в регистр SPIx_TDBR не поступило новых данных (SPIx_TDBR пуст). В этом случае передаваемое содержимое зависит от состояния бита SZ в регистре SPIx_CTL. Бит TXE очищается по технологии W1C (write-1-clear), т. е. для очистки нужно записать в него 1.
Флаг RBSY в регистре SPIx_STAT установится, когда завершена новая передача, однако перед этим не были прочитаны данные из регистра SPIx_RDBR. Состояние бита GM в регистре SPIx_CTL определяет, что при этом произойдет - либо SPIx_RDBR обновится новыми данными, либо нет. Бит RBSY очищается по технологии W1C (write-1-clear), т. е. для очистки нужно записать в него 1.
Флаг TXCOL в регистре SPIx_STAT установится, когда запись SPIx_TDBR совпадает с загрузкой регистра сдвига. Запись в SPIx_TDBR может быть произведена либо под управлением программы, либо под управлением DMA. Бит TXCOL показывает, что могла произойти загрузка поврежденных данных в регистр сдвига и передача этих поврежденных данных. В этом случае данные в могут не соответствовать тем данным, которые были переданы. Этой ошибки можно легко избежать правильным управлением со стороны программного обеспечения. Бит TXCOL очищается по технологии W1C (write-1-clear), т. е. для очистки нужно записать в него 1.
[Начало и завершение передач SPI]
Старт и окончание передачи SPI зависит от того, как сконфигурировано устройство - master или slave, от выбранного режима CPHA и от того, какая выбрана инициация передачи битами TIMOD. Для master SPI с CPHA = 0 передача начинается либо записью SPIx_TDBR, либо чтением SPIx_RDBR, в зависимости от TIMOD. При старте передачи разрешенные выходы выборки подчиненных устройств переходят в активное состояние (лог. 0). Однако сигнал SCKx остается не активным на первую половину первого такта SCKx. Для slave с CPHA = 0, передача начнется в тот момент, когда вход ~SPIxSS перейдет в лог. 0.
Для CPHA = 1 передача начнется с первым активным перепадом SCKx и для устройства slave, и для устройства master. Для устройства master передача считается завершенной после отправки и одновременного приема последнего бита данных. Передача для устройства slave завершается на последнем перепаде выборки SCKx.
Бит RXS определяет, когда буфер приема может быть прочитан. Бит TXS определяет, когда буфер передачи может быть заполнен. Окончание передачи одного слова произойдет, когда бит RXS установится, показывая этим, что новое слово было принято и защелкнуто в буфер приема SPIx_RDBR. Для master SPI бит RXS установится почти сразу после последнего перепада выборки SCKx. Для slave SPI бит RXS установится почти сразу после последнего перепада SCKx, независимо от состояния CPHA или CPOL. Задержка составит обычно несколько тактов SCLK, и зависит от TIMOD и скорости передачи. Если сконфигурирована генерация прерывания, когда SPIx_RDBR заполнен (TIMOD = 00), то прерывание активируется через один цикл SCLK после установки бита RXS. Когда прерывания не настроены, окончание передачи может быть определено по опросу бита RXS.
Чтобы сохранить совместимость программного обеспечения с другими устройствами SPI, для опроса имеется также бит SPIF. Поведение этого бита может незначительно отличаться от других коммерчески доступных устройств. Для slave-устройства SPIF очищается почти сразу после начала передачи (когда ~SPIxSS переходит в лог. 0 для CPHA = 0, когда первый активный перепад SCKx при CPHA = 1), и устанавливается одновременно с RXS. Для master-устройства SPIF очищается почти сразу после начала передачи (либо при записи SPIx_TDBR, либо при чтении SPIx_RDBR, в зависимости от TIMOD), и устанавливается на половину SCKx периода после последнего перепада SCKx, независимо от CPHA или CPOL.
Время, в течение которого SPIF установлен, зависит от скорости передачи. Обычно SPIF устанавливается после RXS на самой низкой настройки скорости передачи (SPIx_BAUD < 4). Бит SPIF установится перед RXS, и следовательно перед тем, как новые данные будут захвачены в SPIx_RDBR, из-за задержки. Таким образом, для SPIx_BAUD = 2 или SPIx_BAUD = 3, RXS должен быть установлен перед SPIF для чтения SPIx_RDBR. На более медленных скоростях настройках скорости SPIx_BAUD, RXS гарантированно будет установлен перед установкой SPIF.
Если порт SPI используется для одновременной передачи и приема, или для частого переключения между работой на прием и передачу, то лучше всего использовать режим TIMOD = 00. В этом режиме программа выполняет пустое чтение из регистра SPIx_RDBR для инициирования первой передачи. Если первая передача используется для передачи данных, то программное обеспечение должно записать передаваемое значение в регистр SPIx_TDBR перед выполнением пустого чтения. Если передаваемое значение может быть произвольным, то хорошей практикой будет установка бита SZ, чтобы гарантировать передачу нулей вместо каких-то случайных данных. Когда принимается последнее слово в потоке данных SPI, программа должна гарантировать, что чтение из SPIx_RDBR не приведет к началу новой передачи. Чтобы достичь этого, рекомендуется запретить порт SPI до последнего доступа на чтение регистра SPIx_RDBR. Чтения регистра SPIx_SHADOW недостаточно, так как это не очистит запрос на прерывание.
В режиме master с установленным битом CPHA программа должна вручную выставлять требуемый сигнал выборки slave-устройства перед запуском транзакции. После того, как все данные были переданы, программа обычно снова деактивирует сигнал выборки slave-устройства. Если устройство SPI slave требует удержания линии выборки до завершения передачи, это может быть достигнуто в обработчике прерывания SPI только при работе в режимах TIMOD = 00 или TIMOD = 10. С режимом TIMOD = 01 или TIMOD = 11 запрос на прерывание выдается, когда передача все еще продолжается.
[SPI DMA]
Порты SPI также могут использовать прямой доступ к памяти (direct memory Access, DMA). Подробнее про DMA см. [6].
Как работает SPI DMA. Каждый порт SPI имеет модуль DMA, который можно сконфигурировать либо для канала передачи, либо приема, но не одновременно. Таким образом, когда сконфигурирован канал передач, принятые данные в действительности будут отбрасываться. Соответственно когда сконфигурирован канал приема DMA, то все то, что передается, не имеет смысла. Вместе с DMA работает 16-битный буфер FIFO глубиной 4 слова (без возможности использования пакетов) - для увеличения пропускной способности через шину доступа DMA (DMA access bus, DAB).
Когда используется DMA для передачи SPI, прерывание DMA_DONE сигнализирует о том, что буфер FIFO DMA пуст. Однако в этот момент все еще могут быть в наличии данные SPI DMA FIFO, ожидающие передачи. Таким образом, программа должна опрашивать бит TXS в регистре SPIx_STAT, пока он не перейдет в 0 на 2 последовательных чтения, и только в этот момент можно считать пустым SPI DMA FIFO. Когда поле этого установится бит SPIF, то это будет означать, что было передано последнее слово.
FIFO глубиной 4 слова очищается, когда порт SPI запрещен.
Работа DMA в режиме master. Когда работа SPI разрешена как master, и подсистема DMA сконфигурирована для передачи или приема данных, интерфейс SPI0 работает следующим образом:
1. Ядро процессора записывает записывает соответствующие регистры DMA для разрешения канала SPI DMA и конфигурирования нужных блоков, направления передачи, количества слов, и так далее. Подробнее см. [6].
2. Ядро процессора записывает регистр SPI0_FLG, устанавливая один или большее количество битов флагов выборки SPI (FLSx).
3. Ядро процессора записывает регистры SPI0_BAUD и SPI0_CTL, разрешая устройство для работы в качестве master, и конфигурируя систему SPI указанием подходящей длины слова, формата передачи, скорости и т. д. Поле TIMOD должно быть сконфигурировано либо для приема через DMA (TIMOD = 10), либо передачи через DMA (TIMOD = 11).
4. Если был сконфигурирован прием, то он инициируется после разрешения SPI. Последующие передачи инициируются чтениями данных из регистра SPI0_RDBR и записью в SPI DMA FIFO. Затем SPI запрашивает запрашивает для DMA запись в память. Подсистема DMA читает слово из SPI DMA и записывает его в память.
Если была сконфигурирована передача, SPI запрашивает чтения DMA из памяти. Подсистема DMA читает слово из памяти и записывает его в SPI DMA FIFO. Так как SPI записывает данные из SPI DMA FIFO в регистр SPI0_TDBR, это инициирует передачу через канал SPI.
5. Затем SPI генерирует запрограммированные импульсы тактов на выводе SCK0, и одновременно выдвигает данные через MOSI0 и вдвигает данные, поступающие через MISO0. Для приема значение из регистра сдвига загружается в регистр SPI0_RDBR по окончании передачи слова. Для передачи значение в регистре SPI0_TDBR загружается в регистр сдвига в момент начала передачи.
6. В режиме приема, пока есть данные в SPI DMA FIFO (FIFO не пуст), SPI продолжает делать запросы записи DMA в память. Подсистема DMA продолжает читать слово из SPI DMA FIFO и записывает его в память, пока счетчик слов SPI DMA не перейдет от 1 к 0. SPI продолжит принимать слова, пока режим SPI DMA не будет запрещен.
Для SPI1 и SPI2 происходит та же самая последовательность действий, за исключением того, что ядро сначала должно проверить, что выводы GPIO настроены для использования портом SPIx, и не разрешены для работы в качестве GPIO. По умолчанию выводы предоставляются под использование для SPI, подробнее см. [4]. В режиме передачи, пока еще есть место в SPI DMA FIFO (FIFO не заполнен), SPI продолжает делать запросы чтения DMA из памяти. Подсистема DMA продолжает читать слово из памяти и записывать его в SPI DMA FIFO, пока регистр счетчика слов не перейдет от 1 к 0. SPI продолжит передавать слова, пока SPI DMA FIFO не опустошится.
Для работы DMA на прием, если подсистема DMA не может поддержать поток поток принимаемых данных, буфер приема работает в соответствии с состоянием бита GM. Если GM = 1, и DMA FIFO заполнен, то устройство продолжит принимать новые данные через вывод MISOx, перезаписывая старые данные в регистре SPIx_RDBR. Если GM = 0, и DMA FIFO заполнен, то приходящие данные отбрасываются, и регистр SPIx_RDBR не обновляется. Когда выполняется прием DMA, то подразумевается, что буфер передачи пуст (и установлен TXE). Если SZ = 1, устройство постоянно передает нули через вывод MOSIx. Если SZ = 0, то устройство постоянно передает содержимое регистра SPIx_TDBR. В этом режиме событие недогрузки передачи (TXE underrun condition) не может генерировать прерывание ошибки.
Для работы DMA на передачу master SPI инициирует передачу слова только когда есть данные в DMA FIFO. Если DMA FIFO пуст, то SPI ждет подсистему DMA для записи DMA FIFO перед началом передачи. Все аспекты приема SPI должны быть проигнорированы, когда сконфигурирован режим передачи через DMA, включая данные в буфере SPIx_RDBR и состояние битов RXS и RBSY. В этом режиме события переполнения приема (RBSY overrun condition) не могут генерировать прерывание ошибки. Событие недогрузки передачи (TXE underrun condition) не может произойти в этом режиме (режим master DMA TX), потому что master SPI не инициирует передачу, если нет данных в DMA FIFO.
Не должна происходить запись в регистр SPIx_TDBR при активной передаче SPI с использованием DMA, потому что данные DMA будут перезаписаны. Записи в регистр SPIx_TDBR при активном приеме SPI с использованием DMA разрешены. Чтения из регистра SPIx_RDBR разрешены в любое время.
Запросы DMA генерируются, когда DMA FIFO не пуст (при TIMOD = 10), или когда DMA FIFO не заполнен (при TIMOD = 11).
Прерывания ошибки генерируются, когда произошло событие переполнения приема (RBSY overflow error condition) при TIMOD = 10.
Последовательность SPI DMA в режиме master может вовлекать передачу точка-точка и/или прием с несколькими блоками DMA. Контроллер SPI поддерживает такую последовательность с минимальным участием ядра.
Работа DMA в режиме slave. Когда работа SPI разрешена как slave, и сконфигурирована передача или прием через DMA, начало передачи срабатывает по переходу сигнала ~SPIxSS в активное состояние (1 -> 0) или по первому активному перепаду SCKx, в зависимости от состояния бита настройки CPHA.
Следующие шаги иллюстрируют последовательность приема или передачи SPI с участием DMA, когда блок SPI работает как подчиненное устройство (slave, отвечающее на действия master).
1. Ядро процессора записывает соответствующие регистры DMA, чтобы разрешить работу канала SPI DMA и сконфигурировать нужные рабочие блоки, направление доступа, счетчик слов и т. д. Подробнее см. [6].
2. Ядро процессора записывает регистр SPIx_CTL для настройки режима канала связи (формата фрейма), чтобы настройки соответствовали настройкам SPI master. Поле TIMOD конфигурируется для выбора либо приема через DMA (TIMOD = 10), либо передачи через DMA (TIMOD = 11).
3. Если сконфигурирован прием, то как только вход выборки подчиненного устройства ~SPIxSS станет активным (перейдет в лог. 0), slave начнет принимать и передавать данные по перепадам тактов SCKx, которые генерирует master. Значение в регистре сдвига загружается в регистр SPIx_RDBR по окончании передачи. Поскольку SPI читает данные из регистра SPIx_RDBR и записывает в SPI DMA FIFO, то это запрашивает доступ DMA на запись в память. Подсистема DMA читает слово из SPI DMA FIFO и записывает его в память.
Для SPI1 и SPI2выводы SPI должны настроены не для GPIO, а для работы с периферийным устройством SPI. Подробнее про настройку портов см. [4].
Если сконфигурирована передача, то SPI запрашивает чтения DMA из памяти. Подсистема DMA читает слово из памяти и записывает его в SPI DMA FIFO. Затем SPI читает данные из SPI DMA FIFO и записывает их в регистр SPIx_TDBR, ожидая начала следующей передачи. Как только вход выборки подчиненного устройства станет активным, slave начнет принимать и передавать данные по перепадам SCKx. Значение регистра SPIx_TDBR загружается в регистр сдвига в момент начала передачи.
4. В режиме приема, как только данные появятся в SPI DMA FIFO (FIFO не пуст), SPI slave продолжит запрашивать запись DMA в память. Подсистема DMA продолжит читать слово из SPI DMA FIFO и записывать в память, пока счетчик слов SPI DMA не перейдет от 1 к 0. SPI slave продолжит принимать слова по перепадам SCKx, пока вход выборки подчиненного устройства находится в активном состоянии.
В режиме передачи, как только появляется место в SPI DMA FIFO (FIFO не заполнен), SPI slave продолжит запрашивать чтение DMA из памяти. Подсистема DMA продолжит читать слово из памяти и записывать его в SPI DMA FIFO, пока счетчик слов SPI DMA не перейдет от 1 к 0. SPI slave продолжит передавать слова по перепадам SCKx, пока вход выборки подчиненного устройства находится в активном состоянии.
Для работы DMA на прием, если подсистема DMA не может поддержать поток данных приема, буфер приема работает в соответствии с состоянием бита GM. Если GM = 1 и DMA FIFO заполнен, устройство продолжит принимать новые данные через вывод MOSIx, перезаписывая старые данные в регистре SPIx_RDBR. Если GM = 0 и DMA FIFO заполнен, то приходящие данные отбрасываются, и регистр SPIx_RDBR не обновляется. Во время выполнения приема DMA подразумевается, что буфер передачи пуст, и бит TXE установлен. Если SZ = 1, то устройство постоянно передает нули через вывод MISOx. Если SZ = 0, то устройство постоянно передает содержимое регистра SPIx_TDBR register. В этом режиме событие недогрузки передачи (TXE underrun condition) не может генерировать прерывание ошибки
Для работы DMA на передачу, если подсистема DMA не может поддержать поток данных передачи, то порт передачи работает в соответствии с состоянием бита SZ. Если SZ = 1 и буфер DMA FIFO пуст, устройство постоянно передает нули через свой вывод MISOx pin. Если SZ = 0 и DMA FIFO пуст, то устройство постоянно передает последнее слово, которое было передано до того, как буфер DMA стал пуст. Все аспекты приема SPI должны игнорироваться при передаче в режиме DMA, включая данные в регистре SPIx_RDBR и биты состояния RXS и RBSY. В этом режиме события переполнения приема (RBSY overrun condition) не могут генерировать прерывание ошибки.
Не должны происходить записи в регистр SPIx_TDBR во время активной передачи SPI DMA, потому что данные DMA будут перезаписаны. Записи в регистр SPIx_TDBR во время активного приема SPI DMA разрешены. Чтения из регистра SPIx_RDBR разрешены в любое время.
Запросы DMA генерируются, когда DMA FIFO не пуст (при TIMOD = 10), или когда DMA FIFO не заполнен (при TIMOD = 11).
Прерывания ошибки генерируются, когда произошло событие переполнения приема (RBSY overflow error condition) при TIMOD = 10, или когда произошло событие недогрузки передачи (TXE underflow error condition) при TIMOD = 11.
Интервалы времени SPI. Каждый из интервалов времени enable lead time (T1), enable lag time (T2), и время последовательной задержки передачи sequential transfer delay time (T3) должен быть всегда больше или равен половине длительности периода SCKx, см. рис. 10-14. Минимальное время между последовательными передачами (T4) составляет 2 периода SCKx. Это измеряется от последнего активного перепада SCKx одного слова до первого активного перепада SCKx следующего слова. Это не зависит от конфигурации SPI (состояния бит CPHA, MSTR, и т. д.).
Рис. 10-14. Интервалы времени SPI.
Для устройства master с битом CPHA = 0, выход выборки подчиненного устройства находится в неактивном состоянии (лог. 1) на как минимум половину периода SCKx. В этом случае интервалы T1 и T2 каждый всегда равны половине периода SCKx.
[Заключение: несколько слов от переводчика]
Общее впечатление от портов SPI Backfin удручающее по сравнению с SPI других процессоров, недостатков куча:
- Нельзя одновременно организовать DMA на прием и передачу. - Аппаратная генерация выборки зависит от настройки формата фрейма (от состояния бита CPHA). Если CPHA==0, то выборка может генерироваться аппаратно, если CPHA==1, то только программно, других вариантов нет. - Если сигнал выборки подчиненного устройства генерируется программно, то очень неудобно определять физический момент окончания передачи (чтобы деактивировать выборку): сначала нужно дождаться сброса бита TXS, и после этого еще нужно дождаться установки бита SPIF. - Нельзя настроить аппаратные задержки появления выборки для фрейма. - Нельзя гибко настраивать количество бит во фрейме - либо только 8, либо 16. - Система прерываний недостаточно гибкая.
К сожалению, из-за аппаратных различий модулей SPI0 и SPI1/SPI2 описание их работы получилось довольно путаным и трудным для понимания в первом чтении. С одной стороны, порт SPI у Blackfin дубовый и простой, с урезанным функционалом. С другой стороны, чтобы его полноценно использовать, нужно изучить тонкости не только конкретной модели процессора, но и еще особенности, связанные с номером порта SPI (SPI0, SPI1 или SPI2).