Skip to content

drivers/cc110x: add power off (sleep) functions#16232

Merged
benpicco merged 4 commits into
RIOT-OS:masterfrom
maribu:drivers/cc110x
Jul 6, 2021
Merged

drivers/cc110x: add power off (sleep) functions#16232
benpicco merged 4 commits into
RIOT-OS:masterfrom
maribu:drivers/cc110x

Conversation

@maribu

@maribu maribu commented Mar 25, 2021

Copy link
Copy Markdown
Member

Contribution description

Add cc110x_sleep() and cc110x_wakeup() to allow low power operation for the CC110x transceivers.

Testing procedure

The test in tests/driver_cc110x has been extended to also contain the sleep and wakeup shell commands.

I used a MIoT-Lab Testbed Node (a Nucleo-F767ZI which contains among others a CC1101 transceiver and a 6 channel power monitoring solution, of which one channel is monitoring the CC1101) for testing.

2021-03-25 12:50:51,778 # main(): This is RIOT! (Version: 2021.04-devel-1144gNETOPT_RX_END_IRQ not implemented by driver
2021-03-25 12:50:51,782 # NETOPT_TX_END_IRQ not implemented by driver
2021-03-25 12:50:51,784 # ec756-drivers/cc110x)
2021-03-25 12:50:51,786 # cc110x driver test application
2021-03-25 12:50:51,789 # ==============================
2021-03-25 12:50:51,789 # 
2021-03-25 12:50:51,795 # Use the shell and two boards equipped with an CC1100/CC1101
2021-03-25 12:50:51,799 # transceiver to test the driver. Common testing tasks:
2021-03-25 12:50:51,799 # 
2021-03-25 12:50:51,801 # - Using "ifconfig":
2021-03-25 12:50:51,807 #     - Check the information stated for plausibility/correctness
2021-03-25 12:50:51,812 #     - Try to get/set parameters like TX power, channel, address, ...
2021-03-25 12:50:51,818 #     - BEWARE: With short communication distances (<=1m) for boards
2021-03-25 12:50:51,824 #       with high gain antennas a high TX power may result in packet
2021-03-25 12:50:51,829 #       loss: The incoming signal can only be demodulated when the
2021-03-25 12:50:51,834 #       input signal is at most +10 dBm on the CC1101.
2021-03-25 12:50:51,839 #     - Check the statistics for correctness/plausibility (after
2021-03-25 12:50:51,843 #       sending frames using "txtsnd" or "ping6")
2021-03-25 12:50:51,845 # - Using "ping6":
2021-03-25 12:50:51,850 #     - Does the other device respond to the ping?
2021-03-25 12:50:51,855 #     - Does the measured RSSI increase when the nodes are closer
2021-03-25 12:50:51,856 #       together?
2021-03-25 12:50:51,862 #     - Try to increase the size of the pings, so that the TX/RX FIFO
2021-03-25 12:50:51,870 #       needs to be filled/drain more than once per frame. The TX/RX
2021-03-25 12:50:51,871 #       FIFO can hold 64 bytes
2021-03-25 12:50:51,875 #     - Try to increase the size of the pings in order to trigger L2
2021-03-25 12:50:51,881 #       fragmentation. The driver supports frames of up to 255 bytes
2021-03-25 12:50:51,883 # - Using "txtsnd":
2021-03-25 12:50:51,889 #     - Turn on packet dumping using the command "dump y" on node A
2021-03-25 12:50:51,894 #     - Send both unicast and broadcast frame from node B to A
2021-03-25 12:50:51,896 # - Using "cc110x":
2021-03-25 12:50:51,902 #     - This tool will print low level details for all CC110x devices
2021-03-25 12:50:51,903 #       attached
2021-03-25 12:50:51,909 #     - This will be mostly useful for debugging, not for testing
2021-03-25 12:50:51,910 # - Using "sleep":
2021-03-25 12:50:51,916 #     - Puts the given (or all, if no iface is given) transceiver into
2021-03-25 12:50:51,918 #       deep sleep mode
2021-03-25 12:50:51,919 # - Using "awake":
2021-03-25 12:50:51,926 #     - Wakes up the given (or all, if no iface is given) transceiver(s)      
2021-03-25 12:50:51,926 #

    ---- power consumption: varying between 0.0616 W at 0.0623 W ----

