cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L0 Problem with EXTI handler on platform.io & arduino framework

Frog
Associate II

Hi,

 

I'm using a STM32L031K6 with platform.io & arduino framework. I know this forum is not relevant to platform.io or arduino, but most of my code is with LL drivers which should change nothing (but maybe ?).

 

First, i don't understand the IRQn. I'm using PB1 as input interrupt on rising, it's on line 1, so to start, it should be :

 
NVIC_EnableIRQ(EXTI0_1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
//as refered :
 EXTI0_1_IRQn                = 5,      /*!< EXTI Line 0 and 1 Interrupts 

But the interrupt work only if i enable EXTI2_3_IRQn. I don't get it, and in example EXTI_ToggleLedOnIT for NUCLEO-L073RZ, there is the same +1 on IRQn.

So, change made, and i can see the change of the interrupt on IEXTI->PR, depending on the rising on PB1. the problem is the call back function. On STM32 IDE, there is a *_it.h/c which don't exist on platform.io. Maybe the point come here.

First, i wanted to change the function handler using :

void IRQ_Module_0(void) {;}

NVIC_SetVector(EXTI2_3_IRQn, (uint32_t) &IRQ_Module_0);

But it seems to do nothing as the adress return by NVIC_GetVector stay the same. Or maybe i forgot something.

Second, i try to figure out with the defaut handler (which was hard to find, documentation is not clear) :

/**
  * @brief This function handles external line 2 to 3 interrupt request.
  *   None
  * @retval None
  */
void EXTI2_3_IRQHandler(void)
{
  uint32_t pin;
  for (pin = GPIO_PIN_2; pin <= GPIO_PIN_3; pin = pin << 1) {
    HAL_GPIO_EXTI_IRQHandler(pin);
  }
}
// ->
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}
// ->
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);

  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */
}

with a new function :

extern "C" void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {;}

 And get an error :

test.cpp:(.text.HAL_GPIO_EXTI_Callback+0x0): multiple definition of `HAL_GPIO_EXTI_Callback'; .pio/build/nucleo_l031k6/SrcWrapper/src/stm32/interrupt.cpp.o:interrupt.cpp:(.text.HAL_GPIO_EXTI_Callback+0x0): first defined here

But it is defined as __weak

There is also in interrupt.cpp some :

void EXTI0_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

 Finally, i'm totally lost. Did i make some missunderstanding ? Or maybe it is relative to platform.io ?

I search for some same error and didn't find it.

Some help would be appreciate.

Thx in advance,

1 ACCEPTED SOLUTION

Accepted Solutions
Frog
Associate II

So, i add __weak to EXTI0_1_IRQHandler and EXTI1_2_IRQHandler inside framework-arduinoststm32\libraries\SrcWrapper\src\stm32\interrupt.cpp

It's dirty, but fastest way to solve it. I need to go to stmcube framework, but can't find a "all in one" LL (or HAL) printf library. Actually, i don't want to make my own.

Thanks,

View solution in original post

5 REPLIES 5

@Frog wrote:

I know this forum is not relevant to platform.io or arduino, ,


Indeed - maybe better to try here: https://www.stm32duino.com/

 

In fact, there is a mistake cause of VSCode when i was looking to the function

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

Refer to the hal_gpio library, but in fact, it is declared inside interrupt.cpp

/**
  * @brief This function his called by the HAL if the IRQ is valid
  * @PAram  GPIO_Pin : one of the gpio pin
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  uint8_t irq_id = get_pin_id(GPIO_Pin);

  if (gpio_irq_conf[irq_id].callback != NULL) {
    gpio_irq_conf[irq_id].callback();
  }
}

 

But arduino framework or not, that change nothing about the EXTI2_3_IRQn for line1 and the problem of NVIC_SetVector which are from LL drivers

Frog
Associate II

So, i add __weak to EXTI0_1_IRQHandler and EXTI1_2_IRQHandler inside framework-arduinoststm32\libraries\SrcWrapper\src\stm32\interrupt.cpp

It's dirty, but fastest way to solve it. I need to go to stmcube framework, but can't find a "all in one" LL (or HAL) printf library. Actually, i don't want to make my own.

Thanks,


@Frog wrote:

i add __weak to EXTI0_1_IRQHandler and EXTI1_2_IRQHandler inside framework-


If you're adding it, don't specify the __weak - that's saying, "this is just a default; could be overwritten"

If that's solved the issue, please mark the solution:

https://community.st.com/t5/community-guidelines/help-others-to-solve-their-issues/ta-p/575256

 


@Frog wrote:

can't find a "all in one" LL (or HAL) printf library. Actually, i don't want to make my own.

Thanks,


Not sure what you mean by that?

But maybe this helps:

https://community.st.com/t5/stm32-mcus/how-to-redirect-the-printf-function-to-a-uart-for-debug-messages/ta-p/49865

If not, please start a new thread with the new question.

I mean, it was :

void EXTI0_1_IRQHandler(void)

It become

__weak void EXTI0_1_IRQHandler(voir)

So i can overwrite it. It's not really a solution because it change the main library, so on next update i will need to change it again. In fact, i don't understand why its not "__weak" by defaut so the user can choose to overwrite or not.

 

I mean a .c/.cpp/.h to include and it works, but your solution looks not to hard to make it working. Thanks :)