AnsweredAssumed Answered

Bug IN HAL STM32L0xx ?

Question asked by foujanet.guillaume on Mar 25, 2015
Latest reply on Apr 1, 2015 by karsten
Hi,

I think there is a bug in the HAL layer of ST. (version 1.1.0)
My code is very simple:
I initialize two GPIO (PB4 and PB5) in Interrupt.
GPIO_InitTypeDef  GPIO_InitStruct;
    // Configure the Port
    GPIO_TO_CHECK_1_CLK_ENABLE();
    GPIO_TO_CHECK_2_CLK_ENABLE();
 
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
 
    GPIO_InitStruct.Pin = GPIO_TO_CHECK_1_PIN;
    HAL_GPIO_Init(GPIO_TO_CHECK_1_PORT, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_TO_CHECK_2_PIN;
    HAL_GPIO_Init(GPIO_TO_CHECK_2_PORT, &GPIO_InitStruct);
 
    // Enable and set Button EXTI Interrupt to the priority 0x03
    NVIC_SetPriority((IRQn_Type)GPIO_TO_CHECK_1_EXTI_IRQn, 0x03);
    HAL_NVIC_EnableIRQ((IRQn_Type)GPIO_TO_CHECK_1_EXTI_IRQn);
 
    NVIC_SetPriority((IRQn_Type)GPIO_TO_CHECK_2_EXTI_IRQn, 0x03);
    HAL_NVIC_EnableIRQ((IRQn_Type)GPIO_TO_CHECK_2_EXTI_IRQn);

Then I code the IRQ handler. PB4 and PB5 are on the same IRQ vector :
void EXTI4_15_IRQHandler(void)
{
      if(__HAL_GPIO_EXTI_GET_IT(GPIO_TO_CHECK_2_PIN) != RESET)
      {
          __HAL_GPIO_EXTI_CLEAR_IT(GPIO_TO_CHECK_2_PIN);
          counter2++;
          __HAL_GPIO_EXTI_CLEAR_IT(GPIO_TO_CHECK_2_PIN);
      }
 
      if(__HAL_GPIO_EXTI_GET_IT(GPIO_TO_CHECK_1_PIN) != RESET)
      {
          __HAL_GPIO_EXTI_CLEAR_IT(GPIO_TO_CHECK_1_PIN);
          counter1++;
          __HAL_GPIO_EXTI_CLEAR_IT(GPIO_TO_CHECK_1_PIN);
      }
}

With the debugger, I check with a breakpoint if counter1++ and counter2++ are executed.
The problem is: In function of the order of init of gpio, just one or the both interrupt work. 
If I initialize PB4 then PB5 : IT(PB4): NOK, IT(PB5):OK
if I initialize PB5 then PB4 : IT(PB4): OK and IT(PB5): OK

The solution: 
In the file stm32l0xx_gpio.c, when the SYSCFG->EXTICR register is configured, the mask to clear the interrupt line is false. All the register is cleared, instead of just the line. 
The code fixed  is (line 258): 
//Original
//        temp = SYSCFG->EXTICR[position >> 2];
//        temp &= ~((uint32_t)0x0F) << (4 * (position & 0x03));
//        temp |= ((uint32_t)(GET_GPIO_SOURCE(GPIOx)) << (4 * (position & 0x03)));
//        SYSCFG->EXTICR[position >> 2] = temp;
//bug Fixed
        temp = SYSCFG->EXTICR[position >> 2];
        temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03)));
        temp |= ((uint32_t)(GET_GPIO_SOURCE(GPIOx)) << (4 * (position & 0x03)));
        SYSCFG->EXTICR[position >> 2] = temp;
 Just a parenthesis is add for the not (~) operator. 

@ST microelectronics: Thanks to you to tell me if it's a bug or not. If it's a bug, could you send me a bug report number to know when this bug will be fixed in the new HAL library. And if you are already a new HAL version ( I work with the version 1.1.0), please send me the latest version.


Outcomes