Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ADSP BF532 и TMS320C6745
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Сигнальные процессоры и их программирование - DSP
__inline__
Здравствуйте.

Ищу процессор в QFP корпусе, который будет производительнее, чем ADSP BlackFin BF532.
Цель: запуск обильного кода с 2D графикой (bitblt, colorkey, alfablending) + немножко 3D (поворот, перенос, масштабирование), тригонометрия. + эмуляция процессоров -8 и 16 бит:
Z80, 6502, M68000. + декодирование видео (H264, MJPEG,...) аудио (MP3, FLAC)

Пробовал собирать эмуляторы на BF532, разогнал до 700 МГц. Иногда эмуляция всей системы не достигает 60 FPS из-за отсутствия floating point, медленной производительности.

В качестве кандидата на замену рассматриваю : TMS320C6745 - доступен, корпус QFP, 475 МГц, шина SDRAM 32 бита, есть floating point, VLIW до 6 команд одновременно. Вроде как лучше чем BF532 ? Или даст выигрыш по сравнению с 532-м незначительно?
jcxz
Цитата(__inline__ @ Mar 26 2018, 16:51) *
В качестве кандидата на замену рассматриваю : TMS320C6745 - доступен, корпус QFP, 475 МГц, шина SDRAM 32 бита, есть floating point, VLIW до 6 команд одновременно. Вроде как лучше чем BF532 ? Или даст выигрыш по сравнению с 532-м незначительно?

Так если Вы говорите что OMAP-L137 есть уже в QFP, то почему тогда не его? Там помимо DSP, ещё 3 ядра - думаю не лишние будут rolleyes.gif
По-крайней мере у меня ARM-ядро всей периферией занималось, разгружая DSP для вычислений.
+ ещё два PRU-ядра, которые предназначены для эмуляции недостающей периферии (для Ваших эмуляторов может как раз подойдут), имеют очень параллельную систему команд (как смутно вспоминается - одна команда кодирует сразу несколько операций). Правда в моё время для PRUSS можно было писать только на асм - си-компилёра не существовало. Но может уже сделали.

PS: Да и кроме OMAP-L137 есть ещё его собрат: OMAP-L138 - он по скорости такой-же, только вроде поддерживает DDR, имеет немного другой набор периферии и у него дефолтным ядром является - ARM (у L137 дефолтное - DSP). Правда насколько помню, в BGA он имел бОльшее кол-во ног, так что его может и не быть в QFP.
_pv
allwinner V3s
__inline__
Цитата(_pv @ Mar 26 2018, 17:09) *
allwinner V3s


У вас есть опыт работы с этим камнем без пингвина и ведра?

Внешней шины для подключения дополнительной периферии, наподобие как FSMC у STM32 у V3s как я понял нет? Если так - прощай дисплеи с контроллерами и своей памятью ..


Цитата(jcxz @ Mar 26 2018, 15:00) *
Так если Вы говорите что OMAP-L137 есть уже в QFP, то почему тогда не его? Там помимо DSP, ещё 3 ядра - думаю не лишние будут rolleyes.gif

Тот что в QFP OMAPL137-HT недоступен для заказа из-за политики США по отношению к РФ.
В БГА мне неинтересно.
__inline__
Смотрю в даташит на 6745 и вижу - 2 шины EMIF A, B, что очень радует. Но огорчила урезанность шин в 2 раза в QFP корпусе: вместо 32- и 16- имеем 16- и 8- соответственно.

Посему возник вопрос. Планирую дисплей с шиной 16 бит (LCD, не тупая матрица) соединить по шине 8 бит. Можно ли сделать 16-битность дисплею таким макаром:

Код
CPU   LCD

D0-----D0
D1-----D1
D2-----D2
D3-----D3
D4-----D4
D5-----D5
D6-----D6
D7-----D7

BA0----D8
BA1----D9
A0------D10
A1------D11
A2 ------D12
A3------D13
A4------D14
A5------D15

A12-----Command/Data
CS[]-----LCD CS
nWR-----LCD nWR
Pull Up----LCD nRD


И обращаться к регистрам/ данным дисплея так:

обращаться к памяти LCD:
Код
*(int*)(LCD_Data_Base|(Data>>8))=Data;


к командам:
Код
*(int*)(LCD_Command_Base|(Command>>8))=Command;


Всёравно для дисплея нужен только 1 адресный бит, более ничего на шине не будет. А SDRAM будет висеть на 16-битной шине.

Пройдет или нет?

Правда , ещё DMA-пересылки надо будет хорошо продумать при таком подключении
jcxz
Цитата(__inline__ @ Mar 28 2018, 14:24) *
Всёравно для дисплея нужен только 1 адресный бит, более ничего на шине не будет. А SDRAM будет висеть на 16-битной шине.

я уже смутно помню, но вроде EMIX B - для дин.памяти, а EMIF A - для статической и всего остального.
Ну или достать OMAP и реализовать контроллер LCD на PRUSS с любой шиной. laughing.gif
_pv
Цитата(__inline__ @ Mar 28 2018, 12:51) *
У вас есть опыт работы с этим камнем без пингвина и ведра?

