Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2478 + TFT 320x240 совсем рябит (
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
overloaded
Частота клока 6,5 МГц (По ДШ рекоммендуют 6,75). С чем может быть связано рябение (я так понимаю постоянно прорисовываются то четные- то нечетные строки)?.
Рябит вместе с курсором. Картинка изначально была сдвинута влево вверх, чтоб стала посредине, значительно увеличил Vertical front porch и horizontal front porch(от значений, рекоммендуемых ДШ на ТФТ).

При некоторых стечениях обстоятельств)) (положение курсора, данные тестовой картинки) ТФТ вообще отказывается что-либо показывать... (Белый фон, как до инициализации).
Смотрел сигналы осциллографом - форма верт. и гор синхронизаций нормальная, синхр. данных (DCLK) - почти синус. Это нормально?
Еще интересная особенность - значения LCD_POL(IPC Invert panel clock., IHS Invert horizontal synchronization., IVS Invert vertical synchronization.) в в нескольких комбинациях на картинку не влияют.
Подскажите плз в какую вообще сторону думать? )

На всякий случай код с парой тестов и картинку с ДШ ТФТ прилагаю.
Код
#define LCD_RES_H 320
#define LCD_RES_V 240
#define LCD_BUF_SIZE (LCD_RES_H*LCD_RES_V*2)

unsigned char VideoBuf[LCD_BUF_SIZE] __attribute__((at(NOR_FLASH_BASE))); //SDRAM

void InitLCD()
{
  int i, testnum = 0;
  int k=0;
  unsigned short *Pall = (unsigned short *)&LCD_PAL;
  unsigned short *Vbuf = (unsigned short *)&VideoBuf;
  unsigned short *Curs = (unsigned short *)&CRSR_IMG;
    
    PCONP|= (1<<20); //LCD

    PINSEL11 = (6<<1)|(1<<0);// bit0=1 - LCD port is enabled.    bit1...3 = 110 TFT 16-bit. (1:5:5:5 mode)
  
  LCD_CFG    = 10;//72 MHz div 11
  //1
//  LCD_TIMH   = (((42-1)<<24) | ((67-1)<<16) | ((11-1)<<8) | (((LCD_RES_H/16)-1)<<2));
//  LCD_TIMV   = ((6<<24) | (16<<16) | ((3-1)<<10) | (LCD_RES_V-1));
  //2
  //LCD_TIMH   = (((31-1)<<24) | ((67-1)<<16) | ((11-1)<<8) | (((LCD_RES_H/16)-1)<<2));
  //LCD_TIMV   = ((3<<24) | (16<<16) | ((3-1)<<10) | (LCD_RES_V-1));
  //kartinka posredine
  LCD_TIMH   = (((61-1)<<24) | ((67-1)<<16) | ((11-1)<<8) | (((LCD_RES_H/16)-1)<<2));
  LCD_TIMV   = ((33<<24) | (16<<16) | ((3-1)<<10) | (LCD_RES_V-1));

  LCD_POL    = ((0<<27) | (1<<26) | (((LCD_RES_H/1)-1)<<16) | (0<<14)
                  | (1<<13)| (1<<12) | (1<<11)| (0<<6) | (0<<5) | (2<<0));

  LCD_CTRL   = ((0<<10) | (0<<9) | (0<<8) | (1<<5) | (4<<1)); // 100 = 16 bpp, 1:5:5:5 mode.

  for(i=0; i<256; i++)
      Curs[i] = 0xFFFF;

  CRSR_CFG = 0;
  CRSR_XY = (110<<16)|(160<<0);
  CRSR_CTRL = 1;//Cursor on

  LCD_UPBASE = (unsigned long)VideoBuf;
  LCD_LPBASE = (unsigned long)VideoBuf;    

    
    for(i=0; i<256; i++)//test
    {
        Pall[i] = 0xFF00+i;
    }
                            

  LCD_CTRL |= 1;//Enable
  LCD_CTRL |= 1<<11;//PWR ON

    testnum = 3;
    while(1)
    {
          switch(testnum)
          {
              case 0://bleklie tsveta
              for(i=0; i<(LCD_BUF_SIZE/2); i++)
                  if(i < (LCD_BUF_SIZE/4))
                    Vbuf[i]= (32<<10)|(0<<5)|(0<<0);
                else
                    Vbuf[i]= (0<<10)|(0<<5)|(32<<0);
            testnum = -1;
            break;
        
            case 1://ne vivodit - vse beloe
              for(i=0; i<(LCD_BUF_SIZE/2); i++)
                  if(i < (LCD_BUF_SIZE/4))
                    Vbuf[i]= 0;
                else
                    Vbuf[i]= 0xFFFF;
            testnum = -1;
            break;
        
            case 2://sverhu beloe, vnizu-4ernoe
              for(i=0; i<(LCD_BUF_SIZE/2); i++)
                  if(i < (LCD_BUF_SIZE/4))
                    Vbuf[i]= 0xFFFF;
                else
                    Vbuf[i]= 0;
            testnum = -1;
            break;
        
            case 3://poloski
              for(i=0; i<(LCD_BUF_SIZE/2); i++)
            {
                if((i % (320*20)) == 0)
                    k = rand();
                Vbuf[i]= k;
            }
            testnum = -1;
            break;
        
            case 4://random
              for(i=0; i<(LCD_BUF_SIZE/2); i++)
                Vbuf[i]= rand() & 0xFFFF;
            testnum = -1;
            break;

            default:
            break;
          }
    }

}

