cancel
Showing results for 
Search instead for 
Did you mean: 

Hall sensors not triggering IRQ from TIMER2

Bogdan
Senior
Posted on January 02, 2017 at 18:14

Hello,

i am working on a bldc motor project for school, and for start to understand whats happening inside the IRQ handler, i have configured timer2  on ch1,2,3 with 3 emulated hardware signals, imitating the CW of a bldc motors

The hall emulated signals are coming from another development board. The signals are bellow

0690X00000605yKQAQ.png

These signals ( H1,H2,H3) are feed into a STM32F407 device, on PA0, PA1 and PA2   which are Ch1,2,3 of the TIMER2 

i have prepared only the initialization of the timer2 to see if the hall signals trigger the CC1 event in the irq handler, but its not triggering.

I've put a small toggle on a PC1 pin just to see when its triggering inside the TIM2_IRQhandler,

But there is no triggering,

At this point Timer1 is not initialized, i just want to see how it behaives on the hall signals.

I am missing something?  Of does the Timer2 takes some kind of feedback from TIM1 in order to trigger CC1 event?

void timer2_setup(void){

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);

//**** PC1 is used for toggle in IRQ handlers to see with logic analyzer

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

GPIO_Init(GPIOC, &GPIO_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

TIM_TimeBaseStructure.TIM_Prescaler = 126;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseStructure.TIM_Period = 65530;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_SelectHallSensor(TIM2, ENABLE);

TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);

TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 ;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;// listen to T1, the HallSensorEvent

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;// Div:1, every edge

TIM_ICInitStructure.TIM_ICFilter = 0;

TIM_ICInit(TIM2, &TIM_ICInitStructure);

// Enable CC1 interrupt request

TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

TIM_Cmd(TIM2, ENABLE);

}

void TIM2_IRQHandler(void){

if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)

{

GPIO_ToggleBits(GPIOC,GPIO_Pin_1); // Toggle the pin for logic analyzer

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

}

}

10 REPLIES 10
Khouloud GARSI
Lead II
Posted on January 02, 2017 at 19:38

Hi

Anton.Bogdan

,

Try to modify your input polarity from both edges to rising edge:

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

I'm waiting for your feedback.

If this solves your issue, please click on correct

:)

.

Best regards,

Khouloud.

Bogdan
Senior
Posted on January 02, 2017 at 21:43

Hello Khouloud,

i tryied modifing  

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

And the same behaviour, there is no trigger on the CC1 IRQ

Posted on January 02, 2017 at 22:19

.CPP or C++ compilation? Try extern 'C' void TIM2_IRQHandler(void){ .. }

Have you checked the linkage via the Vector Table?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on January 03, 2017 at 00:20

Hello Clive,

after the code from above see it wasnt working, i decided to modify the code just for simple update event.

The code is writen in C only, using IAR enviroment.

After modifing the IRQ handler for the TIM_IT_UPDATE it still wasnt working,    tryied with a demo project provided by ST in IAR enviroment, and that was working. But still i didnt understand why...

Normaly for working with interupts i know the following components are needed to the enviroment   :

- misc.c/h

- stm32f4xx_it.c/h

- the vector file ( in my case startup_stm32f40_41xxx.s for IAR Ewarm)

If i am mistaken, please corect me.

Now after almost 2hours of coffe and code debug, i noticed a stupid thing

my main routine is this normaly in this structure

int main(void) {

RCC_ClocksTypeDef clocks;

RCC_GetClocksFreq(&clocks);

NVIC_InitTypeDef NVIC_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

GPIO_Init(GPIOD, &GPIO_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

TIM_TimeBaseStructure.TIM_Prescaler = 500;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseStructure.TIM_Period = 65530; // tick arround  2.5 hertz for the eye....

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

TIM_Cmd(TIM2, ENABLE);

while(1) { } // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! whitout this line, the IRQ handler is not working !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

}

void TIM2_IRQHandler(void){

 

 

if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)

 

{

 

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

 

// GPIO_ToggleBits(GPIOC,GPIO_Pin_1);

 

GPIO_ToggleBits(GPIOD,GPIO_Pin_14);

 

 

}

 

}

If i  put a while(1){}  in my  main function,  the irq works,   if not .... its not working.... Now i am not very experienced in C language but i found this very strange....  I even try ending the int main(void) function with a return 0;   and didn not work... It seems its working only if i have a while(1){} inside my main program.

I will return to my main motor code and see if this was the issue.

I will keep updated 

Thanks

Posted on January 03, 2017 at 00:42

Returning from main() drops into nowhere, unless specially handled by the startup code I'd expect the system to crash/fail. See also exit() or abort().

Here in Keil the BX __main provides no expectation of ever returning

...
; Reset handler
Reset_Handler PROC
 EXPORT Reset_Handler [WEAK]
 IMPORT SystemInit
 IMPORT __main
 LDR R0, =SystemInit
 BLX R0
 LDR R0, =__main
 BX R0
 ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
 EXPORT NMI_Handler [WEAK]
 B .
 ENDP
...�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

In an optimistic interpretation it might come back to just before the call to __main (line 10)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Bogdan
Senior
Posted on January 03, 2017 at 13:58

Ok, now that my IRQ handler is working,  i started the following code, i modifyied my timebase to overflow at arround 500 ms

My Hall signals each are 2.9 ms at 50% dutycycle.

Basicaly i have a hall event at every 1ms

The problem is that the CC1 interrupt should occour at every hall rising edge, is this correct?

But from the logic analyzer i see the CC1 is fired haoticaly,  and i wonder why....

0690X00000605qcQAA.png

Here is my code 

int main(void){

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);

//**** PC1 is used for toggle in IRQ handlers to see with logic analyzer

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 |GPIO_Pin_3 ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

GPIO_Init(GPIOC, &GPIO_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

TIM_TimeBaseStructure.TIM_Prescaler = 647;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseStructure.TIM_Period = 65000;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_SelectHallSensor(TIM2, ENABLE);

TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);

TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 ;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;// listen to T1, the HallSensorEvent

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

TIM_ICInitStructure.TIM_ICFilter = 0x0F;

TIM_ICInit(TIM2, &TIM_ICInitStructure);

// Enable CC1 interrupt request

TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

TIM_Cmd(TIM2, ENABLE);

while(1){}

}

void TIM2_IRQHandler(void){

if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)

{

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

GPIOC->BSRRH = GPIO_Pin_1; //reset

GPIOC->BSRRL = GPIO_Pin_1; //set

GPIOC->BSRRH = GPIO_Pin_1; //reset

}

Khouloud GARSI
Lead II
Posted on January 13, 2017 at 18:58

Hi

Anton.Bogdan

,

Pleasetry with a basic configuration without using the filter :

TIM_ICInitStructure.TIM_ICFilter = 0;

And send me a new screen shot of the signals seen on the analyser.

Khouloud.

Bogdan
Senior
Posted on January 22, 2017 at 23:24

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6ZI&d=%2Fa%2F0X0000000bqr%2FUQfLNNJ8Ffw3Q5x1Tt8u_ciDasSFDqE5bMSNJ.LvI50&asPdf=false
Bogdan
Senior
Posted on January 25, 2017 at 22:31

In the end i solved'it,  it was because of the GPIO PullUP enabled for  the 6pwm outputs,  after configured with NOPULL everything is as expected.

Thanks guys