mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LPC2103 neue Codebeispiele: Problem Interrupts


Autor: Franz Wudy (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo beisammen,
ich habe mir grad ein Board gebastelt mit einem LPC2103 als Controller 
und habe begonnen einige Code-Beispiele zusammenzubasteln, UART, EA-DOG, 
Fast-I/O etc...

Fast I/O funktioniert schon super, EA-DOG auch schon (stelle ich 
demnächst mal online), nur gibt es ein Problem, will man timing mit 
Timer-Interrupts betreiben. Auch die Interrupts der UART-Schnittstelle 
machen Probleme.

Es folgt ein kurzes Example, das ich zusammengebastelt habe um nicht 
irrsinninge Codemengen einstellen zu müßen, welches die grundlegende 
Problematik vermitteln sollte:

Meine Main.c:
#include "lpc2103.h" // gechecked, laut Datenblatt okay!
#include "main.h"
#include <math.h>
#include "/usr/local/arm/arm-elf/include/sys/string.h"
#include "/usr/local/arm/arm-elf/include/sys/types.h"

# compiled with arm-elf-gcc (GCC) 4.1.0

int main(void)
{
  unsigned int i;  

  sysinit();
  
  // set-up interrupts
  MEMMAP = (1 << 0);              // map interrupt vectors space into FLASH
  VICIntEnClr = 0xFFFFFFFF;          // clear all interrupts
  VICIntSelect = 0x00000000;          // clear all FIQ selections == alles ist trad. IRQ
  VICDefVectAddr = (unsigned long) reset;    // point unvectored IRQs to reset() (aus startup)

  // Timer 2, siehe: http://www.keil.com/forum/docs/thread10347.asp
  T2PR = 0x00000005; //Load prescaler
  T2TCR = 0x00000002; //Reset counter and prescaler
  T2MCR = 0x00000003; //match reset the counter and generate an interrupt
  T2MR0 = 0x00000010; //cycle time
  T2TCR = 0x00000001; //enable timer
  VICVectAddr4 = (unsigned long)ISR; //Set the timer ISR vector address
  VICVectCntl4 = 0x0000003A; //Set channel control
  VICIntEnable |= 0x04000000; //Enable the TIMER2 interrupt

  // FIO
  FIODIR |= 1 << 4; // P0.4 is an output
  while( 1 )
  {
    i++;
  }
}

void __attribute__ ((interrupt("IRQ"))) ISR(void)
{
  FIOCLR = 1 << 4;
  T2IR = 0x00000001;       //Clear match 0 interrupt
  VICVectAddr = 0x00000000;   //Dummy write to signal end of interrupt
  FIOSET = 1 << 4;
}

void sysinit(void)
{
  // PLL Setup
  PLLCFG |=  (1 << 0) | (1 << 5);     // M=1 und P = 1, schon dekrementiert
  // das sollten 40 MHz Bustakt ergeben
  
  // PLL starten
  PLLCON |= (1 << 0);
  PLLFEED = 0xAA;                       // Make it happen.  These two updates
  PLLFEED = 0x55;                       // MUST occur in sequence.
  
  // wait for settling PLL
  while (!(PLLSTAT &  (1 << 10)))
  continue;

  // PLL starten und connectieren
  PLLCON = (1 << 1) | (1 << 0);
  PLLFEED = 0xAA;                       // Make it happen.  These two updates
  PLLFEED = 0x55;                       // MUST occur in sequence.

  // Memory Acceleration
  MAMTIM = 3;  // 3 cycles
  MAMCR = 2; // full acceleration

  // peripheral clock
  APBDIV = 1; // periph clock = processor clock

  // fast GPIO
  SCS = (1 << 0); //enable fast GPIO in System Control Setup

}

Es wird nix großartiges betrieben, sysinit setzt die üblichen parameter 
für die PLL etc.
Nachfolgend werden die Interrupts in den Flash-Bereich gebracht, IRQs 
aktiviert und FIQ's deaktiviert, etc.
Danach wird laut einem KEIL-example Timer2 angeworfen, der in 
regelmäßigen Intervallen den Handler aufrufen sollte.
Das tut er aber nicht!

Oszi: 20 MHz, Clock: 40 MHz
GCC 4.1.0
crt0.S und linker-Skript (ROM) habe ich angehängt, sind aus Beispielen 
zusammenkopiert.

Meine Vermutung: Irgendetwas mit den startup-Skript stimmt nicht. Ich 
kenne mich aber zu wenig aus. Vielleicht kann bitte mal jemand drüber 
sehen, der sich damit besser auskennt.

Ürbigens: Das gleiche Problem mit den IRQ-SR habe ich auch mit dem UART, 
etc... die Routine wird einfach nicht aufgerufen.

Vielleicht weiß ja jemand Rat!

Beste Grüße - Franz

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus dem Startup heraus sind IRQ und FIQ Disable Bits im Statusregister 
des Prozessors gesetzt, d.h. die Interrupts sind gesperrt. Wenn die 
nicht irgendwo mal freigegeben werden kommt natürlich auch keiner durch.

Autor: Franz Wudy (wizzy450)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo PRX,
danke für deine Antwort.
Eine Frage für startup-Anfänger: Woran erkennt man dass die Disable-Bits 
gesperrt sind? Ich will ja was lernen! G
Sind das die Zeilen:
        .equ  I_BIT, 0x80               // when I bit is set, IRQ is disabled
        .equ  F_BIT, 0x40               // when F bit is set, FIQ is disabled
???
Und eine praktische Frage: Wie gebe ich die wieder frei?
Danke - Franz

BTW:
Das hat mir Martin Thomas zurückgeschrieben:

[Zitat]
Dies beachtet? // - Leave in System Mode with Interrupts Disabled und in
Folge das gesetzte I_BIT für sys-mode CPSR.
Sehe zumindest auf Anhieb nicht, wo die IRQs auf Core-Ebene (CPSR des
gewählten run-modes) später freigegeben/aktiviert werden. Wenn
tatsächlich nicht der Fall wird der Handler nie aufgerufen (ist im
Prinzip wie bei den ADuC ARM7 nur das bei LPC2k "danach" noch der VIC
geschaltet ist).
[/Zitat]

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Franz Wudy wrote:

> Sind das die Zeilen:

Jein. Die Bits ja. Die Zeilen sind weiter unten. Gut kommentiert aber.

> Und eine praktische Frage: Wie gebe ich die wieder frei?

Tja - meine eigenen Funktionen für Interrupt-Steuerung habe ich hier 
nicht parat. Wirst ein bischen im Netz suchen müssen. Wobei es etwas 
komplizierter wird wenn du den Thumb Mode verwenden solltest.

Such auch mal in Examples, egal zu welchem ARM Controller. Das ist bei 
allen ARMs gleich.

Auch möglich, ist aber eher unsauber: Im Startup-Code in der 
Initialisierung vom System Mode die beiden Bits rausnehmen. Ist leicht 
zu finden, denke ich.

PS: Martin hat nichts anderes gesagt als ich, nur eben auf geekisch.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.