Нажмите для просмотра прикрепленного файла
skripach
Вы бы сделали что-то вроде:
Код
// init Horizontal Timing
  LCD_TIMH_bit.HBP   =  C_GLCD_H_BACK_PORCH - 1;
  LCD_TIMH_bit.HFP   =  C_GLCD_H_FRONT_PORCH - 1;
  LCD_TIMH_bit.HSW   =  C_GLCD_H_PULSE - 1;
  LCD_TIMH_bit.PPL   = (C_GLCD_H_SIZE/16) - 1;
  // init Vertical Timing
  LCD_TIMV_bit.VBP   =  C_GLCD_V_BACK_PORCH;
  LCD_TIMV_bit.VFP   =  C_GLCD_V_FRONT_PORCH;
  LCD_TIMV_bit.VSW   =  C_GLCD_V_PULSE;
  LCD_TIMV_bit.LPP   =  C_GLCD_V_SIZE - 1;
,
а то народ ленится битики считать.
overloaded
Сделал более удобочитаемым. Что еще заметил - вдоль левой грани квадрата курсора (по вертикали) проскакивают пиксели, полу-случайно. Т.е. (*-проскакивающий пиксель smile.gif ):

Код
*|------------|
  |  курсор   |
  |               |
*|               |
  |----------- |



Кстати, от негативной ауры глючащего ТФТ)) и на телефоне экран заглючил :-)))) Боюсь как-бы монитор не сдох теперь lol.gif

Код
#define LCD_RES_H 320
#define LCD_RES_V 240
#define LCD_BUF_SIZE (LCD_RES_H*LCD_RES_V*2)

#define LCD_TIMH_HBP    (61-1)    //42-1(ili 31-1 ??) po datasheet na TFT
#define LCD_TIMH_HFP    (67-1)
#define LCD_TIMH_HSW    (11-1)
#define LCD_TIMH_PPL    ((LCD_RES_H/16)-1)

#define LCD_TIMV_VBP    33        //6(ili 3 ??) po datasheet na TFT
#define LCD_TIMV_VFP    16
#define LCD_TIMV_VSW    (3-1)
#define LCD_TIMV_LPP    (LCD_RES_V-1)

#define LCD_POL_BCD        1
#define LCD_POL_CPL        ((LCD_RES_H/1)-1)
#define LCD_POL_IOE        0
#define LCD_POL_IPC        1
#define LCD_POL_IHS        1
#define LCD_POL_IVS        1
#define LCD_POL_CLKSEL     0
#define LCD_POL_PCD_LO    1

#define LCD_CTRL_BEPO    0
#define LCD_CTRL_BEBO    0
#define LCD_CTRL_BGR    0
#define LCD_CTRL_LCDTFT    1
#define LCD_CTRL_LCDBPP    4


unsigned char VideoBuf[LCD_BUF_SIZE] __attribute__((at(NOR_FLASH_BASE))); //SDRAM

