-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cpu/nrf5x_common: fix uart_poweroff() #19926
base: master
Are you sure you want to change the base?
Conversation
bors merge |
19923: boards: add Silabs EFM32 Giant Gecko GG11 Starter Kit r=benpicco a=gschorcht ### Contribution description The PR adds the support for the EFM32GG11B family and the Silabs EFM32 Giant Gecko GG11 Starter Kit board. The Silabs EFM32 Giant Gecko GG11 has the following on-board features: - EFM32GG11B MCU with 2 MB flash and 512 kB RAM - J-Link USB debugger - 176x176 RGB LCD (not supported) - 2 user buttons, 2 user RGB LEDs and a touch slider - Si7021 Relative Humidity and Temperature Sensor - Si7210 Hall-Effect Sensor (not supported) - USB OTG interface (Device mode supported) - 32 MByte Quad-SPI Flash (not supported yet) - SD card slot (not supported yet, follow-up PR based on PR #19760) - RJ-45 Ethernet (not supported) - Dual microphones (not supported) ### Testing procedure Basic tests should work. ### Issues/PRs references 19926: cpu/nrf5x_common: fix uart_poweroff() r=benpicco a=maribu ### Contribution description Previously, uart_poweroff() and uart_poweron() were no-ops. This replaces them with the logic to indeed power on and power off the UART device. ### Testing procedure - ideally, power consumption should be less after a call to `uart_poweroff()` - beware: this is untested. however, at least a call to `uart_write()` while powered off would get stuck if not for the special handling, while before the UART remained fully operational when "powered off" - regular operation should resume after again calling `uart_poweron()` - this is tested ### Issues/PRs references None Co-authored-by: Gunar Schorcht <[email protected]> Co-authored-by: Marian Buschsieweke <[email protected]>
Build failed (retrying...): |
19926: cpu/nrf5x_common: fix uart_poweroff() r=benpicco a=maribu ### Contribution description Previously, uart_poweroff() and uart_poweron() were no-ops. This replaces them with the logic to indeed power on and power off the UART device. ### Testing procedure - ideally, power consumption should be less after a call to `uart_poweroff()` - beware: this is untested. however, at least a call to `uart_write()` while powered off would get stuck if not for the special handling, while before the UART remained fully operational when "powered off" - regular operation should resume after again calling `uart_poweron()` - this is tested ### Issues/PRs references None Co-authored-by: Marian Buschsieweke <[email protected]>
bors cancel The build failure seemingly was caused by this PR :-/ |
Canceled. |
e70e5c0
to
3ddfeee
Compare
3ddfeee
to
0ac856d
Compare
Probably not worth backporting but I always like fixes, Is it still WIP? |
To test this PR, I modified the tests/periph/uart test a little bit and added significantly longer delays so a slow human (me) can read off the multimeter in time. This is from the tests/periph/uart/main.c file, lines 203ff: static void sleep_test(int num, uart_t uart)
{
printf("UARD_DEV(%i): test uart_poweron() and uart_poweroff() -> ", num);
uart_poweroff(uart);
//xtimer_usleep(POWEROFF_DELAY);
xtimer_msleep(4000);
uart_poweron(uart);
xtimer_msleep(4000);
puts("[OK]");
} When the UART is powered off, the nRF52832 on my nRF52DK consumes 0.474mA and with the UART powered on it consumes 0.530mA. IMO this PR is well worth backporting, especially since most of the changes regarding the register accesses are already done in the mainline code, so this PR should shrink to only a handful of lines changed. |
0ac856d
to
a4bd18c
Compare
OK, rebased. I don't have the hardware at hands, so this is yet untested. The looks reasonable after resolving the merge conflict, though. |
I can't add that as a comment, but you can delete the ENABLE_ON and ENABLE_OFF macros from lines 44, 45, 52 and 53. They are now unused. This is the expansion of the test code in tests/periph/uart: static void sleep_test(int num, uart_t uart)
{
printf("UARD_DEV(%i): test uart_poweron() and uart_poweroff() -> ", num);
xtimer_msleep(5);
uart_poweroff(uart);
uint8_t data[8] = "asdf";
uart_write(uart, data, sizeof(data)); // this should not output any data but not hang either
//xtimer_usleep(POWEROFF_DELAY);
xtimer_msleep(4000);
uart_poweron(uart);
xtimer_msleep(4000);
puts("[OK]");
} The additional 5ms sleep is there to make sure the data is sent before the UART goes to sleep. This looks good from my side, thank you for addressing this so quickly :) |
Indeed. But I wonder if those were actually more readable than what I did when mergeing 🤣 |
126d5e8
to
4c4f996
Compare
I was so free to squash directly and I changed the code to instead make use of |
I agree that using ENABLE_ON and ENABLE_OFF is more elegant. I can test the latest version tomorrow, but I wouldn't expect any problems. One more thing that might be worth looking at are Lines 140-143: #ifndef UARTE_PRESENT
/* only the legacy non-EasyDMA UART needs to be powered on explicitly */
dev->POWER = 1;
#endif The "dev->POWER = 1;" line is present in set_power() as well, so one of the two places is probably redundant. |
4c4f996
to
65a0aa1
Compare
Was the change of the bmp.py file supposed to smuggle into the PR? |
65a0aa1
to
de99c64
Compare
Thx, good catch! |
It appears that this breaks |
That is odd, stdio_uart does not care about the return value of uart_write and uart_write is the only function that calls get_power. Could it be that UARTE_PRESENT is not set anywhere in RIOT currently? But if that's the case, the registers for the nRF52 UARTE are not set corretly. Edit: Sorry that this became such a can of worms, that was certainly not intended 👀 |
The define is in the vendor header files:
But even without In fact, for the nRF52832 we previously did so, likely because it was just overlooked that this MCU does have the UARTE. The crash I have is in the |
I don't understand why the Github search does not find these files, but hey, it would've been too easy I guess. Maybe it is just stack related? When get_power is forced to return true, the compiler likely optimizes it away, resulting in one less function on the stack. |
A stack overflow should actually be detected by the MPU stack guard. Unless of course that happened too early on. |
According to the UFSR it is an INVSTATE fault some time between Interestingly: If step with I wonder if there is a race condition with the radio sending events to the event queue, but the event queue not yet fully set up. I'll take another look tomorrow. I'm too tired now to investigate. |
It probably won't help if I say "works for me" 👀
I can't really say if the board is actually sending something, but it looks convincing:
For some reason though the ble subsystem is not added for the nRF52840DK and I did not figure out why. This is what the log looks like for the nRF52DK:
But neither of these things have anything to do with what you're seeing I guess? |
No. I also fail to reproduce the issue on a different nrf52840-dk (one that has "nRF52840-Preview-DK" on the silkscreen where the affected board only has "nRF52840-DK"). Maybe I should check the errata. |
The board I have here is a PCA10056 Revision 3.0.1 from 2023.6. The nRF52840 has the following text written on it:
QIAAF0 means that the chip is Revision 3. We have some chips here with Revision CKAAD0, which is Revision 2. But they are not on a Devboard, but integrated in another project. |
OK, here is what I have found so far:
I'm almost certain it is an issue with RIOT not implementing the locks newlib requires to correctly implement reentrant functions, but only protects In any case, I'm 99.999% certain that the issues are unrelated to this PR. |
Previously, uart_poweroff() and uart_poweron() were no-ops. This replaces them with the logic to indeed power on and power off the UART device. Co-authored-by: crasbe <[email protected]>
de99c64
to
f20f795
Compare
I just rebased this. It does now indeed still fix the test in |
@@ -242,6 +260,7 @@ void uart_poweron(uart_t uart) | |||
|
|||
if (isr_ctx[uart].rx_cb) { | |||
uart_config[uart].dev->TASKS_STARTRX = 1; | |||
set_power(uart, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if only tx is configured the UART stays powered down?
Contribution description
Previously, uart_poweroff() and uart_poweron() were no-ops. This replaces them with the logic to indeed power on and power off the UART device.
Testing procedure
uart_poweroff()
uart_write()
while powered off would get stuck if not for the special handling, while before the UART remained fully operational when "powered off"uart_poweron()
Issues/PRs references
None