Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:2
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:6
Форум » starterkit.ru » Embedded Linux
imx233 + driver lms430
ADA007
Добавлено 28.01.2012 22:33
0
Сообщение: 1
ADA007
0

Пункты: 3113
Регистрация: 01.08.2011
Пол: Мужчина
Приветствую всех форумчан.
Прошу помочь разобраться с драйвером под LMS430. Пытаюсь подключить связку imx233+EPM7064+ADV7125=VGA. Как видно из текста lcd_lms430.c =>
Код

static struct mxs_platform_fb_entry fb_entry = {
.name = "lms430",
.x_res = 480,
.y_res = 640,
.bpp = 32,
.cycle_time_ns = 40,
.lcd_type = MXS_LCD_PANEL_DOTCLK,
.init_panel = init_panel,
.release_panel = release_panel,
.blank_panel = blank_panel,
.run_panel = mxs_lcdif_run,
.stop_panel = mxs_lcdif_stop,
.pan_display = mxs_lcdif_pan_display,
.bl_data = &bl_data,
};


Драйвер использует режим DotClk - тоесть будет выдаваться сигнал HSYNC и VSYNC. Для стандарта 640х480х60Гц необходима частота 25.175МГц = 40 нс(что и выбрано выше).
bpp=32. Т.е. передается 3-и цвета по 8 бит mxsfb.c =>
Код

red = CNVT_TOHW(red, 8);
green = CNVT_TOHW(green, 8);
blue = CNVT_TOHW(blue, 8);
transp = CNVT_TOHW(transp, 8);


Дефайнами выставил в соответствие с описанием задержки. Правда немного пришлось подогнать...получилось так lcd_lms430.c =>
Код

#define DOTCLK_H_ACTIVE 640
#define DOTCLK_H_PULSE_WIDTH 96
#define DOTCLK_HF_PORCH 16
#define DOTCLK_HB_PORCH 12
#define DOTCLK_H_WAIT_CNT (DOTCLK_H_PULSE_WIDTH + (3 * DOTCLK_HB_PORCH))
#define DOTCLK_H_PERIOD (DOTCLK_H_WAIT_CNT + DOTCLK_HF_PORCH + DOTCLK_H_ACTIVE)

#define DOTCLK_V_ACTIVE 480
#define DOTCLK_V_PULSE_WIDTH 2
#define DOTCLK_VF_PORCH 10
#define DOTCLK_VB_PORCH 33
#define DOTCLK_V_WAIT_CNT (DOTCLK_V_PULSE_WIDTH + DOTCLK_VB_PORCH)
#define DOTCLK_V_PERIOD (DOTCLK_VF_PORCH + DOTCLK_V_ACTIVE + DOTCLK_V_WAIT_CNT)


Идея заключается в том, чтобы последовательно защелкивать по 8 бит цвета и на 3-и такте выдавать их в adv7125.
Значит собираю я ядро с этим драйвером и вижу а выходе из imx по линии dotclk частоту ~25MHz на осцилле...т.е. то, что заказывали в драйвере...но как же ему удается выполнить условие передачи цвета, как описано в mxsfb.c? Частота же должна быть в 3-и раза выше..т.е. 75 MHz...на сколько я понимаю.
В результате 224 битный tux (извиняюсь за плохое качество фото) выглядет вот так => title
Пробовал выводить картинки в фреймбуфер 640х480 залитые красным, синим, зеленым - но наблюдаю какие-то полосы с градиентами цвета...очень тусклые.
Подскажите, как получить мне 3-и цвета по 8 бит с нужной частотой для разрешения 640х480?
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 28.01.2012 23:02 Сообщение: 2
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Исходники драйверов это одно, вы почитайте даташит - контроллеру LCD нужно сообщить что у него шина на выходе 8 бит иначе вы один цвет получаете - он же должен как-то понять что вы от него хотите serial RGB.
Спуститься к концу Подняться к началу
Персональная информация
ADA007
Добавлено 30.01.2012 11:40 Сообщение: 3
ADA007
0