void InitLCD()
{
  int i, testnum = 0;
  int k=0;
  unsigned short *Pall = (unsigned short *)&LCD_PAL;
  unsigned short *Vbuf = (unsigned short *)&VideoBuf;
  unsigned short *Curs = (unsigned short *)&CRSR_IMG;
    
    PCONP|= (1<<20); //LCD
    
    PINSEL11 = (6<<1)|(1<<0);// bit0=1 - LCD port is enabled.    bit1...3 = 110 TFT 16-bit. (1:5:5:5 mode)

  //AHBCFG1    = ((0<<0)|(3<<1)|(1<<4)|(3<<4)|(1<<8)|(4<<12)|(3<<16)|(2<<20)|(1<<24)|(5<<28));
  
  LCD_CFG    = 10;//72 MHz div 11

  LCD_TIMH   = (LCD_TIMH_HBP<<24) | (LCD_TIMH_HFP<<16) | (LCD_TIMH_HSW<<8) | (LCD_TIMH_PPL<<2);
  LCD_TIMV   = (LCD_TIMV_VBP<<24) | (LCD_TIMV_VFP<<16) | (LCD_TIMV_VSW<<10) | LCD_TIMV_LPP;

  LCD_POL    = (0<<27) | (LCD_POL_BCD<<26) | (LCD_POL_CPL<<16) | (LCD_POL_IOE<<14)
                  | (LCD_POL_IPC<<13)| (LCD_POL_IHS<<12) | (LCD_POL_IVS<<11)| (0<<6) | (LCD_POL_CLKSEL<<5) | (LCD_POL_PCD_LO<<0);

  LCD_CTRL   = (LCD_CTRL_BEPO<<10) | (LCD_CTRL_BEBO<<9) | (LCD_CTRL_BGR<<8) | (LCD_CTRL_LCDTFT<<5) | (LCD_CTRL_LCDBPP<<1); // 100 = 16 bpp, 1:5:5:5 mode. 011=8bit(palette?);

  for(i=0; i<256; i++)
      Curs[i] = 0xFFFF;

  CRSR_CFG = 0;
  CRSR_XY = (110<<16)|(160<<0);
  CRSR_CTRL = 1;//Cursor on

  LCD_UPBASE = (unsigned long)VideoBuf;
  LCD_LPBASE = (unsigned long)VideoBuf;    

    
    for(i=0; i<256; i++)//test
    {
        Pall[i] = 0xFF00+i;
    }                                                   
  
  LCD_CTRL |= 1;//Enable
  LCD_CTRL |= 1<<11;//PWR ON

...
}
skripach
Тогда так, а именно.
SPACUM
У Меня эффект мерцания был на экране 640х480 при низкой тактовой частоте контроллера или при медленной работе внешней памяти. До конца устранить не удалось. Но если не применять яркости пикселов в диапазоне 1/2 ... 1/4 от максимальной, мерцания практически не заметно. Еще сильное мерцание было при незаземлении металлической рамки вокруг дисплея(от полной яркости до нуля при прикосновении рукой).
skripach
Рябь и мерцание разные вещи.
Dog Pawlowa
Цитата(overloaded @ Apr 5 2010, 13:18) *
Что еще заметил - вдоль левой грани квадрата курсора (по вертикали) проскакивают пиксели, полу-случайно. Т.е. (*-проскакивающий пиксель smile.gif ):

Это свидетельствует о неправильной полярности синхросигнала, ну или о плохом качестве сигналов вообще.
overloaded
Судя по изображению, явно что-то не то с сигналами т.к. совсем плохое, на незаземленную рамку не похоже.. Рябит так, что кажется , что изобрадение дергается вверх-вниз, + черного нет, он сероватый..
Полярность и форма синхросигналов правильная, а вот форма DCLK смущает..(см. осц-грамму: ~0,5 В\дел, 0,04мкс\дел) Плата в которую подключен ТФТ с платой с контроллером соединяется шлейфом IDC-40 20см. При отключении ТФТ форма не меняется. Шлейф укорачивал с 50см - форма не поменялась.. Померять на плате с контроллером не удалось т.к. осциллограф не синхронизируется) Но подозреваю что там все нормально.. Неужели шлейф так все портит? Он же в ATA используется.. Пулл-ап\даун отключены.
Или форма все-таки не смертельная и причина в другом?
Нажмите для просмотра прикрепленного файла
ar__systems
Цитата(overloaded @ Apr 6 2010, 06:01) *
Судя по изображению, явно что-то не то с сигналами


Что за осциллограф и probe?
overloaded
Спасибо, как-то об этом не подумал)) Действительно, Осциллограф С1-49 Полоса пропускания, МГц 5, 1МОм 50 пФ (( Поставил клок 2 Мгц - форма стала нормальная. Т.е. рябь скорее всего чисто логическая выходит.. Буду думать дальше)
ar__systems
у LPC если не ошибаюсь front & back порч означают не совсем то, что должны бы, а совсем наоборот, т.е front справа на графике, а back слева.

Вообще дешевый USB logic analyzer сэкономит вам массу времени при отладке LCD.
aaarrr
Как экран зовут?
overloaded
Анализатор в ближайшие пару дней возможности достать нет...

экран COM41T4148 (http://www.data-modul.com/eu/products/tft_displays/single_tft_small/com41t4148xlc.html?nav=pn) в режме MODE = VSS - т.е. с конфигурацией через SPI. Но тут вроде тоже все уже много раз пересмотрел + если б формат был неправильный, он бы просто не включился т.к. стартует в режиме standby,
а командой по SPI этот стендбай отключается, да и на команды flip horizontal, vertical реагирует...

В общем методом научного перебора)), на всякиц случай, перепробовал все комбинации
LCD_POL_IPC, LCD_POL_IHS, LCD_POL_IVS.. а также разные бек и фронт порчи, которые только двигают картинку.

Снижал клок вплоть до 1 кадр в 2 секунды - все то-же самое..
Что удалось заметить: Каждый кадр то ниже то выше на 1 пиксель (чередуются).
+при активном сбросе контроллера на работающем ТФТ, половина линий(опять-же через одну) белые, остальные- тех цветов что и были

Пиксели слева
(а при некоторых настройках порчей и справа) от курсора продолжают появляться - в каждом кадре
на разной высоте...
Пока все сводится к покупке анализатора.. (((
scorp1969
пару мыслеи:
видео буфер выровнен по границе 8?
а RGB выводы правильные используются в режиме 555 out of 888?
и вообще, у вас видео буфер как char pазмером 2х320х240 при этом режим 555 один пиксел это 16бит но ни как не char
Dog Pawlowa
Работа с ПДАшными платами от Колибри научила меня настороженно относиться к дисплеям, которые конфигурируются по SPI.
Вы бы по мусоркам покопались и нашли "человеческий" TFT, ага?
Мы подключали четыре типа дисплеев к 2478 и подобных проблем не было ни с одним режиме 16 и 32 бит (ну кроме быстродействия, конечно).
scorp1969
а земля точно хорошая к дисплею идет?
overloaded
Цитата(Dog Pawlowa @ Apr 6 2010, 18:41) *
Вы бы по мусоркам покопались и нашли "человеческий" TFT, ага?

Да этот во 2-м режиме тоже может быть "человеческий", в крайнем случае его и буду пробовать, но хотел по СПИ менять яркость\контраст..

Цитата(scorp1969 @ Apr 6 2010, 18:22) *
видео буфер выровнен по границе 8?
а RGB выводы правильные используются в режиме 555 out of 888?
и вообще, у вас видео буфер как char pазмером 2х320х240 при этом режим 555 один пиксел это 16бит но ни как не char

выровнян(0х80000000).

вроде да)) (старшие к старшим ТФТ, младшие ТФТ на землю.) в любом случае были бы искаженные цвета, но на развертку это бы врядли повлияло..

это просто буфер так задан, заполняется он через short* . А сейчас вообще в 8бит (палитру) переделал,
от этого суть не меняется..

Присмотрелся внимательней на медленной развертке - ВСЕ кадры выводятся черезстрочно, сначала четные, потом - нечетные или наоборот)..Те что "не выводятся"- - белые.. Это я так понимаю контроллер в ТФТ так их выдает? Или все-таки МК?
overloaded
До сих пор не могу заставить нормально работать ((

1. Оба экрана ведут себя абсолютно одинаково.
2. Пробовал и "нормальный" режим - с сигналом DE.
3. Все data линии кроме старшего бита синего настроены как пулл-даун (для теста)
4. LCD интерфейс переписан на IO, проверен логическим анализатором.
5. Тестовые данные (пару верт. и горизонтальных синих строк) выводятся стабильно, правильно, на своем месте.
6. Изменение Common-electrode drive DC output тоже ни на что в плане убирания полос не влияет.
7. Параметры настройки LCD интерфейса брались и из ДШ и из аппноты по настройке EPSONовского ЛСД контроллера.

При всем вышеперечисленном изменений в работе не произошло.

Еще раз о проблеме:
все четные/не четные строки (меняются местами каждый кадр) выводятся почти белым цветом (почти - потому, что например синий сегмент синего пикселя в этой белой строке светится все-же с немного большей интенсивностью чем остальные - компоненты чисто "белых" пикселей).

В связи с этими белыми строками черный фон совсем не черный, а на нормальной частоте обновления и вовсе все рябит и белесое.

Есть желание выкинуть ЛСД в окно)) , но нельзя, т.к. альтернатив по размеру ему нету..
Что делать дальше вообще без понятия (((
overloaded
Заработало! =)) Все-таки надо было более тщательно подойти к настройке VCOM...
+увеличил частоту в 1.5 раза от рекоммендуемой, убрал яркости, увеличил контраст - черный стал похож на черный) Но пиксели сбоку курсора все еще пробегают.. Как с правильной полярностью клока, так и с неправильной (с неправильной больше).
А вообще обычно ставят согласующие резисторы на видео-интерфейсы? Посмотреть форму DCLK пока нечем..
overloaded
Не прошло и года =) В общем фон стал окончательно черным после того как нашел ошибку в схемотехнике подключения экрана (было неправильное напряжение для общего электрода TFT)
SergeyDDD
Цитата(overloaded @ Mar 16 2011, 19:06) *
Не прошло и года =) В общем фон стал окончательно черным после того как нашел ошибку в схемотехнике подключения экрана (было неправильное напряжение для общего электрода TFT)


а что такое "напряжение для общего электрода TFT"?
overloaded
Это COMMON ELECTRODE CENTER VOLTAGE. Т.е. средняя точка, относительно которой подается то прямая то обратная полярность на ТФТ транзисторы (чтоб не было берн-ина т.е. "вжегшейся" картинки). Есть разные схемы организации экранов, в этом одна полярность подавалась на четные, другая на нечетные строки, на следующем кадре - наоборот. Т.к. напряжение было неправильным, строки (через одну) были серого цвета вместо черного, чередуясь через каждый кадр давали серый фон и рябь.
Prinz
Здравтсвуйте.
У меня немного похожий вопрос. Разбираюсь с отладочной платой QVGA v1.0
SD заработала на ура, вывожу картинку на экран, работаю с внешней памятью.
А как повысить частоту обновления этого дисплея?
Я брал готовый код, сейчас разбираюсь, там вроде всё по максимуму стоит, а обноление всё равно не очень.
Например:
// 0 = divide by 1
LCD_CFG = 0x0;
Где ещё что псмотреть???
Prinz
Уточню, контроллер тот же LPC2478. Ядро на частоте 72MHz.
Дисплей тотже, как я понял TFT 320x240.
Я прочитал, что может ещё зависеть от скорости работы с внешней озу. Подскажите, пожалуйста, что увеличивать?
M_Andrey
Цитата(Prinz @ Apr 4 2011, 09:09) *
// 0 = divide by 1
LCD_CFG = 0x0;

И после этого дисплей все еще работает, максимальная частота вашего дисплея вряд-ли может быть более 25МГц, а тут превышение в три раза. Приведите всю инициализацию дисплея.
Prinz
Цитата(M_Andrey @ Apr 5 2011, 15:11) *
И после этого дисплей все еще работает, максимальная частота вашего дисплея вряд-ли может быть более 25МГц, а тут превышение в три раза. Приведите всю инициализацию дисплея.



Уточнение. Где-то значит что-то ещё делиться, так как DOTCLK = 4 MHz с хвостиком.
Осцилографом натыкал.
Вроде ка бы обновление порядочное. Шина паралельная 18 бит.

И вот что я хаметил, если с SD грузить однородная картинка, то всё норма.
Нарисовал пару квадратиков на ней, мерцание заметно только на одном, который такого тёмно-зелёного цвета. Я вот сейчас вообще в шоке.
Всё нормально кроме одного маленького квадратика.
В чём может быть ароблема???

CODE
#define NULL 0
#define MUL 72/8
#define ACTIVATE_CS FIO0CLR = 0x10000
#define DEACTIVATE_CS FIO0SET = 0x10000
#define SET_RS FIO0SET = 0x80000
#define RESET_RS FIO0CLR = 0x80000
pInt32U a;
extern void delay(int cnt);
unsigned long buf[4]={0x56FF,0x7447,8098,87};

spiSend(BYTE data)
{
unsigned int failsafe;

S0SPDR = data;
failsafe = 0;
while(((S0SPSR & 0x80) == 0) && (failsafe < 5000))
failsafe++;

if(failsafe >= 5000)
{
S0SPCCR = 8;
S0SPCR = 0x38;
}
}

void writeToReg(WORD addr, WORD data)
{
RESET_RS;
ACTIVATE_CS;
spiSend(0);
spiSend(addr & 0xff);
DEACTIVATE_CS;

SET_RS;
ACTIVATE_CS;
spiSend(data >> 8);
spiSend(data & 0xff);
DEACTIVATE_CS;

RESET_RS;
ACTIVATE_CS;
spiSend(0);
spiSend(0x22);
DEACTIVATE_CS;
}


void lcd_hw_init(void)
{
//Turn on power to LCD
FIO2DIR |= 0x1;
FIO2SET = 0x1;
//set P1.18 as PWM output (PWM1.1, second alternative function)
PINSEL3 &= 0xFFFFFFCF;
PINSEL3 |= 0x00000020;
PWM1PR = 0x00; //no prescaling
PWM1MCR = 0x02; //reset counter if MR0 match
PWM1MR0 = 0x3000; //period time equal about 5 ms
PWM1MR1 = 0x1000;
PWM1LER = 0x03; //latch MR0 and MR1
PWM1PCR = 0x0200; //enable PWMENA1
PWM1TCR = 0x09; //enable counter and PWM
FIO0DIR |= 0x90000;
FIO0SET = 0x90000;
PINSEL10 = 0;
PINSEL0 = (PINSEL0 & 0xFFF000FF) | 0x00055500;
PINSEL3 = (PINSEL3 & 0xF00000FF) | 0x05555500;
PINSEL4 = (PINSEL4 & 0xF0300000) | 0x054FFFFF;
PINSEL9 = (PINSEL9 & 0xF0FFFFFF) | 0x0A000000;
PINSEL11 = 0x0000000d;
}

void lcd_display_init(void)
{

writeToReg (0x00,0x0001);
delay(20000);
writeToReg (0x03,0xA2A4);
writeToReg (0x0C,0x0004);
writeToReg (0x0D,0x0308);
writeToReg (0x0E,0x3000);
delay(50000);
writeToReg (0x1E,0x00AF);
writeToReg (0x01,0x2B3F);
writeToReg (0x02,0x0600);
writeToReg (0x10,0x0000);
writeToReg (0x07,0x0233);
writeToReg (0x0B,0x0039);
writeToReg (0x0F,0x0000);
delay(50000);
writeToReg (0x30,0x0707);
writeToReg (0x31,0x0204);
writeToReg (0x32,0x0204);
writeToReg (0x33,0x0502);
writeToReg (0x34,0x0507);
writeToReg (0x35,0x0204);
writeToReg (0x36,0x0204);
writeToReg (0x37,0x0502);
writeToReg (0x3A,0x0302);
writeToReg (0x3B,0x0302);
writeToReg (0x23,0x0000);
writeToReg (0x24,0x0000);
writeToReg (0x48,0x0000);
writeToReg (0x49,0x013F);
writeToReg (0x4A,0x0000);
writeToReg (0x4B,0x0000);
writeToReg (0x41,0x0000);
writeToReg (0x42,0x0000);
writeToReg (0x44,0xEF00);
writeToReg (0x45,0x0000);
writeToReg (0x46,0x013F);
delay(50000);
writeToReg (0x44,0xEF00);
writeToReg (0x45,0x0000);
writeToReg (0x4E,0x0000);
writeToReg (0x4F,0x0000);
writeToReg (0x46,0x013F);
}

void lcd_ctrl_init(tLcdParams* pParams)
{
DWORD regValue = 0;
// disable the display
LCD_CTRL &= ~LCD_CTRL_REG_EN;
// ppl value to set = ppl / 16 -1 (2:7)
// hsw value to set = hsw - 1 (8:15)
// hfp value to set = hfp - 1 (16:23)
// hbp value to set = hbp - 1 (24:31)
regValue= ( ((((pParams->ppl/16)-1)&0x3F) << 2)
| (( (pParams->hsw-1) &0xFF) << 8)
| (( (pParams->hfp-1) &0xFF) << 16)
| (( (pParams->hbp-1) &0xFF) << 24) );
LCD_TIMH = regValue;
regValue =((((pParams->lpp-1) &0x3FF) << 0)
| (((pParams->vsw-1) &0x03F) << 10)
| (((pParams->vfp-1) &0x0FF) << 16)
| (((pParams->vbp-1) &0x0FF) << 24) );
LCD_TIMV = regValue;
regValue = 0;
if(pParams->acb != 0)
{
regValue = (((pParams->acb-1) & 0x1F) << 6);
}
if(pParams->ioe != 0)
{
regValue |= LCD_POL_REG_IOE;
}
if(pParams->ipc != 0)
{
regValue |= LCD_POL_REG_IPC;
}
if(pParams->ihs != 0)
{
regValue |= LCD_POL_REG_IHS;
}
if(pParams->ivs != 0)
{
regValue |= LCD_POL_REG_IVS;
}
// clocks per line (CPL)
switch(pParams->panelType)
{
case LCD_MONO_4: regValue |= ((((pParams->ppl / 4)-1) & 0x3FF) << 16); break;
case LCD_MONO_8: regValue |= ((((pParams->ppl / 8)-1) & 0x3FF) << 16); break;
case LCD_CSTN: regValue |= (((((pParams->ppl * 3)/8)-1) & 0x3FF) << 16); break;
case LCD_TFT:
case LCD_ADTFT:
case LCD_HRTFT:
default: regValue |= (((pParams->ppl-1) & 0x3FF) << 16);
}
// panel clock divisor, lower bits
regValue |= ((17)-2)&0x0F; // TODO: should be calculated from fcclk
//regValue
LCD_POL = regValue;
// skip line end control
LCD_LE = 0;
// disable interrupts
LCD_INTMSK = 0;
// default 16 bits per pixel
regValue = LCD_CTRL_REG_BPP24;
// default BGR
regValue |= LCD_CTRL_REG_BGR;
switch(pParams->panelType)
{
case LCD_ADTFT:
case LCD_HRTFT:
case LCD_TFT: regValue |= LCD_CTRL_REG_TFT; break;
case LCD_MONO_4: regValue |= LCD_CTRL_REG_BW_MONO; break;
case LCD_MONO_8: regValue |= (LCD_CTRL_REG_MONO8 | LCD_CTRL_REG_BW_MONO); break;
case LCD_CSTN: break;
default: break;
}
if(pParams->dp == 1)
{
regValue |= LCD_CTRL_REG_DUAL;
}
LCD_CTRL = regValue;
// 0 = divide by 1
LCD_CFG = 0;
}


/******************************************************************************
* Implementation of public functions
*****************************************************************************/



void
lcdSetColorFormat(tColorFormat format)
{
switch(format)
{
case COLOR_FORMAT_RGB:
LCD_CTRL &= ~LCD_CTRL_REG_BGR;
break;
case COLOR_FORMAT_BGR:
LCD_CTRL |= LCD_CTRL_REG_BGR;
break;
default:
// ERROR
break;

}
}

void lcdSetBacklight(BYTE percent)
{
PWM1MR1 = ((unsigned long)0x3000 * (unsigned long)(100-percent)) / (unsigned long)100;
PWM1LER = 0x02;
}

void
lcdSetBpp(tLcdBpp bpp)
{

LCD_CTRL &= 0xfffffff1;
switch (bpp)
{
case LCD_BPP1:
LCD_CTRL |= LCD_CTRL_REG_BPP1;
break;
case LCD_BPP2:
LCD_CTRL |= LCD_CTRL_REG_BPP2;
break;
case LCD_BPP4:
LCD_CTRL |= LCD_CTRL_REG_BPP4;
break;
case LCD_BPP8:
LCD_CTRL |= LCD_CTRL_REG_BPP8;
break;
case LCD_BPP16:
LCD_CTRL |= LCD_CTRL_REG_BPP16;
break;
case LCD_BPP24:
LCD_CTRL |= LCD_CTRL_REG_BPP24;
break;
case LCD_BPP16_565:
LCD_CTRL |= LCD_CTRL_REG_BPP16_565;
break;
case LCD_BPP12_444:
LCD_CTRL |= LCD_CTRL_REG_BPP12_444;
break;

}

}


void
lcdTurnOn(void)
{
// enable LCD
LCD_CTRL |= LCD_CTRL_REG_EN;

// power on
LCD_CTRL |= LCD_CTRL_REG_PWR;

delay(5000);
//lcd_display_init();

lcdSetBacklight(100);
}

void
lcdInit(tLcdParams* pParams)
{
unsigned int i;
//char *d;
lcd_hw_init();
a=(pInt32U)0xA0000000; //óêàçàòåëü íà âíåøíþþ ïàìÿòü íà áóôåð îáíîâëåíèÿ 320 x 240 x 32 bit
lcdSetBacklight(0);
lcd_ctrl_init(pParams);
// set the frame buffer
LCD_UPBASE = 0xA0000000;
a=(pInt32U)0xFFE10800;
for(i=0;i<256;i++)
*a++=0x00;
//CRSR_CTRL=21;
CRSR_CTRL=0x0; //îòêëþ÷èëè êóðñîð
CRSR_CFG=2;
CRSR_CLIP=0x00001010;
CRSR_XY=0x00000000;
CRSR_PAL0=0x00FF0000;
CRSR_PAL1=0x0000FF00;
}



В майне вызывается lcdInit(&ea_QVGA_v2);


static tLcdParams ea_QVGA_v2 =
{
28, /* Horizontal back porch */
10, /* Horizontal front porch */
2, /* HSYNC pulse width */
240, /* Pixels per line */
3, /* Vertical back porch */
2, /* Vertical front porch */
2, /* VSYNC pulse width */
320, /* Lines per panel */
0, /* Do not invert output enable */
1, /* Invert panel clock */
1, /* Invert HSYNC */
1, /* Invert VSYNC */
1, /* AC bias frequency (not used) */
24, /* Bits per pixel */
LCD_ADTFT, /* LCD panel type */
0, /* Single panel display */
};

Исследования:
0xffff00 - не мирцает
0x000000 - не мирцает
0x008000 - мирцает
0x00ff80 - не мирцает
0x0000ff - не мирцает
0x00ff00 - не мирцает
0x8080ff - мирцает
0xff8040 - мирцает
M_Andrey
1. PINSEL11 = 0x0000000d; - это режим 1:5:5:5
не стыкуется с:
24, /* Bits per pixel */
LCD_ADTFT, /* LCD panel type */
надо PINSEL11 = 0x0000000F;

2. 240, /* Pixels per line */ - по горизонтали наверное 320, а
320, /* Lines per panel */ - по вертикали 240

3. regValue |= ((17)-2)&0x0F; // TODO: should be calculated from fcclk
LCD_POL = regValue;
как раз делит 72МГц на 17 = 4,24МГц

4. Если не ошибаюсь у вас кадры обновляются с частотой:
(72/17)/((HBP+HFP+HPW+PPL)*(VBP+VFP+VPW+LPP))=47,63Гц.
Можете попробовать постепенно уменьшать число из пред.пункта до 8 для достижения требуемого результата.
Prinz
Цитата(M_Andrey @ Apr 5 2011, 21:29) *
1. PINSEL11 = 0x0000000d; - это режим 1:5:5:5
не стыкуется с:
24, /* Bits per pixel */
LCD_ADTFT, /* LCD panel type */
надо PINSEL11 = 0x0000000F;

2. 240, /* Pixels per line */ - по горизонтали наверное 320, а
320, /* Lines per panel */ - по вертикали 240

3. regValue |= ((17)-2)&0x0F; // TODO: should be calculated from fcclk
LCD_POL = regValue;
как раз делит 72МГц на 17 = 4,24МГц

4. Если не ошибаюсь у вас кадры обновляются с частотой:
(72/17)/((HBP+HFP+HPW+PPL)*(VBP+VFP+VPW+LPP))=47,63Гц.
Можете попробовать постепенно уменьшать число из пред.пункта до 8 для достижения требуемого результата.



1. Там джампера есть переключени на 16. Но у меня стояло 24, поэтому я переделал на PINSEL11 = 0x0000000F;
2. Тут всё нормально. Там по вертикале 320, а по горизонтале 240. Он как бы развёрнут.
3. Я поставил 9, получилось ровно 8 MHz, вроде всё стало работать шикарно.
Спасибо большое за помощь. Разобрался.
slava2148
Вообще-то должны быть либо HSYNC и VSYNC либо DCLK. Это разные режимы. И если используются HSYNC и VSYNC, то вход дисплея DCLK должен быть единицей, а не синусом. Рябить также может, если большая частота развёртки, а память не успевает.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.