Datum: 08.04.2008 09:30
Moin, ich versuche gerade meinen AT91-Sam7EX256 dazu zu bringen eine bestimmte Funktion auszuführen, wenn an einem Pin (PA29) vom PioB ein Flankenwechsel von Low auf High bzw. umgekehrt eintritt. Da der Flankenwechsel evtl. sehr schnell auftritt würde ich das gerne mit dem FIQ machen, versuche mich aber erstmal am normalen IRQ. Nur leider klappts net. Der Prozi bleibt in der ISR hängen und kommt nicht wieder raus. Habe schon den ganzen Vormittag nach HowTo's oder Code-Exampeln gesucht, welche aber alle nur über den Timer Counter reden - bring mir aber nix. Ich brauch ja den Externen Interrupt. Mein Code sieht gerade so aus:
void initISR(void){ *AT91C_PMC_PCER = (1 << AT91C_ID_PIOA) | /* Enable Clock for PIO */ (1 << AT91C_ID_IRQ0); /* Enable Clock for IRQ */ //First disable IRQ for PIOA AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_PIOA; //Save interrupt handler routine vector AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA] = (unsigned int)ISR_Test; //Store in Source Mode Register, set priority AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA] = AT91C_AIC_SRCTYPE_POSITIVE_EDGE | AT91C_AIC_PRIOR_HIGHEST; //Enable den Interrupt für Pin29 AT91C_BASE_PIOA->PIO_IER = (AT91C_PIO_PA29); //Re-enable the interrupt AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_PIOA); } |
Die Aufgerufene Funktion ISR_Test() enthält lediglich eine Debug ausgabe für ein FTDI Kabel (bisher). Die Funktion wird aufgerufen sobald die initISR(); Funktion aufgerufen wird - allerdings nur einmal. Also nicht wiederholt. Fehlt mir in der ISR sowas wie eine Rücksprungadresse? Register Sichern? Macht der ARM das nicht selbst? Ich übernehm jetzt mal keine Garantie das alles was da oben steht auch wichtig ist - eigentlich bin ich ja mehr HighLevel... Vielleicht hat ja jemand von euch ein Codebeispiel für eine ISR mit externem Interrupt (also ein von einem PIN) Regards, Kalle
Datum: 11.04.2008 13:54
schau mal diesen SAM7... code an (läuft auf S.., XC.. & SE..) -
vielleicht hilft er dir, auch wenn die org. Register-definition nicht
verwendet wird.
INIT
-----
AT91S_PIO_PER = AT91S_SPI_CD_pin; // enable GPIO of CD
AT91S_PIO_ODR = AT91S_SPI_CD_pin; // output disable CD
AT91S_PIO_OWDR = AT91S_SPI_CD_pin; // write disable CD
AT91S_PIO_PUER = AT91S_SPI_CD_pin; // pullup enable CD
AT91S_PMC_PCER = (1 << AT91S_ID_PIO); // enable clock on
PIO-interface A for reading
AT91S_AIC_IDCR = (1 << AT91S_ID_PIO); // disable the
interrupt on the interrupt controller
AT91S_PIO_IFER = AT91S_SPI_CD_pin;
AT91S_PIO_IER = AT91S_SPI_CD_pin;
AT91S_PIO_IMR = AT91S_SPI_CD_pin;
AT91S_AIC_SVR->s[AT91S_ID_PIO] = (U32)(FFSPort_MMC_ISR);// Save the
interrupt handler routine pointer and the interrupt priority
AT91S_AIC_SMR->s[AT91S_ID_PIO] =
AT91S_AIC_SRCTYPE_INT_HIGHLEVEL_SENSITIVE | PIOPort_INT_PRIO; // Store
the Source Mode Register
AT91S_AIC_ICCR = (1 << AT91S_ID_PIO); // Clear the interrupt
on the interrupt controller
AT91S_AIC_IECR = (1 << AT91S_ID_PIO); // Enable the
interrupt on the interrupt controller
ISR
------
void FFSPort_MMC_ISR(void)
{
if(AT91S_PIO_ISR & AT91S_SPI_CD_pin) {
if(AT91S_PIO_PDSR & AT91S_SPI_CD_pin) // card-lost or
card-inserted
FFSPort_MMC_CDi = 1; // remember a
lost-card interrupt
}
#ifndef _IAR_SYSTEMS_ICC_
AT91S_AIC_EOICR = 0; // End-of-Interrupt
#endif
}
Datum: 14.04.2008 11:08
Hiho. Danke. Ich war schon ein wenig weitergekommen. Aber über ein Problem bin ich noch nicht weggekommen: Selbst wenn ich die "initISR" Funktion wieder aufrufe, wird der Interrupt nur einmal ausgeführt - also um nochmal in die ISR zu springen muss ich die CPU resetten. Was muss ich wo wieder auf null drehen damit der Interrupt wieder freigeschaltet ist? MFG Kalle
Datum: 08.05.2008 10:37
Habe ein ähnliches Problem (siehe Beitrag "Externer Interrupt auf AT91SAM7X-EK mit Eclipse" ) Bei mir wird der Interrupt zur Zeit offenbar einmal mit initISR() aufgerufen und verbleibt dann darin ohne je in's Hauptprogramm zu gelangen. Irgendwo im Internet muß es doch ein Beispiel für einen externen Interrupt geben oder hier jemanden, der sowas schon mal gemacht hat!? (Oder wenigstens ein Tutorial außer dem Datenblatt, das aufzeigt, welche Register man alle wie setzen muß) !!?? P.S. Am Ende der ISR soll wohl AIC_EOICR gecleart werden um aus dem IR wieder herauszukommen (aber was noch?): void ex_int_handler (void) { volatile unsigned int dummy; dummy = AT91C_BASE_PIOA->PIO_ISR; ... AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_TC0->TC_SR;/* Interrupt Ack*/ AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0);/* Interrupt Ack*/ *AT91C_AIC_EOICR = 0;/* End of Interrupt*/ //bzw.: AT91C_BASE_AIC->AIC_EOICR = 0; }
Datum: 09.05.2008 14:28
Weiß inzwischen woran es liegt (an ethernut; brauche ich leider wegen tcpip) kann es aber auch nicht "reparieren". Ohne ethernut läuft bei mir folgendes Testprogramm:
void ex_int_handler (void) { volatile unsigned int ulDummy; AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_ICCR = 0x04000000; AT91C_BASE_PIOB->PIO_CODR=AT91C_PIO_PB19; // LED1 im Interrupt zum Test anmachen asm("mrs r7,CPSR"); asm("bic r7,r7,#0x80"); asm("msr CPSR,r7"); AT91C_BASE_AIC->AIC_IECR = 0x04000000; AT91C_BASE_AIC->AIC_IVR = 0x0; AT91C_BASE_AIC->AIC_EOICR = 0x0; ulDummy = AT91C_BASE_PITC->PITC_PIVR; AT91C_BASE_AIC->AIC_EOICR = ulDummy; } |
und in
main(){
...
AT91C_BASE_PIOA->PIO_PER=INTTAST;
AT91C_BASE_PIOA->PIO_ODR =INTTAST;
AT91C_BASE_PIOA->PIO_CODR=INTTAST;
AT91C_BASE_PIOA->PIO_PPUER=INTTAST;
AT91C_BASE_PIOA->PIO_ASR=INTTAST;
AT91C_BASE_PIOA->PIO_OWDR=INTTAST;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA]=AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | 0;
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA]=(unsigned int)ex_int_handler;
AT91C_BASE_PIOA->PIO_IFER=INTTAST;
int io_status = AT91C_BASE_PIOA->PIO_ISR;
AT91C_BASE_AIC->AIC_IECR=(1 << AT91C_ID_PIOA);
AT91C_BASE_PIOA->PIO_IER=INTTAST;
...
while(1){
... // hier LED2 blinken lassen
}
|
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel