Всем привет. Хочу организовать 2 кольцевых FIFO-буфера для передачи и приема данных по UART. Если делать тупо прерываниями, то проблем не воникает. Но хочется использовать DMA, чтобы избавить проц от лишних телодвижений.
Работать должно так:
Имеется n байт. Проверяем заполненность буфера и смотрим влезут-ли туда эти n байт.
Если влезут, записываем и запускаем дма на передачу данных из буфера в UART, если нет, то сигнализируем об ошибке.
Вся проблема в том, что у дма недоступно значение смещения от базового адреса памяти. Следовательно нельзя узнать сколько байт уже ушло и проверить заполненность буфера.
В сязи с чем возникает вопрос, как можно реализовать такую штуку? Нашел этот апноут, но там, кроме того, что "DMA является крутой штукой для организации FIFO" ничего толкового не сказано.
STM32 DMA Кольцевой FIFO-буфер
Неправда, узнать количество байт, переданных DMA можно, регистр CNDTR или функция DMA_GetCurrDataCounter STшной библиотеки.
Допустим DMA пишет данные из буфера в UART. А мы хотим записать в этот буфер еще пакет данных на отправку. Останавливаем ДМА. Узнаем из CNDTR, что уже ушло 3 байта. Проверяем остаток в буфере, ага, новый пакет данных влезет, записываем его туда. Как теперь сказать DMA, что данных стало больше? Писать в CNDTR нельзя, т.к. DMA начнет чтение с базового адреса. Базовый адрес менять тоже нельзя, т. к. потеряется "цикличность".
нужно просто данные для передачи копировать так как их будет читать DMA, тоесть начиная с CNDTR пишем байты, учитывая что когда CNDTR = 0, данные начинают читаться со стартового адреса.
Я понимаю, что копировать байты надо так, чтобы ДМА последовательно их читал. Сейчас еще раз попробую объяснить ситуацию:
Есть буфер размером, скажем, 10 байт. Есть несколько блоков данных, допустим, по 3 байта. Закидываем в буффер два блока (6 байт). Как заставить переслать ДМА только эти 6 байт, но так, чтобы на начальный адрес он переключился только после того, как дойдет до конца 10-байтового буфера (т.е. после того, как мы накидаем в буфер еще пакетов).
Есть буфер размером, скажем, 10 байт. Есть несколько блоков данных, допустим, по 3 байта. Закидываем в буффер два блока (6 байт). Как заставить переслать ДМА только эти 6 байт, но так, чтобы на начальный адрес он переключился только после того, как дойдет до конца 10-байтового буфера (т.е. после того, как мы накидаем в буфер еще пакетов).
Менять количество байт, которое должен передать ДМА. Тоесть система должна быть такая - заполнили буфер - включили дма - пока он передает, заполняем буфер дальше по кольцу. Когда он передал, ставим ему новые указатели и включаем опять.
BSVi, кажется я понял твою мысль. Спасибо, попробую реализовать. Правда видится один недостаток у такого решения - пока дма не отправит весь "пакет" место в буфере не освободится.
Освободиться, можно писать новые данные до (стартового адреса + количество отправлных байт).
Люди, может кто просветит: Можно ли через DMA перезаписывать ячейки flash памяти самого контроллера(при. STM32f103)?
Можно. Но они должны быть предварительно стерты, и в момент записи нужно ее разблокировать.
Вернуться в «Микроконтроллеры и ПЛИС»
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 14 гостей