charkin 0 25 октября, 2017 Опубликовано 25 октября, 2017 (изменено) · Жалоба Всем привет. Подскажите, каким образом можно гарантированно определить, что обмен по SPI (прием/передача, с использованием DMA) завершен? У меня обращение к внешней флэш-памяти по SPI может происходить из главного цикла, а также в обработчике прерывания EXTI. Если прерывание возникло в момент, когда в главном цикле что-то писалось/читалось во флэш, то данные конечно же портятся.. Пробовал смотреть биты SPI-модуля - TXE, RXNE И BUSY, но подобрать правильно условие так и не смог, либо оно никогда не выполняется, либо наоборот выполняется тогда, когда нельзя запускать обмен по SPI. Почитал про флаги DMA, они выставляются по завершению чтения/записи, но в соответствующем обработчике прерываний эти флаги сбрасываются.. И, похоже, использовать их для определения завершения обмена не получится. Понимаю, что можно убрать код обращения к флэш-памяти из обработчика прерывания EXTI (пока так и сделал), но тем не менее - каким образом можно узнать, что данные прочитаны/отправлены и можно запускать обмен по SPI? Изменено 16 ноября, 2022 пользователем haker_fox Уточнил название темы, добавил теги, переместил в нужный раздел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 25 октября, 2017 Опубликовано 25 октября, 2017 · Жалоба Как вариант - заведите свой собственный флаг dmaBusy. В прерывании по концу DMA RX его снимайте, при начале работы с SPI - ставьте Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 25 октября, 2017 Опубликовано 25 октября, 2017 · Жалоба Подскажите, каким образом можно гарантированно определить, что обмен по SPI (прием/передача, с использованием DMA) завершен? Зависит от используемого МК. В разных МК периферия SPI и DMA устроена по-разному. Но в общем случае можно считать что транзакция закончилась по завершению приёма блока SPI-DMA. У меня обращение к внешней флэш-памяти по SPI может происходить из главного цикла, а также в обработчике прерывания EXTI. Если прерывание возникло в момент, когда в главном цикле что-то писалось/читалось во флэш, то данные конечно же портятся.. Пробовал смотреть биты SPI-модуля - TXE, RXNE И BUSY Здесь никакие биты не помогут. Вам надо править консерваторию алгоритм. Такого просто не должно быть - чтобы из разных мест (да ещё из фона и ISR) шло асинхронное обращение к периферии. Если подходить грамотно: пишется служба доступа к флешь, и только эта служба может работать с этим SPI-FLASH. И эта служба должна обслуживать клиентские запросы операций с FLASH от разных клиентов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 55 25 октября, 2017 Опубликовано 25 октября, 2017 · Жалоба Для начала надо определиться, что делать если в прерывании надо читать, а SPI занят. Как определитесь с этой ситуацией - дальше решение будет очевидным. Оно же будет грамотным и рабочим. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
charkin 0 25 октября, 2017 Опубликовано 25 октября, 2017 (изменено) · Жалоба Зависит от используемого МК. В разных МК периферия SPI и DMA устроена по-разному. Но в общем случае можно считать что транзакция закончилась по завершению приёма блока SPI-DMA. Проц STM32F429. можно считать что транзакция закончилась по завершению приёма блока SPI-DMA. - то есть, если в моем случае чтение данных из внешней флэш разбивается на две команды (сначала Transmit_DMA, в которой передается адрес и команда чтения, а затем Receive_DMA, которая и читает данные из памяти), то завершение транзакции надо отслеживать именно после Receive_DMA, правильно? Здесь никакие биты не помогут. Вам надо править консерваторию алгоритм. Такого просто не должно быть - чтобы из разных мест (да ещё из фона и ISR) шло асинхронное обращение к периферии. Если подходить грамотно: пишется служба доступа к флешь, и только эта служба может работать с этим SPI-FLASH. И эта служба должна обслуживать клиентские запросы операций с FLASH от разных клиентов. Понятно, спасибо. Для начала надо определиться, что делать если в прерывании надо читать, а SPI занят. Как определитесь с этой ситуацией - дальше решение будет очевидным. Оно же будет грамотным и рабочим. Если в обработчике прерывания выяснится, что по SPI идет обмен, то можно просто пройти дальше, ждать пока SPI освободится не надо. Изменено 25 октября, 2017 пользователем charkin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 55 25 октября, 2017 Опубликовано 25 октября, 2017 · Жалоба Передача и прием это одна транзакция. Например - записать надо 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 234 25 октября, 2017 Опубликовано 25 октября, 2017 · Жалоба Transmit_DMA, в которой передается адрес и команда чтения, а затем Receive_DMA, которая и читает данные из памяти), то завершение транзакции надо отслеживать именно после Receive_DMA, правильно? Я не знаю что такое у вас Transmit_DMA/Receive_DMA, но стандартный SPI работает одновременно на приём и передачу. Соответственно - и связанные с ним DMA-каналы (TX и RX) тоже работают одновременно. Почти одновременно. RX-DMA заканчивает свою работу чуть позже. Вот завершение его работы обычно удобно использовать в качестве признака завершения всей транзакции. Если конечно в данном конкретном МК нет отдельного специального сигнала завершения SPI-транзакции - тогда лучше использовать его. Если в обработчике прерывания выяснится, что по SPI идет обмен, то можно просто пройти дальше, ждать пока SPI освободится не надо. ISR может выставить флаг запроса операции с флешью (с полным описанием требуемой операции: тип операции, адрес начала, размер и т.п.). Служба доступа к флешь, завершив очередную операцию, просматривает флаги запрошенных операций (флаги запросов могут быть отсортированы по приоритету) и если имеется запрос операции от ISR - запустить его обработку. По завершении обработки, поместить результаты операции в нужные места (если нужно) и выставить статус этому запросу - "выполнен". ISR при следующем обращении увидит что операция выполнена. Все остальные источники запросов операций с флешью (клиенты Службы доступа к флешь) общаются с ней в таком же порядке - формируют запрос операции и выставляют флаг запроса. Примерно так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
0men 2 25 октября, 2017 Опубликовано 25 октября, 2017 · Жалоба Проц STM32F429. если использовать HAL, то там есть такая каллбэк функция, которая вызовется при завершении транзакции SPI_DMATransmitCplt Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться