Настроить обработчик прерываний для разных выводов GPIO одного и того же порта
Я хочу использовать 5 Gpios в качестве пользовательских кнопок ввода в mqx TWRK60D100. Я следовал за конфигурацией как
#define LEFT_BUTTON (GPIO_PORT_E | GPIO_PIN26)
#define LEFT_BUTTON_MUX_IRQ (LWGPIO_MUX_E26_GPIO)
#define RIGHT_BUTTON (GPIO_PORT_A | GPIO_PIN19)
#define RIGHT_BUTTON_MUX_IRQ (LWGPIO_MUX_A19_GPIO)
#define UP_BUTTON (GPIO_PORT_C | GPIO_PIN5)
#define UP_BUTTON_MUX_IRQ (LWGPIO_MUX_C5_GPIO)
#define DOWN_BUTTON (GPIO_PORT_C | GPIO_PIN4)
#define DOWN_BUTTON_MUX_IRQ (LWGPIO_MUX_C4_GPIO)
#define TEST_BUTTON (GPIO_PORT_C | GPIO_PIN1)
#define TEST_BUTTON_MUX_IRQ (LWGPIO_MUX_C1_GPIO)
#define BUTTON_PRESS_NOT_PENDING 0
#define LEFT_BUTTON_PRESSED 1
#define RIGHT_BUTTON_PRESSED 2
#define UP_BUTTON_PRESSED 3
#define DOWN_BUTTON_PRESSED 4
#define TEST_BUTTON_PRESSED 5
void int_service_routine(void *);
LWGPIO_STRUCT Left_Button;
LWGPIO_STRUCT Right_Button;
LWGPIO_STRUCT Up_Button;
LWGPIO_STRUCT Down_Button;
LWGPIO_STRUCT Test_Button;
volatile uint_8 Button_Press_Status = BUTTON_PRESS_NOT_PENDING;
/*ISR*-----------------------------------------------------
*
* Task Name : int_service_routine
* Comments :
* Button press ISR
*END*-----------------------------------------------------*/
void int_service_routine(void *pin)
{
printf("In Isr %u \n",pin);
if(pin==&Left_Button)
{
Button_Press_Status=LEFT_BUTTON_PRESSED;
}
else if(pin==&Right_Button)
{
Button_Press_Status=RIGHT_BUTTON_PRESSED;
}
else if(pin==&Up_Button)
{
Button_Press_Status=UP_BUTTON_PRESSED;
}
else if(pin==&Down_Button)
{
Button_Press_Status=DOWN_BUTTON_PRESSED;
}
else if(pin==&Test_Button)
{
Button_Press_Status=TEST_BUTTON_PRESSED;
}
lwgpio_int_clear_flag((LWGPIO_STRUCT_PTR) pin);
}
void Individual_Button_Config(LWGPIO_STRUCT_PTR button_name,
LWGPIO_PIN_ID pin_id,uint_32 button_mux_irq)
{
/*
Open the pin for input, initialize interrupt and set handler.
*/
/* opening pins for input */
if (!lwgpio_init(button_name, pin_id,
LWGPIO_DIR_INPUT,LWGPIO_VALUE_NOCHANGE))
{
printf("Initializing button GPIO as input failed.\n");
_task_block();
}
/* Some platforms require to setup MUX to IRQ functionality,
for the rest just set MUXto GPIO functionality */
lwgpio_set_functionality(button_name, button_mux_irq);
lwgpio_set_attribute(button_name, LWGPIO_ATTR_PULL_UP, LWGPIO_AVAL_ENABLE);
/* enable gpio functionality for given pin, react on falling edge */
if (!lwgpio_int_init(button_name, LWGPIO_INT_MODE_FALLING))
{
printf("Initializing button GPIO for interrupt failed.\n");
_task_block();
}
/* install gpio interrupt service routine */
_int_install_isr(lwgpio_int_get_vector(button_name),
int_service_routine, (void *) button_name);
/* set the interrupt level, and unmask the
interrupt in interrupt controller*/
_bsp_int_init(lwgpio_int_get_vector(button_name), 3, 0, TRUE);
/* enable interrupt on GPIO peripheral module*/
lwgpio_int_enable(button_name, TRUE );
printf("\n Button pin has been configured as input GPIO interrupt pin.\n");
}
/*
* Function Name : Button_Init
* Returned Value : None
* Comments : This function will initialise gpio buttons as input
*
*/
void Button_Init(void)
{
//Configuring Left Button
Individual_Button_Config(&Left_Button,LEFT_BUTTON,LEFT_BUTTON_MUX_IRQ);
//Configuring Right Button
Individual_Button_Config(&Right_Button,RIGHT_BUTTON,RIGHT_BUTTON_MUX_IRQ);
//Configuring Up Button
Individual_Button_Config(&Up_Button,UP_BUTTON,UP_BUTTON_MUX_IRQ);
//Configuring Down Button
Individual_Button_Config(&Down_Button,DOWN_BUTTON,DOWN_BUTTON_MUX_IRQ);
//Configuring Test Button
Individual_Button_Config(&Test_Button,TEST_BUTTON,TEST_BUTTON_MUX_IRQ);
}
Обработка прерываний разных пинов говорят (GPIO_PORT_E | GPIO_PIN26) ,(GPIO_PORT_A | GPIO_PIN19)
работал нормально. Но из (GPIO_PORT_C | GPIO_PIN5), (GPIO_PORT_C | GPIO_PIN4), (GPIO_PORT_C | GPIO_PIN1),
только последний настроенный (GPIO_PORT_C | GPIO_PIN1)
был только сработан. Обработчик прерываний другого вывода get выполняется повторно без очистки флага прерывания. Когда я прокомментировал (GPIO_PORT_C | GPIO_PIN1)
конфигурация контактов, (GPIO_PORT_C | GPIO_PIN4)
работал нормально, но проблема осталась (GPIO_PORT_C | GPIO_PIN5).
Когда я посмотрел адрес контакта в обработчике прерываний, все прерывания порта c показывают адрес последнего настроенного GPIO C PIN1
,
Что может быть не так с моим кодом?
Как настроить обработчик прерываний для разных выводов одного и того же порта?