нет, и скорее всего граблей там будет предостаточно, учитывая китайскую документацию.
но как будто пингвин это что-то плохое.
Цитата(__inline__ @ Mar 28 2018, 12:51) *
Внешней шины для подключения дополнительной периферии, наподобие как FSMC у STM32 у V3s как я понял нет? Если так - прощай дисплеи с контроллерами и своей памятью ..

там есть параллельный 24х видео выход,
и он даже support i80 interface with 18/16/9/8 bit, если не врут.
ну а вообще мелкая cpld за <1$ параллельную шину для дисплея сделать может даже из SDIO какого-нибудь. раз уж так надо именно дисплей со своим контроллером подключить, хотя дисплей со своим контроллером при наличии на борту памяти и видеовыхода - "троллейбус из буханки черного или белого хлеба.jpg"
Цитата(__inline__ @ Mar 28 2018, 12:51) *
В БГА мне неинтересно.

qfp и производительность гораздо больше чем у блэкфина, sdram, и дисплей - тут или трусы снимите или крестик наденьте.
__inline__
Цитата(_pv @ Mar 28 2018, 19:34) *
нет, и скорее всего граблей там будет предостаточно, учитывая китайскую документацию.
там есть параллельный 24х видео выход,
и он даже support i80 interface with 18/16/9/8 bit, если не врут.


Смотрел даташит на v3s и схему камдроида на нём и пришёл к 2-м печальным выводам:
1) шина там только на 8 бит
2) и только RGB, а не i8080, управляющих стробов (nWR,nRD,nCS) я не нашёл, также как и их описания в даташите.

Кусок подключения LCD к v3s в камдроиде:
Нажмите для просмотра прикрепленного файла

Цитата(_pv @ Mar 28 2018, 19:34) *
ну а вообще мелкая cpld за <1$ параллельную шину для дисплея сделать может даже из SDIO какого-нибудь. раз уж так надо именно дисплей со своим контроллером подключить,

И проиграть в помехозащищённости - гнать БИТОВЫЙ клок, который должен быть в 8- или в -16 раз больше по частоте чтобы битики в байты преобразовать (некий параллельный регистр с последовательной загрузкой). Ну и нагромождение.

Цитата(_pv @ Mar 28 2018, 19:34) *
хотя дисплей со своим контроллером при наличии на борту памяти и видеовыхода - "троллейбус из буханки черного или белого хлеба.jpg"


А один фиг тупую матрицу прийдётся цеплять на SPI или I2S, так что одним RGB-интерфейсом не отделаешься! А вот если i8080 - то это уже сказка! sm.gif

Но беда в том, что C6745 который мне так понравился в QFP содержит только 16 и 8 битную шину, а хочется 32 и 16 как в БГА sm.gif

Цитата(_pv @ Mar 28 2018, 19:34) *
qfp и производительность гораздо больше чем у блэкфина, sdram, и дисплей - тут или трусы снимите или крестик наденьте.


Нашёл тут ещё кандидата - STM32H743 - у него 1 Мбайт внутренней оперативы на частоте 400 МГц- весь код эмулятора туда можно затолкать,
32 бита SDRAM - на случай если некоторвые эмуляторы не поместятся + чтение РОМ-ов для эмуляторов + спроецированная FatFS - всё в SDRAM!

Ну и RGB интерфейс там 24-битный (в корпусе LQFP208 точно!) и 32 разряда на SDRAM.

И ещё питание одно - 3.3V, нет дополнительного гемороя с питанием как в Оллвиннерах и C6745.

Ядро Cortex-M7 с его вкусным многооперандными командами Ассемблера типа: addeq r0,r1,r2 LSL r3 - 4 действия в одном - это лучше чем BF532 на 400 МГц и его 16-битной шиной!
И наличие плавающей точки!
И QFP корпус.
И шить можно ST-LINK-ом то бишь дискавери.

И 2D- ускоритель с 2-D DMA, цвет прозрачности, BitBlt - это всё для эмуляторов нужно!! sm.gif

Одни плюсы!

В общем вижу его в кандидатах на замену 532-го. santa2.gif
_pv
Цитата(__inline__ @ Mar 29 2018, 07:23) *
Смотрел даташит на v3s и схему камдроида на нём и пришёл к 2-м печальным выводам:
1) шина там только на 8 бит
2) и только RGB, а не i8080, управляющих стробов (nWR,nRD,nCS) я не нашёл, также как и их описания в даташите.


мы наверное в разные даташиты смотрим.
1) LCD_D[23:0]
2) бит TCON0_IF в регистре TCON0_CTL_REG и регистры TCON0_CPU_*
CS, WR, RD, A1 должны быть мультиплексированы с Hsync, Vsync, LCD_Clk, LCD_DE
но документация - китайская

Цитата(__inline__ @ Mar 29 2018, 07:23) *
И проиграть в помехозащищённости - гнать БИТОВЫЙ клок, который должен быть в 8- или в -16 раз больше по частоте чтобы битики в байты преобразовать (некий параллельный регистр с последовательной загрузкой). Ну и нагромождение.

да ладно, sdram на сотне МГц с 16/32 параллельной шиной так в помехозащищенности видимо выигрывает, а вот 4х битный SDIO на 80 - уже почему-то нет.
__inline__
Цитата(_pv @ Mar 29 2018, 05:35) *
мы наверное в разные даташиты смотрим.
1) LCD_D[23:0]
2) бит TCON0_IF в регистре TCON0_CTL_REG и регистры TCON0_CPU_*
CS, WR, RD, A1 должны быть мультиплексированы с Hsync, Vsync, LCD_Clk, LCD_DE
но документация - китайская