> sleep
2021-03-25 12:50:55,460 # sleep
2021-03-25 12:50:55,463 # Putting to sleep CC110x #0:

    ---- power consumption: varying between 0.0000 W and 0.0003 W ----

> wakeup
2021-03-25 12:51:01,247 # wakeup
2021-03-25 12:51:01,248 # Waking up CC110x #0:
>

    ---- power consumption: varying between 0.0616 W at 0.0623 W ----

The datasheet say power consumption on RX at 433 MHz receiving at 250 kBaud with settings optimized for current consumption is 17.1 mA (that would be 56.4 mW at 3.3V). In sleep mode current consumption is 200 nA (or ~ 0mW).

Since the driver is not trading in reception quality for lower current consumption, the measurements seem to roughly match the datasheet.

Issues/PRs references

Based on #12294

@maribu maribu added Area: drivers Area: Device drivers Area: network Area: Networking Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation labels Mar 25, 2021
@maribu maribu requested review from benpicco and kYc0o March 25, 2021 12:47
@maribu maribu added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 25, 2021
@benpicco

Copy link
Copy Markdown
Contributor

Why not hook this up with NETOPT_STATE so ifconfig <interface> set state sleep works?
This allows for a generic way to put the radio to sleep, e.g. when the main CPU enters hibernation.

@maribu

maribu commented Mar 26, 2021

Copy link
Copy Markdown
Member Author

Why not hook this up with NETOPT_STATE so ifconfig <interface> set state sleep works?
This allows for a generic way to put the radio to sleep, e.g. when the main CPU enters hibernation.

Done

@maribu

maribu commented Mar 26, 2021

Copy link
Copy Markdown
Member Author

Picked wrong commit for the --fixup param. Should be correct now.

Comment thread drivers/cc110x/cc110x_netdev.c
Comment thread drivers/cc110x/cc110x_netdev.c Outdated
@github-actions github-actions Bot added Area: tests Area: tests and testing framework and removed Area: network Area: Networking labels Jun 8, 2021
@benpicco

benpicco commented Jun 8, 2021

Copy link
Copy Markdown
Contributor

Is there something to pay attention to when using this transceiver?

I wired up two cc1101 modules to a same54-xpro and a samr21-xpro but they don't receive any packets (this is on master still)

node A

2021-06-08 15:57:35,389 # Iface  5  HWaddr: AA  Channel: 0 
2021-06-08 15:57:35,395 #            TX-Power: 0dBm L2-PDU:253  MTU:1280  HL:64  RTR  
2021-06-08 15:57:35,397 #           6LO  IPHC  
2021-06-08 15:57:35,401 #           Source address length: 1
2021-06-08 15:57:35,403 #           Link type: wireless
2021-06-08 15:57:35,408 #           inet6 addr: fe80::ff:fe00:aa  scope: link  VAL
2021-06-08 15:57:35,411 #           inet6 group: ff02::2
2021-06-08 15:57:35,414 #           inet6 group: ff02::1
2021-06-08 15:57:35,417 #           inet6 group: ff02::1:ff00:aa
2021-06-08 15:57:35,418 #           
2021-06-08 15:57:35,421 #           Statistics for Layer 2
2021-06-08 15:57:35,424 #             RX packets 0  bytes 0
2021-06-08 15:57:35,429 #             TX packets 4 (Multicast: 4)  bytes 88
2021-06-08 15:57:35,432 #             TX succeeded 4 errors 0
2021-06-08 15:57:35,435 #           Statistics for IPv6
2021-06-08 15:57:35,438 #             RX packets 0  bytes 0
2021-06-08 15:57:35,442 #             TX packets 4 (Multicast: 4)  bytes 224
2021-06-08 15:57:35,446 #             TX succeeded 4 errors 0
2021-06-08 15:57:35,446 # 
> cc110x
2021-06-08 15:57:38,874 # cc110x
2021-06-08 15:57:38,875 # CC110x #0:
2021-06-08 15:57:38,879 #   GDO0: 0 (High while frame is incoming / outgoing)
2021-06-08 15:57:38,885 #   GDO2: 0 (High when frame received or RX FIFO needs draining)
2021-06-08 15:57:38,888 #   Receiving: 0, CCA: 1, CS: 0
2021-06-08 15:57:38,891 #   RSSI: -104.0dBm, TX power: 0dBm
2021-06-08 15:57:38,896 #   L2 addr: aa, physical channel: 0, virtual channel: 0
2021-06-08 15:57:38,900 #   Driver state: RX mode, transceiver state: RX mode
2021-06-08 15:57:38,902 #   TX FIFO: 0B
2021-06-08 15:57:38,903 #   RX FIFO: 0B