Пункты: 3113
Регистрация: 01.08.2011
Пол: Мужчина
Цитата
контроллеру LCD нужно сообщить...

В файле /../mach-mx23/include/mach/lcdif.h в функции setup_dotclk_panel поменял LCD_DATABUS_WIDTH =>
Код

__raw_writel(BF_LCDIF_CTRL_WORD_LENGTH(3) |/* 24 bit */
BM_LCDIF_CTRL_DATA_SELECT |/* data mode */
BF_LCDIF_CTRL_INPUT_DATA_SWIZZLE(0) |/* no swap */
BF_LCDIF_CTRL_LCD_DATABUS_WIDTH(1),/* 8 bit */
REGS_LCDIF_BASE + HW_LCDIF_CTRL_SET);


Но что-то частота dotclk как была 25 МГц, так и осталась 25.
Или что-то еще нужно менять? Подскажите где?
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 30.01.2012 13:20 Редактировалось 30.01.2012 13:22 Сообщение: 4
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Попробуйте с такими настройками и изменениями

Код

static struct mxs_platform_fb_entry fb_entry = {
.name = "lms430",
.x_res = 480,
.y_res = 640,
.bpp = 32,
.cycle_time_ns = 13,
.lcd_type = MXS_LCD_PANEL_DOTCLK,
.init_panel = init_panel,
.release_panel = release_panel,
.blank_panel = blank_panel,
.run_panel = mxs_lcdif_run,
.stop_panel = mxs_lcdif_stop,
.pan_display = mxs_lcdif_pan_display,
.bl_data = &bl_data,
};


Код

#define DOTCLK_H_ACTIVE (640*3)
#define DOTCLK_H_PULSE_WIDTH (96*3)
#define DOTCLK_HF_PORCH (16*3)
#define DOTCLK_HB_PORCH (12*3)
#define DOTCLK_H_WAIT_CNT (DOTCLK_H_PULSE_WIDTH + (3 * DOTCLK_HB_PORCH))
#define DOTCLK_H_PERIOD (DOTCLK_H_WAIT_CNT + DOTCLK_HF_PORCH + DOTCLK_H_ACTIVE)

#define DOTCLK_V_ACTIVE 480
#define DOTCLK_V_PULSE_WIDTH 2
#define DOTCLK_VF_PORCH (10/3)
#define DOTCLK_VB_PORCH (33/3)
#define DOTCLK_V_WAIT_CNT (DOTCLK_V_PULSE_WIDTH + DOTCLK_VB_PORCH)
#define DOTCLK_V_PERIOD (DOTCLK_VF_PORCH + DOTCLK_V_ACTIVE + DOTCLK_V_WAIT_CNT)


Код

__raw_writel(BF_LCDIF_CTRL_WORD_LENGTH(1) |/* 8 bit */
BM_LCDIF_CTRL_DATA_SELECT |/* data mode */
BF_LCDIF_CTRL_INPUT_DATA_SWIZZLE(0) |/* no swap */
BF_LCDIF_CTRL_LCD_DATABUS_WIDTH(1),/* 8 bit */
REGS_LCDIF_BASE + HW_LCDIF_CTRL_SET);
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 30.01.2012 14:10 Сообщение: 5
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Поправка ! Помоему вот это

#define DOTCLK_VF_PORCH (10/3)
#define DOTCLK_VB_PORCH (33/3)

лишнее и нужно оставить как было

#define DOTCLK_VF_PORCH 10
#define DOTCLK_VB_PORCH 33
Спуститься к концу Подняться к началу
Персональная информация
ADA007
Добавлено 30.01.2012 15:57 Редактировалось 30.01.2012 16:01 Сообщение: 6
ADA007
0

Пункты: 3113
Регистрация: 01.08.2011
Пол: Мужчина
Цитата
Попробуйте с такими настройками и изменениями...

С Вашими настройками (без поправки) выводит Tux-a , только он серый весь(скорее всего в fpga прошивку надо сменить...у меня сейчас 3-и такта считывает данные с шины, а на 4-й такт выводит в adv7125)...
Это при BF_LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x7)...Вообще по ДШ не смог понять на какие байты влияет этот регистр...Они нарисовали что мол можно выбирать вывод ABCD байт..но что они обозначают? кто из них RGB? мне казалось, что RGB=ABC соответственно..так ли это?
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 30.01.2012 16:12 Редактировалось 30.01.2012 18:45 Сообщение: 7
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата
у меня сейчас 3-и такта считывает данные с шины, а на 4-й такт выводит в adv7125)...
Это при BF_LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x7)...Вообще по ДШ не смог понять на какие байты влияет этот регистр...Они нарисовали что мол можно выбирать вывод ABCD байт..но что они обозначают? кто из них RGB? мне казалось, что RGB=ABC соответственно..так ли это?


BYTE_PACKING_FORMAT - указывает, сколько байт из входного 32 битного слова оставлять, т. е. в вашем случае без правки в fpga нужно указать BF_LCDIF_CTRL1_BYTE_PACKING_FORMAT(0xf) и соответственно увеличить частоту и все остальное, вот так
Код

static struct mxs_platform_fb_entry fb_entry = {
.name = "lms430",
.x_res = 480,
.y_res = 640,
.bpp = 32,
.cycle_time_ns = 10,
.lcd_type = MXS_LCD_PANEL_DOTCLK,
.init_panel = init_panel,
.release_panel = release_panel,
.blank_panel = blank_panel,
.run_panel = mxs_lcdif_run,
.stop_panel = mxs_lcdif_stop,
.pan_display = mxs_lcdif_pan_display,
.bl_data = &bl_data,
};


Код

#define DOTCLK_H_ACTIVE (640*4)
#define DOTCLK_H_PULSE_WIDTH (96*4)
#define DOTCLK_HF_PORCH (16*4)
#define DOTCLK_HB_PORCH (12*4)
#define DOTCLK_H_WAIT_CNT (DOTCLK_H_PULSE_WIDTH + (3 * DOTCLK_HB_PORCH))
#define DOTCLK_H_PERIOD (DOTCLK_H_WAIT_CNT + DOTCLK_HF_PORCH + DOTCLK_H_ACTIVE)

#define DOTCLK_V_ACTIVE 480
#define DOTCLK_V_PULSE_WIDTH 2
#define DOTCLK_VF_PORCH (10/4) // ???
#define DOTCLK_VB_PORCH (33/4) // ???
#define DOTCLK_V_WAIT_CNT (DOTCLK_V_PULSE_WIDTH + DOTCLK_VB_PORCH)
#define DOTCLK_V_PERIOD (DOTCLK_VF_PORCH + DOTCLK_V_ACTIVE + DOTCLK_V_WAIT_CNT)


Код

__raw_writel(BF_LCDIF_CTRL_WORD_LENGTH(1) |/* 8 bit */
BM_LCDIF_CTRL_DATA_SELECT |/* data mode */
BF_LCDIF_CTRL_INPUT_DATA_SWIZZLE(0) |/* no swap */
BF_LCDIF_CTRL_LCD_DATABUS_WIDTH(1),/* 8 bit */
REGS_LCDIF_BASE + HW_LCDIF_CTRL_SET);


Правда мне не ясно - по идее для вертикальной синхронизации юниты - количество строк, тайминги для _целой строки_ остаются те-же - частоту увеличили в 4 раза но и увеличили число тактов на строку в 4 раза. По поводу ARGB - там все правильно, это же регистр, байты написаны старший-первый, но выводятся младший-первый (little-endian), см. Figure 18-3. 8-Bit LCDIF Register Programming—Example A стр. 945 + стр. 960 HW_LCDIF_CTRL Bit Field Descriptions
INPUT_DATA_SWIZZLE:
NO_SWAP = 0x0 No byte swapping.(Little endian)
LITTLE_ENDIAN = 0x0 Little Endian byte ordering (same as
NO_SWAP).

Кстати - у вас наверно цвета будут перемешаны, так как получается он выводит BGR - я не помню этот момент, помоему у себя я в настройках контроллера внешнего LCD указывал что данные в BGR идут - не получится средствами этого контроллера LCD выдавать на шину R->G->B->A - все что угодно кроме этого :)
При этих настройках на шину будет выдаваться B->G->R->A, если оставите как я писал в предыдущем посте, там будет B->G->R, чтобы получить R->G->B (или A->R-G->B соотвественно если в маске оставить все входные байты)) можно исправить так:

Код

__raw_writel(BF_LCDIF_CTRL_WORD_LENGTH(1) |/* 8 bit */
BM_LCDIF_CTRL_DATA_SELECT |/* data mode */
BF_LCDIF_CTRL_INPUT_DATA_SWIZZLE(1) |/* BIG_ENDIAN_SWAP = 0x1 */
BF_LCDIF_CTRL_LCD_DATABUS_WIDTH(1),/* 8 bit */
REGS_LCDIF_BASE + HW_LCDIF_CTRL_SET);
Спуститься к концу Подняться к началу
Персональная информация
ADA007
Добавлено 30.01.2012 23:26 Редактировалось 30.01.2012 23:29 Сообщение: 8
ADA007
0

Пункты: 3113
Регистрация: 01.08.2011
Пол: Мужчина
С ARGB понятно, спасибо...Значит я использую настройки =>
Код

#define DOTCLK_H_ACTIVE 640*4
#define DOTCLK_H_PULSE_WIDTH 96*4
#define DOTCLK_HF_PORCH 16*4
#define DOTCLK_HB_PORCH 12*4
#define DOTCLK_H_WAIT_CNT (DOTCLK_H_PULSE_WIDTH + (3 * DOTCLK_HB_PORCH))
#define DOTCLK_H_PERIOD (DOTCLK_H_WAIT_CNT + DOTCLK_HF_PORCH + DOTCLK_H_ACTIVE)

#define DOTCLK_V_ACTIVE 480
#define DOTCLK_V_PULSE_WIDTH 2
#define DOTCLK_VF_PORCH 10/4 // Без деления - не работает
#define DOTCLK_VB_PORCH 33/4
#define DOTCLK_V_WAIT_CNT (DOTCLK_V_PULSE_WIDTH + DOTCLK_VB_PORCH)
#define DOTCLK_V_PERIOD (DOTCLK_VF_PORCH + DOTCLK_V_ACTIVE + DOTCLK_V_WAIT_CNT)

Код

static struct mxs_platform_fb_entry fb_entry = {
.name = "lms430",
.x_res = 480,
.y_res = 640,
.bpp = 32,
.cycle_time_ns = 10,
.lcd_type = MXS_LCD_PANEL_DOTCLK,
.init_panel = init_panel,
.release_panel = release_panel,
.blank_panel = blank_panel,
.run_panel = mxs_lcdif_run,
.stop_panel = mxs_lcdif_stop,
.pan_display = mxs_lcdif_pan_display,
.bl_data = &bl_data,
};

Код

__raw_writel(BF_LCDIF_CTRL1_BYTE_PACKING_FORMAT(0xF) |
BM_LCDIF_CTRL1_RECOVER_ON_UNDERFLOW,
REGS_LCDIF_BASE + HW_LCDIF_CTRL1_SET);

Код

__raw_writel(BM_LCDIF_CTRL_WORD_LENGTH |
BM_LCDIF_CTRL_INPUT_DATA_SWIZZLE |
BM_LCDIF_CTRL_LCD_DATABUS_WIDTH,
REGS_LCDIF_BASE + HW_LCDIF_CTRL_CLR);
__raw_writel(BF_LCDIF_CTRL_WORD_LENGTH(1) |/* 24 bit */
BM_LCDIF_CTRL_DATA_SELECT |/* data mode */
BF_LCDIF_CTRL_INPUT_DATA_SWIZZLE(0) |/* no swap */
BF_LCDIF_CTRL_LCD_DATABUS_WIDTH(1),/* 8 bit */
REGS_LCDIF_BASE + HW_LCDIF_CTRL_SET);

Таким образом на выходе должна получаться частота 100МГц (осциллом не проверял, верю). И данные должны выходить B->G->R->A. DOTCLK_HB_PORCH пришлось поправить, а то частота была слишком высокая (~>65MHz). В результате получилось не совсем то, что ожидалось:

TUX = http://s2.ipicture.ru/uploads/20120131/vsT0HLQk.jpg
На самом деле лапы и клюв с желтоватым оттенком (на фотке плохо видно).

УЭИТ = http://s2.ipicture.ru/uploads/20120131/Wd742J2u.jpg
При выводе цветного чего-то картинка не статическая.....полосы, которыми берется цвет все время меняются в цвете.

Оригинал УЭИТ для сравнения = http://s2.ipicture.ru/uploads/20120131/zSQdPhUN.jpg

Данные о строчной развертке по цветам начинаю считывать по перепаду сигнала LCD_ENABLE из '0' в '1'. Считываю три цвета подряд (3-и такта), на 4-м вывожу в цап. Код VHDL =
Код



library ieee;
use ieee.std_logic_1164.all;

entity VGA_ALTERA is
port
(
RST_IN : in std_logic;
CLK_DOTCLK_IN : in std_logic;
HSYNC_IN : in std_logic;
VSYNC_IN : in std_logic;
ENABLE_IN : in std_logic;
DATA_IN : in std_logic_vector (7 downto 0);

R_COLOR_OUT : out std_logic_vector (7 downto 0) := X"00";
G_COLOR_OUT : out std_logic_vector (7 downto 0) := X"00";
B_COLOR_OUT : out std_logic_vector (7 downto 0) := X"00";
SYNC_OUT : out std_logic := '1';
BLANK_OUT : out std_logic := '1';
PSAVE_OUT : out std_logic := '1';
CLOCK_OUT : out std_logic := '1'

);

end entity VGA_ALTERA;

architecture VGA_ALTERA_ARCH of VGA_ALTERA is

signal green_color_reg_s, blue_color_reg_s : std_logic_vector (7 downto 0) := X"00";
signal clock_out_s, hsynk_del1, hsynk_del2 : std_logic := '0';
signal three_color_cnt_s : integer range 0 to 3 := 0;

begin


process ( CLK_DOTCLK_IN, RST_IN )
begin
if rising_edge (CLK_DOTCLK_IN) then
if (RST_IN = '0') then
R_COLOR_OUT <= X"00";
G_COLOR_OUT <= X"00";
B_COLOR_OUT <= X"00";
green_color_reg_s <= X"00";
blue_color_reg_s <= X"00";
SYNC_OUT <= '1';
BLANK_OUT <= '1';
PSAVE_OUT <= '1';
else
SYNC_OUT <= HSYNC_IN;
BLANK_OUT <= VSYNC_IN;
PSAVE_OUT <= RST_IN;

if (ENABLE_IN = '1') then
case (three_color_cnt_s) is
when 0 =>
blue_color_reg_s <= DATA_IN;
when 1 =>
green_color_reg_s <= DATA_IN;
CLOCK_OUT <= '0';
when 2 =>
R_COLOR_OUT <= DATA_IN;
G_COLOR_OUT <= green_color_reg_s;
B_COLOR_OUT <= blue_color_reg_s;
when 3 =>
CLOCK_OUT <= '1';
end case;

