Перейти к содержанию
    

PIO IRQ на AT91SAM7X

Использую AT91SAM7X - EK и yagarto

Надо повесить джойстик на прерывание.

Перерыл все примеры, сделал как там - все равно не работает.

Инициализация

        
        AT91C_BASE_PIOA->PIO_PER = (0x1F <<21);
        AT91C_BASE_PIOA->PIO_ODR = (0x1F <<21);
        AT91C_BASE_PIOA->PIO_IFER = (0x1F <<21);
        AT91C_BASE_PIOA->PIO_CODR = (0x1F <<21);
        AT91C_BASE_PIOA->PIO_IER = (0x1F <<21);
        AT91C_BASE_PIOA->PIO_MDDR = (0x1F <<21);
        AT91C_BASE_PIOA->PIO_PPUER = (0x1F <<21);
        AT91C_BASE_PIOA->PIO_OWDR = (0x1F <<21);
        //LEDS
        AT91C_BASE_PIOB->PIO_PER = (0xF<<19);
        AT91C_BASE_PIOB->PIO_OER = (0xF<<19);
        AT91C_BASE_PIOB->PIO_IFDR = (0xF<<19);
        AT91C_BASE_PIOB->PIO_SODR = (0xF<<19);
        AT91C_BASE_PIOB->PIO_IDR = (0xF<<19);
        AT91C_BASE_PIOB->PIO_MDDR = (0xF<<19);
        AT91C_BASE_PIOB->PIO_PPUDR = (0xF<<19);
        AT91C_BASE_PIOB->PIO_OWDR = (0xF<<19);
        //interrupts
        AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA;
        AT91F_AIC_ConfigureIt(AT91C_ID_PIOA, BUTT_INT_LEVEL_PRIORITY, AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE, ( void (*)( void ) ) ButtonsISR_Test );
        AT91C_BASE_AIC->AIC_IMR = 1 << AT91C_ID_PIOA;
        AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_PIOA;

 

Обработчик (в отдельном модуле, компилится по ARM)

void __attribute__((interrupt("IRQ"), naked )) ButtonsISR_Test() 
{
    AT91C_BASE_PIOB->PIO_CODR = (0x1<<19);
}

 

Подскажите, может я где-то что-то упустил? заранее спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Использую AT91SAM7X - EK и yagarto

void __attribute__((interrupt("IRQ"), naked )) ButtonsISR_Test()

Совершенно непонятно, зачем вы комбинируете IRQ и naked, они ведь взаимно исключающие. IRQ указывает формировать пролог/эпилог обработчика исключения IRQ, а naked - не формировать пролога/эпилога. Покажите, что у вас находится по вектору 0x18, т.е. каким образом происходит выбор обработчика из AIC.

Не знаю как последняя версия yagarto, но весенняя имела в себе старый-старый баг GCC с прологом/эпилогом функций с атрибутом IRQ (можно поискать по форуму, klen описывал, кажется в теме "Вливаюсь в ряды АРМоводов") - там дважды вычитается 4 из LR. Не видя вашего обработчика на векторе 0x18 трудно советовать что-то еще.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

пардон, что не отвечал - был в отъезде

 

по 0x18 лежит

ldr pc, [pc, #-0xF20]

при этом прерывание от ЕМАС работает

 

 

атрибуты перебирал и naked и interrupt по отдельности - все равно не работает

если неправильные атрибуты, то как я понимаю программа должна умирать, у меня же не заходит в прерывание, а работу продолжает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

        AT91F_AIC_ConfigureIt(AT91C_ID_PIOA, BUTT_INT_LEVEL_PRIORITY, AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE, ( void (*)( void ) ) ButtonsISR_Test );

У AT91F_AIC_ConfigureIt lib_AT91SAM7Xxxx.h на входе 5 параметров. Компилятор должен был бы ругнуться.

 

        AT91C_BASE_AIC->AIC_IMR = 1 << AT91C_ID_PIOA;

Это write-only регистр.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У AT91F_AIC_ConfigureIt lib_AT91SAM7Xxxx.h на входе 5 параметров. Компилятор должен был бы ругнуться.

хм, у меня выглядит так

#define AT91F_AIC_ConfigureIt( irq_id, priority, src_type, newHandler )        \
{                                                                            \
    unsigned int mask;                                                        \
                                                                            \
    mask = 0x1 << irq_id;                                                    \
    /* Disable the interrupt on the interrupt controller */                    \
    AT91C_BASE_AIC->AIC_IDCR = mask;                                        \
    /* Save the interrupt handler routine pointer and the interrupt priority */    \
    AT91C_BASE_AIC->AIC_SVR[irq_id] = (unsigned int) newHandler;            \
    /* Store the Source Mode Register */                                    \
    AT91C_BASE_AIC->AIC_SMR[irq_id] = src_type | priority ;                \
    /* Clear the interrupt on the interrupt controller */                    \
    AT91C_BASE_AIC->AIC_ICCR = mask;                                        \
}

 

 

Это write-only регистр.

ну да, оплошал, но все равно не играет роли

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

AT91F_AIC_ConfigureIt(AT91C_ID_PIOA, BUTT_INT_LEVEL_PRIORITY, AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE, ( void (*)( void ) ) ButtonsISR_Test );

Источник прерывания внутренний, поэтому должно быть AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

странно, вроде раньше перебирал все значения SRCTYPE - не работало, а сейчас заработало, спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...