Página 1 de 2

EMC LPC2478

MensagemEnviado: 11 Jan 2011 09:51
por die6o
Pessoal.
Desenvolvemos o projeto sobre a plataforma da IAR.
A placa da IAR possui 32MB de RAM, sendo duas memorias de 16 bits.
Ou seja, ele possui palavras de 32 bits diretamente.
Pois estamos utilizando display de 24 bits, mapeado para memoria externa.

Na placa que esta chegando, eu utilizei uma memoria apenas de 8MB de 16 bits, pois havia visto esta mesma plataforma de desenvolvimento com uma memoria apenas. Hoje me caiu a ficha....!!!
Como vou utilizar 24 bits, e DMA dedicada para o display. O EMC tem a configuração para ele pegar duas palavras de 16 externa e montar uma de 32 interna, para a fifo do display ir cospindo isto para o barramento ?

Eu estou desde ontem estudando o EMC, e não consegui entender como funciona esta configuração, e se existe esta possibilidade.

Obrigado, Antecipadamente!!

die6o

MensagemEnviado: 15 Jan 2011 00:13
por fanl
Tenho quase certeza que o periférico EMC ajeitará o concatenamento dos bytes. Preste bem atenção para ligar a memória externa adequadamente.


Na sua plataforma de desenvolvimento configure o EMC como 16bits e teste a leitura e escrita a endereços, se os dados vão ser concatenados adequadamente.

Att.

MensagemEnviado: 18 Jan 2011 07:05
por die6o
fanl escreveu:Tenho quase certeza que o periférico EMC ajeitará o concatenamento dos bytes. Preste bem atenção para ligar a memória externa adequadamente.


Na sua plataforma de desenvolvimento configure o EMC como 16bits e teste a leitura e escrita a endereços, se os dados vão ser concatenados adequadamente.

Att.

fanl, esta acontecendo uma coisa muito estranha.
Agora de manhã assim que cheguei, fiz o teste de utilizar apenas 1 memória de 4*16 ao invés das duas de 4*16.
Muito estranho, ele joga a cor correta de 24 bits no display, só que acontece uma coisa estranha. É como se ele pulasse um pixel para escrever na horizontal. Na prática, esta acontecendo como se eu quisesse apontar e mudar 32 bits, e ele incrementassem 64 ou coisa do tipo. Estou utilizando ponteiro.
Já fiz de tudo aqui, tentei todas as configurações da tabela do user manual e nenhuma deu resultado.

Alguém já passou por isto?

die6o

MensagemEnviado: 18 Jan 2011 11:12
por fanl
Diego,

LCD a 24bits usa 32bits por pixel. o 1o byte é dumb. Porque o EMC não consegue fazer leituras de 3 bytes somente, o alinhamento é 1,2 ou 4 bytes.

Eu tenho uma sugestão que vai me ajudar a te ajudar, faça um programa que:

Com um apontador (char*), escreva 4 bytes: 0xff 0xee 0xdd 0xcc
Depois leia com apontador (char*) 4 incrementos, (short*) 2 incrementos e (int*).
Poste os resultados das leituras aqui.

Tipo assim:
char * pc;
short * ps;
int * pi;

pc = (char*)0xA0000000
*pc++ = 0xff
*pc++ = 0xee
*pc++ = 0xdd
*pc = 0xcc


pc = (char*)0xA0000000
printf("char: %2x %2x %2x %2x", *pc++, *pc++, *pc++, *pc);

ps = (short *)0xA0000000
printf("short: %4x %4x", *ps++, *ps);

pi = (int *)0xA0000000
printf("int: %8x", *pi);

Uma coisa de cada vêz, primeiro o EMC, depois a gente liga o display.

MensagemEnviado: 19 Jan 2011 06:59
por die6o
Fanl. Tem algo muito estranho aqui.

