Страница 1 из 1

помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Чт сен 05, 2013 10:29:51
avmartugin
здравствуйте. у меня такая задача: генерировать 2 периода скважности PWM-генератора используя DMA и буфер из байтов. причем 3 подряд идущих байта это будущий цвет на светодиоде, каждая логическая "единица" в бите буфера с цветами должна на выходе PWM-генератора иметь определенную скважность, а каждый "ноль" - другую скважность. предложите пожалуйста лучший по быстродействию и памяти алгоритм работы чтобы по минимуму загрузить CPU (собираюсь использовать DMA и буферизацию, если DMA закончил предыдущую пересылку, то CPU ждет 50 микросекунд и снова запускает DMA и таймеры уже с другим подготовленным буфером). если просто цвет (3 байта) превращать в блок из 24 х 16 бит для пересылки генератору, то это будет отнимать процессорное время и отжирать много памяти, хочется чтобы это выполнялось "на лету". заранее всем спасибо.
п.с. камень - stm32f407vet6

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Чт сен 05, 2013 13:09:02
balmer
avmartugin писал(а):здравствуйте. у меня такая задача: генерировать 2 периода скважности PWM-генератора используя DMA и буфер из байтов.
Огласите таки условия задачи. Насколько часто меняются битики?
Может быть имеет смысл посчитать для всего байта среднюю скважность и сказать таймеру ее генерировать?

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Чт сен 05, 2013 13:37:50
avmartugin
каждый светодиод требует 24 бита на цвет (усреднять ниче не получится как бы не хотелось). каждый этот бит должен быть послан на частоте 800 КГц цепочке светодиодов связанных последовательно. задача: получить максимально возможное быстродействие, т.к. цепочек из светодиодов может быть много (чуть меньше чем таймеров в системе) это для экономии, чтобы не городить микрух много, а взять одну и она бы рулила многими светодиодами. кроме этой задачи микруха должна выполнять и сложный код, поэтому максимизировать использование инструментов, которые позволяют обойти сам проц в работе.

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Чт сен 05, 2013 14:25:51
avmartugin
https://github.com/x893/stm-ledstrip
вот такой проект, после беглого изучения понятно что CPU напрягать эта библиотека будет довольно сильно. вот я и хочу обойти ее изъяны. что можно еще аппаратно здесь улучшить?

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Чт сен 05, 2013 17:18:35
balmer
avmartugin писал(а):каждый светодиод требует 24 бита на цвет
Все таки как звучит задача? Есть N светодиодных лент, и надо управлять их яркостью? Или что-то другое? Сколько градаций яркости планируется.
Я просто пытаюсь понять, почему нельзя воспользоваться хардварным PWM, которое в таймерах есть. Оно там хорошее с изменяемой скважностью.
avmartugin писал(а):каждый этот бит должен быть послан на частоте 800 КГц
Частота приличная, излучение будет немаленькое, если провода будут не 5 см. Чтото плохо представляю схему, которую вы хотите сделать.

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Чт сен 05, 2013 17:25:42
balmer
avmartugin писал(а):https://github.com/x893/stm-ledstrip
вот такой проект, после беглого изучения понятно что CPU напрягать эта библиотека будет довольно сильно. вот я и хочу обойти ее изъяны. что можно еще аппаратно здесь улучшить?
Посмотрел на исходники, теперь задача таки понятна :))
Ключевое слово WS2812

