Sida 1 av 1
Problem: ATMega162 + externt ram
Postat: 13 februari 2006, 14:18:31
av frejo
Tja
Har suttit och slittit mitt hår i en vecka nu pga av ett problem som jag inte verkar kunna få rätsida på... så nu är det dags att be om lite hjälp.
Har en uppkoppling som syns på bilden nertill, till vänster en ATMega162V, i mitten en latch ( 74AC573 ) och till höger ett non-volatile minne med realtidsklocka, ( DS1646-120 )
Minnet är på 128K och AVR:n kan bara adressera 64K på den externa adressbussen, därför har jag kopplat A16 till VCC, då jag vill komma åt realtidsklockan som ligger på 1FFF8-1FFFF, vilket jag borde komma åt genom att sända ut FFF8-FFFF i och med att A16 alltid är etta, eller?
Jag får det dock inte att fungera helt. Har gjort en ramtestfunktion och skriver ut lite debug-info på en LCD, jag får 105 bytes som är felaktiga och drygt 60K som är ok.
Har sen felsökt vidare och de adresser som det blir fel på (sett från mikrokontrollerns adressbuss) är:
EFFF-EFF9
DFFF-DFF9
CFFF-CFF9
BFFF-BFF9
AFFF-AFF9
9FFF-9FF9
osv. osv.
Det känns kusligt likt de platser som är reserverade för realtidsklockan... har jag kopplat något fel?
Postat: 13 februari 2006, 16:36:09
av Porto
Om du kopplar A16 till gnd fungerar det bättre då?
Du kan ju prova att göra ett litet program som sätter en utgång i taget på portarna PA(0..7) & PC(0..7). Samt att hålla Latchen U1 öppen hela tiden för att se om signalerna kommer fram med rätt nivåer till RAMet. (om flera utgångar ligger ihop så lär ju spänningen bli ganska låg om man bara har en utgång hög i taget)
Sedan, hur gör du minnestestet?, skriver du en byte i taget och sedan läser tillbaka den?
Om du fyller hela minnet först med data, uträknat enligt någon formel och sedan efteråt läser tillbaka det hela och jämför med samma formel, så att du upptäcker om minnet är överlappat någonstans (pga att någon adresslinje inte fungerar som den ska). Samt att sedan även invertera datat i minnet och testa igen.
Vad har du för klockfrekvens på det hela?, hinner minnet med?
Du råkar inte ha någon JTAG eller dyligt inkopplat som stör de översta adressbitarna?
Postat: 13 februari 2006, 16:37:44
av exile
Har du tänkt på att nedersta address platserna är reserverade för I/O pinnar med mera
Var på du inte kan addresera 64k utan lite mindre
Tänk även på att interna ramminet används istället för det externa ram minet när de är på internas ram minets addreser....
Vet att jag skriver som en kratta men jag hoppas du förstår vad jag menar...

Postat: 13 februari 2006, 17:23:32
av frejo
Att koppla A16 till gnd blir jobbigt då det sitter på ett kretskort.
Testet funkar som så att jag skriver ett visst värde till alla adresserna 0x0500-0xfff8, och sen läser tillbaka och kollar ifall värdet är samma som jag skrev.
vad jag förstått är det interna minnet från 0x0000-0x04ff.
Har inte fixat med linkerscript för avr-gcc utan kör istället med en pekare som hela tiden inkrementeras då jag bara behöver lagra och hämta hela minnet åt gången.
testfunktionen:
Kod: Markera allt
void testRam()
{
uint16_t adr;
uint16_t error,correct,err1,err2,err3,err4, err5,err6,upperlim;
err1=0;
err2=0;
err3=0;
err4=0;
err5=0;
err6=0;
uint8_t test;
error = 0;
correct = 0;
upperlim = 0xfff8;
printString("Testing RAM",1);
for(adr=0x0500;adr<upperlim;adr++)
{
ram = (void *) (adr);
*(ram)=0b00100110;
}
for(adr=0x0500;adr<upperlim;adr++)
{
ram = (void *) (adr);
test= *(ram);
if(test==0b00100110)
{
correct++;
}
else
{
error++;
err6 = err5;
err5 = err4;
err4 = err3;
err3 = err2;
err2 = err1;
err1 = adr;
}
}
}
och init funktionen för det externa minnet:
Kod: Markera allt
void initExternalMem()
{
MCUCR = _BV(SRE) | _BV(SRW10);
EMCUCR = _BV(SRW11);
//SFIOR =
}
errX variablerna är för att lagra positionen för de 6 senaste felen...
Postat: 13 februari 2006, 18:01:21
av Porto
Då är det väl bara att ta fram kniven och börja karva runt A16, eller ta lös hela kapseln. Om du har samma värde som du skriver & läser till alla adresser så ser du inte om det hamnar på den tänkta adressen i minnet. Om du istället fyller hela minnet med data enligt någon formel som kan upprepa resultatet vid läsning så ser du om datat har blivit överskrivet, pga att adresseringen inte fungerar som den ska. (om du sedan ska kolla på bit-nivå så får du även invertera alla data i minnet och köra en test igen, samt upprepa alltihop med en annan formel)
Postat: 13 februari 2006, 19:38:41
av exile
Nu när jag får se hur felet ser ut.... Du har inte disabla jtagen....
Testa följande..
Kod: Markera allt
void testRam()
{
uint16_t adr;
uint16_t error,correct,err1,err2,err3,err4, err5,err6,upperlim;
err1=0;
err2=0;
err3=0;
err4=0;
err5=0;
err6=0;
uint8_t test;
error = 0;
correct = 0;
upperlim = 0xfff8;
printString("Testing RAM",1);
for(adr=0x0500;adr<upperlim;adr++)
{
ram = (void *) (adr);
*(ram)=adr>>12;
}
for(adr=0x0500;adr<upperlim;adr++)
{
ram = (void *) (adr);
test= *(ram);
if(test==(adr>>12))
{
correct++;
}
else
{
error++;
err6 = err5;
err5 = err4;
err4 = err3;
err3 = err2;
err2 = err1;
err1 = adr;
}
}
}
Om du får mycket fel typ 60k så är det garanterat att du har glömt disa jtag (är på defalt)
Postat: 14 februari 2006, 00:18:20
av frejo
suck!
lär mig aldrig när en fuse är programmerad eller ej... fippla lite med jtag:en i början när jag hade andra fel...
provade nu att ändra den fusen och vipps så har jag 0 adresser med errors med min simpla testmetod.
tack!
synd bara att man suttit och lagt ner tid på något så simpelt och vanligt fel, känner sig nästan lite dum
0 errors!
64248 bytes OK!
Postat: 14 februari 2006, 08:20:45
av exile
Jag håller med fusebitarna är ett mörker i bland, men det är ju tur att det var så pass enkelt fel
