Отговори на тема  [ 4 мнения ] 
Прекъсвания при LPC ARM7 
Автор Съобщение
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Окт 31, 2004 3:42 pm
Мнения: 175
Мнение Прекъсвания при 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.

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


Нед Авг 26, 2007 5:06 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 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.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Нед Авг 26, 2007 8:25 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Окт 31, 2004 3:42 pm
Мнения: 175
Мнение 
пробвах с моят код,но променен - няма успех.
Пробвах с посоченият от Zdrav - отново без успех.

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



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

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


Прикачени файлове:
crt.txt [4.39 KiB]
136 пъти
Нед Авг 26, 2007 11:42 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Първо да посоча че бях допуснал грешка в кода който постнах. Надявам се да си направил 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

_________________
Най-опасният враг на истината и свободата е мнозинството.


Пон Авг 27, 2007 12:11 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 4 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни