2021-05-09 10:50 AM
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
Solved! Go to Solution.
2021-05-09 11:03 AM
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
2021-05-09 11:03 AM
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
2021-05-09 12:26 PM
... "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