cancel
Showing results for 
Search instead for 
Did you mean: 

Timer Capture code not working

BTrem.1
Senior II

Hi All,

To get around a problem I was having with timer capture using DMA (another topic) I changed my timer code to use interrupts. The seems to work when I debug step through it but not when I run. I am using TIM8 in input capture mode for CH1 and CH3.

Here is the IRQ:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim)
{
	if( htim->Instance == TIM8)      // 1190    ------ bp#1
	{                                                                                                
		 // Check if/which capture flag is set   
		 // read CC register & store value in buffer1 or buffer2 
		 // clear flag CCIF
		 // process result  
		if(__HAL_TIM_GET_FLAG(htim, TIM_SR_CC1IF) != RESET)     // 1196    bp#2
		{ 
			__HAL_TIM_CLEAR_IT(htim, TIM_DIER_CC1IE);              // 1198
			buffer1[0] = htim->Instance->CCR1; 
			g_nFrefSignal = !g_nFrefSignal ; 
		}  
		if(__HAL_TIM_GET_FLAG(htim, TIM_SR_CC3IF) != RESET)     // 1202 ----- bp#3
		{  
			__HAL_TIM_CLEAR_IT(htim, TIM_DIER_CC3IE);  
			buffer2[0] = htim->Instance->CCR3 ; 
		}  
	} 

If I only enable break point #2 or #3 the break points DO NOT get hit. If I enable breakpoint #1 it does get hit and I can then step through the code at #2 and #3.

I do have the HAL_DBGMCU_EnableDBGStopMode(); executed at the beginning of main() to stop clocks during debug.

Also, even though it steps through line #1198 I do not see the SR.CC1IF flag get cleared. I do see buufer1[0] and g_nFrefSignal get updated.

The macro at line #1196 is defined as:

#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__)   ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__))

What am I missing?

> why does stepping through code hit the bp but running does not?

> why does __HAL_TIM_CLEAR_IT() not clear the interrupt?

> why does read CC1IF not get cleared when I read CCR1?

FYI, here is the assembly code:

......... ...
1197      		if(__HAL_TIM_GET_FLAG(htim, TIM_SR_CC1IF) != RESET)
08001dd2:   ldr     r3, [r3, #16]
08001dd4:   tst.w   r3, #2
08001dd8:   beq.n   0x8001df4 <HAL_TIM_IC_CaptureCallback+44>
1199      			__HAL_TIM_CLEAR_IT(htim, TIM_DIER_CC1IE);
08001dda:   ldr     r3, [pc, #52]   ; (0x8001e10 <HAL_TIM_IC_CaptureCallback+72>)
08001ddc:   mvn.w   r2, #2
08001de0:   str     r2, [r3, #16]
1200      			buffer1[0] = htim->Instance->CCR1;
08001de2:   ldr     r3, [r0, #0]
08001de4:   ldr     r2, [r3, #52]   ; 0x34
08001de6:   ldr     r3, [pc, #44]   ; (0x8001e14 <HAL_TIM_IC_CaptureCallback+76>)
08001de8:   str     r2, [r3, #0]
1201      			g_nFrefSignal = !g_nFrefSignal ;
08001dea:   ldr     r2, [pc, #44]   ; (0x8001e18 <HAL_TIM_IC_CaptureCallback+80>)
08001dec:   ldrb    r3, [r2, #0]
08001dee:   eor.w   r3, r3, #1
08001df2:   strb    r3, [r2, #0]
1204      		if(__HAL_TIM_GET_FLAG(htim, TIM_SR_CC3IF) != RESET)
08001df4:   ldr     r3, [r0, #0]
08001df6:   ldr     r2, [r3, #16]
08001df8:   tst.w   r2, #8
08001dfc:   beq.n   0x8001dd0 <HAL_TIM_IC_CaptureCallback+8>
1206      			__HAL_TIM_CLEAR_IT(htim, TIM_DIER_CC3IE);
08001dfe:   mvn.w   r2, #8
08001e02:   str     r2, [r3, #16]
1207      			buffer2[0] = htim->Instance->CCR3 ;
08001e04:   ldr     r3, [r0, #0]
08001e06:   ldr     r2, [r3, #60]   ; 0x3c
08001e08:   ldr     r3, [pc, #16]   ; (0x8001e1c <HAL_TIM_IC_CaptureCallback+84>)
08001e0a:   str     r2, [r3, #0]
1213      }
08001e0c:   b.n     0x8001dd0 <HAL_TIM_IC_CaptureCallback+8>
08001e0e:   nop     
08001e10:   adds    r4, #0
08001e12:   ands    r1, r0
08001e14:   asrs    r0, r1, #24
08001e16:   movs    r0, #0
08001e18:   asrs    r4, r4, #14
08001e1a:   movs    r0, #0
08001e1c:   asrs    r0, r0, #23
08001e1e:   movs    r0, #0
1346      {
          sendPrompt:
08001e20:   push    {r3, r4, r5, lr}
08001e22:   mov     r5, r0
1349      	sprintf(msg, "\r\n>");
08001e24:   ldr     r4, [pc, #20]   ; (0x8001e3c <sendPrompt+28>)
08001e26:   ldr     r3, [pc, #24]   ; (0x8001e40 <sendPrompt+32>)
08001e28:   str     r3, [r4, #0]
1350      	HAL_UART_Transmit_IT(huart, (uint8_t *) msg, strlen(msg));
08001e2a:   mov     r0, r4
08001e2c:   bl      0x8000234 <strlen>
08001e30:   uxth    r2, r0
08001e32:   mov     r1, r4
08001e34:   mov     r0, r5
08001e36:   bl      0x8005bc0 <HAL_UART_Transmit_IT>
1352      }
08001e3a:   pop     {r3, r4, r5, pc}
08001e3c:   asrs    r4, r2, #10
08001e3e:   movs    r0, #0
08001e40:   lsrs    r5, r1, #8
08001e42:   movs    r6, r7
1355      {
          sendVer:
08001e44:   push    {r3, r4, r5, lr}
08001e46:   mov     r5, r0
1359      	strcpy(msg, VERSION);
08001e48:   ldr     r4, [pc, #40]   ; (0x8001e74 <sendVer+48>)
08001e4a:   ldr     r1, [pc, #44]   ; (0x8001e78 <sendVer+52>)
08001e4c:   mov     r0, r4
08001e4e:   bl      0x800ac00 <strcpy>
1360        strcat(msg, "\r\n>");
08001e52:   mov     r0, r4
08001e54:   bl      0x8000234 <strlen>
08001e58:   mov     r3, r0
08001e5a:   ldr     r2, [pc, #32]   ; (0x8001e7c <sendVer+56>)
08001e5c:   ldr     r0, [r2, #0]
08001e5e:   str     r0, [r4, r3]
1361      	HAL_UART_Transmit_IT(huart, (uint8_t *) msg, strlen(msg));
08001e60:   mov     r0, r4
08001e62:   bl      0x8000234 <strlen>
08001e66:   uxth    r2, r0
08001e68:   mov     r1, r4
08001e6a:   mov     r0, r5
08001e6c:   bl      0x8005bc0 <HAL_UART_Transmit_IT>
1363      }
08001e70:   pop     {r3, r4, r5, pc}
08001e72:   nop     
08001e74:   asrs    r0, r5, #10
08001e76:   movs    r0, #0
08001e78:   lsls    r4, r5, #1
08001e7a:   movs    r0, #0
08001e7c:   stmia   r5!, {r3, r4}
08001e7e:   lsrs    r0, r0, #32
......... ...

Thanks,

Brian

1 ACCEPTED SOLUTION

Accepted Solutions

In Cube/HAL, you are not supposed to check/manipulate the TIM registers directly. At the moment when HAL_TIM_IC_CaptureCallback() is called, the CCxIF has been already cleared. Look at the available examples, or read the Cube/HAL manual:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
...

 If you place a breakpoint and don't set the respective DBGMCU flag, timers continue to run and set the flags as appropriate, while the program is stopped.

JW

View solution in original post

2 REPLIES 2

In Cube/HAL, you are not supposed to check/manipulate the TIM registers directly. At the moment when HAL_TIM_IC_CaptureCallback() is called, the CCxIF has been already cleared. Look at the available examples, or read the Cube/HAL manual:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
...

 If you place a breakpoint and don't set the respective DBGMCU flag, timers continue to run and set the flags as appropriate, while the program is stopped.

JW

... "In Cube/HAL, you are not supposed to check/manipulate the TIM registers directly."

I changed my code to use only that shown below and it appears to be working now while running. I read the App Note UM2570 Description of STM32G4 HAL and low-layer drivers but didn't find any specifics on the use HAL_TIM_IC_CaptureCallback, just a description of the parameters and return value. The code below only reads the CCRx register and does not manipulate any other TIM registers. I found this in an example online.

I'd like to see some ST document that says "don't do this : .................".

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim)
{
	if( htim->Instance == TIM8)
	{
		if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			buffer1[0] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
			g_nFrefSignal = !g_nFrefSignal ;
		}
 
		if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
		{
			buffer2[0] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
		}
	}
}

Thanks,

Brian