должны быть, но не обязаны. Я глянул даташит на V3s что у меня есть (на английском), там расписаны времянки, но самих стробов CS, WR, адресные биты A* на выводах микроконтроллера НЕ нашёл. Таблицы мультиплексирования выводов тоже молчат.

Просто приводят картинку с времянками, которая как бы намекает, что без дополнительной логики (ПЛИС, ЦПЛД,рассыпуха) не обойтись:

Нажмите для просмотра прикрепленного файла

У вас даташит другой или тоже английский?

Цитата(_pv @ Mar 29 2018, 05:35) *
да ладно, sdram на сотне МГц с 16/32 параллельной шиной так в помехозащищенности видимо выигрывает, а вот 4х битный SDIO на 80 - уже почему-то нет.


Был один головняк(SDRAM), будет два (преобразователь SDIO в i8080 для LCD sm.gif )

А линукс и камадроид не даст ответов на этот вопрос, потому что там везде "стандартная" связка LCD с v3s по RGB-интерфейсу.
jcxz
Цитата(__inline__ @ Mar 29 2018, 03:23) *
Ядро Cortex-M7 с его вкусным многооперандными командами Ассемблера типа: addeq r0,r1,r2 LSL r3 - 4 действия в одном - это лучше чем BF532 на 400 МГц и его 16-битной шиной!

Только не забываем, что ARM-у чтобы сделать эту самую ADD над операндами в памяти, нужно эти операнды ещё в регистры загрузить, да потом ещё результат возможно нужно обратно в память выгрузить. В то время как система команд DSP обычно позволяет это делать одновременно. На C64xx-ядрах DSP я почти не писал на асм (за исключением небольших кусков), но вот к примеру на C55xx-ядре за один такт(!) можно посчитать 2 порядка КИХ-фильтра, т.е.: выполнить загрузку 1-го коэффициента фильтра из памяти + загрузку двух вх.значений из памяти + 2 MAC операции + 2 выгрузки вых.результатов в память + 0 тактов на организацию цикла (ведь всё это должно выполняться в цикле) + 0 тактов на организацию кольцевой адресации (если работаем с кольцевыми буферами вх и вых. данных). И всё это за один такт частоты ядра! И думаю, что на C64xx-ядре возможности должны быть явно не хуже, так как это более старшее ядро.
А теперь вопрос: за сколько тактов выполнит это всё STM32H7? Если учесть что ARM-ядро не поддерживает параллельное выполнение операций (загрузку/выгрузку из/в память одновременно с операцией на АЛУ), требует для доступа к памяти (1+1*N) тактов (где: N - число читаемых/записываемых слов в одной команде), не поддерживает аппаратные циклы и циклическую адресацию памяти.
Я конечно не имел дела с ADSP и блэкфинами, но думаю они должны иметь примерно такую же архитектуру, как и ядра TI.

Цитата(__inline__ @ Mar 29 2018, 03:23) *
Ядро Cortex-M7 с его вкусным многооперандными командами Ассемблера типа: addeq r0,r1,r2 LSL r3 - 4 действия в одном - это лучше чем BF532 на 400 МГц и его 16-битной шиной!

И где кстати тут 4 действия? Всего одно - сложение одного операнда с другим сдвинутым на R3 разрядов. laughing.gif
ARM вообще не имеет команд выполняющих более одного действия. Это архитектурное ограничение. МАС-операция это тоже не 2 или 3 или сколько там действий, а одно - MAC.
А вот настоящие DSP как правило - имеют. В этом и есть их главное различие.

Цитата(__inline__ @ Mar 29 2018, 10:33) *
Был один головняк(SDRAM), будет два (преобразователь SDIO в i8080 для LCD sm.gif )

