|
|
  |
STM32F4, DMA GPIO event, нельзя начать транзакцию по событию от GPIO? |
|
|
|
Sep 12 2014, 13:30
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
В LPC ДМА следит как за флагом готовности данных если оно читает их, так и за флагом готовности передатчика если передает. Задаете куда и сколько байт заслать, запускаете процесс, наслаждаитесь.
Не думаю что в STM настолько тупо сделано, что ДМА будет просто тупой писалкой из адреса в адрес. Наверняка там можно выбрать что будет приемником адрес или периферия, а если так, то оно должно само справиться с этой задаче.
Потому с вероятностью 90% (или я буду еще хуже думать об СТМ) задача решается запуском ДМА записи и чтения, я бы запускал по прерыванию, но можно ножкой запустить таймер, а от таймера запустить ДМА, но какая то это долбанная матрешка....
|
|
|
|
|
Sep 12 2014, 13:36
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата 1) можно ли решить задачу используя два DMA и один таймер? Можно с использованием EXTI. Т.е. прерывание по каждому сигналу готовности. Цитата 2) не понятно как именно осуществляется транзакция нескольких байт последовательно в SPI_TX через DMA. Я понимаю так: как только DMA получает сигнал о готовности данных (от таймера или от флага, установленного в обработчике прерывания GPIO) то, в соответствии с настройками, DMA отправляет последовательно 16-байт в SPI_TX. Не понятно как именно DMA узнает что байт улетел наружу и можно кидать следующий байт в SPI_TX. если ниак, то получается что DMA тупо перезапишет регистр 16-раз. О готовности данных он узнает по запросам на DMA-транзакцию. Например, SPI_TX. Не от таймера или флага GPIO, а именно от SPI_TX. Однако, ничто не мешает копировать в SPI_DR по запросам от таймера или GPIO, но в этом случае программист должен гарантировать, что не будет перезаписи, а ранее записанные данные уже обработаны. Вопрос в том, как заставить таймер сказать DMA, что можно начинать передавать данные в SPI_DR по запросам от SPI_TX?
|
|
|
|
|
Sep 12 2014, 14:06
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Цитата(adnega @ Sep 12 2014, 17:36)  О готовности данных он узнает по запросам на DMA-транзакцию. Например, SPI_TX. Не от таймера или флага GPIO, а именно от SPI_TX. запрос на транзакцию от SPI_TX для DMA может быть только по готовности данных в SPI_TX. Т.е. появился байт в SPI_TX - возникает событие для DMA. У меня два DMA: один передает "тупые" данные, другой принимает валидные. Так вот первый должен как-то узнать о том что отправлять надо не сразу 16 байт один за другим, а только когда один отправился - -отправлять другой, при этом запрос на транзакцию он принимает от флага GPIO(или таймера). Вы предлагаете третий DMA завести, который будет принимать запрос от SPI_TX? но как это поможет первому DMA узнать когда нужно отправить слудующий байт из 16ти... не понимаю логику...  P.S. или существует механизм(наличие флага?), позволяющий определить что SPI_TX пуст?
|
|
|
|
|
Sep 12 2014, 14:42
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(TigerSHARC @ Sep 12 2014, 18:06)  запрос на транзакцию от SPI_TX для DMA может быть только по готовности данных в SPI_TX. Т.е. появился байт в SPI_TX - возникает событие для DMA. У меня два DMA: один передает "тупые" данные, другой принимает валидные. Так вот первый должен как-то узнать о том что отправлять надо не сразу 16 байт один за другим, а только когда один отправился - -отправлять другой, при этом запрос на транзакцию он принимает от флага GPIO(или таймера). Вы предлагаете третий DMA завести, который будет принимать запрос от SPI_TX? но как это поможет первому DMA узнать когда нужно отправить слудующий байт из 16ти... не понимаю логику...  P.S. или существует механизм(наличие флага?), позволяющий определить что SPI_TX пуст? Допустим мы используем SPI1. SPI1_TX можно найти на канале 3 в DMA2_Stream3, SPI1_RX можно найти на канале 3 в DMA2_Stream2. Настраиваем DMA2_Stream3 на копирование данных из памяти, в которой лежит 0xFF, в SPI1->DR. Длина 16 транзакций. Настраиваем DMA2_Stream2 на копирование данных из SPI1->DR в буфер приема. Длина 16 транзакций. Устанавливаем в SPI1 TXDMAEN и RXDMAEN. В SPI будет отправлено 16 раз 0xFF и принято 16 байт в буфер приема.
|
|
|
|
|
Sep 12 2014, 16:34
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(TigerSHARC @ Sep 12 2014, 17:35)  Это как в прерывании дёргать пин чтобы меандр нужной частоты получить без прерывваний экономичнее получается (в плане расхода процессорного времени). Ну, не преувеличивайте  Основной-то обмен всё же будет по DMA. Насчёт расхода процессорного времени я бы не был так уверен. DMA тоже выполняется процессором. И, боюсь, что 2(или даже 3 - ещё возможно надо будет записывать TXDMAEN в SPI_CR2) дополнительных канала DMA могут нагрузить процессор больше, чем ма-а-аленькая процедурка прерывания с тремя командами внутри. Ещё одно соображение: каналов DMA не так уж много, и это может быть более ценный ресурс, чем процессорное время.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 12 2014, 19:46
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AHTOXA @ Sep 12 2014, 22:34)  Насчёт расхода процессорного времени я бы не был так уверен. DMA тоже выполняется процессором. И, боюсь, что 2(или даже 3 - ещё возможно надо будет записывать TXDMAEN в SPI_CR2) дополнительных канала DMA могут нагрузить процессор больше, Вот это открытие так открытие! Кто-ж знал-то??? Я-то по скудости ума всегда думал, что DMA - это такой периферийный узел, главное назначение которого - разгрузить CPU от тупого перетаскивания байтов по шине. А значит - это совершенно разные узлы. Ан нет, он оказывается тоже какая-то часть CPU... левая задняя нога наверное.. Цитата(AHTOXA @ Sep 12 2014, 22:34)  чем ма-а-аленькая процедурка прерывания с тремя командами внутри. Маленькая процедурка с сохранением контекста на входе и выходе в ISR, десятком команд, с выборкой их из памяти (заполнение как минимум 2-3 prefetch-буферов по 128/256бит каждый), +несколько обращений по шине для чтения/записи данных, и опять заполнение prefetch-буферов командами после возврата из ISR. И Вы утверждаете, что это быстрее чем заранее настроенному каналу DMA активироваться и сделать 2-3 пересылки по шине для записи управляющих регистров таймера или другого канала DMA для запуска пакета из 16 операций обмена с SPI??? Ню-ню.... Цитата(AHTOXA @ Sep 12 2014, 22:34)  Ещё одно соображение: каналов DMA не так уж много, и это может быть более ценный ресурс, чем процессорное время. Это уже разработчику решать - что ему важнее: потратить несколько DMA-каналов или по всему коду программы вводить жёсткие ограничения на длительность запретов прерываний, понижать приоритеты других ISR (в которых тоже время реакции может оказаться критичным). Если речь идёт о периоде событий порядка 10 мкс (и это только период стартовых импульсов, а время реакции на них значит ещё в разы меньше), то требования к времени реакции на прерывание (если делать по прерыванию) весьма жёсткие. При таких требованиях имхо надо всё делать максимально без-процессорно, всё свалив на DMA. Для того он и нужен. А более медленную периферию можно и программно обслужить, если каналов DMA не хватит. PS: Кстати - ТС указал период стартовых событий (10мкс), но забыл указать более важное - максимальное время реакции на стартовый импульс. Оно будет зависеть ещё от частоты SPI и необходимого запаса времени между последней SPI-пересылкой и новым импульсом.
|
|
|
|
|
Sep 12 2014, 20:14
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(jcxz @ Sep 12 2014, 23:46)  Вот это открытие так открытие! Кто-ж знал-то??? Я-то по скудости ума всегда думал, что DMA - это такой периферийный узел, главное назначение которого - разгрузить CPU от тупого перетаскивания байтов по шине. А значит - это совершенно разные узлы. Ан нет, он оказывается тоже какая-то часть CPU... левая задняя нога наверное..  Я бы предостерег от категоричных высказываний) 1. DMA и CPU разделяют общие шины. 2. Инициализация DMA тоже занимает ресурс CPU. 3. Пересылка крошечными блоками не эффективна. 4. DMA транзакция может выполняться с задержкой, считая от момента возникновения запроса (больше 12 тактов). DMA хорош только на больших объемах данных, не привязанных строго к тактам.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|