Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Прекъсвания при LPC ARM7
http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=4700
Страница 1 от 1

Автор:  Quadro [ Нед Авг 26, 2007 5:06 pm ]
Заглавие:  Прекъсвания при LPC ARM7

Тормозя се тук от известно време с прекъсванията при LPC2148 ( olimex dev board ).
Използвам Eclipse + GNU tools, засега всичко е от flash-a.

Кода :

Код:
void IRQ_Routine (void)   __attribute__ ((interrupt("IRQ")));
void FIQ_Routine (void)   __attribute__ ((interrupt("FIQ")));

        MEMMAP = 0x1; <- ексепшъна сочи в flash-a

        PINSEL0 |= 0x80000000; <- PIN 0.15 като EINT2 ( явява се бутон1 на платката )

   EXTMODE = 0x04;    <- разрешаване на interrupt за EINT2 при падащ фронт на входа
   EXTINT = 0x04;
   EXTPOLAR = 0x00;
   
   VICIntSelect = 0x00010000;  <- избира се EINT2
   VICIntEnable = 0x00010000;  <- enable на EINT2 interrupt
   VICVectCntl0 = 0x20 | 16;  <-  EINT2 Interrupt [това не ми е много ясно]
   VICVectAddr0 = (unsigned long)IRQ_Routine;



После функцията за interrupt :
Код:
void IRQ_Routine (void)
{
   
        светва светодиоди,активира зумера
   EXTINT = 0x04; <- би трябвало да изчиства флага за EINT2
   VICVectAddr = 0; // Acknowledge Interrupt
}


При така написаният код не тръгват нещата...няма значение дали натискам бутона, "зададен" за EINT2 входа или не,няма никаква реакция от арм-а.

От къде може да е проблема - нямам идея...четох pdf-на за прекъсванията,процедурата там е същата с изключение на EXTxxx дефинирането - май така или иначе при инициализация по default за falling edge,edge sensitive.

Ако някои може да помогне...

Автор:  Zdrav [ Нед Авг 26, 2007 8:25 pm ]
Заглавие:  Re: Прекъсвания при LPC ARM7

Ето тук конфигурираш VIC да предизвиква FIQ.
Quadro написа:
VICIntSelect = 0x00010000; <- избира се EINT2

Така че не очаквай да се изпълни обработчика на IRQ. Който си конфигурирал иначе правилно.
Махни горния ред и нещата ще тръгнат.
Аз лично обаче бих направил конфигурирането така:
Код:
void IRQ_Routine (void)   __attribute__ ((interrupt("IRQ")));

MEMMAP = 0x01; // таблицата с ексепшън векторите е във flash-a
VICIntEnClr = (1<<16);  // за всеки случай
       
EXTMODE = 0x04;    // конфигуриране на interrupt за EINT2 при падащ фронт
EXTPOLAR = 0x00;
PINSEL0 = (PINSEL0 & ~(0х03<<30)) | (0х02<<30);  // P0.15 като EINT2 ( явява се бутон1 на платката )
EXTINT = 0x04;  // изчистваме евентуален лъжлив интеръпт заради сетването на PINSEL0

VICVectAddr0 = (unsigned long)IRQ_Routine;
VICVectCntl0 = 0x20 | 16;  //  Активираме канал 0 към източник #16(EINT2)
VICIntEnable = (1<<16);  // enable на EINT2 interrupt

Разбира се очаква се да имаш на адрес 0х00000018 ето това:
Код:
ldr     pc, [pc, #-0xFF0]

И във startup в обработчика на ресет вектора да си конфигурирал правилно стековия указател за IRQ режима. И да е свален бит 7 в CPSR, с което разрешаваш глобално IRQ сигнала към ядрото, преди извикване на main.
Ако пък целта ти е да предизвикаш FIQ там вече е друга история.

[EDIT] Оправена моя грешка в сетването на PINSEL0.

Автор:  Quadro [ Нед Авг 26, 2007 11:42 pm ]
Заглавие: 

пробвах с моят код,но променен - няма успех.
Пробвах с посоченият от Zdrav - отново без успех.

В crt.s относно коментарите на Zdrav имам :
Код:
.set  IRQ_STACK_SIZE, 0X00000080
...
ldr     PC, [PC,#-0xFF0]



Което би трябвало да отговаря на изискванията.

Прикачам целият crt.s под формата на тхт,ако някои има желание да го прегледа за евентуални грешки.
Четох из yahoo групите,би трябвало с тези стойности да се активират прекъсванията. Но не мога да разбера аз ли бъркам някъде или...

Прикачени файлове:
crt.txt [4.39 KiB]
137 пъти

Автор:  Zdrav [ Пон Авг 27, 2007 12:11 am ]
Заглавие: 

Първо да посоча че бях допуснал грешка в кода който постнах. Надявам се да си направил copy-paste след като я оправих.
Второ в startup файла който ползваш се извиква main с вдигнат I bit в CPSR. Т.е. прекъсванията ти са забранени глобално. Освен ако в main някъде в началото не го сваляш. Махни редовете:
Код:
msr   CPSR_c, #MODE_SYS|I_BIT|F_BIT    /* User Mode */
mov   sp, r0

И добави непосредствено преди "b main" това:
Код:
/******************************************************************************/
/* Enable interrupts, enter supervisor mode and branch to start of 'C' code */
    msr     cpsr_c, #0x13       /* I=0 F=0 T=0 MODE=supervisor */

Твоят startup те оставя в user mode. Като за начало ползвай supervisor mode.

.set IRQ_STACK_SIZE, 0X00000080
Може да се окаже малко в един момент.

И нещо което е препоръчително - добави си обработчик на Default вектора.
Преди "b main"
Добавяш:
Код:
/******************************************************************************/
/* Configure Default Vector Address to point to the safety trap */
    ldr     r0, =VICDefVectAddr
    ldr     r1, =do_DefaultIRQ
    str     r1, [r0]

И някъде след "b main" самия обработчик:
Код:
/******************************************************************************   
/*      Default ISR
/*      Provided to handle situations when VIC fails to determine
/*      the correct source of IRQ and reads the value of VICDefVectAddr
/*      as vector to ISR. 
/*****************************************************************************/
.arm
.text
.global     do_DefaultIRQ 
.func       do_DefaultIRQ

do_DefaultIRQ:                     
                                           
                                         
    stmfd   sp!, {r11}
    ldr     r11, =VICVectAddr
    str     r11, [r11]
    ldmfd   sp!, {r11}
    subs    pc, lr, #4
/******************************************************************************   
/*                        End of Default ISR
******************************************************************************/   
.size   do_DefaultIRQ,.-do_DefaultIRQ;                                             
.endfunc                                                                         
/*****************************************************************************/

разбира се в началото на crt.s трябва да имаш и:
Код:
.equ        VICDefVectAddr,         0xFFFFF034         
.equ        VICVectAddr,            0xFFFFF030

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/