2024-05-24 10:44 AM - edited 2024-05-24 05:17 PM
Colleagues,
Here’s a code snippet which changes the state of two GPIO lines with delays in between.
[My actual firmware has more code, and I’ve reduced it to this condensed example which still has the issue.]
HAL_GPIO_WritePin(LED_DRIVER_ENABLE_GPIO_Port, LED_DRIVER_ENABLE_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(LED_STATUS_GREEN_GPIO_Port, LED_STATUS_GREEN_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(LED_DRIVER_ENABLE_GPIO_Port, LED_DRIVER_ENABLE_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(LED_STATUS_GREEN_GPIO_Port, LED_STATUS_GREEN_Pin, GPIO_PIN_RESET);
The resulting picture on the oscilloscope looks quite wrong.
Legend for the oscilloscope plot:
Channel A is LED_DRIVER_ENABLE (PA3)
Channel B is LED_STATUS_GREEN (PB0)
The most troubling part is that the LED_STATUS_GREEN goes up before LED_DIVER_ENABLE on the oscilloscope. In the code LED_DIVER_ENABLE precedes LED_STATUS_GREEN. [It's more visible in my update below.]
In addition, the first call to HAL_Delay(1) produced a 0.1ms delay instead of expected 1ms. The second and third calls to HAL_Delay(1) produced 4ms and 2ms delays.
What could be causing these issues?
Any suggestion, insight or reference is really appreciated!
STM32G474. I ran the code on two copies of the board, and the microcontrollers are from the same reel. I see the same anomaly on both of them.
The compiler is CubeIDE v1.15.1 . The optimization is -O0 (no optimization, which is the default setting). Let me know if I should provide more information.
Sincerely,
- Nick
2024-05-24
11:38 AM
- last edited on
2024-05-27
11:26 PM
by
Lina_DABASINSKA
(you know of course that HAL_Delay(1) can take any time from 1 to 2 ms ? )
2024-05-24 03:20 PM - edited 2024-05-24 03:53 PM
update:
Here's an even more condensed code for this issue. I removed the delays, but the GPIO outputs are still out of order.
HAL_GPIO_WritePin(LED_DRIVER_ENABLE_GPIO_Port, LED_DRIVER_ENABLE_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_STATUS_GREEN_GPIO_Port, LED_STATUS_GREEN_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_DRIVER_ENABLE_GPIO_Port, LED_DRIVER_ENABLE_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_STATUS_GREEN_GPIO_Port, LED_STATUS_GREEN_Pin, GPIO_PIN_RESET);
Legend for the oscilloscope plot:
Channel A is LED_DRIVER_ENABLE (pin PA3)
Channel B is LED_STATUS_GREEN (pin PB0)
time axis in [microseconds]
edit: Here's the disassembly. I'll have to read-up before I can understand it.
222 HAL_GPIO_WritePin(LED_DRIVER_ENABLE_GPIO_Port, LED_DRIVER_ENABLE_Pin, GPIO_PIN_SET);
0800077c: movs r2, #1
0800077e: movs r1, #8
08000780: mov.w r0, #1207959552 @ 0x48000000
08000784: bl 0x8003828 <HAL_GPIO_WritePin>
226 HAL_GPIO_WritePin(LED_STATUS_GREEN_GPIO_Port, LED_STATUS_GREEN_Pin, GPIO_PIN_SET);
08000788: movs r2, #1
0800078a: movs r1, #1
0800078c: ldr r0, [pc, #328] @ (0x80008d8 <main+808>)
0800078e: bl 0x8003828 <HAL_GPIO_WritePin>
229 HAL_GPIO_WritePin(LED_DRIVER_ENABLE_GPIO_Port, LED_DRIVER_ENABLE_Pin, GPIO_PIN_RESET);
08000792: movs r2, #0
08000794: movs r1, #8
08000796: mov.w r0, #1207959552 @ 0x48000000
0800079a: bl 0x8003828 <HAL_GPIO_WritePin>
232 HAL_GPIO_WritePin(LED_STATUS_GREEN_GPIO_Port, LED_STATUS_GREEN_Pin, GPIO_PIN_RESET);
0800079e: movs r2, #0
080007a0: movs r1, #1
080007a2: ldr r0, [pc, #308] @ (0x80008d8 <main+808>)
080007a4: bl 0x8003828 <HAL_GPIO_WritePin>
2024-05-25 12:51 PM - edited 2024-05-25 12:51 PM
Does one of the GPIOs "gate" the other? So that one cannot raise until the other is in high state?
Bring more water.
2024-05-26 01:49 AM
As @Pavel A. said above, a minimum-1ms-time-wasting-delay with 1ms granularity can take 2ms, and it does, if it is invoked two times in a row.
> The most troubling part is that the LED_STATUS_GREEN goes up before LED_DIVER_ENABLE on the oscilloscope. In the code LED_DIVER_ENABLE precedes LED_STATUS_GREEN.
My guess is that you set LED_STATUS_GREEN in the code you haven't shown us, before the snippet you've shown us.
Place a breakpoint - or infinite loop - just before that code and observe LED_STATUS_GREEN.
JW
2024-05-26 02:04 AM
Make sure to set the scope to CHOP mode (not ALT).