Balaganoff 0 17 сентября, 2008 Опубликовано 17 сентября, 2008 · Жалоба Помогите разобраться, что не так. Хочу разобраться с прерываниями по изменению уровня на PIOA, прерывание должно наступать по нажатию джойстика. Код брал из примера,немного переработав для удобства. Не входит в прерывание и все тут. void main (void) { AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ); AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK ); AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_MASK ); AT91F_PIO_CfgInput(AT91C_BASE_PIOA, SW3_MASK | SW4_MASK); AT91F_AIC_ConfigureIt ( pAic, AT91C_ID_PIOA, PIO_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, pio_c_irq_handler); AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA,SW4_MASK); //* set the interrupt by software AT91F_AIC_EnableIt (pAic, AT91C_ID_PIOA); for (;;) {} } // обработчик void pio_c_irq_handler ( void ) { int dummy; count_int_pio++; AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED2); delay_t (2000000); AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED2); delay_t (2000000); dummy =AT91C_BASE_PIOA->PIO_ISR; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 17 сентября, 2008 Опубликовано 17 сентября, 2008 · Жалоба // обработчик Это не весь обработчик. Показывайте, что сидит на векторе исключения, как осуществляется переход по адрусу из контроллера прерываний. Используете ли отладчик? Если да - не открыто ли окно с регистрами контроллера прерываний? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dlwest 0 18 сентября, 2008 Опубликовано 18 сентября, 2008 (изменено) · Жалоба можно просмотреть ассемблерный обработчик, начиная с IRQ_Handler_Entry; внешние резисторные подтяжки могут оказаться не лишними; AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL иногда помогает заменить на AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE (по причинам, до конца мне не ясным:)); + сбрасывать флаги прерываний в периферии и AIC надежней вручную; кроме того, бит PIO_ISR устанавливается (и генерит прерывание по & с PIO_IMR) на каждый фронт; компилятор может выкинуть последнюю строчку из хэндлера, вычитывающую PIO_ISR при "оптимизации" Изменено 18 сентября, 2008 пользователем VSt& Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 18 сентября, 2008 Опубликовано 18 сентября, 2008 · Жалоба AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL иногда помогает заменить на AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE (по причинам, до конца мне не ясным:)); Дык Вы бы уяснили для себя причины, прежде чем советы давать. Работать по фронту с внутренними источниками весьма черевато. кроме того, бит PIO_ISR устанавливается (и генерит прерывание по & с PIO_IMR) на каждый фронт; компилятор может выкинуть последнюю строчку из хэндлера, вычитывающую PIO_ISR при "оптимизации" Не может, ибо это volatile. Но можно просто написать AT91C_BASE_PIOA->PIO_ISR, без всяких dummy. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Balaganoff 0 18 сентября, 2008 Опубликовано 18 сентября, 2008 · Жалоба Не сердитесь, если что не так, я хочу разобраться. Использую JTAG SAM-ICE Segger + кит на AT91SAM7A3 + IAR 4.42A . Окно с регистрами контроллера прерываний было, открыто,закрыл, все равно... Флаги прерываний AIC и PIO сбросил вручную. менял AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL на AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE . Все тоже. Объясните,пожалуйста,как все это происходит Я не назначаю вручную адресс обработчика прерывания.Я так понимаю это должно делаеться автоматически. При возникновении прерывания от PIO,если оно разрешено, автоматом читается вектор прерывания AIC_IVR и возвращается значение адресса обработчика соответсвующего прерывания, который должен сидеть AIC_SVR[AT91C_ID_PIOA] для прерывания от PIO. А как посмтотреть что сидит на векторе исключения, как осуществляется переход по адрессу из контроллера прерываний? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 18 сентября, 2008 Опубликовано 18 сентября, 2008 · Жалоба Ну вот. Зная компилятор можно продолжать. Использую JTAG SAM-ICE Segger + кит на AT91SAM7A3 + IAR 4.42A .Тогда откройте окно дизассемблера и посмотрите на адрес 0x18. Там будет или что-то вроде LDR PC,[PC, #24] и тогда по адресу 0x38 будет лежать адрес обработчика, либо там будет LDR PC, [PC, #-3872] - тогда это как раз и есть чтение AIC_IVR и передача управления. В певом случае вам надо в окне дизассемблера пролистать до адреса обработчика и посмотреть, что там находится. Если там заглушка типа "переход на себя", надо добавить в программу обработчик: #pragma vector = 0x18 __irq __arm void IRQ_Switch() { void (*Handler)() = (void(*)())AT91C_BASE_AIC->AIC_IVR; Handler(); AT91C_BASE_AIC->AIC_EOICR = 0; // Reset AIC logic } Во втором случае надо ваш обработчик объявить как __irq __arm void pio_c_irq_handler ( void ) и добавить в его конце AT91C_BASE_AIC->AIC_EOICR = 0; В любом случае полезно добавить в программу после настройки контроллера строчку AT91C_BASE_AIC->AIC_EOICR = 0; ибо если вы находясь в обработчике прерывания нажмете иконку сброса в отладчике, сброса контроллера прерываний не происходит и прерывания с таким и более низким приоритетом останутся запрещены. И самое главное - я не вижу в вашей программе строчки __enable_interrupt(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Balaganoff 0 18 сентября, 2008 Опубликовано 18 сентября, 2008 · Жалоба по Адрессу irgvec : 0x18 содержится IRQ_Handler_Entry ; IRQ 0x90 по IRQ_Handler_Entry: 0x90 SUB LR,LR, #0x4 Это наверное и есть обработчик, А почему нет разрешения прерываний, ведь // настроили прерывания,указали обработчик AT91F_AIC_ConfigureIt ( pAic, AT91C_ID_PIOA,PIO_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, pio_c_irq_handler); // разрешили прерывания от маски SW4_MASK PIOA AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA,SW4_MASK); // разрешили прерывания для контроллера прерываний от периферии AT91C_ID_PIOA AT91F_AIC_EnableIt (pAic, AT91C_ID_PIOA); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 18 сентября, 2008 Опубликовано 18 сентября, 2008 · Жалоба по IRQ_Handler_Entry: 0x90 SUB LR,LR, #0x4 Это наверное и есть обработчик, А дальше что (по коду)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 18 сентября, 2008 Опубликовано 18 сентября, 2008 · Жалоба А почему нет разрешения прерываний, ведьА кто будет сбрасывать бит I в CPSR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Balaganoff 0 19 сентября, 2008 Опубликовано 19 сентября, 2008 · Жалоба Подключил <intrinsics.h> и вставил функцию __enable_interrupt(). Вот текст программы void pio_c_irq_handler ( void ) { int dummy; count_int_pio++; AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED2); delay_t (2000000); AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED2); delay_t (2000000); dummy =AT91C_BASE_PIOA->PIO_ISR; dummy=AT91C_BASE_AIC->AIC_ISR; dummy=AT91C_BASE_AIC->AIC_IECR; } void main( void ) { AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ); AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK ); AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_MASK ); AT91F_PIO_CfgInput(AT91C_BASE_PIOA, SW4_MASK); AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_PIOA,PIO_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, pio_c_irq_handler); AT91C_BASE_AIC->AIC_EOICR = 0; __enable_interrupt(); AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA,SW4_MASK); AT91F_AIC_EnableIt (pAic, AT91C_ID_PIOA); for (;;) { } } Вот, то что в окне дизасемблерра IRQ_Handler_Entry: 00000090 E24EE004 SUB LR, LR, #0x4 00000094 E92D4000 STMDB SP!, {LR} 00000098 E14FE000 MRS LR, SPSR 0000009C E92D4000 STMDB SP!, {LR} 000000A0 E92D0001 STMDB SP!, {R0} 000000A4 E59FE048 LDR LR, [PC, #+72] ; [_?2 (0xF4)] =AIC_SMR (0xFFFFF000) 000000A8 E59E0100 LDR R0, [LR, #+256] 000000AC E58EE100 STR LR, [LR, #+256] 000000B0 E321F013 MSR CPSR_c, #0x13 000000B4 E92D500E STMDB SP!, {R1,R2,R3,R12,LR} 000000B8 E1A0E00F MOV LR, PC 000000BC E12FFF10 BX R0 000000C0 E8BD500E LDMIA SP!, {R1,R2,R3,R12,LR} 000000C4 E321F092 MSR CPSR_c, #0x92 000000C8 E59FE024 LDR LR, [PC, #+36] ; [_?2 (0xF4)] =AIC_SMR (0xFFFFF000) 000000CC E58EE130 STR LR, [LR, #+304] 000000D0 E8BD0001 LDMIA SP!, {R0} 000000D4 E8BD4000 LDMIA SP!, {LR} 000000D8 E16FF00E MSR SPSR_cxsf, LR 000000DC E8FD8000 LDMIA SP!, {PC}^ AT91F_Default_FIQ_handler: 000000E0 EAFFFFFE B AT91F_Default_FIQ_handler; 0xE0 AT91F_Default_IRQ_handler: 000000E4 EAFFFFFE B AT91F_Default_IRQ_handler; 0xE4 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 19 сентября, 2008 Опубликовано 19 сентября, 2008 · Жалоба Подключил <intrinsics.h> и вставил функцию __enable_interrupt(). Хорошо. Пойдем от самого простого. Поставьте точку останова на адрес 0x18. Вы попадете на эту точку останова? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Balaganoff 0 22 сентября, 2008 Опубликовано 22 сентября, 2008 · Жалоба При том же исходном тесте , если комментирую в основном тексте программы,после настройки контроллера прерываний строчку AT91C_BASE_AIC->AIC_EOICR = 0 , то в точку останова не попадаю. Если оставляю AT91C_BASE_AIC->AIC_EOICR = 0 , то если запаскаю программу на выполнение -начинает прерываться постоянно вне зависимости от уровня сигнала от джойстика. Ставлю точку на адрес 0x18, попадаю туда, далее пошагово попадаю на IRQ_Handler_Entry, а с нее попадаю на pio_c_irq_handler, далее по коду дохожу до "вечного цикла", причем джойстик я не трогаю, т.е. прервание не инициализирую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 22 сентября, 2008 Опубликовано 22 сентября, 2008 · Жалоба При том же исходном тесте , если комментирую в основном тексте программы,после настройки контроллера прерываний строчку AT91C_BASE_AIC->AIC_EOICR = 0 , то в точку останова не попадаю.Почему это происходит я писал в конце сообщения #6.Если оставляю AT91C_BASE_AIC->AIC_EOICR = 0 , то если запаскаю программу на выполнение -начинает прерываться постоянно вне зависимости от уровня сигнала от джойстика.Простите, а какой уровень приходит на входы порта от джойстика в состоянии покоя? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Balaganoff 0 23 сентября, 2008 Опубликовано 23 сентября, 2008 · Жалоба В состоянии покоя на входах джойстика уровни "1" , но эти уровни от встроенных Pull-up резисторов в котроллер. При нажатии на джойстик происходит замыкание входа на "землю". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 23 сентября, 2008 Опубликовано 23 сентября, 2008 · Жалоба В состоянии покоя на входах джойстика уровни "1" , но эти уровни от встроенных Pull-up резисторов в котроллер.А какого поведения вы ожидаете от контроллера после AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_PIOA,PIO_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, pio_c_irq_handler);? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться