Nauka ARMów - przerwania (na LPC2378)

Witam!!

Tak, to kolejne pytnie pod tytułem "coś nie działa", ale tym razem będzie chyba trochę prościej - bo przerwanie DZIAŁA, jeśli wykorzystuję je jako szybkie (FIQ), a w wersji normalnej (IRQ) nie działa - procesor się resetuje.... Pomijając zbędne fragmenty wkleiłem kod poniżej... jeśli w komentarzach są jakiś instrukcje, to znaczy, że są one dla trybu FIQ... po zastąpieniu instrukcji tymi z komentarza program zaczyna działać ;)...

PINSEL4 &= ~(3<<26); PINSEL4 |= (1<<26); EXTMODE |= 0x08; EXTPOLAR &= ~0x08; EXTINT = 0x08; VICIntSelect = 0; // VICIntSelect = 1<<EINT3_INT; VICVectAddr17 = (unsigned int) FIQ_Routine; VICVectCntl17 = LOWEST_PRIORITY; VICIntEnable = 1<<EINT3_INT;

enable_irq(); // enable_fiq();

// endless loop to toggle the red LED P0.1 while (1) { FIO0SET = 1; Waitms (250); FIO0CLR = 1; Waitms (250); } }

void IRQ_Routine (void) { short k; for (k=0;k<5;k++) { FIO0SET = 1; Waitms (75); FIO0CLR = 1; Waitms (75); } EXTINT = 0x08; VICVectAddr = 0; }

void FIQ_Routine (void) { short i; for (i=0;i<5;i++) { FIO0SET = 1; Waitms (75); FIO0CLR = 1; Waitms (75); } EXTINT = 0x08; }

Pewnie robię jakiś głupi błąd albo coś... bo zarówno program jak i procedura obsługi przerwania muszą być poprawne (skoro w trybie FIQ działa). Stos dla IRQ i FIQ oczywiście zdeklarowany, w obu przypadkach na 128 bajtów... Nie wiem, co jeszcze może być źle... uczę się tego dopiero i coś kiepsko mi to idzie :(... Mam książkę do LPCków, ale tam są te starsze modele, w których jest 16 kanałów przerwania i 32 źródła przerwania, tam się przypisuje danemu kanałowi numer przerwania itp... sprawdzałem - taką metodą też nie działa ;)....

Pozdrawiam Konoppo

Reply to
Konop
Loading thread data ...

Fiq są w obsłudze banalne tylko jeden wektor obsługi - dlatego działa. Natomiast jeżeli irq resetuje program to znaczy, że masz niewłaściwie ustawiony wektor w VIC, nie wnikając w kod i nie mając debugera wpisałbym adres obsługi pod wszystkie innych VICVectAddr. Potem metodą Macajewa dochodzić który wektor jest właściwie obsługiwany i dlaczego.

Mister

Reply to
Mister

Mister pisze:

Sam na to nieco później wpadłem i wpisałem pod wszystkie (od 0 do 31), w tym ARMie chyba nie ma "domyslnego" adresu dla niewektoryzyowanych przerwań... I dalej resetował... na 100% jest to związane z obsługą przerwania, bo np. zablokowanie przerwań albo tego konkretnego przerwania powoduje, że wszystko jest OK (czyli nie to, że ten przycisk mi coś zwiera, albo że przez pomyłkę podpiąłem go do resetu ;P)... . Na pewno też program NIE WCHODZI w procedurę obsługi przerwania, bo jest ona tak napisana (w celach testowych), że zawiera opóźnienia, łącznie na prawie sekundę - więc bym zobaczył, że wszedł i np. przy wyjściu reset... Główne pytanie - czy dobrze wpisuję ten adres?? VICVectAddr17 = (unsigned int) nazwa_funkcji_obsługującej_przerwanie; albo VICVectAddr17 = (unsigned long) nazwa_funkcji_obsługującej_przerwanie;

Bo może gdzieś tu jest błąd??

Pozdrawiam Konoppo

Reply to
Konop

Ja siedze na 2138 wiec troche starszy ale niby tez arm7tdmi, wiec jest domyslny adres, jak cos jest nie tak to bierze z VICDefVectAddr

A co masz w kodzie inicjujacym procesor (asm'owym) w miejscu wektora IRQ ? W 2138 jest: _vectors: ldr PC, Reset_Addr ldr PC, Undef_Addr ldr PC, SWI_Addr ldr PC, PAbt_Addr ldr PC, DAbt_Addr nop /* Reserved Vector (holds Philips ISP checksum) */ ldr PC, [PC,#-0xFF0] /* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin */ ldr PC, FIQ_Addr

Moze nie masz tego -0xFF0 albo dla 2378 jest cos innego wymagane.

Jeszcze pytanie co to jest:

U mnie wyglada to tak VICVectCntl9 = BIT5 | 0x0000000F ; // Wlacz Vectored i zrodlo ustaw na EINT1 (bo EINT1 to nr 15 czyli 0x0F)

Reply to
invalid unparseable

No ale niestety, chyba VIC się nieco różni :(... mam książkę Lucjana Bryndzy o LPC2000 - tam też piszą o tym VICDefVectAddr, ale niestety, takiego w 2378 nie ma - nie widzę go ani w pliku LPC23xx.h, ani w dokumentacji do LPC... Różnice są też inne, o nich później.

Mam to -0xFF0, plik jest dla 23xx, ale sprawdzę, czy ta wartość jest poprawna, bo w sumie założyłem, że to jest dobrze... poszukam :)...

No tu jest właśnie kolejna różnica ;)... chodzi o to, że w prockach 23xx zrezygnowali z 16 slotów dla 32 przerwań - masz 32 sloty, do których "na sztywno" przypisane są określone przerwania, dlatego rejestr VICVectCntl to tak naprawdę VICVectPriority i wpisuje się tam po porstu priorytet danego przerwania... tak przynajmniej ja to rozumiem ;)...

Jakby co, opis tych rejestrów masz w tym PDFie w rozdziale 7, punkt 4: (UWAGA! Ponad 4MB!!)

formatting link
I tu jest ten problem - jest to nowy typ tych przerwań, a opisy wszędzie są do starego typu :(....

Pozdrawiam Konoppo

Reply to
Konop

BINGO!!! To tu był błąd!! :)... w dotychczasowych LPC'kach VICVectAddr był pod adresem FFFF F030h, więc skok realizowała instrukcja LDR PC,[PC,#0xFF0] :)... i wszystko śmigało :)... w LPC23xx rejesetr VICVectAddr mamy pod adresem FFFF FF00, więc tego LDRa, trzeba napisać tak: LDR PC,[PC,#0x120] i też działa dobrze!! :)... Nie czaję tyko, czemu w pliku startowym (dostarczonym przez OLIMEXa do płytki!!!!) nie było to zmienione :/... no ale cóż, bywa :)... Dzięki wielkie za nakierowanie mnie na ten błąd!! :)....

Pozdrawiam Konop

Reply to
Konop

bo tam nie wszystko działa niestety....

Pozdrawiam Janusz Brela

Reply to
Janusz Brela

DLA POTOMNYCH: Ma być oczywiście odpowiednio tak: LDR PC,[PC,#-0xFF0] LDR PC,[PC,#-0x120]

Reply to
Konop

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.