Контроллер ПДП (DMA)

hinto

New member
1.
В случае ввода значений не удовлетворяющих делению на блоки, или ввода значений превышающих размер буфера канала, возможно непредвиденное поведение контроллера. (K1948VK_018_015_MIK32_AMUR_2_2_2.pdf стр.19)
Я так понял, должно выполняться условие
WRITE_BURST_SIZE >= WRITE_SIZE
READ_BURST_SIZE >= READ_SIZE
но при этом WRITE_BURST_SIZE и READ_BURST_SIZE могут быть любыми по отношению друг к другу ?
То есть, если WRITE_BURST_SIZE > READ_BURST_SIZE, то чтобы началась запись, требуеться несколько чтений, каждое из которых должно ждать подтверждения от переферии ?

2.
Похоже значение ..._BURST_SIZE представляет собой место в буфере, но вот каков размер этого буфера ?
Опыт показал, что при WRITE_BURST_SIZE (или READ_BURST_SIZE) > 2 пересылка памяти не выполняется.
То есть 2^2=4 байта размер буфера канала? похоже в RV64, это значение будет минимум 3. хммм...
А вобще там отводиться 3 бита на ..._BURST_SIZE, то есть максимум 2^7=128 байт. Был соблазн использовать этот буферок, но вглядит так , что только 4 байта...

3.
Есть линия DAC, но нет ADC. Есть идея снимать данные по таймеру.
Можно например взять timer32_1, поскольку он на тойже шине что ADC (APB_P)
В этом случае рассинхронизации быть не должно, или не ?
Разумееться приоритет канала DMA будет наивысшим, иначе очередь может просто недойти.
Остаёться ещё вероятность, что сам CPU займёт шину AHB дольше, чем на 1 отсчёт.
Какие ещё засады могут быть?
 
Последнее редактирование:
1. Я для себя решил, что эта фишка нужна для "соединения" по DMA двух блоков с разной шириной шины чтения и записи, например UART (8 бит) и CRYPTO (32 бита). Реальное использование подсмотрено в той же доке в описании блока SPIFI и использовано в загрузчике.
2. Скорее всего, Вы правы, и этот самый буфер содержит только 32 бита.
3. Когда обработчик прерывания в ОЗУ и первым делом проверяется флаг прерывания от таймера, и если оно, то читаются данные от ADC и тут же запускается следующее преобразование - вроде бы всё норм, кроме небольшой неопределённости момента попадания в прерывания (т.е. надо доку на ядро SCR1 читать) или кто-то ещё в это время лезет по DMA в блок на одной шине с ADC. Т.е. если не гнаться за максимальной частотой переобразования, то эти неопределённости будут влиять достаточно мало. Ну и по-моему никакой разницы нет, использовать таймер на APB_P или на APB_M или вообще системный, в итоге всё равно всё проходит через обработчик прерывания, ибо аппаратного триггера для ADC нет.
 

hinto

New member
Спасибо за ответ.
Ну и по-моему никакой разницы нет, использовать таймер на APB_P или на APB_M или вообще системный, в итоге всё равно всё проходит через обработчик прерывания, ибо аппаратного триггера для ADC нет.
Я имел ввиду совсем другую возможность, без использования прерываний.
Преобразование ADC запускаеться в непрерывном режиме, а таймер настраивается кратно этой частоте, таким образом несуществующий аппаратный триггер ADC подменяется аппаратным триггером от таймера.
Ведь таймер может напрямую посылать запросы в DMA, если выбран в качестве периферии, и так могут только 3 таймера: Timer32_0, Timer32_1, Timer32_2. Ну, так написано...
Раз этот метод не обкатан, значить буду ставить экспирименты.
 
А, интересно. Кстати, про 12 тактов на SAH: "Сигнал Start должен подаваться на АЦП и защёлкиваться по переднему фронту CLK. При этом его длительность должна быть не менее 12 тактов CLK при заданных параметрах входа данных.". Кроме того, в документации не расписаны тайминги "непрерывного преобразования", так что действительно остаётся только экспериментировать :) Если не сложно, опубликуйте результаты опытов.
 

hinto

New member
Кроме того, в документации не расписаны тайминги "непрерывного преобразования", так что действительно остаётся только экспериментировать :)
После того как выяснил тайминги, идея выбирать значения по таймеру, через DMA сработала.
На дисплее полученная синусоида, с частотой выборки 1МГц, визуально выглядит красиво. (В теме по ADC расписал и показал)
Как я и опасался, обращение цпу к памяти ломает выборку и значения пропускаются,
синусоида превращается в рваную и апериодичную ломаную.
Что бы это работало, нужно отключать прерывания, если они есть и крутиться в цикле ожидания, пока идёт выборка.
В теории в это время ещё можно заняться тем, что не требует обращений к AHB,
например, вычислять синусы или квадратные корни , если оно нужно ;).
Но результатом я удовлетворён, не стоило ожидать чудес.

Так что буду считать по теме DMA, я разобрался.
Пробовал даже сделать программный SPI, через GPIO с использованием DMA.
Пересылка в порт через DMA в итоге происходила примерно на треть (в полтора раза?) медленее, чем прямая запись в GPIO.
Куча накладных расходов памяти и времени. Извращение ради извращения, ой, ради экспиремента !
 
Последнее редактирование:
Сверху