Memória RAM externa no LPC2478

Software e Hardware para linha ARM

Moderadores: 51, guest2003, Renie, gpenga

Mensagempor MarcusPonce » 01 Mai 2009 11:47

Ok quanto os testes, já esclareceram mais um pouco.
O teste que o Marcelo sugeriu também é importante fazer.

Segundo os documentos da NXP, este ARM consegue usar memórias de 16 bits sem restrições. Também acho que seria bizarro não poder usar variáveis de 32 bits nesta memória de 16 bits.

O interessante é que usando o ponteiro de 32 bits vemos que o controlador já funciona para metade dos endereços. Ou seja, o controlador realmente armazena e lê variáveis de 32 bits na memória de 16 bits em metade dos endeteços.

Segundo o manual, quando o burst do EMC está ativado temos acessos sempre de 16 bytes, então para a memória com 16 bits de largura são realizados sempre 8 ciclos de leitura ou escrita. Concidência ou não, o problema no teste com o ponteiro 32bits se repete em regiões de 16 bytes em 16 bytes na RAM.

Qual o valor você está usando em EMCDynamicConfig ?
MarcusPonce
Byte
 
Mensagens: 166
Registrado em: 12 Fev 2007 13:58
Localização: Campinas - SP

Mensagempor styg » 04 Mai 2009 23:12

Beleza Marcelo, vamo pro teu teste:

o código usado foi o que tu postou.

resultados, leitura de word:

End: 0xA000 0000 Valor: 0x0100 // ok
End: 0xA000 0002 Valor: 0x0302 // ok
End: 0xA000 0004 Valor: 0x0504 // ok
End: 0xA000 0006 Valor: 0x0706 // ok
End: 0xA000 0008 Valor: 0x0706 // erro
End: 0xA000 000A Valor: 0x0706 // erro
End: 0xA000 000C Valor: 0x0706 // erro
End: 0xA000 000E Valor: 0x0706 // erro
End: 0xA000 0010 Valor: 0x1110 // ok
End: 0xA000 0012 Valor: 0x1312 // ok
End: 0xA000 0014 Valor: 0x1514 // ok
End: 0xA000 0016 Valor: 0x1716 // ok
End: 0xA000 0018 Valor: 0x1716 // erro
End: 0xA000 001A Valor: 0x1716 // erro
End: 0xA000 001C Valor: 0x1716 // erro
End: 0xA000 001E Valor: 0x1716 // erro
End: 0xA000 0020 Valor: 0x2120 // ok
End: 0xA000 0022 Valor: 0x2322 // ok
End: 0xA000 0024 Valor: 0x2524 // ok
End: 0xA000 0026 Valor: 0x2726 // ok
End: 0xA000 0028 Valor: 0x2726 // erro
End: 0xA000 002A Valor: 0x2726 // erro e por assim vai..


resultados, leitura de long:

End: 0xA000 0000 Valor: 0x03020100 // ok
End: 0xA000 0004 Valor: 0x07060504 // ok
End: 0xA000 0008 Valor: 0x07060706 // erro
End: 0xA000 000C Valor: 0x07060706 // erro
End: 0xA000 0010 Valor: 0x13121110 // ok
End: 0xA000 0014 Valor: 0x17161514 // ok
End: 0xA000 0018 Valor: 0x17161716 // erro
End: 0xA000 001C Valor: 0x17161716 // erro
End: 0xA000 0020 Valor: 0x23222120 // ok
End: 0xA000 0024 Valor: 0x27262524 // ok
End: 0xA000 0028 Valor: 0x27262726 // erro
End: 0xA000 002C Valor: 0x27262726 // erro
End: 0xA000 0030 Valor: 0x33323130 // ok, e por assim vai...



Marcus, o EMCDynamicConfig tá assim -> EMC_DYN_CFG0 = 0x0280;

e Sergio, o clock do 'bixim' ta em 12MHz :)
Lucas
Avatar do usuário
styg
Word
 
Mensagens: 799
Registrado em: 16 Out 2006 08:24
Localização: Floripa abaixo de zero.

Mensagempor msamsoniuk » 05 Mai 2009 01:00

pois eh... antes nao estava funcionando com word? :)

eu tenho impressao que a sua sdram esta programada para burst de apenas 4 ciclos e o controlador de memoria esta tentando bursts de 8 ciclos. a memoria fornece os 4 primeiros acessos corretamente e entao repete o ultimo nos 4 ciclos adicionais nao previstos.

