Double interrupt problem on FRDMK64F - MQX RTOS

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Double interrupt problem on FRDMK64F - MQX RTOS

跳至解决方案
1,932 次查看
titusstalin
Contributor V

Dear All,

I'm working with FRDMK64F board with MQX RTOS s/w and facing some weird issue when I used 2 interrupts.

i.e, I'm getting continuous interrupts from second interrupt and nothing from first interrupt (ISR)

I've taken GPIO code for reference from following location.

C:\Freescale\Freescale_MQX_4_1\mqx\examples\gpio

I need PTC2 and PTC3 for interrupt generations.

Actually I want to develop wiegand protocol.

PTC2 is for DATA0 and PTC3 is for DATA1.

I'm getting correct no's of output when I enabled only one interrupt and other one set to disabled (lwgpio_int_enable(&d0, FALSE);)

This is my code,

/* Titus */

#define BSP_SWPTC2                     (GPIO_PORT_C | GPIO_PIN2)

#define BSP_SWPTC3                     (GPIO_PORT_C | GPIO_PIN3)

#define BSP_DATA0                 BSP_SWPTC2

#define BSP_DATA1                 BSP_SWPTC3

#define BSP_PTC2D0_MUX_GPIO            (LWGPIO_MUX_C2_GPIO)

#define BSP_PTC3D1_MUX_GPIO            (LWGPIO_MUX_C3_GPIO)

#define BSP_PTC2_MUX_GPIO        BSP_PTC2D0_MUX_GPIO

#define BSP_PTC2_MUX_IRQ         BSP_PTC2D0_MUX_GPIO

#define BSP_PTC3_MUX_GPIO        BSP_PTC3D1_MUX_GPIO

#define BSP_PTC3_MUX_IRQ         BSP_PTC3D1_MUX_GPIO

void int_service_routine_d1(void *pin)

{

    lwgpio_int_clear_flag((LWGPIO_STRUCT_PTR) pin);

    printf("DATA1 interrupt raised\n");

//    count++;

    _lwsem_post(&lwsem);

}

void int_service_routine_d0(void *pin)

{

    lwgpio_int_clear_flag((LWGPIO_STRUCT_PTR) pin);

    printf("DATA0 interrupt raised\n");

//    count++;

    _lwsem_post(&lwsem2);

}

      if (!lwgpio_init(&d0, BSP_DATA0, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE))
      {
          printf("Initializing DATA0 as input failed.\n");
          _task_block();
      }
      if (!lwgpio_init(&d1, BSP_DATA1, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE))
     {
          printf("Initializing DATA1 as input failed.\n");
         _task_block();
      }

      lwgpio_set_functionality(&d0, BSP_PTC2_MUX_IRQ);
      lwgpio_set_attribute(&d0, LWGPIO_ATTR_PULL_UP, LWGPIO_AVAL_ENABLE);
      lwgpio_set_functionality(&d1, BSP_PTC3_MUX_IRQ);
      lwgpio_set_attribute(&d1, LWGPIO_ATTR_PULL_UP, LWGPIO_AVAL_ENABLE);

      /* enable gpio functionality for given pin, react on falling edge */
      if (!lwgpio_int_init(&d0, LWGPIO_INT_MODE_FALLING))
      {
          printf("Initializing DATA0 for interrupt failed.\n");
          _task_block();
      }
      /* enable gpio functionality for given pin, react on falling edge */
      if (!lwgpio_int_init(&d1, LWGPIO_INT_MODE_FALLING))
      {
          printf("Initializing DATA1 for interrupt failed.\n");
          _task_block();
      }

      /* install gpio interrupt service routine */
      _int_install_isr(lwgpio_int_get_vector(&d0), int_service_routine_d0, (void *) &d0);
      /* set the interrupt level, and unmask the interrupt in interrupt controller */
      _bsp_int_init(lwgpio_int_get_vector(&d0), 3, 0, TRUE);
      /* enable interrupt on GPIO peripheral module */
      lwgpio_int_enable(&d0, TRUE);

      /* install gpio interrupt service routine */
      _int_install_isr(lwgpio_int_get_vector(&d1), int_service_routine_d1, (void *) &d1);
      /* set the interrupt level, and unmask the interrupt in interrupt controller */
      _bsp_int_init(lwgpio_int_get_vector(&d1), 3, 0, TRUE);
      /* enable interrupt on GPIO peripheral module */
      lwgpio_int_enable(&d1, TRUE);

Now I'm getting interrupt continuously from "int_service_routine_d1" ISR but nothing got from "int_service_routine_d0"

Both interrupt code was working good but it won't work when I enabled both the interrupts.

Is that anything I'm missing or any change required here ?

Could you please support us on this.

标记 (1)
1 解答
1,513 次查看
RadekS
NXP Employee
NXP Employee

For example:

/******************************************************************************

*

* Functio Name      : int_service_routine

* Comments          : The interrupt service routine triggered by gpio

*

******************************************************************************/

void int_service_routine(void *pin)

{

PORT_MemMapPtr  pctl;

pctl = (PORT_MemMapPtr)PORTC_BASE_PTR;

if (pctl->PCR[1] & PORT_PCR_ISF_MASK)

  {

  //your code

  pctl->PCR[1] |= PORT_PCR_ISF_MASK;;

  }

if (pctl->PCR[2] & PORT_PCR_ISF_MASK)

  {

  //your code

  pctl->PCR[2] |= PORT_PCR_ISF_MASK;;

  } 

  _lwsem_post(&lwsem);

}

OR

/******************************************************************************

*

* Functio Name      : int_service_routine

* Comments          : The interrupt service routine triggered by gpio

*

******************************************************************************/

void int_service_routine(void *pin)

{

if (lwgpio_int_get_flag(&btn1) == TRUE)

  {

  //your code

  lwgpio_int_clear_flag(&btn1);

  }

if (lwgpio_int_get_flag(&btn2) == TRUE)

  {

  //your code

  lwgpio_int_clear_flag(&btn2);

  }

  _lwsem_post(&lwsem);

}

I hope it helps you.

在原帖中查看解决方案

0 项奖励
回复
4 回复数
1,513 次查看
RadekS
NXP Employee
NXP Employee

Yes, this is just misunderstanding.

For the lwgpio, the Kinetis PORT module generates a single interrupt that asserts when the interrupt status flag is set for any enabled interrupt for that port.


Thus, we get into this vector by any enabled PORTx interrupt, and so we need to test PORTx_ISFR register in the interrupt service routine to find out, which pin of that port causes the interrupt request. (or, alternatively, lwgpio_int_get_flag() checks ISF bit of the specified PORTx_PCRn register).

I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,513 次查看
titusstalin
Contributor V

Thanks RadekS.

Actually I've used different port for each GPIO.

Say, I've used PTC3 and PTB9 instead of PTC2 and PTC3.

Then I got expected results, so it seems you are right.

Could you share the code snippet for that, to find which port pin got interrupted which needs to be added in ISR.

Thank you.

0 项奖励
回复
1,514 次查看
RadekS
NXP Employee
NXP Employee

For example:

/******************************************************************************

*

* Functio Name      : int_service_routine

* Comments          : The interrupt service routine triggered by gpio

*

******************************************************************************/

void int_service_routine(void *pin)

{

PORT_MemMapPtr  pctl;

pctl = (PORT_MemMapPtr)PORTC_BASE_PTR;

if (pctl->PCR[1] & PORT_PCR_ISF_MASK)

  {

  //your code

  pctl->PCR[1] |= PORT_PCR_ISF_MASK;;

  }

if (pctl->PCR[2] & PORT_PCR_ISF_MASK)

  {

  //your code

  pctl->PCR[2] |= PORT_PCR_ISF_MASK;;

  } 

  _lwsem_post(&lwsem);

}

OR

/******************************************************************************

*

* Functio Name      : int_service_routine

* Comments          : The interrupt service routine triggered by gpio

*

******************************************************************************/

void int_service_routine(void *pin)

{

if (lwgpio_int_get_flag(&btn1) == TRUE)

  {

  //your code

  lwgpio_int_clear_flag(&btn1);

  }

if (lwgpio_int_get_flag(&btn2) == TRUE)

  {

  //your code

  lwgpio_int_clear_flag(&btn2);

  }

  _lwsem_post(&lwsem);

}

I hope it helps you.

0 项奖励
回复
1,513 次查看
titusstalin
Contributor V

Thank you so much.

0 项奖励
回复