Лично мое мнение - оптимальнее, чем в той библиотеке не сделать.
color2pwm правда не особо быстрая, а в остальном там все хорошо, и DMA используется.

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пт сен 06, 2013 07:20:51
avmartugin
есть ли способ для STM запихивать в таймер значение скважности исходя из значения бита в массиве? или если ли способ задать значение скважности как функцию от значения ячейки памяти?
http://www.micromouseonline.com/2013/01 ... z2e5C7ieOP
ссылка про bit banding, как думаете это поможет оптимизировать color2pwm функцию?

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пт сен 06, 2013 10:57:04
Galizin
Можно попытаться использовать spi. Кодировать в обном байте SPI 2 бита цвета. Предположительно будет быстрее чем через таймер. Недостаток - нужно подбирать частоту кварца что бы SPI работало с нужными частотами.

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пт сен 06, 2013 11:13:17
avmartugin
spi мало в системе, всего 3. а мне нужно 10-12 таких каналов передачи чтобы уж микруху по полной использовать и не городить гирлянду из микрух

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пт сен 06, 2013 12:18:30
dosikus
avmartugin выплевывать буфер через DMA, DMA пинать таймером .
Итого до 16 каналов . Единственное памяти уйдет много ...
uint16_t buf[240] - где то так , плюс где то хранить уже обработанные массивы для эффектов

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пт сен 06, 2013 12:23:45
avmartugin
нашел в итоге крутую возможность для портов STM32: GPIOx->ODR=0xFFFF - устанавливает все ножки порта в 1, GPIOx->ODR=0x0000 - в ноль, так что если научится при этом рулить скважностью этих ногодрыганий, то это и будет решением задачи. да и еще тут можно получить больше чем 10-12, может даже на 2 порта кидать данные. будет 32 канала вообще. памяти должно быть всего в 2 раза больше кушать чем объем данных для передачи. товарищи, хакеры, есть у кого идеи? : )

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пт сен 06, 2013 12:28:35
dosikus
avmartugin, выше читай, не все так радужно ....

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пт сен 06, 2013 13:27:58
avmartugin
вот я и предлагаю скважностью рулить по времени, а не по значению скважности таймера для каждой ножки. при этом надо как-то эмулировать скважность сигнала, хотя вроде можно завести с 1 таймера все ноги в "1", потом прерывание от второго таймера часть ног в "0", а часть в единицу и далее все ноги в "0".
3 таймера и дма.
памяти нужно будет с такой схемой всего в 2 раза больше чем объем данных о цветах (учитываю буферизацию), т.е. на каждый светодиод по 24 бита. и кстати не надо будет при этом вычислять массив данных для скважности, тут и производительность подскочит.

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пт сен 06, 2013 14:53:25
dosikus
avmartugin писал(а): 3 таймера и дма.
1 таймер и DMA и никаких прерываний . Вечером более детально обрисую , а пока здесь посмотри - с этого поста и далее http://kazus.ru/forums/showpost.php?p=6 ... count=3218

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Сб сен 07, 2013 07:58:12
avmartugin
dosikus, ты предлагаешь создать массив из значений нужной скважности, запустить 1 таймер и прикрутив к нему DMA мы получим нужный сигнал на 1 ноге. множим этот принцип на нужное кол-во ног и получаем profit? это будет работать, да (я уже это попробовал). но такой подход отжирает кучу памяти (для каждого светодиода 24 х sizeof(uint16_t)) и необходимо значение каждого бита цвета превращать в значение скважности (хотя здесь очевидная оптимизация это создание таблицы значений скважности для 1 байта к примеру, тут мы потратим кучу флеш-памяти, но ее и так очень много. сэкономим процессорное время)
http://www.pjrc.com/teensy/td_libs_OctoWS2811.html
оригинальное решение этой задачи для процессоров freescale. как я понял они сразу 8 ног дрыгают по 2 таймерам и DMA. в разделе Technical Details есть картинки и описание:

The hardware events which trigger the DMA channels are a pair of PWM waveforms, corresponding to the WS2811 bit low and high waveforms. The rising edge (both PWM rise at the same moment) triggers channel #1, which copies a fixed byte (0xFF) to an I/O register which sets all 8 output bits, causing the WS2811 waveform to begin each bit. The first falling edge triggers DMA channel #2, which copies one byte of the actual frame buffer data to all 8 pins. The bits which are low transition to low at the correct time to create a zero bit to each WS2811 LED.

