mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik IRQ funktioniert bei LPC2468 nicht!


Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich schreibe an einem Programm, wo ich 2 timer von LPC2468 benutze, der 
Timer 1 sollte einen FIQ auslösen, der die ISR (IRQ) von Timer 2 
unterbricht und seinen Timer Counter zurücksetzt,der FIQ von Timer 1 
funktioniert einwandfrei aber die ISR von Timer 2 wird nicht ausgeführt, 
hat jemand vielleicht eine Idee?

die Init. Routinen von Timer ,FIQ und IRQ sind folgendes:

/************************************************
TIMER 1 und der zugehörigen FIQ :
/************************************************


#include "irq.h" // von Keil

void init_timer1(void)
{

  PCLKSEL0 &= (~(0x3<<4)); //PCLK = CCLK/4

  PINSEL3 |= 0x000C0000;  // set P1.25 to Match 1.1

  T1CTCR = 0;         // Timer mode

  T1PR = 144;         //Load prescaler

  T1TCR = 0x00000002;     //Reset TC and PR
  T1TC  = 0;               //Timer Counter: Set to zero


  T1MR0 = 62500;            // Toggle by TC=MR0 (500ms)

  T1EMR = 0xC2;             //Ext. mach reg. at match1.1
          //and set to toggle P1.25
  T1MR1=62500;             //Interrupt by TC=MR1 (500ms)

  T1MCR=(3<<3)|(1<<1);    //Reset timer on match and generate 
interrupt


  VICIntSelect |= 0x00000020; // Enable a VIC Channel as FIQ
  VICIntEnable |= 0x00000020; // Enable the Timer/counter1 interrupt in 
the VIC*/

}

extern void   FIQ_Handler(void) _attribute_ ((interrupt("")));

void FIQ_Handler(void)
{

  time_ms += 1;  //increment
  T2TC = 0;         //Timer Counter 2: Set to zero

  T1IR  |= 0x02;    // clear interrupt flag  on timer 1

}
/***********************************************************
TIMER 2 und der zugehörigen IRQ:
/***********************************************************
void init_timer2(void)
{

  PCLKSEL1 = (PCLKSEL1 & (~(0x3<<12))) | (0x01 << 12); // PCLK= CCLK = 
72MHz

  FIO0DIR |= 0x01;

  T2CTCR   = 0;         // Timer mode
  T2PR = 7;            //load  the  prescal Register
  T2TCR = 0x00000002;     //Reset TC and PR

  T2TC  = 0;               //Timer Counter: Set to zero

        T2MR0 = 1;             // load MR0 (100ns)


  T2MCR = 0x01;           // generate interrupt when TC = MR0

  install_irq( TIMER2_INT, (void *)timestamp_Handler, HIGHEST_PRIORITY ) 
;

}
/***
extern void    timer2_Handler(void) _attribute_ ((interrupt()));

void timer2_Handler(void)
{
  T2MR0 += 1;    // load MR0 with new value
   /* 100 ns */
  time_ns += 1;

  T2IR |= 0x01;      // clear interrupt flag
  VICVectAddr = 0;  //Acknowledge Interrupt

}

ich bin für jede Anweisung sehr dankbar.

Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich möchte gerne wissen, warum ich hier keine Hilfe bekomme!
und zwar jedesmal.....!!!!!!!!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  install_irq( TIMER2_INT, (void *)timestamp_Handler, HIGHEST_PRIORITY )

timestamp_Handler ist nicht der Name deines Int. Handlers.

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Hatte mit einem anderen LPC ein ähnliches Problem.
Lösung war, dass ich verschachtelte Interrupts erst enablen musste. Von 
sich aus arbeitet der VIC kooperativ, d.h. eine ISR kann nicht 
unterbrochen werden. Schau mal nach der Funktion enableIRQ(), oder so 
ähnlich, findet man hier im Forum oder in diversen Beispielprogrammen.

Gruß
Jansus

Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
soweit ich weiss braucht man einen nested interrupt nur wenn man zwei 
IRQ ausführen muss...oder?

Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
..und ein FIQ Interrupt kann doch einen IRQ unterbrechen ohne einen 
nested interrupt zu insatllieren..

