|
Хочу писать в 16 линеек WS2812B на макс. скорости., Хочу весь буфер без участия процессора с минимумом накладных. |
|
|
|
Dec 13 2017, 17:25
|

Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 24-10-07
Из: zp.ua
Пользователь №: 31 690

|
Сразу предупреждаю, в STM32 я полный новичек, пока знакомлюсь. Все чего пока добился, это моргать в кейле светодиодом на двухдолларовой плате с stm32f103c8t6. До этого частенько писал для авр на бейсике и ассемблере, так что освоение stm32 вопрос времени. Вопрос мой будет не столько про код, а про возможность выполнения нужного мне алгоритма переферией автономно. Не буду скрывать, хочу без участия процессора выдавать поток данных сразу в 16 длинных линеек светодиодов WS2812B. Для выдачи одного бита нужно на отдельном выводе сначала ~ на треть периода выставить 1, потом на треть данные, и на треть 0. В принципе при помощи DMA данная задача реализуема, но вот этот ноль в начале и еденица в конце утроят размер буфера (и добавят неудобства работы с ним).
Поэтому возник вопрос, а можно ли как то внутренними или наружными выходами таймеров переводить (или заполнить) весь 16 битный порт GPIO в высокий и низкий уровни? Вероятно можно было бы задействовать второй DMA для цикличной выдачи двух констант (с нулями и еденицами) в тот же порт, но думаю целый ДМА для этого жирновато. Возможно не зная завязок и возможностей переферии я узковато мыслю, и есть более красивые решения, был бы рад услышать.
|
|
|
|
|
Dec 13 2017, 17:54
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 18-10-06
Из: Москва
Пользователь №: 21 459

|
Да и с 3 каналами DMA нормальное решение от одного таймера, первый настроить только на выдачу 1, второй по буферу, третий - 0. В STM32 таймер не может управлять целым портом.
|
|
|
|
|
Dec 13 2017, 18:05
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(-=TRO=- @ Dec 13 2017, 19:25)  Возможно не зная завязок и возможностей переферии я узковато мыслю, и есть более красивые решения, был бы рад услышать. Можно взять другой МК, имеющий внешнюю 16-разрядную шину и выдавать на неё при помощи DMA требуемый поток. А если в этом МК ещё и стоит хороший контроллер DMA, умеющий передачи "свЯзным списком", то его вообще можно запрограммировать так, чтобы он брал скажем два первых 16-битных слова с фиксированного адреса, а третье слово - из вашего кольцевого буфера. Либо взять LPC43xx и на его SGPIO-интерфейсе (с DMA) реализовать требуемую диаграмму работы. Цитата(DeNi @ Dec 13 2017, 19:54)  Да и с 3 каналами DMA нормальное решение от одного таймера, первый настроить только на выдачу 1, второй по буферу, третий - 0. В STM32 таймер не может управлять целым портом. Автор не озвучил частоту выдачи. И требуемую максимальную фазовую погрешность. На высоких частотах (от МГц) такое будет работать неустойчиво. Ещё вариант - использовать Infineon XMC4700 или XMC4800. Он имеет до 3 USIC-ов. Каждый USIC - это два последовательных порта. Которые можно запрограммировать в режим quad-SPI и получить 3*2*4 последовательных битовых потока имеющих DMA-поддержку и FIFO-буфера глубиной до 32 слов. Размер слова запрограммировать кратным 3 (например 30 бит). Данные в слове кодировать так, чтобы шли: 0, 1, 1-й информационный бит, 0, 1, 2-й информационный бит, .... . Такое решение будет работать даже на нескольких десятках МГц без проблем с очень точным выдерживанием временных интервалов. Вобщем - на более-менее высоких частотах битового потока нормально будут работать только решения на каком-либо последовательном интерфейсе (с буферизацией). Например - несколько параллельных quad-SPI или SGPIO. Никакие решения на таймер+DMA+GPIO стабильно не будут работать пока процессор лазит по той же шине, где работают эти пересылки DMA->GPIO. Они будут сбивать времянку.
|
|
|
|
|
Dec 13 2017, 18:32
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 18-10-06
Из: Москва
Пользователь №: 21 459

|
Цитата(jcxz @ Dec 13 2017, 21:05)  Можно взять другой МК, имеющий внешнюю 16-разрядную шину и выдавать на неё при помощи DMA требуемый поток. А если в этом МК ещё и стоит хороший контроллер DMA, умеющий передачи "свЯзным списком", то его вообще можно запрограммировать так, чтобы он брал скажем два первых 16-битных слова с фиксированного адреса, а третье слово - из вашего кольцевого буфера. И чем выдача на шину выигрышние выдачи в порт GPIO через DMA? Цитата(jcxz @ Dec 13 2017, 21:05)  Автор не озвучил частоту выдачи. Он озвучил цену за плату в 2$. И этот светодиод где-то и работает до мегагерца максимум.
Сообщение отредактировал DeNi - Dec 13 2017, 18:35
|
|
|
|
|
Dec 13 2017, 19:32
|

Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 24-10-07
Из: zp.ua
Пользователь №: 31 690

