Atmega 8515 + external SRAM

Witam,

Szlag mnie już trafia. Rzeźbię w domu pierwszy swój przypadek, w którym mam atmegę z zewnętrzną pamięcią.

Pamięć dołączona jak z w dataszicie z latchem 74hc573, tyle że 128x8

70ns ((najstarszy bit adresu do masy narazie, może dołączę kiedyś do którejś nogi i będę stronicował). Całość napędza kwarc 9.216MHz (bo chcę mieć RS dokładny).

Używam avrgcc pod windą. Ustawiam w programie bit SRE. Makefile wygenerowany stosownym narzędziem, z obsługą external SRAM na potrzeby sterty.

No i dzieją się cuda wianki. Próba zaalokowania czegoś większego na stercie powoduje, że program mi się w kółko resetuje z powodu wystepowania nieobsługiwanych przerwań. Przyznam że już mi się nie chce czytać dokładnie dataszita aby zobaczyć co przeoczyłem.

Czy zrobiłem gdzieś jakiś błąd czy muszę się wybrać do zaprzyjaźnionego analizatora stanów i popatrzeć czy bity lecą jak trzeba ;)

TP.

Reply to
Tomasz Piasecki
Loading thread data ...

Tomasz Piasecki napisał(a):

Wywoływanie nieobsługiwanych przerwań to raczej wg mnie nie ma zwiazku z podłaczeniem external ram, raczej z jakims błędem w kodzie.

Spróbuj raczej użyć JTAG'a . Analizator to tylko stany na portach Ci pokaże, a JTAG oprócz tego jeszcze pomoże prześledzić program, bo tam widzę raczej przyczynę.

Reply to
"Miłosz K."

Sun, 13 Nov 2005 23:38:52 +0100, na pl.misc.elektronika, Tomasz Piasecki napisał(a):

Może nie do końca dobrze skonfigurowana sterta - i wjeżdża na stos? Zobacz dla porównania kawałek (działajacego) testu z podobnego układu (at8515 +

32kB) : <code> [..] #define HEAP_START RAMEND+1 #define HEAP_END 0x7fff+RAMEND+1 // w ten sposób wykorzystujemy całą kostkę ram - A15 jest // nieczynny i adresy od 0x8000 są fizycznie traktowane jak od 0

// funkcje : bool CheckRam(void) { bool chkcell; chkcell=true;

uint i,k; k=(uint)HEAP_END+1;

for (i=HEAP_START;i<k;i++) { *((uchar*)i)=0xa5; }

for (i=HEAP_START;i<k;i++) { if (*((uchar*)i) != 0xa5) { chkcell = false; break; } }

for (i=HEAP_START;i<k;i++) { *((uchar*)i)=0x5a; }

for (i=HEAP_START;i<k;i++) { if (*((uchar*)i) != 0x5a) { chkcell = false; break; } } return chkcell; }

void InitExtRam(void) { //ponieważ .data i .bss pozostały w wewnętrznej ram // wystarczy inicjalizacja w programie głównym - bez // wchodzenia w init1 DDRE |= _BV(PE0); // na przystosowanej płytce od 652 // PE0 pozostał połączony z CS ramu i musi byc ustawiony na Low MCUCR |= _BV(SRE); // włączenie interfejsu // na razie nie robimy rozdziału na sektory // i nie wprowadzamy dodatkowych wait-state'ów // przy 8 MHz zwykły 74HC573 powinien jeszcze wystarczyć SFIOR |= _BV(XMBK) | _BV(XMM0); // włączamy podtrzymywanie magistrali danych i wyłączamy najwyższy (A15) // pin adresowania - na płytce nie jest używany }

void InitHeap(void) { // sterta na całą pojemność zewnętrznego ramu 62256 (32k) __malloc_heap_start=(char*)HEAP_START; __malloc_heap_end=(char*)HEAP_END; } //==================== // funkcja main() int main(void) { // inicjalizacja OSCCAL=eeprom_read_byte((uchar*)E2END); // calibration for internal 8 MHz InitHeap(); InitExtRam();

DDRB |= _BV(LED);

//if(CheckRam()) //PORTB |=_BV(LED);

Ptab100 = malloc(100);

*Ptab100 = 10; *(Ptab100 + 99) = 20;

InitT0(); sei(); [..] itd. </code>

Reply to
Jurek Szczesiul

Jurek Szczesiul snipped-for-privacy@wycin.ep.com.pl> napisał(a):

Dzięki za ten kawałek kodu, popatrzę w domu, może coś mi się wyjasni.

Co normalnie robi procek po odwołaniu sie do ramu, który nie istnieje? Wrażenie mam takie, jakby odwołanie do pamięci, która ma być zewnętrzna, maże się po sramie wewnętrznym. A może to stos... Sprawdzę to jeszcze, ale w makefile kazałem tylko stertę w zewnętrznym ramie umieścić.

No nie wiem. W akcie desperacji w makefile wywaliłem obsługę pamięci zewnętrznej, i po prostu w kodzie napisałem, że wskaźnik na mój bufor to jest np. (void*)(0x1000). I dzieje się to samo.

Błędów w samym programie mających wywoływać niechciane przerwania na 100% nie ma. Program narazie nic nie robi, tylko próbuję alokowac bufor, wpisać odpowiednie wartości i wysłać go bajt po bajcie przez usart.

Reply to
Tomasz Piasecki

Tomasz Piasecki przemówił ludzkim głosem:

Patrzyłeś może jak wygląda ten makefile "wygenerowany stosownym narzędziem"? W którym miejscu w ramie zaczyna się sterta, a w którym stos? Bo standardowo początek stosu jest w ostatniej komórce wewnętrznego ramu (stała RAMEND), a początek sterty za ostatnim bajtem segmentu bss, więc dołożenie ramu bez przeniesienia początku sterty nic Ci nie da. W manualu w rozdziale "Tunables for malloc()" jest opisane jak przenieść stertę do zewnętrznego ramu.

The variables malloc heap start and malloc heap end can be used to restrict the malloc() function to a certain memory region. These variables are statically initialized to point to heap start and heap end, respectively, where heap - start is filled in by the linker to point just beyond .bss, and heap end is set to 0 which makes malloc() assume the heap is below the stack. If the heap is going to be moved to external RAM, malloc heap end must be adjusted accordingly. This can either be done at run-time, by writing directly to this variable, or it can be done automatically at link-time, by adjusting the value of the symbol heap end. The following example shows a linker command to relocate the entire .data and .bss segments, and the heap to location 0x1100 in external RAM. The heap will extend up to address 0xffff. avr-gcc ... -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff ...

Reply to
Zbych

No i się wyjasniło. RAM działa dobrze, sterta jest gdzie trzeba. Problem był w czym innym.

Timerem 1 pracującym w CTC odliczam sobie czas. Ustawiam OCR1A jak należy i robię cośtam w przerwaniu TIMER1 COMPA. Nie wiedzieć czemu, wywoływane jest też przerwanie TIMER1 COMPB. A bit OCIE1B w TIMSK mam wyzerowany... :/

Oczywiście nie miałem handlera tego przerwania w związku z czym resetowało mi to w kółko maszynkę.

TP.

Reply to
Tomasz Piasecki

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.