styg escreveu:Beleza Marcelo, vamo pro teu teste:

o código usado foi o que tu postou.

resultados, leitura de word:

End: 0xA000 0000 Valor: 0x0100 // ok
End: 0xA000 0002 Valor: 0x0302 // ok
End: 0xA000 0004 Valor: 0x0504 // ok
End: 0xA000 0006 Valor: 0x0706 // ok
End: 0xA000 0008 Valor: 0x0706 // erro
End: 0xA000 000A Valor: 0x0706 // erro
End: 0xA000 000C Valor: 0x0706 // erro
End: 0xA000 000E Valor: 0x0706 // erro
End: 0xA000 0010 Valor: 0x1110 // ok
End: 0xA000 0012 Valor: 0x1312 // ok
End: 0xA000 0014 Valor: 0x1514 // ok
End: 0xA000 0016 Valor: 0x1716 // ok
End: 0xA000 0018 Valor: 0x1716 // erro
End: 0xA000 001A Valor: 0x1716 // erro
End: 0xA000 001C Valor: 0x1716 // erro
End: 0xA000 001E Valor: 0x1716 // erro
End: 0xA000 0020 Valor: 0x2120 // ok
End: 0xA000 0022 Valor: 0x2322 // ok
End: 0xA000 0024 Valor: 0x2524 // ok
End: 0xA000 0026 Valor: 0x2726 // ok
End: 0xA000 0028 Valor: 0x2726 // erro
End: 0xA000 002A Valor: 0x2726 // erro e por assim vai..


resultados, leitura de long:

End: 0xA000 0000 Valor: 0x03020100 // ok
End: 0xA000 0004 Valor: 0x07060504 // ok
End: 0xA000 0008 Valor: 0x07060706 // erro
End: 0xA000 000C Valor: 0x07060706 // erro
End: 0xA000 0010 Valor: 0x13121110 // ok
End: 0xA000 0014 Valor: 0x17161514 // ok
End: 0xA000 0018 Valor: 0x17161716 // erro
End: 0xA000 001C Valor: 0x17161716 // erro
End: 0xA000 0020 Valor: 0x23222120 // ok
End: 0xA000 0024 Valor: 0x27262524 // ok
End: 0xA000 0028 Valor: 0x27262726 // erro
End: 0xA000 002C Valor: 0x27262726 // erro
End: 0xA000 0030 Valor: 0x33323130 // ok, e por assim vai...



Marcus, o EMCDynamicConfig tá assim -> EMC_DYN_CFG0 = 0x0280;

e Sergio, o clock do 'bixim' ta em 12MHz :)
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor MarcusPonce » 05 Mai 2009 01:27

Os testes trouxeram resultados interessantes. Estou concordando com o Samsoniuk: pode ser que a SDRAM esteja programada para apenas 4 ciclos e não 8.

Isso me lembra do famoso comando que no início era assim:
dummy = *((volatile unsigned short *)(SDRAM_BASE_ADDR | (0x33 << 12)));

E para este último teste, ficou assim ou já estava com ( 0x33 << 11 ) ?
MarcusPonce
Byte
 
Mensagens: 166
Registrado em: 12 Fev 2007 13:58
Localização: Campinas - SP

Mensagempor styg » 05 Mai 2009 13:45

No ultimo teste estava assim:
mode = *((volatile unsigned int *) (0xa0000000 | (0x33 << 12)));

vou ver como ta configurado esse lance do burst.
Lucas
Avatar do usuário
styg
Word
 
Mensagens: 799
Registrado em: 16 Out 2006 08:24
Localização: Floripa abaixo de zero.

Mensagempor MarcusPonce » 05 Mai 2009 14:13

Este é o ajuste do burst !
Nos post anteriores ficamos de passar para << 11, acho bem provável que usando << 11 faça diferença nos testes.

Seria bom repetir aquele último teste do Samsoniuk.
MarcusPonce
Byte
 
Mensagens: 166
Registrado em: 12 Fev 2007 13:58
Localização: Campinas - SP

Mensagempor styg » 06 Mai 2009 11:34

marcus, refiz o teste do marcelo carregando o mode register com << 11, e realmente deu uma melhorada.
mas ainda ta estranho, de cada 16bytes perco os 2 ultimos. e ta com um tipo de offset de 2bytes no inicio.

resultados, leitura de word:

End: 0xA000 0000 Valor: 0xFFFF
End: 0xA000 0002 Valor: 0x0100
End: 0xA000 0004 Valor: 0x0302
End: 0xA000 0006 Valor: 0x0504
End: 0xA000 0008 Valor: 0x0706
End: 0xA000 000A Valor: 0x0908
End: 0xA000 000C Valor: 0x0B0A
End: 0xA000 000E Valor: 0x0D0C
End: 0xA000 0010 Valor: 0xFFFF
End: 0xA000 0012 Valor: 0x1110
End: 0xA000 0014 Valor: 0x1312
End: 0xA000 0016 Valor: 0x1514
End: 0xA000 0018 Valor: 0x1716
End: 0xA000 001A Valor: 0x1918
End: 0xA000 001C Valor: 0x1B1A
End: 0xA000 001E Valor: 0x1D1C
End: 0xA000 0020 Valor: 0xFFFF
End: 0xA000 0022 Valor: 0x2120
End: 0xA000 0024 Valor: 0x2322
End: 0xA000 0026 Valor: 0x2524
End: 0xA000 0028 Valor: 0x2726 E ASSIM VAI..

resultados, leitura de long:

End: 0xA000 0000 Valor: 0x0100FFFF
End: 0xA000 0004 Valor: 0x05040302
End: 0xA000 0008 Valor: 0x09080706
End: 0xA000 000C Valor: 0x0D0C0B0A
End: 0xA000 0010 Valor: 0x1110FFFF
End: 0xA000 0014 Valor: 0x15141312
End: 0xA000 0018 Valor: 0x19181716
End: 0xA000 001C Valor: 0x1D1C1B1A
End: 0xA000 0020 Valor: 0x2120FFFF E ASSIM VAI..
Lucas
Avatar do usuário
styg
Word
 
Mensagens: 799
Registrado em: 16 Out 2006 08:24
Localização: Floripa abaixo de zero.

Mensagempor MarcusPonce » 06 Mai 2009 11:59

Estamos no caminho certo, os testes parecem indicar que o correto é <<11 mesmo. Provavelmente o deslocamento resolve se você usar o seguinte:

mode = *((volatile unsigned int *) (0xa0000000 | (0x23 << 11)));

Veja que além do <<11 também precisa mudar o 0x33 para 0x23. Assim deixaremos o CAS latency correto.

Poderia por favor refazer o teste ?
MarcusPonce
Byte
 
Mensagens: 166
Registrado em: 12 Fev 2007 13:58
Localização: Campinas - SP

Mensagempor msamsoniuk » 06 Mai 2009 16:39

parece que esta quase funcionando! :)

mas concordo com isso ae, o que ocorre eh que o controlador deve estar operando com cas latency 3 e a memoria programada para cas latency 2: ela clocka as words em sequencia, soh que na primeira word nao tem nada (0xffff) e o conteudo da primeira word eh clockado na memoria como sendo a segunda word.

MarcusPonce escreveu:Estamos no caminho certo, os testes parecem indicar que o correto é <<11 mesmo. Provavelmente o deslocamento resolve se você usar o seguinte:

mode = *((volatile unsigned int *) (0xa0000000 | (0x23 << 11)));

Veja que além do <<11 também precisa mudar o 0x33 para 0x23. Assim deixaremos o CAS latency correto.

Poderia por favor refazer o teste ?
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor styg » 06 Mai 2009 22:18

AEEEEWWWWWWWWWWWWW!!!!!

putz como faz falta o conhecimento né?? como nunca mexi com sdram e talz e nao tava familiarizado com cas, ras etc... nem me liguei que poderia ser isso!
ja voces 2 ja ligaram uma coisa à outra rapidamente.

bom, o bagulhinho agora funfou, e soh pra constar o código foi esse:

Código: Selecionar todos
volatile unsigned int *wr_ptr;
volatile unsigned short *short_wr_ptr;
volatile unsigned char *char_wr_ptr;
volatile unsigned long long *long_ptr;
unsigned int  i;

for(i=0;i!=256;i++)
{
  *bptr++ = i; // preenchimento
}

for(i=0;i!=128;i++)
{
  *wptr++; // leitura
}

for(i=0;i!=64;i++)
{
  *lptr++; // leitura
}


e a inicialização da sdram assim:


Código: Selecionar todos
/* Enable module, normal memory map and normal power mode */
EMC_CTRL = 1;
/* Use little-endian mode and 1:1 clock ratio */
EMC_CONFIG = 0;
/* Global dynamic settings */
/* FIXME */
EMC_DYN_APR = 2;
/* Data-in to active command period tWR + tRP */
EMC_DYN_DAL = 4;
/* Load mode register to active or refresh command period 2 tCK */
EMC_DYN_MRD = 1;
/* Active to precharge command period 44 ns */
EMC_DYN_RAS = 3;
/* Active to active command period 66 ns */
EMC_DYN_RC = 4;
/* Use command delayed strategy */
EMC_DYN_RD_CFG = 1;
/* Auto refresh period 66 ns */
EMC_DYN_RFC = 4;
/* Precharge command period 20 ns */
EMC_DYN_RP = 1;
/* Active bank a to active bank b command period 15 ns */
EMC_DYN_RRD = 1;
/* FIXME */
EMC_DYN_SREX = 5;
/* Write recovery time 15 ns */
EMC_DYN_WR = 1;
/* Exit self refresh to active command period 75 ns */
EMC_DYN_XSR = 5;
/* Dynamic Memory 0 settings */
/* Use SDRAM, 0 0 001 01 address mapping, disabled buffer, unprotected writes*/
EMC_DYN_CFG0 = 0x0280;
/* CAS and RAS latency */
EMC_DYN_RASCAS0 = 0x0202;
/* Wait 50 micro seconds */
arm_delay_u5s(119);
/* Send command: NOP */
EMC_DYN_CTRL = 0x00000183;
/* Wait 50 micro seconds */
arm_delay_u5s(119);
/* Send command: PRECHARGE ALL */
EMC_DYN_CTRL = 0x00000103;
/* Shortest possible refresh period */
EMC_DYN_RFSH = 0x01;
for(i = 0; i < 0x40; i++);   /* wait 128 AHB clock cycles */
/* Wait 1 micro second */
arm_delay_u5s(3);
/* Set refresh period */
EMC_DYN_RFSH = 0x46;
/* Send command: MODE */
EMC_DYN_CTRL = 0x00000083;
/* Set mode registerin SDRAM */
mode = *((volatile unsigned int *) (0xa0000000 | (0x23 << 11)));
/* Send command: NORMAL */
EMC_DYN_CTRL = 0;
/* Enable buffer */
EMC_DYN_CFG0 |= 0x00080000;


valeu a ajuda!
Lucas
Avatar do usuário
styg
Word
 
Mensagens: 799
Registrado em: 16 Out 2006 08:24
Localização: Floripa abaixo de zero.

Mensagempor MarcusPonce » 06 Mai 2009 22:41

Ótimo! Deu trabalho mas funcionou !
Qualquer coisa estamos por aqui...
MarcusPonce
Byte
 
Mensagens: 166
Registrado em: 12 Fev 2007 13:58
Localização: Campinas - SP

Mensagempor regiscruz » 07 Mai 2009 00:11

Nussa, até eu fiquei feliz!!!...rs...

Esse foi phoda, vcs são os KARAS. :P :P :P
Existem três leis que governam o mundo...
A Lei da gravidade, a Lei do mais forte e a lei de Murphy.
Avatar do usuário
regiscruz
Byte
 
Mensagens: 154
Registrado em: 21 Out 2006 10:22
Localização: Uberaba - MG

Mensagempor Abuda » 13 Ago 2009 15:49

Aproveitando o tópico estou tentando configurar uma SDRAM 64Mb (2MX32) com o LPC2478 e estou encontrando problemas.

Se leio e escrevo variáveis short tenho o seguinte resultado:

pos 0: OK
pos 1: erro
pos 2: OK
pos 3: erro

e assim vai.

Caso a variável seja inteira.

pos 0: OK
pos 1: erro
pos 2: erro
pos 3: erro
pos 4: OK
pos 5: erro
pos 6: erro
pos 7: erro
pos 8: OK
pos 9: erro
pos 10: erro
pos 11: erro

E assim vai.

A config é essa:
#define CPUSPEED 48 // 48MHz

#define SDRAM_ROW_ADD 11 //Row addressing: 11bits=2K (A0-A10)
#define SDRAM_REFRESH 7813//64ms
#define SDRAM_TRP 18 //18n
#define SDRAM_TRAS 42 //42n
#define SDRAM_TAPR 1 //1tCK
#define SDRAM_TDAL 4 //4tCK
#define SDRAM_TWR 2 //2tCK
#define SDRAM_TRC 60 //60n
#define SDRAM_TRFC 60 //60n
#define SDRAM_TXSR 1 //1tCK
#define SDRAM_TRRD 12 //12n
#define SDRAM_TMRD 2 //2tCK

#define P2C(Period) (1 + Period*CPUSPEED/1000)
#define SDRAM_BASE_ADDR *(volatile U32*)0xA0000000 //DYCS0
#define SDRAM_DYCS0_BASE (0xA0000000)

// Init SDRAM controller
// Enable EMC clock
PCONP|=0x0800; //enable EMC power
EMC_CTRL=1; // enable EMC

EMC_DYN_RD_CFG=1; //Configures the dynamic memory read strategy(Command delayed strategy)
EMC_DYN_RASCAS0=0x0202; //CAS latency=2; RAS latency(active to read/write delay)=2

EMC_DYN_RP=P2C(SDRAM_TRP);
EMC_DYN_RAS=P2C(SDRAM_TRAS);
EMC_DYN_SREX=SDRAM_TXSR;
EMC_DYN_APR=SDRAM_TAPR;
EMC_DYN_DAL=SDRAM_TDAL;
EMC_DYN_WR=SDRAM_TWR;
EMC_DYN_RC=P2C(SDRAM_TRC);
EMC_DYN_RFC=P2C(SDRAM_TRFC);
EMC_DYN_XSR=SDRAM_TXSR;
EMC_DYN_RRD=P2C(SDRAM_TRRD);
EMC_DYN_MRD=SDRAM_TMRD;
EMC_DYN_CFG0=0x00004300; // 32mb external bus, 64MB (2Mx32), 4 banks, row length=11, column length=8, Micron Sync Flash

// JEDEC General SDRAM Initialization Sequence:
EMC_DYN_CTRL=0x0183; // Issue SDRAM NOP command; CLKOUT runs continuously; All clock enables are driven HIGH
for(i=2000; i; i--); // Delay to allow power and clocks to stabilize (>200us).
EMC_DYN_CTRL=0x0103; // Issue SDRAM PALL (precharge all) command.
EMC_DYN_RFSH=1; // Indicates 1x16 CCLKs between SDRAM refresh cycles.
for(i=128; i; i--); // Wait >SDRAM_TRFC.
EMC_DYN_RFSH=P2C(SDRAM_REFRESH) >> 4; // //Number of CCLKs between SDRAM refresh cycles.
EMC_DYN_CTRL=0x00000083; //Issue SDRAM MODE command.
dummy = *((volatile unsigned int *)(SDRAM_DYCS0_BASE | 0X22<<12));
EMC_DYN_CTRL=0x0000; //Issue SDRAM norm command; CLKOUT stop; All clock enables low
EMC_DYN_CFG0|=0x00080000; //Buffer enabled for accesses to DCS0 chip
}

Qualquer coisa que eu tente gravar no MODE que é a parte onde se dá o shift no 0x22 não altera o comportamento.

Estou com a impressão de que a SDRAM não está pegando a configuração. Já escrevi valores absurdos ali e nada muda.

Alguem tem idéia do que pode estar acontecendo?
Abuda
Byte
 
Mensagens: 214
Registrado em: 04 Mai 2007 09:38
Localização: SP

Mensagempor Abuda » 25 Ago 2009 19:43

OK pessoal consegui resolver o meu problema que foi descrito acima.

Era uma mistura de problemas. Configuração, mal contatos e curtos.

RESOLVIDO!!!!
Abuda
Byte
 
Mensagens: 214
Registrado em: 04 Mai 2007 09:38
Localização: SP

Mensagempor styg » 10 Dez 2009 14:43

O Abuda, posta o teu código usado na inicialização da memória, e qual o modelo de sdram que ta usando...
Lucas
Avatar do usuário
styg
Word
 
Mensagens: 799
Registrado em: 16 Out 2006 08:24
Localização: Floripa abaixo de zero.

Anterior

Voltar para ARM

Quem está online

Usuários navegando neste fórum: Bing [Bot] e 1 visitante

x