Jump to content

    
Sign in to follow this  
Spider

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

Recommended Posts

Добрый день!

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

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

Варианты:

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

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

Share this post


Link to post
Share on other sites
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?

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
On 6/28/2020 at 10:35 PM, Eddy_Em said:

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites
3 hours ago, Spider said:

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

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

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

Share this post


Link to post
Share on other sites
23.06.2020 в 10:24, Spider сказал:

Варианты:

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

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

Share this post


Link to post
Share on other sites
23.06.2020 в 10:24, Spider сказал:

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

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

Share this post


Link to post
Share on other sites
11 часов назад, Xenia сказал:

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

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

Share this post


Link to post
Share on other sites
On 7/2/2020 at 8:10 PM, jcxz said:

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

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this