|
Цитата(DeNi @ Dec 13 2017, 21:54)  Да и с 3 каналами DMA нормальное решение от одного таймера, первый настроить только на выдачу 1, второй по буферу, третий - 0. В STM32 таймер не может управлять целым портом. Секундочку, я грешным делом думал, что если одному DMA дать задание через его один канал, то пока он весь свой цикл не отработает, по другим каналам его озадачивать нельзя... Я выходит думал не правильно? Огурцов, спасибо, но тут у меня под STM32 задачек не одна, и твердо решил изучать его, пока никуда не распыляясь.
Сообщение отредактировал -=TRO=- - Dec 13 2017, 19:35
|
|
|
|
|
Dec 13 2017, 19:38
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(DeNi @ Dec 13 2017, 20:32)  И чем выдача на шину выигрышние выдачи в порт GPIO через DMA? Ничем. Для низких частот и низких требований к стабильности длительностей фаз - и то и другое пойдёт одинаково. Моя фраза насчёт последовательных интерфейсов касалась высоких частот (от нескольких МГц). Цитата(DeNi @ Dec 13 2017, 20:32)  Он озвучил цену за плату в 2$. И этот светодиод где-то и работает до мегагерца максимум. Не знаю. Недавно на одном из форумов читал, что некто собирался тактировать такие линейки несколькими МГц. Или даже больше 10. Цитата(-=TRO=- @ Dec 13 2017, 21:32)  что если одному DMA дать задание через его один канал, то пока он весь свой цикл не отработает, по другим каналам его озадачивать нельзя Можно
|
|
|
|
|
Dec 13 2017, 20:08
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(-=TRO=- @ Dec 13 2017, 21:47)  У этих светодиодов четко 1.25мкс на битовый период, и довольно жесткие допуски по длительностям (около 10-20%, точно не вспомню, даташит надо открывать). Ну вот и прикиньте: на один битовый период вам нужно успеть выполнить 3 пересылки через DMA (установка 0, установка 1, установка бита данных). И с точностью фазы 10% максимальная допустимая задержка будет = 1.25/3*0.1= ~42нс. А какая частота CPU? Наверное не более 72МГц? Это ~14 нс/такт. А теперь представьте, что вот пришёл к DMA запрос от таймера выполнить очередную пересылку ОЗУ->GPIO, а в это время CPU по этой же самой шине выполняет команду например: POP {R0-R12,PC} т.е. - 15 тактов. Сколько нс DMA будет ждать своей очереди? Конечно у DMA-каналов обычно есть FIFO (но есть ли оно в этом МК и сколько?) - может оно и поможет как-то....
|
|
|
|
|
Dec 13 2017, 20:10
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 18-10-06
Из: Москва
Пользователь №: 21 459

|
Здесь можно почитать подробней про DMA в STM32 - AN2548 Using the STM32F101xx and STM32F103xx DMA controller
По приоритетам обслуживания CPU и DMA в STM32 одинаковые, и если не будет 100% загрузки шины, то запросы будут выполняться довольно точно.
|
|
|
|
|
Dec 13 2017, 20:41
|

Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 24-10-07
Из: zp.ua
Пользователь №: 31 690

|
Цитата(Plain @ Dec 14 2017, 00:07)  Отсюда и решение — все данные форматировать на сильной стороне, т.е. перетасовывать биты и избыточно кидать в SD лишние 0 и 1, а STM32 будет лишь тупой молотилкой. Если гнать с компа то поток хотелось бы тоже не быстрый (например через UART пропихнуть), а экономить хочется оперативку, это ведь из неё через ДМА выгребатся все будет (20 кило байт оперативы, по 3 байта на цвет, уже 6 килопикселей, а это 80x80 всего, если запихнуть еще старт-стопы, то даже 50x50 не поместится). К тому же эти самы непредсказуемые джиттеры ДМА и подначивали решать старстоповые дела без ДМА (все же нагрузка в три раза меньше). Была мысль с аппаратным решением проблеммы, поставить буферный регистр с третьим состоянием, одним выходом таймера переводить регистр в третье состояние, а другим таймером формировать подтяжками нули и еденицы, а ДМА инициировать как раз в начале перехода регистров в Z состояние (за 80мкс старстопов ДМА должен успеть), тогда по фронтам должно быть все шоколадно... но это два корпуса регистров и 16 сопротивлений (или штук пять корпусов логики). Но ведь хочется то же самое все силами контроллера.
Сообщение отредактировал -=TRO=- - Dec 13 2017, 20:51
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|