Iniciando no endereço "0XA0000000".
Eu fiz um laço com 16 posições escrevendo de 0 a 15, os valores de 0 a 15.
Acontece o seguinte.
Código: Selecionar todos
0XA0000000   00 01 02 03 04 05 06 00 06 00 06 00 06 00 06 00  XX XX XX

Ou seja, não tenho idéia do que possa ser...!

De 0 a 6 ele coloca os valores nas posições corretas, no 7 ele repete 6, e sucessivo. Ele escreve em posições sem nexo à lógica!

a configuração que estou utilizando é esta.

EMC_DYN_CFG0 = (0x00000000) | (1<<12 | 1<<9 | 1<<7 | 1 << 3);

Bit - 7,9,12 = conforme tabéla.
Bit - 3 = low power SDram.

A única coisa que eu sei, é que a escrita na RAM esta completamente maluca!

MensagemEnviado: 19 Jan 2011 11:37
por die6o
Nossa que coisa mais estranha!

Pessoal o modelo de memória que eu estou utilizando é.
Samsung "K4S561632J".
4MB - 16BIT (4 banks, 16 bits, x bits length).

Eu por curiosidade, reconfigurei os pinsel para utilizar 16 bits, 14 bits de endereço, desliguei o DQ2 e DQ3.
Minha surpresa foi que compilei, gravei, e funcionou perfeitamente!

Ao verificar a tabela de configuração do registrador “EMC_DYN_CFG", me deparei com a seguinte configuração.
Código: Selecionar todos
  EMC_DYN_CFG0 = 0x00005488;

  O mesmo que:
 
  EMC_DYN_CFG0=(0x00000000) | (1<<14 |1<<12 | 1<<9 | 1<<7| 1<<3);

Observando a tabela de configuração, ele confere com a seguinte configuração:
Código: Selecionar todos
  1 1 010 01 128 MB (8Mx16), 4 banks, row length = 12, column length = 9. 
   


Veja que esta memória esta configurada para trabalhar como se fosse 8MB*16bit, e na verdade ela é de 4MB*16bit.

Se eu configurar como sendo 4MB*16bit, simplesmente fica louco!

MensagemEnviado: 20 Jan 2011 00:08
por fanl
Não configure a memória como lowpower. Ela não é lowpower.

Use esta configuração:
0 0 001 01 64 MB (4Mx16), 4 banks, row length = 12, column length = 8

Não sete o bit 3 do registrador em questão.


Lembre-se de fazer acessos a 32bits e 16 também à memória.

Att.

MensagemEnviado: 20 Jan 2011 06:22
por fabim
fanl escreveu:Não configure a memória como lowpower. Ela não é lowpower.

Use esta configuração:
0 0 001 01 64 MB (4Mx16), 4 banks, row length = 12, column length = 8

Não sete o bit 3 do registrador em questão.


Lembre-se de fazer acessos a 32bits e 16 também à memória.

Att.


não Sr!! Não funciona. Fica doida!!!

MensagemEnviado: 20 Jan 2011 06:49
por fabim
Eu e o die6o estamos nos descabelando com isso !! To ficando doido doido doido, malucão, putaquepariudessascoisasdoscaraidaporra !!!

Tipow, pensa doseguintejeito!!!! Funciona, mais não é de 8MB*4baks!!!! Ei frudinhou tudo.
Tipo, imagina que eu vou ter que ficar verificando se chegou nos 4mB pra pular pra 8.XmB e sair forinhado dos 4MB que nun ecsiste !!! Isto não ecsiste!!
Tu coloquinhou 64MB ?
4 * 4 = 16 MB e não 64!!!
Tipow, essa memoria que estamos usinhando não bate com nenhuma daquelas lá !!! Testei todas daquela tabela, e a unica que fucinha é essanha !!!

MensagemEnviado: 20 Jan 2011 13:02
por Sergio38br

MensagemEnviado: 20 Jan 2011 14:44
por fabim
Então.. Deixa eu explicar melhor o negocio.

Na configuração correta não funciona, na configuração errada funciona...

MensagemEnviado: 20 Jan 2011 20:02
por fanl
A razão deve estar na configuração da SDRAM, usa-se uma leitura "dummy" para configurar a SDRAM. Colocando na configuração errada funciona porque isso faz com que esse Dummy Read configure certo o chip.

Posta aqui o código completo.

MensagemEnviado: 21 Jan 2011 07:44
por fabim
Código: Selecionar todos
  void SDRAMInit( void )
{
  DWORD i, dummy = dummy;

  /*************************************************************************
  * Initialize EMC and SDRAM
  *************************************************************************/
 
 
  EMC_CTRL = 0x00000001;      /*Disable Address mirror*/
  PCONP   |= 0x00000800;      /* Turn On EMC PCLK */

  PINSEL5  = 0x05010115;

  PINSEL6  = 0x55555555;

  PINSEL7  = 0x00000000;

  PINSEL8  = 0x15555555;

  PINSEL9  = 0x00040000;     
 
  EMC_DYN_RD_CFG = 1;      /* Command delayed strategy */
  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: 6(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 */

 
  /* Default setting, RAS latency 2 CCLKs, CAS latenty 2 CCLKs. */
  EMC_DYN_RASCAS0 = 0x00000202;

  /* 32MB, 8Mx16, 4 banks, row=12, column=9 */
  EMC_DYN_CFG0 = 0x00005488;
  //EMC_DYN_CFG0 = (0x00000000) | (1<<14 |1<<12 | 1<<9 | 1<<7/* | 1  << 3*/);

  delayMs(1, 100);         /* use timer 1 */

  /* Mem clock enable, CLKOUT runs, send command: NOP */
  EMC_DYN_CTRL = 0x00000183;
  delayMs(1, 200);         /* use timer 1 */
   
  /* Send command: PRECHARGE-ALL, shortest possible refresh period */
  EMC_DYN_CTRL = 0x00000103;

  /* set 32 CCLKs between SDRAM refresh cycles */
  EMC_DYN_RFSH = 0x00000002; //2
  for(i = 0; i < 0x40; i++);   /* wait 128 AHB clock cycles */
   
  /* set 70 x 16CCLK = 1120CCLK = 15.556uS(@72MHz) between SDRAM refresh cycles */
  EMC_DYN_RFSH = 70;
   
  EMC_DYN_CTRL = 0x00000083;
 
  dummy = *((volatile DWORD *)(SDRAM_BASE_ADDR | (0x22 << 11)));
 
  EMC_DYN_CTRL = 0x00000000;     /* Send command: NORMAL */

  EMC_DYN_CFG0 |= 0x00080000;     /* Enable buffer */
  delayMs(1, 1);              /* Use timer 1 */
  return;

}


Sobre o dummy, veja que você apenas leu dentro da RAM externa, o valor existente no endereço "0XA0011000", ou seja ele leu o byte de numero 69632 dentro da ram. Eu mudei aqui este byte e leu normalmente... e funcionou normalmente. Eu acredito que este dummy seja apenas para o hw se ligar que vai ser usado..rs

Abraços, e muito obrigado por nos dar esta força, e para os outros cumpanhero também!!!

MensagemEnviado: 21 Jan 2011 22:04
por fanl
Calma, pode não ter funcionado se você só fez uma leitura. Tem o cache interno que armazena algumas words.

O Dummy read configura o Modo de operação da SDRAM (CAS, BURST, etc..) Você encontra no manual da SDRAM como configura-lo, chama-se MODE REGISTER.

No seu caso, 8 colunas + barramento 16bits, + 2 bits de bank, dá 11. Então os endereços de ROW, estão do bit 11 em diante. E como o MODE REGISTER tem que ser escrito nos endereços de ROW, se faz um shift de 11. No seu caso você está usando mode register configurado para 0x22 (ver manual da ram).

MensagemEnviado: 22 Jan 2011 14:40
por fabim
certo. mais voce não respondeu.. Porque funcionou com configuração errada, e não funcionou na configuração certa ?