Я не буду ничего советовать по интерфейсу подключения LCD (неохота разбираться в сигналах), но в том же C6745, как говорит сайт TI, есть 2 интерфейса McASP.
Я помню в OMAP-L137 я использовал один из двух McASP: это порт умеющий формировать до 16 последовательных битовых потока (он имеет 16 сериализаторов), каждый из которых можно независимо сконфигурить на ввод или вывод. Диаграмма сигналов на каждом программируется тоже независимо от других сериализаторов и очень гибко.
Обслуживать McASP может EDMA3 умеющий: 1-, 2- и 3-х-мерные пересылки (может пересылать 3-мерные матрицы) с независимыми произвольными приращениями по каждому измерению (можно например по строке делать скажем +N (положительное смещение на N слов), а по столбцу -M (отрицательное смещение на M слов). За счёт этого EDMA3 при пересылке может преобразовать массив с построчного на постолбцовый например. Также EDMA3 имеет 2 трансфер-контроллера, каждый из которых - независимый bus-master со своим приоритетом доступа к шине.

У меня например на одном McASP висело 3 шт. 8-канальных SPI-АЦП + стерео аудио-кодек (ввод и вывод). И всё это работало параллельно одновременно и обслуживалось через EDMA3.
AlexandrY
Цитата(jcxz @ Mar 29 2018, 12:43) *
ARM вообще не имеет команд выполняющих более одного действия. Это архитектурное ограничение. МАС-операция это тоже не 2 или 3 или сколько там действий, а одно - MAC.
А вот настоящие DSP как правило - имеют. В этом и есть их главное различие.

А поинтересуйтесь-ка командой USADA8 в ARMv7-M
Будете удивлены.


jcxz
Цитата(AlexandrY @ Mar 29 2018, 13:04) *
А поинтересуйтесь-ка командой USADA8 в ARMv7-M
Будете удивлены.

Не буду. Писал я на асм и на ARM. И знаю какие там есть инструкции.
Такие операции (не полной разрядности) как раз за счёт малого числа разрядов и могут выполняться на единственном АЛУ.
Я имел в виду операции полной разрядности.
А то ведь можно считать, что ORR R0, R0, R1 выполняет параллельно 32 операции OR...... над 1-битными операндами. laughing.gif
__inline__
Цитата(jcxz @ Mar 29 2018, 09:43) *
И где кстати тут 4 действия? Всего одно - сложение одного операнда с другим сдвинутым на R3 разрядов. laughing.gif

действие 1) проверка условия , если равно, выполняем: addeq r0,r1,r2 LSL r3
действие 2) сдвигаем r2 влево на значение бит в r3: addeq r0,r1,r2 LSL r3
действие 3) складываем r2 с r1: addeq r0,r1,r2 LSL r3:
дейсвтвие 4) записываем результат в r0: addeq r0,r1,r2 LSL r3

У Блекфина как-то тухло:
Код
...
    P1.L = _LCD;
    P1.H = _LCD;
    .align 2
    P0 = 272;
    P1 = P1 + P0;
    P0 = -256;
    P1 = P1 + P0;
    P0 = 144;
    [--SP] = (P5:3);
    P2 = 64;
    P5 = 0
    P5.H = 8193
    LOOP .P36L2L LC0 = P0;
...


Цитата(jcxz @ Mar 29 2018, 09:43) *
Я не буду ничего советовать по интерфейсу подключения LCD (неохота разбираться в сигналах), но в том же C6745, как говорит сайт TI, есть 2 интерфейса McASP.
Я помню в OMAP-L137 я использовал один из двух McASP: это порт умеющий формировать до 16 последовательных битовых потока (он имеет 16 сериализаторов), каждый из которых можно независимо сконфигурить на ввод или вывод. Диаграмма сигналов на каждом программируется тоже независимо от других сериализаторов и очень гибко.


Это типа ногодрыга как GPIO ? Надо 16 бит данных, 1 бит адреса, стробы CS, WR. На строб RD можно забить(не нужен, подтянуть к Vcc).

Цитата
А поинтересуйтесь-ка командой USADA8 в ARMv7-M


Типа DSP-инструкция, SIMD к тому же! sm.gif

-----

Касаемо Олвиннера V3s.
Вышел на форум китайцев https://debugdump.com/t_576.html - тут они тот самый дисплей что у меня (контроллер тот же) подключают к... SPI - и быстродействие всего 10 FPS.
Видимо, через 16 битную шину его не подрубить, раз SPI взяли
jcxz
Цитата(__inline__ @ Mar 29 2018, 13:20) *
действие 1) проверка условия , если равно, выполняем: addeq r0,r1,r2 LSL r3

Это не так. Это действие выполняется в предыдущей инструкции IT. И такт там тратится.
Цитата(__inline__ @ Mar 29 2018, 13:20) *
действие 2) сдвигаем r2 влево на значение бит в r3: addeq r0,r1,r2 LSL r3
действие 3) складываем r2 с r1: addeq r0,r1,r2 LSL r3:
дейсвтвие 4) записываем результат в r0: addeq r0,r1,r2 LSL r3

Вы ещё посчитайте перевод в дополнительный код в команде SUB за отдельное действие. biggrin.gif
Эти "действия" не считаются за отдельные операции в общепринятой терминологии. Даже QDSUB - всего одна операция, хоть там и умножение на два и суммирование и насыщение.
Иначе некоторые DSP-инструкции вообще бы по 20 действий выполняли. biggrin.gif

Цитата(__inline__ @ Mar 29 2018, 13:20) *
У Блекфина как-то тухло:

Странно....
У C55xx например:
FIRSADD *AR0+, *AR1-, *CDP+, AC0, AC1
Выполняется за 1 такт, делает чтение двух операндов из памяти с автоинкрементом (и возможно с циклической адресацией) *AR0+ и *AR1-, чтение одного коэфф. фильтра из памяти *CDP+ с автоинкрементом (и возможно с циклической адресацией), две MAC (AC0 += (*AR0) * (*CDP) и AC1 += (*AR1) * (*CDP)). Плюс ещё можно задать (опционально) умножение результата (после умножения перед сложением) MAC-ов на 2 и вроде ещё насыщение (точно не помню).
И параллельно этой команде можно в параллель ещё одну команду выполнить за тот же такт, лишь бы она не использовала уже занятые ресурсы. Занятые первой командой.

Цитата(__inline__ @ Mar 29 2018, 13:20) *
Это типа ногодрыга как GPIO ? Надо 16 бит данных, 1 бит адреса, стробы CS, WR. На строб RD можно забить(не нужен, подтянуть к Vcc).

