This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Clear of External Interrupt Pending bit

Hi,

I'm using Keil MDK-ARM 4.22a RTX OS on a STM3220G Eval board.

I added RTX and FS to the "Memory" example and everything is working fine. I have tasks that read a file while another one is blinking leds.

I tried to add and external interrupt on the KEY button (PG15 pin) and to do so I integrated the ST StdPeriph library (which is used mainly for setting up the interruption).

But if the button is working, I can't clear the Interrupt Pending bit in the IRQ handler. So when I send a semaphore from it, the OS raises quickly an overflow error.

Here is the code for the interruption setup :

void EXTI_User_Button_Config(void)
{
  EXTI_InitTypeDef   EXTI_InitStructure;
  GPIO_InitTypeDef   GPIO_InitStructure;
  NVIC_InitTypeDef   NVIC_InitStructure;

  /* Enable GPIOG clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
  /* Enable SYSCFG clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  /* Configure PG15 pin as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  GPIO_Init(GPIOG, &GPIO_InitStructure);

  /* Connect EXTI Line0 to PG15 pin */
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOG, EXTI_PinSource15);

  /* Configure EXTI Line0 */
  EXTI_InitStructure.EXTI_Line = EXTI_Line15;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_ClearITPendingBit(EXTI_Line15);

  EXTI_Init(&EXTI_InitStructure);

  /* Enable and set EXTI Line15 Interrupt to the lowest priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

And the IRQ handler :

void EXTI15_10_IRQHandler (void) __irq
{
  if(EXTI_GetITStatus(EXTI_Line15) != RESET)
  {
    /* Clear the EXTI line 15 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line15);

    /* Toggle LED1 */
    STM_EVAL_LEDToggle(LED1);

   /*Send Semaphore */
   isr_sem_send (semaphore1);
   cpt++;
  }
}

The 'cpt' variable is only for debugging purpose, as it's decremented by the task that handles semaphore1. When it's reaching 32 (the ISR FIFO size I defined), the OS raises the overflow error.

The code from the Std library to reset the pending bit :

void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
{
  /* Check the parameters */
  assert_param(IS_EXTI_LINE(EXTI_Line));

  EXTI->PR = EXTI_Line;
}

The interrupt setup is done before launching the OS.

Am I doing something wrong ? Is there another way to clear the interrupt bit ?

Parents
  • Maybe see this:

    http://www.keil.com/forum/18951/


    Normally the Cortex-M3 wait until the previous write is completed before the interrupt return. However, some microcontrollers has a write buffer in the peripheral bridge. The write buffer accelerates single write transfers to peripherals so that the processor don't have to wait until the transfer is done (peripheral bus might be running at slower clock speed).

    However, for clearing an interrupt request, the write buffer reply to the processor that transfer is done, while the actual write transfer actually haven't been completed in the peripheral. So the processor executed interrupt return, and found that the interrupt request from the peripheral is still high and think that it is a new interrupt request.

    By Joseph Yiu

Reply
  • Maybe see this:

    http://www.keil.com/forum/18951/


    Normally the Cortex-M3 wait until the previous write is completed before the interrupt return. However, some microcontrollers has a write buffer in the peripheral bridge. The write buffer accelerates single write transfers to peripherals so that the processor don't have to wait until the transfer is done (peripheral bus might be running at slower clock speed).

    However, for clearing an interrupt request, the write buffer reply to the processor that transfer is done, while the actual write transfer actually haven't been completed in the peripheral. So the processor executed interrupt return, and found that the interrupt request from the peripheral is still high and think that it is a new interrupt request.

    By Joseph Yiu

Children