Autor: Urlauber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der FIQ_Handler() braucht auch ein "VICVectAddr = 0;"

Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nach dem FIQ Beispielprogramm vom LPC2300-Buch(Hitex) wird VICVectAddr 
nicht benötigt!
und das ist auch logisch so, weil die FIQ`s vom VIC-Controller zum ARM 
Core nur weitgeleitet werden und nicht verarbeitet..

Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was ich jetzt gerne gewusst hätte ist, ob man einen nested Interrupt 
braucht wenn man FIQ und IRQ gleichzeitig verwendet...
ich wäre sehr dankbar für eine Antwort..

Autor: Urlauber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, Fehler von mir, der FIQ_Handler() braucht KEIN "VICVectAddr = 0;"
War bei mir drinnen hat aber scheinbar nicht gestört ...

FIQ und IRQ hab ich "gleichzeitig" in Betrieb ohne nested.

Was ist mit:
install_irq( TIMER2_INT, (void *)timestamp_Handler, HIGHEST_PRIORITY )

Wo ist hier der "timestamp_Handler", meckert da der Linker nicht ?

Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der startup code hätte ich vielleicht posten müssen:

/*********************************************************************** 
******
 *
 * Project          : lwIP Web
 * Subproject       :
 * Name             : Startarm.s
 * Function         : Initialisation and vector table
 * Designer         : K. Sterckx
 * Creation date    : 22/01/2007
 * Compiler         : GNU ARM
 * Processor        : LPC2368
 * Last update      :
 * Last updated by  :
 * History          :
 *
 ************************************************************************ 
*****
 *
 * See linker script lpc2368_rom.ld for memory map
 *
 ************************************************************************ 
****/


/*********************************************************************** 
******
 *
 * External references
 *
 ************************************************************************ 
****/

/*
 * Located in linker script lpc2368_rom.ld
 */
.extern        _data_beg_src_
.extern        _data_beg_
.extern        _data_end_

.extern        _bss_beg_
.extern        _bss_end_

.extern        _stack_usr_top_
.extern        _stack_scv_top_
.extern        _stack_irq_top_
.extern        _stack_fiq_top_
.extern        _stack_und_top_


/*
 * Located in handlers.c
 */
.extern        Undef_Handler
.extern        SWI_Handler
.extern        PAbt_Handler
.extern        DAbt_Handler
.extern       FIQ_Handler

/*
 * Located in init_cpu.c
 */
.extern        Init_Wait
.extern        Init_Clocks
.extern        Init_MAM
.extern        Init_Pins
.extern        Init_CPU
.extern        Init_Modules
.extern        Exit_Main

/*
 * Located in main.c
 */
.extern        main

/*********************************************************************** 
******
 *
 * Definitions
 *
 ************************************************************************ 
****/

/*
 * Standard definitions for Mode and interrupt bits in PSRs
 */
.equ           Mode_USR,        0x10
.equ           Mode_FIQ,        0x11
.equ           Mode_IRQ,        0x12
.equ           Mode_SVC,        0x13
.equ           Mode_ABT,        0x17
.equ           Mode_UND,        0x1B
.equ           Mode_SYS,        0x1F

.equ           I_Bit,           0x80
.equ           F_Bit,           0x40

/*
 * Definitions for IO registers
 */
.equ           IOPIN0,          0xE0028000
.equ           IODIR0,          0xE0028008

.equ           IOPIN1,          0xE0028010
.equ           IODIR1,          0xE0028018

.equ           IOPIN2,          0x3FFFC054
.equ           IODIR2,          0x3FFFC040

.equ           IOPIN3,          0x3FFFC074
.equ           IODIR3,          0x3FFFC060

.equ           IOPIN4,          0x3FFFC094
.equ           IODIR4,          0x3FFFC080

/*
 * PORT setup values
 */
.equ           IOPIN0_VALUE,    0x00000000
.equ           IODIR0_VALUE,    0xF0000000

.equ           IOPIN1_VALUE,    0x00000000
.equ           IODIR1_VALUE,    0x00000000

.equ           IOPIN2_VALUE,    0x00000000
.equ           IODIR2_VALUE,    0x00000000

.equ           IOPIN3_VALUE,    0x00000000
.equ           IODIR3_VALUE,    0x00000000

.equ           IOPIN4_VALUE,    0x00000000
.equ           IODIR4_VALUE,    0x00000000

/*********************************************************************** 
******
 *
 * Vector table
 *
 ************************************************************************ 
****/

.section .startup,"ax"
.arm
.align 0

_vectors:
              B     _reset_handler
              LDR   PC,Undef_Addr
              LDR   PC,SWI_Addr
              LDR   PC,PAbt_Addr
              LDR   PC,DAbt_Addr
              NOP                             /* Used for Checksum */
              LDR   PC,[PC,#-0x0120]
              LDR   PC,FIQ_Addr

Undef_Addr:   .word   Undef_Handler
SWI_Addr:     .word   SWI_Handler
PAbt_Addr:    .word   PAbt_Handler
DAbt_Addr:    .word   DAbt_Handler
/*FIQ_Addr:     .word   FIQ_Handler*/
FIQ_Addr:    .word   SyncFIQ_Handler


/*********************************************************************** 
******
 *
 * Protection code
 *
 ************************************************************************ 
*****
 *
 * Fill up to PROTECTION_CODE with 0xFF, make sure that PROTECTION_CODE 
is
 *  on correct address.
 *
 * Change code to 0x87654321 to enable protection
 *
 ************************************************************************ 
****/

.org 0x01FC, 0xFF

PROTECTION_CODE:
              .word   0xFFFFFFFF

.size _vectors, . - vectors

/*********************************************************************** 
*****
 *
 * Startup code
 *
 ************************************************************************ 
****/

.org 0x0200
.arm
.global _reset_handler

_reset_handler:
/*
 * Setup ports 0 and 1 in Slow mode
 */
 /*
              LDR    R1,=IOPIN0_VALUE
              LDR    R0,=IOPIN0
              STR    R1,[R0,#0x0]

              LDR    R1,=IODIR0_VALUE
              LDR    R0,=IODIR0
              STR    R1,[R0,#0x0]

              LDR    R1,=IOPIN1_VALUE
              LDR    R0,=IOPIN1
              STR    R1,[R0,#0x0]

              LDR    R1,=IODIR1_VALUE
              LDR    R0,=IODIR1
              STR    R1,[R0,#0x0]
*/
/*
 * Setup ports 2,3 and 4 in Fast mode
 */
/*
              LDR    R1,=IOPIN2_VALUE
              LDR    R0,=IOPIN2
              STR    R1,[R0,#0x0]

              LDR    R1,=IODIR2_VALUE
              LDR    R0,=IODIR2
              STR    R1,[R0,#0x0]

              LDR    R1,=IOPIN3_VALUE
              LDR    R0,=IOPIN3
              STR    R1,[R0,#0x0]

              LDR    R1,=IODIR3_VALUE
              LDR    R0,=IODIR3
              STR    R1,[R0,#0x0]

              LDR    R1,=IOPIN4_VALUE
              LDR    R0,=IOPIN4
              STR    R1,[R0,#0x0]

              LDR    R1,=IODIR4_VALUE
              LDR    R0,=IODIR4
              STR    R1,[R0,#0x0]
*/

/*
 * Wait a moment so that ULink can interrupt use
 *  This is done before the PLL is running, so the
 *  clock is equal to the crystal frequency.
 */

              LDR    R0,=__stack_scv_top__
              MSR    CPSR_c, #Mode_SVC|I_Bit|F_Bit
              MOV    SP,R0

              BL     Init_Wait
              BL     Init_Clocks
              BL     Init_MAM
              BL     Init_Pins

/*
 * Setup stacks
 */

/*         Undefined instruction -> Undefined mode, uses Undefined stack 
*/
              /*LDR   R0,=__stack_und_top__
              MSR   CPSR_c, #Mode_UND|I_Bit|F_Bit
              MOV   SP,R0


/*         Abort (prefetch+data) -> Abort mode, uses Undefined stack 
*/
              MSR    CPSR_c, #Mode_ABT|I_Bit|F_Bit
              MOV    SP,R0

/*         FIQ -> FIQ mode, use FIQ stack 
*/
              LDR    R0,=__stack_fiq_top__
              MSR    CPSR_c, #Mode_FIQ|I_Bit|F_Bit
              MOV    SP,R0


/*         IRQ -> IRQ mode, use IRQ stack 
*/
              LDR    R0,=__stack_irq_top__
              MSR    CPSR_c, #Mode_IRQ|I_Bit|F_Bit
              MOV    SP,R0


/*         Supervisor mode, use supervisor stack 
*/
              LDR    R0,=__stack_scv_top__
              MSR    CPSR_c, #Mode_SVC|I_Bit|F_Bit
              MOV    SP,R0


/*         We keep running in supervisor mode 
*/

/*
 * Initialize .data : Copy from Flash to RAM
 */

              LDR    R1,=__data_beg_src__
              LDR    R2,=__data_beg__
              LDR    R3,=__data_end__
LoopRel:      CMP    R2, R3
              LDRLO  R0, [R1], #4
              STRLO  R0, [R2], #4
              BLO    LoopRel

/*
 * Initialize .bss : Make zero
 */

              MOV    R0, #0
              LDR    R1,=__bss_beg__
              LDR    R2,=__bss_end__
LoopZI:       CMP    R1, R2
              STRLO  R0, [R1], #4
              BLO    LoopZI


/*
 * Initialize CPU
 */
              BL     Init_CPU
              BL     Init_Modules

/*
 * Enable interrupts
 */
              MSR    CPSR_c, #Mode_SVC

/*
 * Jump to main
 */

              BL    main

/*
 * Jump to Exit_Main
 */
              BL    Exit_Main

/*********************************************************************** 
*****
 *
 * Endless loop, normaly never executed
 *
 ************************************************************************ 
****/

endless_loop:
              B     endless_loop

.size _reset_handler, . - _reset_handler


/*********************************************************************** 
*****
 *
 * End marker
 *
 ************************************************************************ 
****/


.end

Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das was einen einen Fehler von mir beim posten:

install_irq( TIMER2_INT, (void *)timer2_Handler, HIGHEST_PRIORITY )

Autor: Nador Rif (rifman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich komme langsam zum Verzweifeln, Leute ich brauche Hilfe..!

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert denn Deine IRQ alleine?
Was macht install_IRQ genau?
Tippe darauf, dass der Fehler im Zusammenhang mit dem VIC zu finden 
ist...

Autor: Nador Rif (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

ja, die IRQ alleine funktioniert, die irq install macht folgendes:

DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority )
{
    DWORD *vect_addr;
    DWORD *vect_prio;

    VICIntEnClr = 1 << IntNumber;  /* Disable Interrupt */
    if ( IntNumber >= VIC_SIZE )
    {
    return ( FALSE );
    }
    else
    {
    /* find first un-assigned VIC address for the handler */
    vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + 
IntNumber*4);
    vect_prio = (DWORD *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + 
IntNumber*4);
    *vect_addr = (DWORD)HandlerAddr;  /* set interrupt vector */
    *vect_prio = Priority;
    VICIntEnable = 1 << IntNumber;  /* Enable Interrupt */
    return( TRUE );
    }
}

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm, die VIC-Einstellung für meinen Timer0 schauen so aus:

VICIntSelect = 0x00;//nur IRQ -hier muss entspr. Deiner FIQ ne 1 wo rein
VICVectCntl0=0x20|4; // 4 = Timer0
VICVectAddr0=(unsigned long)timer0; // name der isr
VICIntEnable = (1<<4);

Bin mir nicht sicher ob das Deine Funktion auch macht...
Hast mal mit nested probiert?

Autor: Robert Teufel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne ganz bloede Frage, bist Du sicher, dass der Timer 2 ueberhaupt 
laeuft? T0 und T1 sind nach Reset naemlich automatisch enabled, es 
koennte allerdings sein, dass man das fuer den T2 selbst machen muss. 
Die aelteren LPC2000 Modelle hatten nur T0 und T1. Alle neuen 
Peripherals des LPC2000 kommen aus Stromspargruenden nicht enabled aus 
dem Reset.

Hab nicht den Code analysiert, ist mir nur so eingefallen.

Robert

Some additional info www.lpc2000.com see "Application Notes" 
compatibility

Autor: Nador Rif (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Robert Teufel:

danke schön das war es!
ich finde es echt schade das es im user manual unter Timer-Kapitel 
nichts darüber steht.

danke nochmal!

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.