STM32 DMA Memory to GPIO - не работает нулевой пин
- Войдите на сайт для отправки комментариев
Сб, 16/07/2022 - 11:21
Пробую генерировать сложные сигналы при помощи двух синхронных потоков DMA, тактируемых от одного таймера.
В массиве записана последовательность состояний двух пинов. Первый ДМА канал один за другим загружает их в регистр GPIOx->BSRR , второй сбрасывает состояние перед передачей нового значения.
Код (STM32F103C8, аддон Кларка) :
#include <dma_private.h> #define PIN1 PA1 #define PIN2 PA2 const byte nRows = 6; uint8_t mux_mask[nRows] = {0b00000010, 0b00000110, 0b00000100, 0b00000110, 0b00000010, 0b00000000}; #define TIM_PERIOD 8 void setup() { // GPIO setup pinMode(PIN1, OUTPUT); pinMode(PIN2, OUTPUT); volatile uint32_t *muxsetreg = portSetRegister(PIN1); // GPIOx->BSRR uint32_t clr_mask = digitalPinToBitMask(PIN1) | digitalPinToBitMask(PIN2); clr_mask = clr_mask << 16; // timer setup timer_pause(TIMER4); TIMER4_BASE->DIER |= (1 << 11)|(1 << 10); //CH2 & CH3 DMA request enable TIMER4_BASE->PSC = 0; TIMER4_BASE->ARR = (120 * TIM_PERIOD - 1); // 72 MHz / (120 * 8) = 75 KHz cycle TIMER4_BASE->CCR2 = 50 * TIM_PERIOD; // 1 dma request TIMER4_BASE->CCR3 = 100 * TIM_PERIOD; // 2 dma request // dma setup dma_init(DMA1); dma_setup_transfer(DMA1, DMA_CH4, (uint8_t*)muxsetreg, DMA_SIZE_8BITS, (uint8_t*)mux_mask, DMA_SIZE_8BITS, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_FROM_MEM)); dma_set_num_transfers(DMA1, DMA_CH4, nRows); dma_enable(DMA1, DMA_CH4); dma_setup_transfer(DMA1, DMA_CH5, (uint32_t*)muxsetreg, DMA_SIZE_32BITS, (uint32_t*) &clr_mask, DMA_SIZE_32BITS, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_FROM_MEM)); dma_set_num_transfers(DMA1, DMA_CH5, 1); dma_enable(DMA1, DMA_CH5); TIMER4_BASE->CNT = 0; TIMER4_BASE->CR1 = (1 << 0);// Start ешьук } void loop() { // put your main code here, to run repeatedly: }
На пинах PA1 PA2 все работает отлично:
но стоит поменять пины на PA0 PA1, сдвинув соответствующим образом значения в массиве:
uint8_t mux_mask[nRows] = {0b00000001, 0b00000011, 0b00000010, 0b00000011, 0b00000001, 0b00000000};
сигнал с PA0 пропадает:
попробовал на двух разных платах и с портом B - с пинами PB0 PB1 ровно такая же ситуация, так что дело не в железе.
В чем моя ошибка, что я упускаю?
В инете пока все что удалось найти - в комментах вот к этому видео человек тоже жалуется, что у него нулевой пин на GPIO порту не управляется от ДМА.
Народ, кто тесно работает с СТМ - может потестируете мой код?.
Понимаю что наглость... но код вроде простой, повторить его на СТМ-овском аддоне не должно быть сложно.
Почему при настройке DMA1 канал 5 вы ссылаетесь на локальную нестатическую переменную "clr_mask"? Она же расположена в стеке, при выходе из функции сохранность ее значения не гарантируется.
упсс... косяк.
Сделал
глобальными и все заработало.
Спасибо огромное!
Продолжу в этой же ветке, поскольку вопрос снова про ДМА
Попытался запустить скетч из первого сообщения на STM32F4. Не работает.
Решил для начала упростить задачу, отказаться от двух каналов ДМА. Сделал код максимально простым - ДМА по сигналам таймера берет одно слово (32 бит) и пихает в регистр BSRR выходного порта. По идее должен видеть меандр на двух пинах.
Не работает.
Гляньте код, комму не лень - может опять что-то простое не вижу?
и чисто теоретический вопрос
Правильно ли я понимаю, чтобы запустить тактирование ДМА от таймера по compare match, достаточно перевести канал таймера в output mode (где он и так по умолчанию) и включить генерацию сигнала для ДМА в регистре DIER ?
Что-то не срабатывает, на выходах ровная линия
b707, у меня был похожий пример. Отсюда вопрос -а это не ошибка, DMA1 и TIMER3 разве могут в принципе лезть в GPIO?
b707, у меня был похожий пример. Отсюда вопрос -а это не ошибка, DMA1 и TIMER3 разве могут в принципе лезть в GPIO?
да, я вспомнил, мы с вами это уже обсуждали...
Не знаю точно, может и в этом дело. Знаний пока не хватает, чтоб сделать вывод только по докам, надо будет попробовать через ДМА2 и Таймер1. Спасибо за наводку.
Код на stm32F446RE, должен работать, давно не проверял но компилируется.
(На не литертурные комменты (если где остались) не крыситься -);.)
Я разочаровался в дма, когда понял что 12-14 МГц её предел (180 МГц проц). С любой периферией, что ацп, цап, эс-пи-ай и т.д. И на всех F4, G4, H4, F7.
Хардварный предел. H7 (480M) может под 24М дотянуть а потом "буксует" - пропускает данные, без всяких видимых признаков /ошибок.
https://drive.google.com/file/d/1pCtH11iaVhbSIkkeXeupSVaWInZ_dNNW/view?usp=sharing
|
Я разочаровался в дма, когда понял что 12-14 МГц её предел
Спасибо за архив, скачал, можно убирать если надо
Насчет предела ДМА - я пока делаю это (параллельный вывод в порт) в виде бит-бангинга и получаю примерно 4-6 МГц, так что 12 Мгц при почти полной разгрузке ядра выглядят заманчиво.
Я разочаровался в дма, когда понял что 12-14 МГц её предел
Спасибо за архив, скачал, можно убирать если надо
Насчет предела ДМА - я пока делаю это (параллельный вывод в порт) в виде бит-бангинга и получаю примерно 4-6 МГц, так что 12 Мгц при почти полной разгрузке ядра выглядят заманчиво.
Так SPI бустрее будет, на кой тогда GPIO? Если два пина, две эс-пи-ай в паралель. Ещё барст-мода на таймерах, тогда 4-ре ШИМ в раз можно обновить
Если два пина, две эс-пи-ай в паралель. Ещё барст-мода на таймерах, тогда 4-ре ШИМ в раз можно обновить
надо семь :)
RGB матрицы, 6 цветовых каналов и клок
Поменял в коде #4 таймер на TIM1 CH3, а ДМА на DMA2 CH6 Stream6. Не покатило...
Значит будем проверять все с самого начала...
Поменял в коде #4 таймер на TIM1 CH3, а ДМА на DMA2 CH6 Stream6. Не покатило...
Значит будем проверять все с самого начала...
что-то вообще все наперекосяк... я даже PWM на первом таймере получить не могу...
На ТИМ3 PWM настраиваю, сигнал есть. Меняю таймер на ТИМ1 - ничего нет! но ведь регистры то у них одинаковые! как так? ( я не забыл сменить выходной пин...)
Да они ваще разные, тим2-3-4-5 в одной группе примитивов, а тим1-8 адванснутые - продвинутые типа. Примеров на ШИМ полно, гугл в помощь
На ТИМ3 PWM настраиваю, сигнал есть. Меняю таймер на ТИМ1 - ничего нет! но ведь регистры то у них одинаковые! как так? ( я не забыл сменить выходной пин...)
В TIM1 есть глобальный выключатель выхода, по умолчанию выключен , регистр BDTR
Переделал свой пример под кларковский формат, и ваши данные настроек. Всё работает (F401)
dimax, спасибо!
Буду разбираться, почему у меня не работало.
нашел
Посмотрите на строчки 23 и 24 моего кода в посте 4...
Обидно, что на банальную опечатку потрачено несколько дней.
Короче, все работает. Причем работает как в нотации через регистры, так и через функции аддона.
dimax и Волшебник - огромное спасибо.
Грабли ударили другим концом ...
Так, просто к слову :) Не могу удержаться :)
Написал аналогичный параллельный вывод на пины на RP2040 через DMA и PIO-машину. Частота на выходе 55 МГц :) - половина частоты проца. И пишется в общем проще, чем на СТМ32.
55 МГц отличная цифирь ...
Чушь... Что референс, что КУБ... не могут угадать ваших хотелок и различных ситуаций... Это основы... не более... Наилучший результат - юзать логический анализатор... особенно... если для достижения результата меняются регистры на лету...
Я разочаровался в дма, когда понял что 12-14 МГц её предел (180 МГц проц). С любой периферией, что ацп, цап, эс-пи-ай и т.д. И на всех F4, G4, H4, F7.
Значит что-то криво делали... Для начала нужно понимать для чего вообще ДМА... что и для чего вы хотите получить... И да... ДМА не панацея...
В stm32 каждого чипа в даташите конкретно прописано какой DMA висит на какой шине и какова его частота передачи данных и везде, насколько я знаю, это не более половины частоты МК. Из последнего : баловался с spi ili9341 раньше на spi2 всего максимум 18 МГц, перешёл на spi1 шины более высокочастотной, нолучил половину частоты МК - 36 МГц.
Так, просто к слову :) Не могу удержаться :)
Написал аналогичный параллельный вывод на пины на RP2040 через DMA и PIO-машину. Частота на выходе 55 МГц :) - половина частоты проца. И пишется в общем проще, чем на СТМ32.
Чудеса какие-то, смотрю на вики :
The RP2040 is a 32-bit dual ARM Cortex-M0+ microcontroller integrated circuit
М0, это даже не М3 и тем более М4. Расбери это или клюква, шины им менять никто не разрешит, ключевое слово Кортекс, а по общей шине арбитраж как я и написал , /12 делит.
Это не та скорость, 36 / 8 - 4.5 МБайт всего, это если байтами, а 16-бит вордами и того меньше. Мы же обсуждали параллельную ДМА скорость - она 32-битами гоняет данные, паковки там нету как я понял, поэтому хоть 8-бит хоть 32 - всё одно "трансфер" и вот он то и упирается в 12 мег./сек
Не выбесишь - не подставишь, сам сколько толстопогонных выбесил, не сосчитать. А скоко секретов выведал - все уровни безопасности прошёл. Ток на моей "торпеде" таперча батарейки прокисли, не заводится.
Расбери это или клюква, шины им менять никто не разрешит, ключевое слово Кортекс, а по общей шине арбитраж как я и написал , /12 делит.
Я все это наблюдаю при помощи самого дешевого Салеае с его 20 Мегсемплами в секунду. Утверждать что-либо в таких обстоятельствах просто смешно.
Но картинка такая... при делителе 6 пакет из 64 импульсов имеет длину 8.5 мксек, что дает 7.5 МГц. Если поставить делитель 1 - пакет по длине уменьшается ровно в 6 раз, правда рассмотреть число линий в нем я уже не могу
Вроде как 7.5 * 6 = 45 МГц
Уточнение: попробовал сгенерить реальный сигнал (управление светодиодной матрицей) на разных делителях. Шаг частоты получается те же 7.5 МГц.
Сигнал 15 МГц матрица ест и показывает четкую картинку, 23 МГц - экран темный. Правда остается неясным, то ли это матрица не тянет 23 МГц (по даташиту вроде до 30), то ли клюква на этой частоте выдает фигню.
Но 15 МГц реальные точно :)
Это не та скорость, 36 / 8 - 4.5 МБайт всего, это если байтами, а 16-бит вордами и того меньше. Мы же обсуждали параллельную ДМА скорость - она 32-битами гоняет данные, паковки там нету как я понял, поэтому хоть 8-бит хоть 32 - всё одно "трансфер" и вот он то и упирается в 12 мег./сек
Так я ж не спорю :) но в итоге у меня при частоте МК 72 МГц, на пине выходном spi шины 36 МГц. Почему у b707 при частоте МК 110мгц не может быть на выходе 55 МГц?
Это не та скорость, 36 / 8 - 4.5 МБайт всего, это если байтами, а 16-бит вордами и того меньше. Мы же обсуждали параллельную ДМА скорость - она 32-битами гоняет данные, паковки там нету как я понял, поэтому хоть 8-бит хоть 32 - всё одно "трансфер" и вот он то и упирается в 12 мег./сек
Потому что у b707 не SPI, а GPIO. Первый интерфейс - сериал , т.е. дма толкает в него 16-бит слово а эта хрень клокает побитно дальше сама, а дма отдыхает. Второй интерфейс - паралельный, дма скидывает 16-бит и он сразу выставляется на 16-ти пинах.
Счас вспоминаю, что F446RE способна крутить дма на 36МГц, т.е. не виснет. Но я потом проверял аппаратным счётчиком на предмет "проскальзывания" и обнаружил недостающие данные, 0.1%. Осцилоскопом не заметно, нужна именно аппаратная верификация. На ЖКИ или СДИ может и не заметно будет, пихел два моргнет, но меня интересует ЦОС, где потеря бит недопустима в принципе.
Волшебник, ну при чем тут слово или байт? Есть частота переключения цифрового пина и она очент даже легко может быть равна половине частоты МК.
Вы путаете тёплое с мягким. Или намеренно троллите.
Мужики давайте определимся, о чем мы спорим.
На скорость вывода данных на GPIO влияют два фактора - скорость переключения самого GPIO и скорость доставки новых порций бит по DMA.
Волшебник - так о чем Вы, почему не может быть половины системной частоты - потому что пин не переключится или потому что ДМА не успеет?
Что касается пинов - в даташите клюквы утверждается, что PIO машина переключает пин за одну системную инструкцию. Теории я не знаю, но говорят что PIO работает аналогично FPGA и показывает похожую скорость.
Относительно ДМА все проще. Я вывожу на пины только 6 бит за раз. А ДМА "доставляет" 32 бита. Поэтому ей вовсе не обязательно шуршать со скоростью ХХ МГц, достаточно в 4 раза медленнее.
Счас вспоминаю, что F446RE способна крутить дма на 36МГц, т.е. не виснет. Но я потом проверял аппаратным счётчиком на предмет "проскальзывания" и обнаружил недостающие данные, 0.1%. Осцилоскопом не заметно, нужна именно аппаратная верификация.
Осцилом не видно... а логическим анализатором легко - не выдержана латентность ДМА...
И ваще... юзать ДМА на пределе возможности - так себе затея...
Да они ваще разные, тим2-3-4-5 в одной группе примитивов, а тим1-8 адванснутые - продвинутые типа. Примеров на ШИМ полно, гугл в помощь
Да они ваще одинаковые... а стандартные - укошенные расширенные... или расширенные - стандартные с жирком... ничего не меняет по сути... Они даже одинаковые с СТМ8...
М0, это даже не М3 и тем более М4. Расбери это или клюква, шины им менять никто не разрешит, ключевое слово Кортекс, а по общей шине арбитраж как я и написал , /12 делит.
Ващета... М0 и М0+ это две большие разницы !!! Насколько ещё помню... на М0+ (серия G) от СТМ... пинами через ДМА ваще не подрыгаешь... Как это обошли в малинке... не знаю... не интересовался...