Hallo zusammen, habe ein interessantes Problem und wollte wissen, ob ich
vielleicht irgendwo einen Denkfehler gemacht haben.
Zur Hardware:
- ATmega128, ext. Quarz mit 16 MHz
- 74HC373D als Adresslatch
- BS62LV1027S als RAM (ist ein 128K x 8, A16 ist auf Masse gelegt).
Nacheinander ein paar Werte schreiben und anschließend alle zurücklesen
per Bitgewackel (mit deaktiviertem External Memory Interface)
funktioniert problemlos, auch bei 16 MHz und ohne Delays (außer einem
NOP zwischen !RD auf low ziehen und PINA einlesen im Lesezyklus, aber
das liegt ja am Timing der GPIOs bei Atmel). Timing-Probleme halte ich
daher für unwahrscheinlich.
Was ich natürlich eigentlich will, ist, daß sich der AVR um das SRAM
kümmert.
Dafür habe ich eine Testroutine geschrieben. Der Compiler weiß nichts
davon, ich kann also über einen Volatile-Pointer nach Herzenslust im
betreffenden Adressbereich herumstochern.
So nun zu meinem Problem: Versuche ich das, so lese ich nur Müll.
Der Adressbereich, über den ich auf das externe SRAM zugreife, ist doch
ab 0x1100, oder?
Zum Aktivieren des SRAMs verwende ich die folgende Init-Funktion:
1 | void SetAutoSramConfig()
|
2 | {
|
3 | // Externes SRAM durch uC-Hardware verwaltet
|
4 | // (betrifft Ports A, C und G)
|
5 | XMCRA = 0; // Keine Wait states
|
6 | XMCRB = (1 << XMBK); // Bus keeper aktiv, 16-Bittige Adressen
|
7 | MCUCR |= (1 << SRE) | (1 << SRW11) | (1 << SRW10);
|
8 | // SRAM aktivieren, viele Wait states
|
9 | }
|
Mit der folgenden Testfunktion versuche ich erfolglos, 256 Bytes ab
Adresse 0x100 im SRAM zu testen:
1 | void Test_SRAM(char *pErrType, unsigned int *pErrAddr, unsigned char *pErrByte)
|
2 | {
|
3 | volatile unsigned char *pSram = (volatile unsigned char *) 0x1100;
|
4 | volatile unsigned char *pByte;
|
5 | unsigned int i=0;
|
6 | unsigned char b;
|
7 |
|
8 | // Test mit Einsen (0xff)
|
9 | for (pByte=pSram, i=0; i<0x100; i++, pSram++)
|
10 | *pSram = 0xff;
|
11 |
|
12 | for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
|
13 | if ((b = *pSram) != 0xff) {
|
14 | *pErrType = 2;
|
15 | *pErrAddr = i;
|
16 | *pErrByte = b;
|
17 | return;
|
18 | }
|
19 | }
|
20 |
|
21 | // Test mit Nullen
|
22 | for (pByte=pSram, i=0; i<0x100; i++, pSram++)
|
23 | *pSram = 0;
|
24 |
|
25 | for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
|
26 | if ((b = *pSram) != 0) {
|
27 | *pErrType = 1;
|
28 | *pErrAddr = i;
|
29 | *pErrByte = b;
|
30 | return;
|
31 | }
|
32 | }
|
33 |
|
34 |
|
35 | // Test mit Bitmustern
|
36 | for (pByte=pSram, i=0; i<0x100; i++, pSram++)
|
37 | *pSram = (i & 0xff) ^ (i >> 8);
|
38 |
|
39 | for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
|
40 | if ((b = *pSram) != ((i & 0xff) ^ (i >> 8))) {
|
41 | *pErrType = 3;
|
42 | *pErrAddr = i;
|
43 | *pErrByte = b;
|
44 | return;
|
45 | }
|
46 | }
|
47 |
|
48 | *pErrType = 0;
|
49 | *pErrAddr = 0;
|
50 | *pErrByte = 0;
|
51 | }
|
Grüße
Sebastian