Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI DMA, проверка занятости.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
charkin
Всем привет.
Подскажите, каким образом можно гарантированно определить, что обмен по SPI (прием/передача, с использованием DMA) завершен?

У меня обращение к внешней флэш-памяти по SPI может происходить из главного цикла, а также в обработчике прерывания EXTI. Если прерывание возникло в момент, когда в главном цикле что-то писалось/читалось во флэш, то данные конечно же портятся.. Пробовал смотреть биты SPI-модуля - TXE, RXNE И BUSY, но подобрать правильно условие так и не смог, либо оно никогда не выполняется, либо наоборот выполняется тогда, когда нельзя запускать обмен по SPI.
Почитал про флаги DMA, они выставляются по завершению чтения/записи, но в соответствующем обработчике прерываний эти флаги сбрасываются.. И, похоже, использовать их для определения завершения обмена не получится.

Понимаю, что можно убрать код обращения к флэш-памяти из обработчика прерывания EXTI (пока так и сделал), но тем не менее - каким образом можно узнать, что данные прочитаны/отправлены и можно запускать обмен по SPI?
Непомнящий Евгений
Как вариант - заведите свой собственный флаг dmaBusy. В прерывании по концу DMA RX его снимайте, при начале работы с SPI - ставьте
jcxz
Цитата(charkin @ Oct 25 2017, 13:26) *
Подскажите, каким образом можно гарантированно определить, что обмен по SPI (прием/передача, с использованием DMA) завершен?

Зависит от используемого МК. В разных МК периферия SPI и DMA устроена по-разному.
Но в общем случае можно считать что транзакция закончилась по завершению приёма блока SPI-DMA.

Цитата(charkin @ Oct 25 2017, 13:26) *
У меня обращение к внешней флэш-памяти по SPI может происходить из главного цикла, а также в обработчике прерывания EXTI. Если прерывание возникло в момент, когда в главном цикле что-то писалось/читалось во флэш, то данные конечно же портятся.. Пробовал смотреть биты SPI-модуля - TXE, RXNE И BUSY

Здесь никакие биты не помогут. Вам надо править консерваторию алгоритм.
Такого просто не должно быть - чтобы из разных мест (да ещё из фона и ISR) шло асинхронное обращение к периферии.

Если подходить грамотно: пишется служба доступа к флешь, и только эта служба может работать с этим SPI-FLASH.
И эта служба должна обслуживать клиентские запросы операций с FLASH от разных клиентов.
x893
Для начала надо определиться, что делать если в прерывании надо читать, а SPI занят.
Как определитесь с этой ситуацией - дальше решение будет очевидным.
Оно же будет грамотным и рабочим.
charkin
Цитата(jcxz @ Oct 25 2017, 14:32) *
Зависит от используемого МК. В разных МК периферия SPI и DMA устроена по-разному.
Но в общем случае можно считать что транзакция закончилась по завершению приёма блока SPI-DMA.


Проц STM32F429.
можно считать что транзакция закончилась по завершению приёма блока SPI-DMA. - то есть, если в моем случае чтение данных из внешней флэш разбивается на две команды (сначала Transmit_DMA, в которой передается адрес и команда чтения, а затем Receive_DMA, которая и читает данные из памяти), то завершение транзакции надо отслеживать именно после Receive_DMA, правильно?

Цитата(jcxz @ Oct 25 2017, 14:32) *
Здесь никакие биты не помогут. Вам надо править консерваторию алгоритм.
Такого просто не должно быть - чтобы из разных мест (да ещё из фона и ISR) шло асинхронное обращение к периферии.

Если подходить грамотно: пишется служба доступа к флешь, и только эта служба может работать с этим SPI-FLASH.
И эта служба должна обслуживать клиентские запросы операций с FLASH от разных клиентов.


Понятно, спасибо.

Цитата(x893 @ Oct 25 2017, 14:50) *
Для начала надо определиться, что делать если в прерывании надо читать, а SPI занят.
Как определитесь с этой ситуацией - дальше решение будет очевидным.
Оно же будет грамотным и рабочим.


Если в обработчике прерывания выяснится, что по SPI идет обмен, то можно просто пройти дальше, ждать пока SPI освободится не надо.
x893
Передача и прием это одна транзакция.
Например - записать надо 3 байта и потом считать 15.
Задаем передачу 18 байт (3 байта с данными, остальные не важно какие) и прием 18 байт (первые 3 игнорируем, 15 последних будут с данными).
По концу приема (RX_TC) SPI свободен.
В прерывании, если SPI занят - ставите флаг (bool HOUSTON_WE_NEED_SPI = true), что бы SPI никакая сволочь не занимала, если свободен - то используете.
В основном процессе, если SPI свободен и флаг требования (HOUSTON_WE_NEED_SPI == false) не установлен (тут придется прерывания запретить), то используете SPI.
jcxz
Цитата(charkin @ Oct 25 2017, 15:01) *
Transmit_DMA, в которой передается адрес и команда чтения, а затем Receive_DMA, которая и читает данные из памяти), то завершение транзакции надо отслеживать именно после Receive_DMA, правильно?

Я не знаю что такое у вас Transmit_DMA/Receive_DMA, но стандартный SPI работает одновременно на приём и передачу. Соответственно - и связанные с ним DMA-каналы (TX и RX) тоже работают одновременно. Почти одновременно. RX-DMA заканчивает свою работу чуть позже. Вот завершение его работы обычно удобно использовать в качестве признака завершения всей транзакции.
Если конечно в данном конкретном МК нет отдельного специального сигнала завершения SPI-транзакции - тогда лучше использовать его.

Цитата(charkin @ Oct 25 2017, 15:01) *
Если в обработчике прерывания выяснится, что по SPI идет обмен, то можно просто пройти дальше, ждать пока SPI освободится не надо.

ISR может выставить флаг запроса операции с флешью (с полным описанием требуемой операции: тип операции, адрес начала, размер и т.п.).
Служба доступа к флешь, завершив очередную операцию, просматривает флаги запрошенных операций (флаги запросов могут быть отсортированы по приоритету) и если имеется запрос операции от ISR - запустить его обработку. По завершении обработки, поместить результаты операции в нужные места (если нужно) и выставить статус этому запросу - "выполнен". ISR при следующем обращении увидит что операция выполнена.
Все остальные источники запросов операций с флешью (клиенты Службы доступа к флешь) общаются с ней в таком же порядке - формируют запрос операции и выставляют флаг запроса.
Примерно так.
0men
Цитата(charkin @ Oct 25 2017, 15:01) *
Проц STM32F429.


если использовать HAL, то там есть такая каллбэк функция, которая вызовется при завершении транзакции SPI_DMATransmitCplt
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.