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