Skip to main content
BTrem.1
Senior
May 9, 2021
Solved

Timer Capture code not working

  • May 9, 2021
  • 2 replies
  • 1141 views

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

This topic has been closed for replies.
Best answer by waclawek.jan

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

2 replies

waclawek.jan
waclawek.janBest answer
Super User
May 9, 2021

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

BTrem.1
BTrem.1Author
Senior
May 9, 2021

... "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