Наверное сэмулировать 16-битную шину памяти на нём не получится - линий маловато. Ну если только как-то синхронизировать два McASP.
_pv
Цитата(__inline__ @ Mar 29 2018, 14:33) *
должны быть, но не обязаны. Я глянул даташит на V3s что у меня есть (на английском), там расписаны времянки, но самих стробов CS, WR, адресные биты A* на выводах микроконтроллера НЕ нашёл. Таблицы мультиплексирования выводов тоже молчат.
Просто приводят картинку с времянками, которая как бы намекает, что без дополнительной логики (ПЛИС, ЦПЛД,рассыпуха) не обойтись:

картинка намекает ровно на обратное.
а регистры для доступа к шине, конфигурирования интерфейса, отдельные регистры для чтения/записи по двум отдельным адресам через A1 сделали видимо просто так, да ещё и ноги наружу вывести забыли.
таблицы мультиплексирования выводов молчат, так как там либо TCON включается либо нет, а как он уже внутри себя будет свои ноги использовать gpio конечно не знает.
подключение LCD с i80 к А20
Нажмите для просмотра прикрепленного файла
из китайского официального мануала про lcd, для v3s ещё видимо не запилили, но не думаю что периферийные блоки хоть чем-то отличаются, в даташите там всё тоже самое.
а почему линии данных так перекошены - не знаю, в китайском не силён.

Цитата(__inline__ @ Mar 29 2018, 14:33) *
Был один головняк(SDRAM), будет два (преобразователь SDIO в i8080 для LCD sm.gif )

вы сами себе напридумывали трудностей, чтобы потом их героически преодолевать.
__inline__
_pv, большое спасибо! rolleyes.gif Вот как раз этой схемы мне не хватало, а я уже хотел логику прикидывать к CLK, LCDDE, чтобы выдать нужную полярность по стробам.
Зарегался на том форуме и поинтересовался у китайцев - сказали, что всё как в A10, дали инфу по подключению и даташиты:
https://debugdump.com/t_900.html
Что понравилось - отвечают очень оперативно, возможно они контачат с Alwinner напрямую.
Таблица подключения от A10 по назначению пинов совпадает с вашей картинкой:
Нажмите для просмотра прикрепленного файла

Очень надеюсь, что в v3s работа с дисплеем в режиме i8080 присутствует и её алгоритм аналогичен как в A20, A10.

Почему я не хочу подключать дисплей по параллельному RGB? Потому что контроллер будет постоянно вынужден как угорелый рисовать кадр, в то время как он ещё будет не готов, а это несколько неудобно! Плюс отсутствие режимов LCD с выбором прямоугольника отрисовки, направлений - проще через встроенный контроллер дисплея это делать. Ну и как правило, большинство LCD матриц помимо простого RGB содержат ещё I2C/SPI порт для конфигурации. Так что в плане переносимости мне проще через i8080-BUS работать.

Этот Alwinner полон загадок, заманчив высокой тактовой 1,2 ГГц + DDR 400 МГц, QFP корпусом и встроенной памятью. Но его загадочность меня настораживает sm.gif
Надо сообразить простейшую плату для опытов (v3s есть на руках), для питания пока поставлю обычнее LDO на 3.3V, 3V, 1.2V и 1.8V (точно в даташите смотреть надо).
Наподобие как STM-NUCLEO - по минимуму обвязки: питание, кварц, пины на порты, MCU, SD карта памяти для загрузки.

Конечно, после мигания светодиодами и ком-порта, прийдётся ковырять Linux BSP, что наверно трудоемко.

А обращаться к дисплею в режиме 8080 как? (команды и данные слать) . Через TCON0_CPU_WR_REG, TCON0_CPU_RD0_REG и TCON0_CPU_RD1_REG ? Команда или данные выбираются через бит 25 регистра TCON0_CPU_IF_REG ? (управление A1).

На первых порах конечно, линию DC LCD можно посадить на обычный GPIO без ущерба скорости, но хочется чтобы красиво было.

Цитата(_pv @ Mar 29 2018, 17:25) *
картинка намекает ровно на обратное.
а регистры для доступа к шине, конфигурирования интерфейса, отдельные регистры для чтения/записи по двум отдельным адресам через A1 сделали видимо просто так, да ещё и ноги наружу вывести забыли.
таблицы мультиплексирования выводов молчат, так как там либо TCON включается либо нет, а как он уже внутри себя будет свои ноги использовать gpio конечно не знает.
подключение LCD с i80 к А20
Нажмите для просмотра прикрепленного файла
из китайского официального мануала про lcd, для v3s ещё видимо не запилили, но не думаю что периферийные блоки хоть чем-то отличаются, в даташите там всё тоже самое.
а почему линии данных так перекошены - не знаю, в китайском не силён.

__inline__
Поковырял немножко Linux BSP, "linux-master".
Вырисовываются интересные вещи касаемо работы LCD в i8080 bus mode.

Код
__s32 LCD_CPU_WR(__u32 screen_id,__u32 index,__u32 data)
{
    tcon0_cpu_wr_16b(screen_id,index,data);
    return 0;
}

__s32 LCD_CPU_WR_INDEX(__u32 screen_id,__u32 index)
{
    tcon0_cpu_wr_16b_index(screen_id,index);
    return 0;
}

__s32 LCD_CPU_WR_DATA(__u32 screen_id,__u32 data)
{
    tcon0_cpu_wr_16b_data(screen_id,data);
    return 0;
}


Пошёл дальше:

Код
s32 tcon0_cpu_wr_16b(u32 sel, u32 index, u32 data)
{
    tcon0_cpu_wr_24b(sel,tcon0_cpu_16b_to_24b(index),tcon0_cpu_16b_to_24b(data));
    return 0;
}

u32 tcon0_cpu_16b_to_24b(u32 value)
{
    return
          ((value & 0xfc00)<<8)
        | ((value & 0x0300)<<6)
        | ((value & 0x00e0)<<5)
        | ((value & 0x001f)<<3);
}

s32 tcon0_cpu_wr_24b(u32 sel, u32 index, u32 data)
{
    tcon0_cpu_wr_24b_index(sel,index);
    tcon0_cpu_wr_24b_data(sel,data);
    return 0;
}

s32 tcon0_cpu_wr_24b_index(u32 sel, u32 index)
{
    u32 count = 0;
    while((tcon0_cpu_busy(sel)) && (count < 50)) {
        count ++;
        disp_delay_us(100);
    }
    lcd_dev[sel]->tcon0_cpu_ctl.bits.ca = 0;
    lcd_dev[sel]->tcon0_cpu_wr.bits.data_wr = index;
    return 0;
}

s32 tcon0_cpu_wr_24b_data(u32 sel, u32 data)
{
    u32 count = 0;
    while((tcon0_cpu_busy(sel)) && (count < 50)) {
        count ++;
        disp_delay_us(100);
    }
    lcd_dev[sel]->tcon0_cpu_ctl.bits.ca = 1;        //tcon0_cpu_if_reg_t
    lcd_dev[sel]->tcon0_cpu_wr.bits.data_wr = data; //tcon0_cpu_wr_reg_t
    return 0;
}


Тут мы видим, что перед посылкой байтов команды или данных - цикл с ожиданием пока устройство занято. Это очень плохо!
Все параллельные шины с которыми приходилось работать - EBI у AT91RM9200, FSMC у STM32, FBI у Блекфина - не имели костыля для ожидания завершения.

Сама процедура ожидания:

Код
u32 tcon0_cpu_busy(u32 sel)
{
    if(lcd_dev[sel]->tcon0_cpu_ctl.bits.wr_flag
        || lcd_dev[sel]->tcon0_cpu_ctl.bits.rd_flag)
        return 1;
    else
        return 0;
}



Ну и интуитивно понятно, что структуры как раз описывают биты и смещения регистров от базового адреса.

Как всё сложно описано!!! И всё для того чтобы послать на шину 8080 байт данных!!!

Чего стоят только описания структур и юнионов:

Код
static volatile __de_lcd_dev_t *lcd_dev[2];

s32 tcon_set_reg_base(u32 sel, u32 base)
{
    lcd_dev[sel]=(__de_lcd_dev_t *)base;
    return 0;
}


tcon_set_reg_base(screen_id,para->reg_base[DISP_MOD_LCD0]);
tcon_set_reg_base(screen_id,para->reg_base[DISP_MOD_LCD1]);

typedef struct
{
    u32                   reg_base[DISP_MOD_NUM];
    u32                   reg_size[DISP_MOD_NUM];
    u32                   irq_no[DISP_MOD_NUM];

    s32 (*disp_int_process)(u32 sel);
    s32 (*vsync_event)(u32 sel);
    s32 (*start_process)(void);
    s32 (*capture_event)(u32 sel);
    s32 (*shadow_protect)(u32 sel, bool protect);
    disp_sw_init_para *sw_init_para;
}__disp_bsp_init_para;



//device define
typedef struct
{
    tcon_gctl_reg_t                tcon_gctl;                //0x000
    tcon_gint0_reg_t            tcon_gint0;                //0x004
    tcon_gint1_reg_t            tcon_gint1;                //0x008
    tcon_reservd_reg_t            tcon_reg00c;            //0x00c
    tcon0_frm_ctl_reg_t            tcon0_frm_ctl;            //0x010
    tcon0_frm_seed_reg_t        tcon0_frm_seed_pr;        //0x014
    tcon0_frm_seed_reg_t        tcon0_frm_seed_pg;        //0x018
    tcon0_frm_seed_reg_t        tcon0_frm_seed_pb;        //0x01c
    tcon0_frm_seed_reg_t        tcon0_frm_seed_lr;        //0x020
    tcon0_frm_seed_reg_t        tcon0_frm_seed_lg;        //0x024
    tcon0_frm_seed_reg_t        tcon0_frm_seed_lb;        //0x028
    tcon0_frm_tab_reg_t            tcon0_frm_tbl_0;        //0x02c
    tcon0_frm_tab_reg_t            tcon0_frm_tbl_1;        //0x030
    tcon0_frm_tab_reg_t            tcon0_frm_tbl_2;        //0x034
    tcon0_frm_tab_reg_t            tcon0_frm_tbl_3;        //0x038
    tcon_reservd_reg_t            tcon_reg03c;            //0x03c
    tcon0_ctl_reg_t                tcon0_ctl;                //0x040
    tcon0_dclk_reg_t            tcon0_dclk;                //0x044
    tcon0_basic0_reg_t            tcon0_basic0;            //0x048
    tcon0_basic1_reg_t            tcon0_basic1;            //0x04c
    tcon0_basic2_reg_t            tcon0_basic2;            //0x050
    tcon0_basic3_reg_t            tcon0_basic3;            //0x054
    tcon0_hv_if_reg_t            tcon0_hv_ctl;            //0x058
    tcon_reservd_reg_t            tcon_reg05c;            //0x05c
    tcon0_cpu_if_reg_t            tcon0_cpu_ctl;            //0x060
    tcon0_cpu_wr_reg_t            tcon0_cpu_wr;            //0x064
    tcon0_cpu_rd0_reg_t            tcon0_cpu_rd;            //0x068
    tcon0_cpu_rd1_reg_t            tcon0_cpu_fet;            //0x06c
    tcon_reservd_reg_t            tcon_reg070[6];            //0x070~0x84
    tcon0_io_pol_reg_t            tcon0_io_pol;            //0x088
    tcon0_io_tri_reg_t            tcon0_io_tri;            //0x08c
    tcon1_ctl_reg_t                tcon1_ctl;                //0x090
    tcon1_basic0_reg_t            tcon1_basic0;            //0x094
    tcon1_basic1_reg_t            tcon1_basic1;            //0x098
    tcon1_basic2_reg_t            tcon1_basic2;            //0x09c
    tcon1_basic3_reg_t            tcon1_basic3;            //0x0a0
    tcon1_basic4_reg_t            tcon1_basic4;            //0x0a4
    tcon1_basic5_reg_t            tcon1_basic5;            //0x0a8
    tcon_reservd_reg_t            tcon_reg0ac;            //0x0ac
    tcon1_ps_sync_reg_t            tcon1_ps_ctl;            //0x0b0
    tcon_reservd_reg_t            tcon_reg0b4[15];        //0x0b4~0x0ec
    tcon1_io_pol_reg_t            tcon1_io_pol;            //0x0f0
    tcon1_io_tri_reg_t            tcon1_io_tri;            //0x0f4
    tcon_ecc_fifo_reg_t            tcon_ecfifo_ctl;        //0x0f8
    tcon_debug_reg_t            tcon_debug;                //0x0fc
    tcon_ceu_ctl_reg_t            tcon_ceu_ctl;            //0x110
    tcon_reservd_reg_t            tcon_reg104[3];            //0x104~0x10c
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_rr;        //0x110
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_rg;        //0x114
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_rb;        //0x118
    tcon_ceu_coef_add_reg_t        tcon_ceu_coef_rc;        //0x11c
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_gr;        //0x120
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_gg;        //0x124
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_gb;        //0x128
    tcon_ceu_coef_add_reg_t        tcon_ceu_coef_gc;        //0x12c
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_br;        //0x130
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_bg;        //0x134
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_bb;        //0x138
    tcon_ceu_coef_add_reg_t        tcon_ceu_coef_bc;        //0x13c
    tcon_ceu_coef_rang_reg_t    tcon_ceu_coef_rv;        //0x140
    tcon_ceu_coef_rang_reg_t    tcon_ceu_coef_gv;        //0x144
    tcon_ceu_coef_rang_reg_t    tcon_ceu_coef_bv;        //0x148
    tcon_reservd_reg_t            tcon_reg14c[5];            //0x14c~0x15c
    tcon0_cpu_tri0_reg_t        tcon0_cpu_tri0;            //0x160
    tcon0_cpu_tri1_reg_t        tcon0_cpu_tri1;            //0x164
    tcon0_cpu_tri2_reg_t        tcon0_cpu_tri2;            //0x168
    tcon0_cpu_tri3_reg_t        tcon0_cpu_tri3;            //0x16c
    tcon0_cpu_tri4_reg_t        tcon0_cpu_tri4;            //0x170
    tcon0_cpu_tri5_reg_t        tcon0_cpu_tri5;            //0x174
    tcon_reservd_reg_t            tcon_reg178[2];            //0x178~0x17c
    tcon_cmap_ctl_reg_t            tcon_cmap_ctl;            //0x180
    tcon_reservd_reg_t            tcon_reg184[3];            //0x184~0x18c
    tcon_cmap_odd0_reg_t        tcon_cmap_odd0;            //0x190
    tcon_cmap_odd1_reg_t        tcon_cmap_odd1;            //0x194
    tcon_cmap_even0_reg_t        tcon_cmap_even0;        //0x198
    tcon_cmap_even1_reg_t        tcon_cmap_even1;        //0x19c
    tcon_reservd_reg_t            tcon_reg1a0[20];        //0x1a0~0x1ec
    tcon_safe_period_reg_t        tcon_volume_ctl;        //0x1f0
    tcon_reservd_reg_t            tcon_reg1f4[3];            //0x1f4~0x1fc
    tcon_mux_ctl_reg_t            tcon_mul_ctl;            //0x200
    tcon_reservd_reg_t            tcon_reg204[9];            //0x204~0x224
    tcon_reservd_reg_t            tcon_reg228[54];        //0x228~0x2fc
    tcon1_fill_ctl_reg_t        tcon_fill_ctl;            //0x300
    tcon1_fill_begin_reg_t        tcon_fill_start0;        //0x304
    tcon1_fill_end_reg_t        tcon_fill_end0;            //0x308
    tcon1_fill_data_reg_t        tcon_fill_data0;        //0x30c
    tcon1_fill_begin_reg_t        tcon_fill_start1;        //0x310
    tcon1_fill_end_reg_t        tcon_fill_end1;            //0x314
    tcon1_fill_data_reg_t        tcon_fill_data1;        //0x318
    tcon1_fill_begin_reg_t        tcon_fill_start2;        //0x31c
    tcon1_fill_end_reg_t        tcon_fill_end2;            //0x320
    tcon1_fill_data_reg_t        tcon_fill_data2;        //0x324
    tcon_reservd_reg_t            tcon_reg328[54];        //0x328~0x3fc
    tcon_gamma_tlb_reg_t        tcon_gamma_tlb[256];    //0x400
}__de_lcd_dev_t;

typedef union
{
    u32 dwval;
    struct
    {
        u32 trigger_en                 :  1;    // default: 0;
        u32 trigger_start              :  1;    // default: 0;
        u32 trigger_fifo_en            :  1;    // default: 0;
        u32 trigger_fifo_bist_en       :  1;    // default: 0;
        u32 trigger_sync_mode          :  2;    // default: 0;
        u32 res0                       : 10;    // default:;
        u32 flush                      :  1;    // default: 0;
        u32 auto_                       :  1;    // default: 0;
        u32 res1                       :  4;    // default:;
        u32 rd_flag                    :  1;    // default: 0;
        u32 wr_flag                    :  1;    // default: 0;
        u32 vsync_cs_sel               :  1;    // default: 0;
        u32 ca                         :  1;    // default: 0;
        u32 da                         :  1;    // default: 0;
        u32 res2                       :  1;    // default:;
        u32 cpu_mode                    :  4;    // default: 0;
    } bits;
} tcon0_cpu_if_reg_t;

typedef union
{
    u32 dwval;
    struct
    {
        u32 data_wr                    : 24;    // default: 0;
        u32 res0                       :  8;    // default:;
    } bits;
} tcon0_cpu_wr_reg_t;


Предстоит жёсткий секс с Линуксом sm.gif

Начну-ка я наверно с A13, отладочной платы Olinuxino (тоже есть на руках).

Чем-то напомнило индусский код sm.gif Теперь надеюсь, вы поняли, почему я не люблю писать под линукс? Потому что громоздко и тормозит! Нужен чистый поток сознания в программировании!
_pv
что-то всё действительно загадочно, есть регистр tcon0_cpu_wr_reg у которого по даташиту 24 разряда и который при записи должен писать целиком в LCD_D[23:0],
а потом взяли и как попало подключили линии данных, не подряд, а старшие шесть разрядов каждого цвета (ну чтобы 24х разрядный цвет преобразовывать в 666, или 565 схемотехнически), а теперь руками каждый пиксель перепаковываем обратно из 16/18 в 24,
а нельзя было просто подключить шину подряд, LCD_D[15:0] или [17:0], и писать данные как есть, раз они уже изначально в таком формате?
__inline__
Цитата(_pv @ Mar 30 2018, 07:26) *
что-то всё действительно загадочно, есть регистр tcon0_cpu_wr_reg у которого по даташиту 24 разряда и который при записи должен писать целиком в LCD_D[23:0],
а потом взяли и как попало подключили линии данных, не подряд, а старшие шесть разрядов каждого цвета (ну чтобы 24х разрядный цвет преобразовывать в 666, или 565 схемотехнически), а теперь руками каждый пиксель перепаковываем обратно из 16/18 в 24,
а нельзя было просто подключить шину подряд, LCD_D[15:0] или [17:0], и писать данные как есть, раз они уже изначально в таком формате?

Я бы отталкивался от того, по каким линиям пойдут биты байта при записи в регистр tcon0_cpu_wr_reg. Проверить в принципе это можно, просто зациклив передачу в этот регистр и путём вызванивания тестером логического уровня на каждом бите. Увы и ах - осциллографа и логического анализатора под рукой нет. sad.gif

А так да, получается индусский говнокод с нагромождением. Но к сожалению, нормальных SDK под эти чипы нет

Должно хватить вот этого(код я писал):

Код
#define CA 25 /* A1位 A1 bit */

#define TCON 0x01C0C000 /* TCON基地址 TCON Base Address */

#define TCON0_CPU_IF_REG *(volatile u32*)(TCON+0x60)
#define TCON0_CPU_WR_REG *(volatile u32*)(TCON+0x64)

void TCON0_INDEX(u32 index)
{
TCON0_CPU_IF_REG&=~(1UL<<CA); //清除CA位 clear CA bit
TCON0_CPU_WR_REG=index;       //写索引 write index
}

void TCON0_DATA(u32 data)
{
TCON0_CPU_IF_REG|=(1UL<<CA);   //设置CA位 set CA bit
TCON0_CPU_WR_REG=data;         // 写入数据 write data
}


Не забыв отремапить ноги GPIO и включив тактирование нужных узлов периферии.

и отынитить TCON для режима CPU I/F i8080 sm.gif

Ну и второй головняк - тайминги шины. Подозреваю, что на ширину строба записи будет влиять делитель для DCLK, а на длительность цикла - длина VSYNC лили LCDDE
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.