Перейти к содержанию
    

SPI DMA в STM32F429, проверка занятости.

Всем привет.

Подскажите, каким образом можно гарантированно определить, что обмен по SPI (прием/передача, с использованием DMA) завершен?

 

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

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

 

Понимаю, что можно убрать код обращения к флэш-памяти из обработчика прерывания EXTI (пока так и сделал), но тем не менее - каким образом можно узнать, что данные прочитаны/отправлены и можно запускать обмен по SPI?

Изменено пользователем haker_fox
Уточнил название темы, добавил теги, переместил в нужный раздел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как вариант - заведите свой собственный флаг dmaBusy. В прерывании по концу DMA RX его снимайте, при начале работы с SPI - ставьте

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите, каким образом можно гарантированно определить, что обмен по SPI (прием/передача, с использованием DMA) завершен?

Зависит от используемого МК. В разных МК периферия SPI и DMA устроена по-разному.

Но в общем случае можно считать что транзакция закончилась по завершению приёма блока SPI-DMA.

 

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

Здесь никакие биты не помогут. Вам надо править консерваторию алгоритм.

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

 

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

И эта служба должна обслуживать клиентские запросы операций с FLASH от разных клиентов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для начала надо определиться, что делать если в прерывании надо читать, а SPI занят.

Как определитесь с этой ситуацией - дальше решение будет очевидным.

Оно же будет грамотным и рабочим.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зависит от используемого МК. В разных МК периферия SPI и DMA устроена по-разному.

Но в общем случае можно считать что транзакция закончилась по завершению приёма блока SPI-DMA.

 

Проц STM32F429.

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

 

Здесь никакие биты не помогут. Вам надо править консерваторию алгоритм.

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

 

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

И эта служба должна обслуживать клиентские запросы операций с FLASH от разных клиентов.

 

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

 

Для начала надо определиться, что делать если в прерывании надо читать, а SPI занят.

Как определитесь с этой ситуацией - дальше решение будет очевидным.

Оно же будет грамотным и рабочим.

 

Если в обработчике прерывания выяснится, что по SPI идет обмен, то можно просто пройти дальше, ждать пока SPI освободится не надо.

Изменено пользователем charkin

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Передача и прием это одна транзакция.

Например - записать надо 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.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Transmit_DMA, в которой передается адрес и команда чтения, а затем Receive_DMA, которая и читает данные из памяти), то завершение транзакции надо отслеживать именно после Receive_DMA, правильно?

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

Если конечно в данном конкретном МК нет отдельного специального сигнала завершения SPI-транзакции - тогда лучше использовать его.

 

Если в обработчике прерывания выяснится, что по SPI идет обмен, то можно просто пройти дальше, ждать пока SPI освободится не надо.

ISR может выставить флаг запроса операции с флешью (с полным описанием требуемой операции: тип операции, адрес начала, размер и т.п.).

Служба доступа к флешь, завершив очередную операцию, просматривает флаги запрошенных операций (флаги запросов могут быть отсортированы по приоритету) и если имеется запрос операции от ISR - запустить его обработку. По завершении обработки, поместить результаты операции в нужные места (если нужно) и выставить статус этому запросу - "выполнен". ISR при следующем обращении увидит что операция выполнена.

Все остальные источники запросов операций с флешью (клиенты Службы доступа к флешь) общаются с ней в таком же порядке - формируют запрос операции и выставляют флаг запроса.

Примерно так.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проц STM32F429.

 

если использовать HAL, то там есть такая каллбэк функция, которая вызовется при завершении транзакции SPI_DMATransmitCplt

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...