Spider 0 Posted April 3, 2019 · Report post Всем привет! Что-то я делаю не так... цель моя - запустить DMA в кольцевом режиме для приёма данных с UART. Использую LL библиотеку от STM. Ожидаю получение IDLE прерывания от UART и как следствие чтение данных из DMA. Немного не допонимаю что делать с DMA в данный момент... Как понять сколько байт DMA положила в буфер? Как после обработки этих данных "объяснить" DMA что эти данные уже обработаны? Надо как-то сместить "начало" буфера? Чё-то я туплю :( Quote Ответить с цитированием Share this post Link to post Share on other sites
esaulenka 0 Posted April 3, 2019 · Report post 1 hour ago, Spider said: Как понять сколько байт DMA положила в буфер? Завести свою собственную переменную, назвать её "предыдущее значение счётчика". По какому-то событию взять текущее значение счётчика DMA, вычислить их разницу (не забыть, что он бегает "по кругу"), прочитать новые данные. Сохранить "новый" счётчик в переменную "старый счётчик". Да, события - это не только IDLE, но и заполнение (или даже половина заполнения) буфера, если пакет длинный. 1 hour ago, Spider said: Как после обработки этих данных "объяснить" DMA что эти данные уже обработаны? Никак. В кольцевом режиме оно "само" прыгнет на начало, когда надо. PS никогда не пользовался прерыванием IDLE. Это действительно событие "пришёл старт-бит после длинной паузы", как описано в референсе ? А если у меня между пакетами полчаса будет, все полчаса ждать? Как же всё у них через задницу... Quote Ответить с цитированием Share this post Link to post Share on other sites
Spider 0 Posted April 3, 2019 · Report post 30 minutes ago, esaulenka said: PS никогда не пользовался прерыванием IDLE. Это действительно событие "пришёл старт-бит после длинной паузы", как описано в референсе ? А если у меня между пакетами полчаса будет, все полчаса ждать? Как же всё у них через задницу... Оно приходит спустя где-то 1,5 байта после приёма стоп бита последнего принятого байта. Quote Ответить с цитированием Share this post Link to post Share on other sites
AHTOXA 0 Posted April 3, 2019 · Report post 3 часа назад, Spider сказал: Что-то я делаю не так... цель моя - запустить DMA в кольцевом режиме для приёма данных с UART. Использую LL библиотеку от STM. Ожидаю получение IDLE прерывания от UART и как следствие чтение данных из DMA. Немного не допонимаю что делать с DMA в данный момент... Посмотрите мою реализацию здесь. (функция UartIrqHandler()) Quote Ответить с цитированием Share this post Link to post Share on other sites
Spider 0 Posted April 3, 2019 · Report post Спасибо, вроде разобрался. В итоге использую 3 прерывания: IDLE, HTC, TC. Обработчик во всех один и тот же. Вроде пока работает... Quote Ответить с цитированием Share this post Link to post Share on other sites
mcheb 0 Posted April 3, 2019 · Report post Выложили бы код . Чтобы люди знали, как надо Quote Ответить с цитированием Share this post Link to post Share on other sites
AlanDrakes 0 Posted April 6, 2019 (edited) · Report post У себя в проектах использую кольцевой буфер DMA + прерывание USART-IDLE. Работает корректно. Глобальная переменная хранит позицию записи в DMA буфер, которая была обработана последней. При прерывании IDLE сравнивается указатель DMA_ChannelX->CNDTR и переменная. Вычитанием (RCVD = DMA_ChannelX->CNDTR - LAST_CNDTR) получаю количество принятых байт. В случае перехода указателя буфера через ноль - получаем отрицательное число и обрабатываю данные особым образом. В ином случае (положительное число) - копирую их за один проход и вызываю функцию, либо отправляю в очередь ОС. Edited April 6, 2019 by AlanDrakes Quote Ответить с цитированием Share this post Link to post Share on other sites