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


von Franz Wudy (Gast)


Angehängte Dateien:

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:
1
#include "lpc2103.h" // gechecked, laut Datenblatt okay!
2
#include "main.h"
3
#include <math.h>
4
#include "/usr/local/arm/arm-elf/include/sys/string.h"
5
#include "/usr/local/arm/arm-elf/include/sys/types.h"
6
7
# compiled with arm-elf-gcc (GCC) 4.1.0
8
9
int main(void)
10
{
11
  unsigned int i;  
12
13
  sysinit();
14
  
15
  // set-up interrupts
16
  MEMMAP = (1 << 0);              // map interrupt vectors space into FLASH
17
  VICIntEnClr = 0xFFFFFFFF;          // clear all interrupts
18
  VICIntSelect = 0x00000000;          // clear all FIQ selections == alles ist trad. IRQ
19
  VICDefVectAddr = (unsigned long) reset;    // point unvectored IRQs to reset() (aus startup)
20
21
  // Timer 2, siehe: http://www.keil.com/forum/docs/thread10347.asp
22
  T2PR = 0x00000005; //Load prescaler
23
  T2TCR = 0x00000002; //Reset counter and prescaler
24
  T2MCR = 0x00000003; //match reset the counter and generate an interrupt
25
  T2MR0 = 0x00000010; //cycle time
26
  T2TCR = 0x00000001; //enable timer
27
  VICVectAddr4 = (unsigned long)ISR; //Set the timer ISR vector address
28
  VICVectCntl4 = 0x0000003A; //Set channel control
29
  VICIntEnable |= 0x04000000; //Enable the TIMER2 interrupt
30
31
  // FIO
32
  FIODIR |= 1 << 4; // P0.4 is an output
33
  while( 1 )
34
  {
35
    i++;
36
  }
37
}
38
39
void __attribute__ ((interrupt("IRQ"))) ISR(void)
40
{
41
  FIOCLR = 1 << 4;
42
  T2IR = 0x00000001;       //Clear match 0 interrupt
43
  VICVectAddr = 0x00000000;   //Dummy write to signal end of interrupt
44
  FIOSET = 1 << 4;
45
}
46
47
void sysinit(void)
48
{
49
  // PLL Setup
50
  PLLCFG |=  (1 << 0) | (1 << 5);     // M=1 und P = 1, schon dekrementiert
51
  // das sollten 40 MHz Bustakt ergeben
52
  
53
  // PLL starten
54
  PLLCON |= (1 << 0);
55
  PLLFEED = 0xAA;                       // Make it happen.  These two updates
56
  PLLFEED = 0x55;                       // MUST occur in sequence.
57
  
58
  // wait for settling PLL
59
  while (!(PLLSTAT &  (1 << 10)))
60
  continue;
61
62
  // PLL starten und connectieren
63
  PLLCON = (1 << 1) | (1 << 0);
64
  PLLFEED = 0xAA;                       // Make it happen.  These two updates
65
  PLLFEED = 0x55;                       // MUST occur in sequence.
66
67
  // Memory Acceleration
68
  MAMTIM = 3;  // 3 cycles
69
  MAMCR = 2; // full acceleration
70
71
  // peripheral clock
72
  APBDIV = 1; // periph clock = processor clock
73
74
  // fast GPIO
75
  SCS = (1 << 0); //enable fast GPIO in System Control Setup
76
77
}
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

von (prx) A. K. (prx)


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.

von Franz W. (wizzy450)


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:
1
        .equ  I_BIT, 0x80               // when I bit is set, IRQ is disabled
2
        .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]

von (prx) A. K. (prx)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.