Spider 0 23 июня, 2020 Опубликовано 23 июня, 2020 · Жалоба Добрый день! Нацарапал прошивку для STM32F411, которая формирует ШИМ сигнал по содержимому в буфере. Значения в Таймер загружает DMA в кольцевом 2х буферном режиме. Пока грузится один буфер - основной цикл подготавливает второй буфер. И бывает так, что по окончании "полезного" сигнала буфер для DMA заполнен не полностью, ну к примеру DMA настроен на буфер в 512 отсчётов, а в очередной цикл буфер заполнился на 100 отсчётов и по окончании нужно остановить генерацию, т.е. выключить таймер. В очередном прерывании DMA (когда меняются местами буферы TCIFn) я могу определить что очередной "работающий" буфер короче ожидаемого, но вот как об этом сказать DMA? Если верить даташиту, то с запущенным DMA уже ничего не поделать, все манипуляции только после остановки. Но если я его остановлю, я получу "ошибки" в генерации выходного сигнала таймером. Варианты: 1. Забивать остаток не полного буфера "нейтральным" сигналом и останавливать DMA при очередном TCIFn после этого - "не полного" буфера. 2. "ловить" DMA на пол пути ещё одним таймером настроенным заранее в TCIFn из расчёта на кол-во отсчётов. Может как-то ещё? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба А если запускать DMA в однократном режиме, а в прерывании по окончании передачи принимать решение: пойти на следующий круг или остановиться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spider 0 2 июля, 2020 Опубликовано 2 июля, 2020 · Жалоба On 6/28/2020 at 10:35 PM, Eddy_Em said: А если запускать DMA в однократном режиме, а в прерывании по окончании передачи принимать решение: пойти на следующий круг или остановиться? Появляется "джитер" в сигнале в этот момент :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlanDrakes 1 2 июля, 2020 Опубликовано 2 июля, 2020 · Жалоба Грубоватый вариант, но... В тот момент, когда буфер заполнен не полностью, получить прерывание HTIF, заранее вычислить значение DMAx_ChannelY->CNDTR, на котором требуется остановиться, и в цикле ожидать достижения этого значения. При совпадении - остановить DMA. Да, выглядит как костыль и является костылём :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 2 июля, 2020 Опубликовано 2 июля, 2020 · Жалоба 3 hours ago, Spider said: Появляется "джитер" в сигнале в этот момент :( Тогда только нейтральный сигнал остается. Вообще мне не ясен момент быстродействия. Если программа в принципе успевает готовить буферы, то программный доступ к элементам массива значительно быстрее выборки элементов DMA: надо же не просто скопировать данные, надо их высчитать. То есть цикл, который готовит очередной буфер, значительно быстрее времени передачи этого буфера с помощью DMA. Поделив времена на размер буфера получим, что за время между шагами со стороны DMA (период дискретизации как обратная величина частоты дискретизации) процессор должен быть в состоянии исполнить довольно большое количество команд. В этом случае, как только DMA выбрал последний элемент и выработал прерывание TCIF, до выборки им очередного элемента остается время (период дискретизации), за которое процессор уж явно успеет ворваться в прерывание и передернуть пару флагов. Иначе как? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 2 июля, 2020 Опубликовано 2 июля, 2020 · Жалоба 23.06.2020 в 10:24, Spider сказал: Варианты: Вариант тут только единственный: Обеспечить успевание заполнения буфера "основным циклом" (или кем-то другим). Если успевания нет, то нет никакой возможности обеспечить нормальную работу. Обеспечить успевание можно: а) оптимизацией алгоритма работы; б) увеличением глубины буферизации; в) повышением приоритета процесса/ISR, подготавливающего новый буфер с данными; г) повышением быстродействия МК; ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 2 июля, 2020 Опубликовано 2 июля, 2020 · Жалоба 23.06.2020 в 10:24, Spider сказал: 2. "ловить" DMA на пол пути ещё одним таймером настроенным заранее в TCIFn из расчёта на кол-во отсчётов. Вроде бы у всех STM32 есть отдельное прерывание точно в середине буфера (когда передача доходит до середины). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 3 июля, 2020 Опубликовано 3 июля, 2020 · Жалоба 11 часов назад, Xenia сказал: Вроде бы у всех STM32 есть отдельное прерывание точно в середине буфера Выражение "на полпути" здесь было применено в переносном смысле. Мы-то с вами знаем, что половина не может быть большей или меньшей, но бОльшая половина народа этого не понимает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 5 июля, 2020 Опубликовано 5 июля, 2020 · Жалоба On 7/2/2020 at 8:10 PM, jcxz said: Вариант тут только единственный: Обеспечить успевание заполнения буфера "основным циклом" (или кем-то другим). Если успевания нет, то нет никакой возможности обеспечить нормальную работу. Обеспечить успевание можно: а) оптимизацией алгоритма работы; б) увеличением глубины буферизации; в) повышением приоритета процесса/ISR, подготавливающего новый буфер с данными; г) повышением быстродействия МК; ... б) не спасает, если среднее быстродействие подготовки ниже выборки. БОльший буфер помогает при многозадачности, позволяя отвлекаться от подготовки буфера на бОльшее время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться