Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не стартует LPC2478.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Oleg_IT
Есть простенькая программа для LPC2478, тест TFT и передача/приём по COM. Код инициализации LCD взял из примера. Проблема в том, что после каждой прошивки программы приходится передёргивать питание и посылать команду на перерисовку, что бы всё правильно заработало. Если питание не выключить/включить, то LCD модуль LPC вообще не заводится. Если не дать команду на перерисовку, то изображение может быть сдвинуто и с артефактами, точками, линиями.
В чём проблема?

CODE


#define LCD_VRAM_BASE_ADDR_UP0 DYNAMIC_MEM0_BASE
#define LCD_VRAM_BASE_ADDR_LP0 DYNAMIC_MEM0_BASE

void SDRAMInit( void )
{
volatile DWORD i, dummy = dummy;

/*************************************************************************
* Initialize EMC and SDRAM
*************************************************************************/
// SCS |= 0x00000002; /* Reset EMC */
EMC_CTRL = 0x00000001; /*Disable Address mirror*/
PCONP |= 0x00000800; /* Turn On EMC PCLK */
PINSEL4 = 0x50000000;
PINSEL5 = 0x05050555;
PINSEL6 = 0x55555555;
PINSEL7 = 0x55555555;
PINSEL8 = 0x55555555;
PINSEL9 = 0x50555555;

EMC_DYN_RP = 2; /* command period: 3(n+1) clock cycles */
EMC_DYN_RAS = 3; /* RAS command period: 4(n+1) clock cycles */
EMC_DYN_SREX = 7; /* Self-refresh period: 8(n+1) clock cycles */
EMC_DYN_APR = 2; /* Data out to active: 3(n+1) clock cycles */
EMC_DYN_DAL = 5; /* Data in to active: 5(n+1) clock cycles */
EMC_DYN_WR = 1; /* Write recovery: 2(n+1) clock cycles */
EMC_DYN_RC = 5; /* Active to Active cmd: 6(n+1) clock cycles */
EMC_DYN_RFC = 5; /* Auto-refresh: 6(n+1) clock cycles */
EMC_DYN_XSR = 7; /* Exit self-refresh: 8(n+1) clock cycles */
EMC_DYN_RRD = 1; /* Active bank A->B: 2(n+1) clock cycles */
EMC_DYN_MRD = 2; /* Load Mode to Active cmd: 3(n+1) clock cycles */

EMC_DYN_RD_CFG = 1; /* Command delayed strategy */

/* Default setting, RAS latency 3 CCLKs, CAS latenty 3 CCLKs. */
EMC_DYN_RASCAS0 = 0x00000303;

#if ENG_BOARD_LPC24XX /* NXP engineering board */
/* 256MB, 16Mx16, 4 banks, row=12, column=9 */
EMC_DYN_CFG0 = 0x00000480;
#else /* Embedded Artists board */
/* 256MB, 16Mx16, 4 banks, row=13, column=9 */
EMC_DYN_CFG0 = 0x00000680;
#endif
delayMs(1, 100); /* use timer 1 */
//for(i = 0; i < 0x5000*100; i++); /* wait 128 AHB clock cycles */

/* Mem clock enable, CLKOUT runs, send command: NOP */
EMC_DYN_CTRL = 0x00000183;
delayMs(1, 200); /* use timer 1 */
//for(i = 0; i < 0x5000*200; i++); /* wait 128 AHB clock cycles */

/* Send command: PRECHARGE-ALL, shortest possible refresh period */
EMC_DYN_CTRL = 0x00000103;

/* set 32 CCLKs between SDRAM refresh cycles */
EMC_DYN_RFSH = 0x00000002;
for(i = 0; i < 0x40; i++); /* wait 128 AHB clock cycles */

/* set 28 x 16CCLKs=448CCLK=7us between SDRAM refresh cycles */
EMC_DYN_RFSH = 28;

/* To set mode register in SDRAM, enter mode by issue
MODE command, after finishing, bailout and back to NORMAL mode. */
/* Mem clock enable, CLKOUT runs, send command: MODE */
EMC_DYN_CTRL = 0x00000083;

/* Set mode register in SDRAM */
/* Mode regitster table for Micron's MT48LCxx */
/* bit 9: Programmed burst length(0)
bit 8~7: Normal mode(0)
bit 6~4: CAS latency 3
bit 3: Sequential(0)
bit 2~0: Burst length is 8
row position is 12 */
dummy = *((volatile DWORD *)(SDRAM_BASE_ADDR | (0x33 << 12)));

EMC_DYN_CTRL = 0x00000000; /* Send command: NORMAL */

EMC_DYN_CFG0 |= 0x00080000; /* Enable buffer */
delayMs(1, 1); /* Use timer 1 */
//for(i = 0; i < 0x5000; i++); /* wait 128 AHB clock cycles */
return;

}


void GLCD_Ctrl(BOOL bEna)
{
volatile int i;
if (bEna)
{
LCD_CTRL |= LCD_CTRL_LcdEn(0x01);
for(i = C_GLCD_PWR_ENA_DIS_DLY; i != 0; i--);
LCD_CTRL |= LCD_CTRL_LcdPwr(0x01);
}
else
{
LCD_CTRL &= ~LCD_CTRL_LcdPwr(0x01);
for(i = C_GLCD_PWR_ENA_DIS_DLY; i != 0; i--);
LCD_CTRL &= ~LCD_CTRL_LcdEn(0x01);
}
}
void TFT_24_Init(void)
{
FIO0DIR |= (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9);
FIO1DIR |= (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23) | (1 << 24) | (1 << 25) |
(1 << 26) | (1 << 27) | (1 << 28) | (1 << 29);
FIO2DIR |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
(1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 11) | (1 << 12) | (1 << 13);
FIO4DIR |= (1 << 28) | (1 << 29);

PINSEL0 &= ~((3 << 8) | (3 << 10) | (3 << 12) | (3 << 14) | (3 << 16) | (3 << 18));
PINSEL0 |= (1 << 8) | (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16) | (1 << 18);
PINSEL3 &= ~((3 << 8) | (3 << 10) | (3 << 12) | (3 << 14) | (3 << 16) | (3 << 18) |
(3 << 20) | (3 << 22) | (3 << 24) | (3 << 26));
PINSEL3 |= (1 << 8) | (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16) | (1 << 18) |
(1 << 20) | (1 << 22) | (1 << 24) | (1 << 26);
PINSEL4 &= ~((3 << 0) | (3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 10) | (3 << 12) |
(3 << 14) | (3 << 18) | (3 << 22) | (3 << 24) | (3 << 26));
PINSEL4 |= (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 10) | (3 << 12) |
(3 << 14) | (3 << 18) | (3 << 22) | (3 << 24) | (3 << 26);
PINSEL9 &= ~((3 << 24) | (3 << 26));
PINSEL9 |= (1 << 24) | (1 << 26);
PINSEL11 = 0x0F;//1 | ( 0x03 << 1 );

PCONP |= (1 << 20);

LCD_CTRL = //LCD_CTRL_LcdEn(0x00) |
LCD_CTRL_LcdBpp(0x05) | LCD_CTRL_LcdBW(0x00) |
LCD_CTRL_LcdTFT(0x01) | LCD_CTRL_LcdMono8(0x00) | LCD_CTRL_LcdDual(0x00) |
LCD_CTRL_BGR(0x01) | LCD_CTRL_BEBO(0x00) | LCD_CTRL_BEPO(0x00) |
//LCD_CTRL_LcdPwr(0x01) |
LCD_CTRL_LcdVComp(0x00) | LCD_CTRL_WATERMARK(0x00);
LCD_TIMH = LCD_TIMH_PPL((C_GLCD_H_SIZE/16) - 1) | LCD_TIMH_HSW(C_GLCD_H_PULSE - 1) |
LCD_TIMH_HFP(C_GLCD_H_FRONT_PORCH - 1) | LCD_TIMH_HBP(C_GLCD_H_BACK_PORCH - 1);
LCD_TIMV = LCD_TIMV_LPP(C_GLCD_V_SIZE - 1) | LCD_TIMV_VSW(C_GLCD_V_PULSE) |
LCD_TIMV_VFP(C_GLCD_V_FRONT_PORCH) | LCD_TIMV_VBP(C_GLCD_V_BACK_PORCH);
LCD_POL = LCD_POL_PCD_LO(0x00) | LCD_POL_CLKSEL(0x00) | LCD_POL_ACB(0x00) |
LCD_POL_IVS(0x00) | LCD_POL_IHS(0x00) | LCD_POL_IPC(0x00) |
LCD_POL_IOE(0x00) | LCD_POL_CPL(C_GLCD_H_SIZE-1) | LCD_POL_BCD(0x01) |
LCD_POL_PCD_HI(0x00);
// LCD_LE = (1 << 16);
LCD_UPBASE = LCD_VRAM_BASE_ADDR_UP0;
LCD_LPBASE = LCD_VRAM_BASE_ADDR_LP0;

LCD_CFG = LCD_CFG_CLKDIV(7);
}

int main (void) {
char ch[100];
MAMCR = 0;
MAMTIM = 3;
MAMCR = 2;
SDRAMInit();

delayMs(1, 1000); /* Use timer 1 */
GLCD_Ctrl(FALSE);
TFT_24_Init();
GLCD_Ctrl(TRUE);

ClearScreen(255,255,255);
SetColor(250,0,0);
FillPoligon(PAr,3); // рисование треугольника

while(1)
{
if (getline(ch,1) != __FALSE)
{
ParseKey(ch);
}
}
}

skripach
Перед инициализацией Lcd его нужно "выключить". Инициализация уже инициализированного приводит к провисанию.
Oleg_IT
Так, вроде бы так и делаю
GLCD_Ctrl(FALSE); - выключить
TFT_24_Init(); - инициализировать
GLCD_Ctrl(TRUE); - включить

Выключить и включить это питание и энейбл.

И обратной связи нет, тек что программа, как и сам МК "не знают" даже есть на его выходах чего-нибудь или там пусто.
skripach
У меня так, содрал где-то.
Код
void LcdPowerDown(void)
{
  CRSR_CTRL_bit.CrsrOn = 0; // Disable cursor
  for(volatile Int32U e=0; e<50000; e++);
  LCD_CTRL_bit.LcdEn = 0;   // disable GLCD controller
  for(volatile Int32U e=0; e<50000; e++);
  LCD_CTRL_bit.LcdPwr= 0;   // disable power
  for(volatile Int32U e=0; e<50000; e++);
}

Oleg_IT
Увы, не получается. Программа работает, команды обмена и ответы проходят, а LCD модуль не стартует, а после старта, после вкл-выкл МК, память экрана не обновляется. Ввёл секундную задержку между инициализацией и включением LCD модуля и первой отрисовкой экрана. Не помогает.
DpInRock
Цитата
Так, вроде бы так и делаю
GLCD_Ctrl(FALSE); - выключить
TFT_24_Init(); - инициализировать
GLCD_Ctrl(TRUE); - включить


Ибо это бред какой-то. Вот почему бы не воспользоваться примером от производителя микропроцессора? Даже удивительно.


Код
void GLCD_Init (const Int32U *pPain, const Int32U * pPallete)
{
pInt32U pDst = (pInt32U) LCD_VRAM_BASE_ADDR;
  // Assign pin
  PINSEL0 &= BIN32(11111111,11110000,00000000,11111111);
  PINSEL0 |= BIN32(00000000,00000101,01010101,00000000);
  PINMODE0&= BIN32(11111111,11111100,00000000,11111111);
  PINMODE0|= BIN32(00000000,00000010,10101010,00000000);
  PINSEL3 &= BIN32(11110000,00000000,00000000,11111111);
  PINSEL3 |= BIN32(00000101,01010101,01010101,00000000);
  PINMODE3&= BIN32(11110000,00000000,00000000,11111111);
  PINMODE3|= BIN32(00001010,10101010,10101010,00000000);
  PINSEL4 &= BIN32(11110000,00110000,00000000,00000000);
  PINSEL4 |= BIN32(00000101,01001111,11111111,11111111);
  PINMODE4&= BIN32(11110000,00110000,00000000,00000000);
  PINMODE4|= BIN32(00001010,10001010,10101010,10101010);
  PINSEL9 &= BIN32(11110000,11111111,11111111,11111111);
  PINSEL9 |= BIN32(00001010,00000000,00000000,00000000);
  PINMODE9&= BIN32(11110000,11111111,11111111,11111111);
  PINMODE9|= BIN32(00001010,00000000,00000000,00000000);
  PINSEL11&= BIN32(11111111,11111111,11111111,11110000);
  PINSEL11|= BIN32(00000000,00000000,00000000,00001111);
  // Init GLCD cotroller
  PCONP_bit.PCLCD = 1;      // enable LCD controller clock
  CRSR_CTRL_bit.CrsrOn = 0; // Disable cursor
  LCD_CTRL_bit.LcdEn = 0;   // disable GLCD controller
  LCD_CTRL_bit.LcdBpp= 5;   // 24 bpp
  LCD_CTRL_bit.LcdTFT= 1;   // TFT panel
  LCD_CTRL_bit.LcdDual=0;   // single panel
  LCD_CTRL_bit.BGR   = 0;   // notmal output
  LCD_CTRL_bit.BEBO  = 0;   // little endian byte order
  LCD_CTRL_bit.BEPO  = 0;   // little endian pix order
  LCD_CTRL_bit.LcdPwr= 0;   // disable power
  // init pixel clock
  LCD_CFG_bit.CLKDIV =  SYS_GetFsclk() / (Int32U)C_GLCD_PIX_CLK;
  LCD_POL_bit.BCD    = 1;   // bypass inrenal clk divider
  LCD_POL_bit.CLKSEL = 0;   // clock source for the LCD block is HCLK
  LCD_POL_bit.IVS    = 1;   // LCDFP pin is active LOW and inactive HIGH
  LCD_POL_bit.IHS    = 1;   // LCDLP pin is active LOW and inactive HIGH
  LCD_POL_bit.IPC    = 1;   // data is driven out into the LCD on the falling edge
  LCD_POL_bit.IOE    = 0;   // active high
  LCD_POL_bit.CPL    = C_GLCD_H_SIZE-1;
  // 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;
  // Frame Base Address doubleword aligned
  LCD_UPBASE         =  LCD_VRAM_BASE_ADDR & ~7UL;
  LCD_LPBASE         =  LCD_VRAM_BASE_ADDR & ~7UL;
  // init colour pallet

  if(NULL != pPallete)
  {
    GLCD_SetPallet(pPallete);
  }

  if (NULL == pPain)
  {
    // clear display memory
    for(Int32U i = 0; (C_GLCD_H_SIZE * C_GLCD_V_SIZE) > i; i++)
    {
      *pDst++ = 0;
    }
  }
  else
  {
    // set display memory
    for(Int32U i = 0; (C_GLCD_H_SIZE * C_GLCD_V_SIZE) > i; i++)
    {
      *pDst++ = *pPain++;
    }
  }
    
  for(volatile Int32U i = C_GLCD_ENA_DIS_DLY; i; i--);
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.