т.е. нужно так настроить DMA чтобы он реагировал на подъем/спад сигнала от нужных таймеров (PWM-генераторов) настроенных на заранее заданные скважности.

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Сб сен 07, 2013 09:52:05
dosikus
avmartugin писал(а):dosikus, ты предлагаешь создать массив из значений нужной скважности, запустить 1 таймер и прикрутив к нему DMA мы получим нужный сигнал на 1 ноге. множим этот принцип на нужное кол-во ног и получаем profit? это будет работать, да (я уже это попробовал). но такой подход отжирает кучу памяти (для каждого светодиода 24 х sizeof(uint16_t)) и необходимо значение каждого бита цвета превращать в значение скважности (хотя здесь очевидная оптимизация это создание таблицы значений скважности для 1 байта к примеру, тут мы потратим кучу флеш-памяти, но ее и так очень много. сэкономим процессорное время)
Памяти уйдет куча. Зато это полностью аппаратно, ядро не тревожим.
Длтельность бита - 1,25uS . Разбиваем на 10 дискрет . То есть настраиваем таймер на пинки DMA длительностью 0.12 uS .
И того нам нужен буфер 10*24*(uint16_t)
Расписываем длительности согласно даташиту на WS2812.
Для первой посылки первого бита(посылаем единицу) - нулевые биты буфера ( первые 10 ) будут содержать :
1111110000

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Сб сен 07, 2013 19:51:30
avmartugin
dosikus писал(а): Памяти уйдет куча. Зато это полностью аппаратно, ядро не тревожим.
Длтельность бита - 1,25uS . Разбиваем на 10 дискрет . То есть настраиваем таймер на пинки DMA длительностью 0.12 uS .
И того нам нужен буфер 10*24*(uint16_t)
Расписываем длительности согласно даташиту на WS2812.
Для первой посылки первого бита(посылаем единицу) - нулевые биты буфера ( первые 10 ) будут содержать :
1111110000
так не проще ли завести таймер и прикрутив к нему DMA получить все тоже самое и затраты памяти в 24*(uint16_t) на светодиод? или я что-то не понял? DMA на основе матрицы скважностей будет пихать для каждого бита информации одну из 2-х возможных значений скважности и таймер будет выдавать то, что нужно на выходе. все тоже аппаратно, в конце прерывание на окончание передачи информации.

я про другую возможность хочу узнать. на камнях STM32F4 можно ли замутить вот что: на 2 ножки из порта к примеру GPIOA будем посылать 2 разных сигнала PWM (частота 800КГц, скважности соответствуют "0" и "1" которые понимает светодиод, т.е. 20% и 48% заполнение по документации к светодиоду), весь порт GPIOD будем использовать как каналы для управления светодиодами, итого 16 каналов. надо настроить DMA так, чтобы он сначала сработал на подъем с любого из 2-х портов GPIOA и передал в порт GPIOD все единицы, затем сработал на спад в PWM с 20% заполнением и передал в порт GPIOD заранее подготовленный в памяти массив со значением битов для всех 16-ти каналов со светодиодами, далее сработал на спад в PWM с 48% заполнением и передал в порт GPIOD все нули. вот это будет все полностью аппаратно и занимать минимальный объем памяти.

и еще, как DMA записывает данные в порт? может это сделать на основе возможности процов STM32 bit banding? есть ли в этом профит с точки зрения того что в этом случает запись в порт не будет сбита каким-то прерыванием?

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Вс сен 08, 2013 08:10:01
dosikus
avmartugin писал(а): так не проще ли завести таймер и прикрутив к нему DMA получить все тоже самое и затраты памяти в 24*(uint16_t) на светодиод? или я что-то не понял? DMA на основе матрицы скважностей будет пихать для каждого бита информации одну из 2-х возможных значений скважности и таймер будет выдавать то, что нужно на выходе. все тоже аппаратно, в конце прерывание на окончание передачи информации.
?
Это только 1 канал . У меня все 16 сразу...

Re: помогите с алгоритмом для DMA и TIM на STM32

Добавлено: Пн сен 09, 2013 06:14:28
avmartugin
dosikus писал(а): Это только 1 канал . У меня все 16 сразу...
но дальше-то я предложил вариант с минимальными затратами памяти, полностью аппаратный и тоже на 16 каналов