if (three_color_cnt_s = 3) then
three_color_cnt_s <= 0;
else
three_color_cnt_s <= three_color_cnt_s + 1;
end if;
else
end if;
end if;
end if;
end process;
end architecture VGA_ALTERA_ARCH;


Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 31.01.2012 00:53 Редактировалось 31.01.2012 03:08 Сообщение: 9
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
А схему как вы подключаете imx233+EPM7064+ADV7125 можно как-нибуть посмотреть ? мне непонятно почему у вас так включено:

SYNC_OUT <= HSYNC_IN;
BLANK_OUT <= VSYNC_IN;
PSAVE_OUT <= RST_IN;

- вы по примеру делали ? а то в даташите на adv7125
Цитата

The ADV7125 has a single composite sync (SYNC) input
control.
Many graphics processors and CRT controllers have the
ability to generate horizontal sync (HSYNC), vertical sync
(VSYNC), and composite SYNC.
In a graphics system that does not automatically generate a
composite SYNC signal, the inclusion of some additional logic
circuitry enables the generation of a composite SYNC signal.



Потом вы запускаете
Цитата

if (ENABLE_IN = '1') then
case (three_color_cnt_s) is
when 0 =>
blue_color_reg_s <= DATA_IN;
when 1 =>
green_color_reg_s <= DATA_IN;
CLOCK_OUT <= '0';
when 2 =>
R_COLOR_OUT <= DATA_IN;
G_COLOR_OUT <= green_color_reg_s;
B_COLOR_OUT <= blue_color_reg_s;
when 3 =>
CLOCK_OUT <= '1';
end case;


но если вы не меняли ничего в драйвере, у ENABLE активный уровень - низкий (стр 953 Figure 18-8. LCD Interface Signals in DOTCLK Mode) - Default 0 active low during valid data transfer on each
horizontal line, при этом клок adv7125 надо всегда генерировать ибо
Цитата

Clock Input (TTL Compatible). The rising edge of CLOCK latches the R0 to R7, G0 to G7, B0 to B7, SYNC,
and BLANK pixel and control inputs. It is typically the pixel clock rate of the video system. CLOCK
should be driven by a dedicated TTL buffer.

иначе какой смысл выставлять всякие PORCH в драйвере.
если я что-то не так понял - поправьте, я c VHDL незнаком.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 31.01.2012 11:54 Редактировалось 31.01.2012 14:55 Сообщение: 10
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Нашел пример, если интересно
http://www.avrfreaks.net/wiki/index.php/Documentation:Linux/Framebuffer#VGA_with_the_ADV7125

В общем условие нужно убрать и просто делить на 4 клок и выдавать rgb - тупой десериализатор, синхросигналы напрямую на монитор VGA через преобразователи уровней, sync на adv7125 не забыть на землю посадить, blank, psave - подать 3,3В, входы инвертированные. Вот это делить на 4 не надо
Цитата

#define DOTCLK_VF_PORCH 10/4 // Без деления - не работает
#define DOTCLK_VB_PORCH 33/4


blank, psave можно посадить на gpio и дописать драйвер панели вот тут, если нужно энергосбережение:
Код

static int blank_panel(int blank)
{
int ret = 0, count;

switch (blank) {
case FB_BLANK_NORMAL:
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_POWERDOWN:
__raw_writel(BM_LCDIF_CTRL_BYPASS_COUNT,
REGS_LCDIF_BASE + HW_LCDIF_CTRL_CLR);
for (count = 10000; count; count--) {
if (__raw_readl(REGS_LCDIF_BASE + HW_LCDIF_STAT) &
BM_LCDIF_STAT_TXFIFO_EMPTY)
break;
udelay(1);
}
break;

case FB_BLANK_UNBLANK:
__raw_writel(BM_LCDIF_CTRL_BYPASS_COUNT,
REGS_LCDIF_BASE + HW_LCDIF_CTRL_SET);
break;

default:
ret = -EINVAL;
}
return ret;
}


Еще там управление подсветкой надо убрать (удалить просто строку эту)
.bl_data = &bl_data,

тут вам этот ШИМ вообще не нужен.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux