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

"Вовремя" остановить Кольцевой DMA на STM32

Добрый день!

Нацарапал прошивку для STM32F411, которая формирует ШИМ сигнал по содержимому в буфере. Значения в Таймер загружает DMA в кольцевом 2х буферном режиме. Пока грузится один буфер - основной цикл подготавливает второй буфер. И бывает так, что по окончании "полезного" сигнала буфер для DMA заполнен не полностью, ну к примеру DMA настроен на буфер в 512 отсчётов, а в очередной цикл буфер заполнился на 100 отсчётов и по окончании нужно остановить генерацию, т.е. выключить таймер.

В очередном прерывании DMA (когда меняются местами буферы TCIFn) я могу определить что очередной "работающий" буфер короче ожидаемого, но вот как об этом сказать DMA? Если верить даташиту, то с запущенным DMA уже ничего не поделать, все манипуляции только после остановки. Но если я его остановлю, я получу "ошибки" в генерации выходного сигнала таймером. 

Варианты:

1. Забивать остаток не полного буфера "нейтральным" сигналом и останавливать DMA при очередном TCIFn после этого - "не полного" буфера.
2. "ловить" DMA на пол пути ещё одним таймером настроенным заранее в TCIFn из расчёта на кол-во отсчётов.
 

Может как-то ещё?

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


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

On 6/23/2020 at 9:24 AM, Spider said:

Добрый день!

Нацарапал прошивку для STM32F411, которая формирует ШИМ сигнал по содержимому в буфере. Значения в Таймер загружает DMA в кольцевом 2х буферном режиме. Пока грузится один буфер - основной цикл подготавливает второй буфер. И бывает так, что по окончании "полезного" сигнала буфер для DMA заполнен не полностью, ну к примеру DMA настроен на буфер в 512 отсчётов, а в очередной цикл буфер заполнился на 100 отсчётов и по окончании нужно остановить генерацию, т.е. выключить таймер.

В очередном прерывании DMA (когда меняются местами буферы TCIFn) я могу определить что очередной "работающий" буфер короче ожидаемого, но вот как об этом сказать DMA? Если верить даташиту, то с запущенным DMA уже ничего не поделать, все манипуляции только после остановки. Но если я его остановлю, я получу "ошибки" в генерации выходного сигнала таймером. 

Варианты:

1. Забивать остаток не полного буфера "нейтральным" сигналом и останавливать DMA при очередном TCIFn после этого - "не полного" буфера.
2. "ловить" DMA на пол пути ещё одним таймером настроенным заранее в TCIFn из расчёта на кол-во отсчётов.
 

Может как-то ещё?

Несколько сображений.

1. Если основной цикл может не успеть подготовить очередной буфер, то в целом дела плохи.

2. Если можно жить с "нейтральным" сигналом, то что такое " ошибки в генерации выходного сигнала"?

3. Как идея (безотносительно темы): буферы не нужно переключать в TCIF, если запустить DMA на длину всего двойного буфера, а какие-то решения можно принимать по прерыванию HTIF.

4. Ваш DMA срабатывает по готовности какой-то периферии либо тактируется таймером. Может можно остановить эту компоненту, которая пихает DMA?

 

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


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

А если запускать DMA в однократном режиме, а в прерывании по окончании передачи принимать решение: пойти на следующий круг или остановиться?

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


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

On 6/28/2020 at 10:35 PM, Eddy_Em said:

А если запускать DMA в однократном режиме, а в прерывании по окончании передачи принимать решение: пойти на следующий круг или остановиться?

Появляется "джитер" в сигнале в этот момент :(

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


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

Грубоватый вариант, но...

В тот момент, когда буфер заполнен не полностью, получить прерывание HTIF, заранее вычислить значение DMAx_ChannelY->CNDTR, на котором требуется остановиться, и в цикле ожидать достижения этого значения. При совпадении - остановить DMA.

Да, выглядит как костыль и является костылём :(

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


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

3 hours ago, Spider said:

Появляется "джитер" в сигнале в этот момент :(

Тогда только нейтральный сигнал остается.

Вообще мне не ясен момент быстродействия. Если программа в принципе успевает готовить буферы, то программный доступ к элементам массива значительно быстрее выборки элементов DMA: надо же не просто скопировать данные, надо их высчитать. То есть цикл, который готовит очередной буфер, значительно быстрее времени передачи этого буфера с помощью DMA. Поделив времена на размер буфера получим, что за время между шагами со стороны DMA (период дискретизации как обратная величина частоты дискретизации) процессор должен быть в состоянии исполнить довольно большое количество команд. В этом случае, как только DMA выбрал последний элемент и выработал прерывание TCIF, до выборки им очередного элемента остается время (период дискретизации), за которое процессор уж явно успеет ворваться в прерывание и передернуть пару флагов. Иначе как?

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


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

23.06.2020 в 10:24, Spider сказал:

Варианты:

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

Обеспечить успевание можно: а) оптимизацией алгоритма работы; б) увеличением глубины буферизации; в) повышением приоритета процесса/ISR, подготавливающего новый буфер с данными; г) повышением быстродействия МК; ...

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


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

23.06.2020 в 10:24, Spider сказал:

2. "ловить" DMA на пол пути ещё одним таймером настроенным заранее в TCIFn из расчёта на кол-во отсчётов.

Вроде бы у всех STM32 есть отдельное прерывание точно в середине буфера (когда передача доходит до середины).

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


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

11 часов назад, Xenia сказал:

Вроде бы у всех STM32 есть отдельное прерывание точно в середине буфера

Выражение "на полпути" здесь было применено в переносном смысле. Мы-то с вами знаем, что половина не может быть большей или меньшей, но бОльшая половина народа этого не понимает :acute:

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


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

On 7/2/2020 at 8:10 PM, jcxz said:

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

Обеспечить успевание можно: а) оптимизацией алгоритма работы; б) увеличением глубины буферизации; в) повышением приоритета процесса/ISR, подготавливающего новый буфер с данными; г) повышением быстродействия МК; ...

б) не спасает, если среднее быстродействие подготовки ниже выборки. БОльший буфер помогает при многозадачности, позволяя отвлекаться от подготовки буфера на бОльшее время.

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


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

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

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

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

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

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

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

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

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

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