node B

2021-06-08 15:55:29,479 # Iface  5  HWaddr: 5B  Channel: 0 
2021-06-08 15:55:29,484 #            TX-Power: 0dBm L2-PDU:253  MTU:1280  HL:64  RTR  
2021-06-08 15:55:29,486 #           6LO  IPHC  
2021-06-08 15:55:29,489 #           Source address length: 1
2021-06-08 15:55:29,492 #           Link type: wireless
2021-06-08 15:55:29,497 #           inet6 addr: fe80::ff:fe00:5b  scope: link  VAL
2021-06-08 15:55:29,499 #           inet6 group: ff02::2
2021-06-08 15:55:29,502 #           inet6 group: ff02::1
2021-06-08 15:55:29,506 #           inet6 group: ff02::1:ff00:5b
2021-06-08 15:55:29,507 #           
2021-06-08 15:55:29,509 #           Statistics for Layer 2
2021-06-08 15:55:29,512 #             RX packets 0  bytes 0
2021-06-08 15:55:29,517 #             TX packets 2 (Multicast: 2)  bytes 44
2021-06-08 15:55:29,520 #             TX succeeded 2 errors 0
2021-06-08 15:55:29,523 #           Statistics for IPv6
2021-06-08 15:55:29,525 #             RX packets 0  bytes 0
2021-06-08 15:55:29,530 #             TX packets 2 (Multicast: 2)  bytes 112
2021-06-08 15:55:29,533 #             TX succeeded 2 errors 0
2021-06-08 15:55:29,533 # 
cc110xig
2021-06-08 15:55:33,563 # cc110x
2021-06-08 15:55:33,564 # CC110x #0:
2021-06-08 15:55:33,569 #   GDO0: 0 (High while frame is incoming / outgoing)
2021-06-08 15:55:33,574 #   GDO2: 0 (High when frame received or RX FIFO needs draining)
2021-06-08 15:55:33,577 #   Receiving: 0, CCA: 1, CS: 0
2021-06-08 15:55:33,580 #   RSSI: -106.5dBm, TX power: 0dBm
2021-06-08 15:55:33,585 #   L2 addr: 5b, physical channel: 0, virtual channel: 0
2021-06-08 15:55:33,589 #   Driver state: RX mode, transceiver state: RX mode
2021-06-08 15:55:33,591 #   TX FIFO: 0B
2021-06-08 15:55:33,592 #   RX FIFO: 0B
> ping ff02::1
2021-06-08 15:57:18,586 # ping ff02::1
2021-06-08 15:57:21,586 # 
2021-06-08 15:57:21,589 # --- ff02::1 PING statistics ---
2021-06-08 15:57:21,594 # 3 packets transmitted, 0 packets received, 100% packet loss
> ping fe80::ff:fe00:aa
2021-06-08 15:57:28,179 # ping fe80::ff:fe00:aa
2021-06-08 15:57:31,179 # 
2021-06-08 15:57:31,183 # --- fe80::ff:fe00:aa PING statistics ---
2021-06-08 15:57:31,188 # 3 packets transmitted, 0 packets received, 100% packet loss

@maribu

maribu commented Jun 8, 2021

Copy link
Copy Markdown
Member Author

Try with CFLAGS += '-DCC110X_PARAM_PATABLE=(&cc110x_patable_433mhz)' '-DCC110X_PARAM_CHANNELS=(&cc110x_chanmap_433mhz_300khz)' '-DCC110X_PARAM_CONFIG=(&cc110x_config_433mhz_250kbps_300khz)

Assuming you're using the 433 MHz breakout boards with a spring antenna.

@maribu

maribu commented Jun 8, 2021

Copy link
Copy Markdown
Member Author

Maybe I should make 433 the default setting and let the boards in RIOT overwrite with the 868 MHz setting. Even though all boards supported by RIOT are using 868 MHz, it wouldn't hurt to have extra effort once to configure them all. This would ease use of the cheap break out boards, as there no special configuration would then be needed. And like 99% of the break out boards use 433 MHz. And the 868 MHz and 900 MHz CC1101 breakout boards cost more than a proper IEEE 802.15.4 transceiver, so I really cannot see anyone buying 868 MHz CC1101 boards.

@benpicco

benpicco commented Jun 8, 2021

Copy link
Copy Markdown
Contributor

Thank you, with that config it's working.
But the device does not properly wake up from sleep when using ifconfig:

2021-06-08 18:37:05,508 # ping ff02::1
2021-06-08 18:37:05,518 # 12 bytes from fe80::ff:fe00:5b%5: icmp_seq=0 ttl=64 rssi=-38 dBm time=3.122 ms
2021-06-08 18:37:06,519 # 12 bytes from fe80::ff:fe00:5b%5: icmp_seq=1 ttl=64 rssi=-38 dBm time=3.122 ms
2021-06-08 18:37:07,520 # 12 bytes from fe80::ff:fe00:5b%5: icmp_seq=2 ttl=64 rssi=-38 dBm time=3.122 ms
2021-06-08 18:37:07,521 # 
2021-06-08 18:37:07,523 # --- ff02::1 PING statistics ---
2021-06-08 18:37:07,529 # 3 packets transmitted, 3 packets received, 0% packet loss
2021-06-08 18:37:07,533 # round-trip min/avg/max = 3.122/3.122/3.122 ms
ifconfig 5 set state sleep
2021-06-08 18:37:12,061 # ifconfig 5 set state sleep
2021-06-08 18:37:12,065 # success: set state of interface 5 to SLEEP
ping ff02::1ep
2021-06-08 18:37:13,436 # ping ff02::1
2021-06-08 18:37:16,439 # 
2021-06-08 18:37:16,441 # --- ff02::1 PING statistics ---
2021-06-08 18:37:16,447 # 3 packets transmitted, 0 packets received, 100% packet loss
ifconfig 5 set state idle
2021-06-08 18:37:18,885 # ifconfig 5 set state idle
2021-06-08 18:37:18,889 # success: set state of interface 5 to IDLE
ping ff02::1le
2021-06-08 18:37:21,260 # ping ff02::1
2021-06-08 18:37:24,263 # 
2021-06-08 18:37:24,265 # --- ff02::1 PING statistics ---
2021-06-08 18:37:24,271 # 3 packets transmitted, 0 packets received, 100% packet loss
cc110x
2021-06-08 18:37:28,931 # cc110x
2021-06-08 18:37:28,932 # CC110x #0:
2021-06-08 18:37:28,937 #   GDO0: 0 (High while frame is incoming / outgoing)
2021-06-08 18:37:28,942 #   GDO2: 0 (High when frame received or RX FIFO needs draining)
2021-06-08 18:37:28,945 #   Receiving: 0, CCA: 1, CS: 0
2021-06-08 18:37:28,948 #   RSSI: -91.5dBm, TX power: -30dBm
2021-06-08 18:37:28,953 #   L2 addr: aa, physical channel: 0, virtual channel: 0
2021-06-08 18:37:28,958 #   Driver state: RX mode, transceiver state: RX mode
2021-06-08 18:37:28,959 #   TX FIFO: 0B
2021-06-08 18:37:28,960 #   RX FIFO: 0B

@maribu

maribu commented Jun 8, 2021

Copy link
Copy Markdown
Member Author

Was the TX power set to -30 dBm by you, or was the register content lost by the power down? (The data sheet does say that the patable containing the power levels is lost in power off mode. It would make sense if the register containing the currently active power level is also lost.)

@benpicco

benpicco commented Jun 8, 2021

Copy link
Copy Markdown
Contributor

I did not set it, the behavior is not consistent though

2021-06-08 19:01:35,844 # cc110x
2021-06-08 19:01:35,845 # CC110x #0:
2021-06-08 19:01:35,850 #   GDO0: 0 (High while frame is incoming / outgoing)
2021-06-08 19:01:35,855 #   GDO2: 0 (High when frame received or RX FIFO needs draining)
2021-06-08 19:01:35,858 #   Receiving: 0, CCA: 1, CS: 1
2021-06-08 19:01:35,861 #   RSSI: -90.5dBm, TX power: 0dBm
2021-06-08 19:01:35,866 #   L2 addr: 5b, physical channel: 0, virtual channel: 0
2021-06-08 19:01:35,870 #   Driver state: RX mode, transceiver state: RX mode
2021-06-08 19:01:35,871 #   TX FIFO: 0B
2021-06-08 19:01:35,873 #   RX FIFO: 0B
> ifconfig 5 set statsleep 
2021-06-08 19:01:40,854 # ifconfig 5 set state sleep
2021-06-08 19:01:40,858 # success: set state of interface 5 to SLEEP
cc110x
2021-06-08 19:01:42,581 # cc110x
2021-06-08 19:01:42,581 # CC110x #0:
2021-06-08 19:01:42,583 # Device in SLEEP mode
ifconfig 5 set state idle
2021-06-08 19:01:48,142 # ifconfig 5 set state idle
2021-06-08 19:01:48,146 # success: set state of interface 5 to IDLE
cc110x
2021-06-08 19:01:50,733 # cc110x
2021-06-08 19:01:50,733 # CC110x #0:
2021-06-08 19:01:50,736 #   GDO0: 0 (Constant low)
2021-06-08 19:01:50,738 #   GDO2: 0 (Constant low)
2021-06-08 19:01:50,740 #   Receiving: 0, CCA: 1, CS: 0
2021-06-08 19:01:50,743 #   RSSI: -138.0dBm, TX power: 0dBm
2021-06-08 19:01:50,748 #   L2 addr: 5b, physical channel: 0, virtual channel: 0
2021-06-08 19:01:50,752 #   Driver state: RX mode, transceiver state: IDLE
2021-06-08 19:01:50,757 #   WARNING: Transceiver and device state don't match!
2021-06-08 19:01:50,758 #   TX FIFO: 0B
2021-06-08 19:01:50,759 #   RX FIFO: 0B
ping ff02::1
2021-06-08 19:01:54,501 # ping ff02::1
2021-06-08 19:01:57,501 # 
2021-06-08 19:01:57,504 # --- ff02::1 PING statistics ---
2021-06-08 19:01:57,509 # 3 packets transmitted, 0 packets received, 100% packet loss

@maribu

maribu commented Jun 9, 2021

Copy link
Copy Markdown
Member Author

The issue with the incorrect TX power should be fixed now.

I also consistently had a mismatching state of the driver and the transceiver after wake up: driver in RX mode, transceiver in IDLE. This is pretty bad, as the driver expects the transceiver to listen for new frames, while the transceiver doesn't. I have no idea why I didn't encounter this previously. A wild guess would be that the CC110x took longer to power on than the worst case time given in the datasheet. Anyway, I changed the cc110x_power_on() to be more fault tolerant by verifying that the device made it to state IDLE and sending the "go to idle" command until it eventually reaches that state. With this, powering back up works fine for me.

@benpicco benpicco left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sleep & Wakeup now work well, please squash!

@benpicco

Copy link
Copy Markdown
Contributor

Try with CFLAGS += '-DCC110X_PARAM_PATABLE=(&cc110x_patable_433mhz)' '-DCC110X_PARAM_CHANNELS=(&cc110x_chanmap_433mhz_300khz)' '-DCC110X_PARAM_CONFIG=(&cc110x_config_433mhz_250kbps_300khz)

Would be neat to have those settings being set automatically by a submodule, e.g. cc110x_433mhz

@MrKevinWeiss MrKevinWeiss added this to the Release 2021.07 milestone Jun 22, 2021
@benpicco

Copy link
Copy Markdown
Contributor

@maribu ping ;)

@maribu

maribu commented Jun 29, 2021

Copy link
Copy Markdown
Member Author

@maribu ping ;)

Thanks for the reminder!

@maribu

maribu commented Jul 6, 2021

Copy link
Copy Markdown
Member Author

All green now :-)

@benpicco benpicco merged commit 8f9233f into RIOT-OS:master Jul 6, 2021
@MrKevinWeiss MrKevinWeiss removed this from the Release 2021.07 milestone Jul 15, 2021
@benpicco benpicco added this to the Release 2021.10 milestone Oct 20, 2021
@maribu maribu deleted the drivers/cc110x branch January 23, 2022 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: drivers Area: Device drivers Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants