[Home] | [Donate!] [Контакты] |
[<< SPI в STM32. Работа в ведомом и ведущем режимах] | [Регистры SPI >>] |
Оглавление
В процессе приёма, полученные данные сохраняются во внутреннем буфере Rx (сначала принимаемые биты накапливаются в сдвигающем регистре, а когда фрейм полностью получен, он копируется в Rx). Содержимое буфера Rx может быть получено путём чтения регистра данных SPI_DR. При передаче, прежде чем данные будут отправлены, они сначала записываются во внутренний буфер Tx, запись в Tx происходит при записи в SPI_DR.
* В двунаправленном режиме используется только одна линия данных, которая в случае ведущего устройства подключается к выводу MOSI.
* В двунаправленном режиме используется только одна линия данных, которая в случае ведомого устройства подключается к выводу MISO.
В микроконтроллерах STM32 устройства SPI имеют набор флагов (аппаратно устанавливаемых битов) в регистре SPI_SR, значения которых дают информацию о текущем состоянии устройства. Наиболее важны для организации процесса пересылки данных флаги TXE, RXNE.
TXE флаг (Tx buffer empty, Tx буфер пуст) устанавливается, когда данные пересылаются из буфера Tx в сдвигающий регистр. Установка данного флага показывает, что внутренний буфер Tx освободился и готов для загрузки в него новых данных. Также этот флаг установлен вначале работы (до любой записи в SPI_DR). При установке флага генерируется прерывание, если установлен разрешающий бит TXEIE в регистре SPI_CR2. Сброс флага TXE происходит при записи в регистр SPI_DR.
Примечание. Перед записью в SPI_DR, программа должна убедиться в том, что флаг TXE установлен в 1. В противном случае возможна перезапись предыдущих данных в буфере Tx, которые ещё не были загружены в регистр сдвига.
RXNE флаг (Rx buffer not empty, Rx буфер не пуст) устанавливается после копирования принятых данных из сдвигающего регистра в буфер Rx. Установка флага является признаком того, что готовы данные для чтения из регистра SPI_DR. При установке флага генерируется прерывание, если установлен разрешающий бит RXNEIE в регистре SPI_CR2. Сброс бита RXNE происходит при чтении из регистра SPI_DR.
В некоторых случаях может использоваться флаг BSY для ожидания завершения последней передачи данных.
Рисунок %img:mfdtc1 изображает процессы при передаче данных, прежде всего изменение состояния основных флагов для ведущего устройства. Рассматривается непрерывная передача, т.е. без пауз между фреймами, что достигается за счёт того, что программа поставляет передаваемые данные достаточно быстро, новые данные помещаются в буфер до завершения передачи текущего фрейма. Предполагается использование полнодуплексной связи (BIDIMODE = 0 и RXONLY = 0), настройки тактового сигнала: CPOL = 1, CPHA = 1.
Для получения/передачи данных используется следующая процедура.
==
1), после чего записать следующий элемент данных в регистр SPI_DR. Затем ждём установки флага RXNE в 1, после чего считываем полученные данные из SPI_DR (это сбрасывает флаг RXNE). Повторяем этот пункт, пока не будут переданы/получены n - 1 элементов данных.==
1), после чего считываем полученные данные (это будет последний полученный фрейм).==
1, а затем BSY ==
0, прежде чем отключить SPI.Для более эффективной реализации описанных действий, можно использовать обработчик прерывания, вызываемый при установке флагов RXNE, TXE.
На рис. %img:mfdtc2 изображены процессы для аналогичной ситуации, но при работе в режиме ведомого устройства. По диаграмме легко проследить за изменением состояния флагов SPI в процессе передачи/приёма данных. Отметим, что флаг BSY, который у ведущего устройства при непрерывной передаче остаётся установленным на протяжении всего процесса передачи данных, в ведомом устройстве сбрасывается в 0 на один период тактового сигнала SPI между фреймами при непрерывной передаче.
Не будем отдельно рассматривать диаграммы для случаев однонаправленной передачи или двунаправленной передачи при полудуплексной связи, т.к. во многом они аналогичны только что рассмотренным.
Непрерывная и прерывистая передача данных
Если ведущее устройство передаёт данные, и при этом программное обеспечение реагирует достаточно быстро, сразу же записывая в регистр SPI_DR новые данные в ответ на каждую установку флага TXE (или, по крайней мере, успевает сделать запись до завершения текущей передачи фрейма), то такая передача может быть названа непрерывной. В этом случае тактовый сигнал генерируется непрерывно, без остановок между фреймами; флаг BSY ведущего устройства не сбрасывается между пересылками смежных фреймов.
Наоборот, если программа реагирует недостаточно оперативно, могут возникнуть паузы между передачами фреймов. На время, пока отсутствуют данные для передачи, останавливается генерация тактового сигнала SPI; флаг BSY сбрасывается (рис. %img:mfdtd).
В ведущем режиме "только приём" (RXONLY = 1) передача данных всегда непрерывная и флаг BSY всегда имеет значение 1. В руководстве описывается исключение, когда BSY остаётся сброшенным на всём протяжении процесса обмена данными, это происходит в ведущем режиме с двунаправленной связью по одной линии при работе на приём (MSTR = 1, BIDIMODE = 1, BIDIOE = 0), флаг остаётся сброшенным в процессе получения данных.
В ведомом режиме непрерывность передачи данных определяется ведущим устройством, являющимся для ведомого источником тактового сигнала. Но в любом случае, даже если передача непрерывная, флаг BSY принимает значение 0 между пересылками фреймов, как минимум, на продолжительность одного периода тактового сигнала SPI.
В общем-то, вопрос непрерывности передачи не является принципиальным. Наличие отдельной линии для тактового сигнала и использование этого тактового сигнала как ведущим, так и ведомым устройством, снимает любые требования к его периодичности или регулярности; требуется лишь, чтобы не превышались скоростные возможности ведомого устройства. Тактовый сигнал может быть задержан ведущим устройством на любом уровне на любой промежуток времени и это не скажется на целостности передаваемых данных. Важной непрерывность передачи становится в том случае, когда мы хотим достичь наибольшей скорости передачи на данной тактовой частоте.
Возможность вычисления CRC реализована для обеспечения контроля достоверности передаваемых данных. Имеются отдельные вычислители CRC для передаваемых и принимаемых данных. CRC вычисляется с использованием запрограммированного полинома последовательно для каждого бита данных. Вычисления производятся по фиксирующему фронту тактового сигнала (передний или задний, зависит от битов CPHA и CPOL в регистре SPI_CR1).
Примечание. В зависимости от выбранной длины фрейма, при включении контроля CRC будет вычисляться CRC8 или CRC16.
Вычисление CRC включается установкой в 1 бита CRCEN регистра SPI_CR1. Это действие сбрасывает регистры CRC (SPI_RXCRCR и SPI_TXCRCR). При полнодуплексной связи или в режиме "только передача", когда имеет место программное управление пересылкой, необходимо выполнить запись в бит CRCNEXT сразу же после того, как последние данные для передачи будут записаны в регистр SPI_DR. Тогда после того, как будут переданы все данные (и буфер Tx станет пустым), автоматически перешлётся содержимое регистра SPI_TXCRCR. На время передачи CRC, вычисление CRC отключается, для того чтобы передача кода не изменила значение регистра CRC.
В режиме "только приём" необходимо записать бит CRCNEXT после получения предпоследнего фрейма данных, чтобы подготовить SPI к фазе получения CRC после завершения приёма последнего фрейма данных. На время приёма CRC вычисление CRC прекращается. При обнаружении ошибки, устанавливается флаг CRCERR в регистре SPI_SR.
Связь по SPI с контролем CRC осуществляется следующим образом:
Когда SPI сконфигурирован в ведомом режиме с включённой функцией CRC, вычисление CRC выполняется даже при высоком уровне на входе NSS. Это следует учитывать, когда имеется несколько ведомых устройств на одной шине.
Между отменой выбора ведомого (высокий уровень на входе NSS) и повторным выбором (низкий уровень NSS), следует сбросить регистры CRC как на стороне ведущего, так и на стороне ведомого устройства для того, чтобы синхронизировать процессы вычисления CRC.
Сброс CRC производится следующей процедурой:
Для контроля за состоянием SPI используются следующие флаги, устанавливаемые аппаратно.
TXE (Tx buffer empty flag, Tx буфер пуст)
Когда флаг установлен, это является признаком того, что буфер Tx пуст и в него можно загружать новые данные, предназначенные для передачи (путём записи SPI_DR). При записи в регистр SPI_DR происходит сброс флага TXE.
RXNE (Rx buffer not empty, Rx буфер не пуст)
Когда флаг установлен, это является признаком того, что в буфере Rx имеются принятые данные, которые можно получить чтением из SPI_DR. Флаг сбрасывается при чтении из регистра SPI_DR.
BSY (BUSY flag, флаг занятости)
Флаг отображает состояние коммуникационного уровня SPI. Если флаг установлен, это является признаком того, что SPI занят пересылкой данных. Имеется исключение: в ведущем режиме с двунаправленной связью по одной линии при работе на приём (MSTR = 1, BIDIMODE = 1, BIDIOE = 0), флаг остаётся сброшенным в процессе получения данных.
Флаг аппаратно устанавливается, когда начинается пересылка данных (кроме случая, соответствующего описанному выше исключению).
Флаг сбрасывается:
Флаг BSY полезен для обнаружения завершения пересылки данных перед отключением SPI, безопасным для целостности данных (отключение может потребоваться перед переходом в энергосберегающий режим или перед отключением тактового сигнала данного периферийного устройства).
Также флаг может быть полезен для предотвращения коллизий при записи в системах с несколькими ведущими устройствами.
Примечание. Не рекомендуется использовать контроль флага BSY для управления передачей и приёмом данных, для этих целей лучше подходят флаги TXE и RXNE.
Предусмотрено три флага ошибок: MODF, OVR, CRCERR, каждый из которых устанавливаются аппаратно в случае возникновения соответствующей ошибочной ситуации. Если установлен бит ERRIE, то при установке любого флага ошибки будет генерироваться прерывание.
MODF (Master mode fault, ошибка режима ведущего устройства)
Данная ошибка фиксируется, когда SPI работает в режиме ведущего устройства, его вывод NSS настроен как вход и на этом входе появляется сигнал низкого уровня. При обнаружении данной ошибки происходит следующее:
Для сброса бита MODF программа должна выполнить следующую последовательность действий:
Во избежание возникновения конфликтов между ведомыми устройствами в системах, включающих в себя несколько микроконтроллеров, на выводе NSS должен удерживаться сигнал высокого уровня на протяжении всей последовательности действий по сбросу бита MODF. Биты SPE и MSTR могут быть возвращены в свои исходные состояния после выполнения последовательности действий по сбросу MODF. Из соображений безопасности, аппаратными средствами не допускается установка битов SPE и MSTR, пока установлен бит MODF.
В ведомом устройстве бит MODF не может быть установлен. Однако, как было сказано ранее, этот бит остаётся установленным после автоматического перехода из ведущего режима в ведомый в случае конфликта в конфигурации с несколькими ведущими устройствами. То есть, в ведомом устройстве MODF не устанавливается, но он может остаться установленным в режиме ведомого устройства при переходе из ведущего режима.
OVR (Overrun flag, Overrun condition - состояние переполнения)
Переполнение возникает тогда, когда SPI получает очередной фрейм данных, в то время как буферный регистр Rx занят (бит RXNE ещё не был сброшен после его установки в результате получения предыдущих данных).
При переполнении, содержимое приёмного буфера не обновляется новыми получаемыми данными (все последние принятые данные будут потеряны). При чтении SPI_DR будет возвращён последний успешно принятый до переполнения фрейм.
Флаг OVR сбрасывается при чтении из регистра SPI_DR, выполняемого следом за чтением из регистра SPI_SR.
CRCERR (CRC error, ошибка CRC)
Флаг используется для контроля за безошибочностью принимаемых данных. Механизм контроля включается при установке бита CRCEN в регистре SPI_CR1. Флаг CRCERR устанавливается, если полученный CRC код не соответствует значению в регистре SPI_RXCRCR, который содержит локально вычисленный для принятых данных CRC.
Событие | Флаг | Разрешающий бит |
---|---|---|
Буфер передаваемых данных пуст | TXE | TXEIE |
Приёмный буфер не пуст | RXNE | RXNEIE |
Ошибка в ведущем режиме | MODF | ERRIE |
Ошибка переполнения | OVR | |
CRC ошибка | CRCERR |
Когда пересылка данных завершена, приложение может прекратить связь, отключив SPI. Отключение выполняется сбросом бита SPE. Однако если отключение происходит в момент, когда идёт процесс пересылки данных, в некоторых конфигурациях это приводит к искажению передаваемых данных и установке недостоверного значения бита BSY.
Чтобы избежать этого, рекомендуется придерживаться одной из следующих процедур отключения периферийного устройства SPI (выбор варианта зависит от текущего режима работы SPI).
Ведущий или ведомый режим, полнодуплексная связь (BIDIMODE = 0, RXONLY = 0).
==
1 для получения последних данных.==
1.==
0.Ведущий или ведомый режим, однонаправленная связь, "только передача" (BIDIMODE = 0, RXONLY = 0) или двунаправленная связь, режим передачи (BIDIMODE = 1, BIDIOE = 1).
После того, как последние данные записаны в регистр SPI_DR:
==
1.==
0.Ведущий режим, однонаправленная связь, "только приём" (MSTR = 1, BIDIMODE = 0, RXONLY = 1) или ведущий режим, двунаправленная связь, режим приёма (MSTR = 1, BIDIMODE = 1, BIDIOE = 0).
В данном случае следует действовать таким образом, чтобы SPI не инициализировал очередную пересылку, сверх требуемого количества.
==
1 в (n-1) раз.==
1, т.е. будет получен последний ожидаемый фрейм, что будет свидетельствовать о завершении пересылки всех данных.Примечание. В ведущем режиме с двунаправленной связью при работе на приём (MSTR = 1, BIDIMODE = 1, BIDIOE = 0), флаг BSY остаётся сброшенным в процессе получения данных.
Ведомый режим, "только приём" (MSTR = 0, BIDIMODE = 0, RXONLY = 1) или двунаправленная связь, режим приёма (MSTR = 0, BIDIMODE = 1, BIDOE = 0).
Для достижения максимальной скорости SPI, необходимо своевременно поставлять данные для передачи и считывать принятые в Rx буфер данные во избежание переполнения. Решению этих задач может помочь поддержка DMA, реализующая простой протокол запрос/подтверждение. Для разрешения формирования запросов DMA используется регистр SPI_CR2.
Для работы с буферами Tx и Rx используются отдельные запросы.
Когда SPI используется только для передачи данных, может быть включён только SPI Tx канал DMA (для обслуживания запросов на передачу данных). В этом случае, в процессе пересылки данных будет установлен флаг OVR, так как не выполняется чтение из буфера принимаемых данных.
Когда SPI используется только для приёма данных, можно включить только канал SPI Rx DMA.
В режиме передачи, когда DMA система уже записала все данные, предназначенные для отправки (установлен флаг TCIF в регистре DMA_ISR), по флагу BSY можно определить момент фактического завершения пересылки данных по SPI. Это требуется, чтобы избежать потери последней передаваемой порции данных, если далее планируется отключить SPI. Приложение должно дождаться сначала пока установится TXE ==
1, затем - BSY ==
0.
Примечание. В процессе связи, когда осуществляется непрерывная передача данных, имеется задержка в 2 периода тактового сигнала APB между операцией записи в регистр SPI_DR и установкой флага BSY. Следовательно, обязательно, после записи всех данных, нужно ждать сначала до выполнения условия TXE ==
1 и затем до BSY ==
0.
Процессы отправки и получения данных с использованием DMA поясняются диаграммами на рис. %img:spi_dma_tx и рис. %img:spi_dma_rx соответственно.
Пересылка данных через SPI с задействованным механизмом DMA совместима с аппаратным контролем CRC. При включённом контроле CRC и использовании DMA, отправка и получение CRC кода происходит автоматически, без установки бита CRCNEXT. После получения CRC кода, он должен быть прочитан из регистра SPI_DR для того, чтобы сбросить флаг RXNE.
После завершения пересылки данных и CRC кодов, происходит проверка достоверности полученных данных, и в случае обнаружения ошибки, устанавливается флаг CRCERR в регистре SPI_SR.