Skip to content

Commit c518d68

Browse files
authored
Merge pull request #6976 from jepler/picow-pm
Set "disabled" PM at reset, provide PM constants and better documentation
2 parents f9e655d + 40c2de8 commit c518d68

File tree

3 files changed

+77
-5
lines changed

3 files changed

+77
-5
lines changed

ports/raspberrypi/bindings/cyw43/__init__.c

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
#include "shared-bindings/microcontroller/Pin.h"
3333
#include "bindings/cyw43/__init__.h"
3434

35+
36+
static int power_management_value = PM_DISABLED;
37+
38+
void bindings_cyw43_wifi_enforce_pm() {
39+
cyw43_wifi_pm(&cyw43_state, power_management_value);
40+
}
41+
3542
//| class CywPin:
3643
//| """A class that represents a GPIO pin attached to the wifi chip.
3744
//|
@@ -49,23 +56,60 @@ const mp_obj_type_t cyw43_pin_type = {
4956
)
5057
};
5158

59+
//| PM_STANDARD: int
60+
//| """The standard power management mode"""
61+
//| PM_AGGRESSIVE: int
62+
//| """Aggressive power management mode for optimal power usage at the cost of performance"""
63+
//| PM_PERFORMANCE: int
64+
//| """Performance power management mode where more power is used to increase performance"""
65+
//| PM_DISABLED: int
66+
//| """Disable power management and always use highest power mode. CircuitPython sets this value at reset time, because it provides the best connectivity reliability."""
67+
//|
5268
//| def set_power_management(value: int) -> None:
5369
//| """Set the power management register
5470
//|
55-
//| According to Raspberry Pi documentation, the value 0xa11140
56-
//| increases responsiveness at the cost of higher power usage.
71+
//| For transmitter power, see ``wifi.Radio.txpower``.
72+
//| This controls software power saving features inside the cyw43 chip.
73+
//| it does not control transmitter power.
74+
//|
75+
//| The value is interpreted as a 24-bit hexadecimal number of the form
76+
//| ``0x00adbrrm``.
77+
//|
78+
//| The low 4 bits, ``m``, are the power management mode:
79+
//| * 0: disabled
80+
//| * 1: aggressive power saving which reduces wifi throughput
81+
//| * 2: Power saving with high througput
5782
//|
58-
//| Besides this value, there appears to be no other public documentation
59-
//| of the values that can be used.
83+
//| The next 8 bits, ``r``, specify "the maximum time to wait before going back to sleep" for power management mode 2. The units of ``r`` are 10ms.
84+
//|
85+
//| The next 4 bits, ``b``, are the "wake period is measured in beacon periods".
86+
//|
87+
//| The next 4 bits, ``d``, specify the "wake interval measured in DTIMs. If this is set to 0, the wake interval is measured in beacon periods".
88+
//|
89+
//| The top 4 bits, ``a``, specifies the "wake interval sent to the access point"
90+
//|
91+
//| Several ``PM_`` constants gathered from various sources are included
92+
//| in this module. According to Raspberry Pi documentation, the value 0xa11140
93+
//| (called `cyw43.PM_DISABLED` here) increases responsiveness at the cost of higher power
94+
//| usage.
6095
//| """
6196
//|
6297
STATIC mp_obj_t cyw43_set_power_management(const mp_obj_t value_in) {
6398
mp_int_t value = mp_obj_get_int(value_in);
64-
cyw43_wifi_pm(&cyw43_state, value);
99+
power_management_value = value;
100+
bindings_cyw43_wifi_enforce_pm();
65101
return mp_const_none;
66102
}
67103
STATIC MP_DEFINE_CONST_FUN_OBJ_1(cyw43_set_power_management_obj, cyw43_set_power_management);
68104

105+
//| def get_power_management() -> int:
106+
//| """Retrieve the power management register"""
107+
//|
108+
STATIC mp_obj_t cyw43_get_power_management() {
109+
return mp_obj_new_int(power_management_value);
110+
}
111+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(cyw43_get_power_management_obj, cyw43_get_power_management);
112+
69113
const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj) {
70114
if (!mp_obj_is_type(obj, &mcu_pin_type) && !mp_obj_is_type(obj, &cyw43_pin_type)) {
71115
mp_raise_TypeError_varg(translate("Expected a %q or %q"), mcu_pin_type.name, cyw43_pin_type.name);
@@ -83,6 +127,11 @@ STATIC const mp_rom_map_elem_t cyw43_module_globals_table[] = {
83127
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cyw43) },
84128
{ MP_ROM_QSTR(MP_QSTR_CywPin), MP_ROM_QSTR(MP_QSTR_CywPin) },
85129
{ MP_ROM_QSTR(MP_QSTR_set_power_management), &cyw43_set_power_management_obj },
130+
{ MP_ROM_QSTR(MP_QSTR_get_power_management), &cyw43_get_power_management_obj },
131+
{ MP_ROM_QSTR(MP_QSTR_PM_STANDARD), MP_ROM_INT(PM_STANDARD) },
132+
{ MP_ROM_QSTR(MP_QSTR_PM_AGGRESSIVE), MP_ROM_INT(PM_AGGRESSIVE) },
133+
{ MP_ROM_QSTR(MP_QSTR_PM_PERFORMANCE), MP_ROM_INT(PM_PERFORMANCE) },
134+
{ MP_ROM_QSTR(MP_QSTR_PM_DISABLED), MP_ROM_INT(PM_DISABLED) },
86135
};
87136

88137
STATIC MP_DEFINE_CONST_DICT(cyw43_module_globals, cyw43_module_globals_table);

ports/raspberrypi/bindings/cyw43/__init__.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,26 @@
2828
#pragma once
2929

3030
#include "py/obj.h"
31+
#include "common-hal/microcontroller/Pin.h"
3132

3233
extern const mp_obj_type_t cyw43_pin_type;
3334
const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj);
3435
const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj);
36+
37+
#define CONSTANT_CYW43_PM_VALUE(pm_mode, pm2_sleep_ret_ms, li_beacon_period, li_dtim_period, li_assoc) \
38+
(li_assoc << 20 | /* listen interval sent to ap */ \
39+
li_dtim_period << 16 | \
40+
li_beacon_period << 12 | \
41+
(pm2_sleep_ret_ms / 10) << 4 | /* cyw43_ll_wifi_pm multiplies this by 10 */ \
42+
pm_mode /* CYW43_PM2_POWERSAVE_MODE etc */)
43+
44+
// CYW43_DEFAULT_PM (except a compile-time constant)
45+
#define PM_STANDARD CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 200, 1, 1, 10)
46+
// CYW43_AGGRESSIVE_PM (except a compile-time constant)
47+
#define PM_AGGRESSIVE CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 2000, 1, 1, 10)
48+
// CYW43_PERFORMANCE_PM (except a compile-time constant)
49+
#define PM_PERFORMANCE CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 20, 1, 1, 1)
50+
// The 0xa11140 magic value
51+
#define PM_DISABLED CONSTANT_CYW43_PM_VALUE(CYW43_NO_POWERSAVE_MODE, 200, 1, 1, 10)
52+
53+
extern void bindings_cyw43_wifi_enforce_pm(void);

ports/raspberrypi/common-hal/wifi/Radio.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "shared/runtime/interrupt_char.h"
3636
#include "py/gc.h"
3737
#include "py/runtime.h"
38+
#include "bindings/cyw43/__init__.h"
3839
#include "shared-bindings/ipaddress/IPv4Address.h"
3940
#include "shared-bindings/wifi/ScannedNetworks.h"
4041
#include "shared-bindings/wifi/AuthMode.h"
@@ -152,13 +153,15 @@ void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) {
152153

153154
void common_hal_wifi_radio_start_station(wifi_radio_obj_t *self) {
154155
cyw43_arch_enable_sta_mode();
156+
bindings_cyw43_wifi_enforce_pm();
155157
}
156158

157159
void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self) {
158160
}
159161

160162
void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint8_t authmode, uint8_t max_connections) {
161163
mp_raise_NotImplementedError(NULL);
164+
bindings_cyw43_wifi_enforce_pm();
162165
}
163166

164167
void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self) {
@@ -173,6 +176,7 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t
173176
// TODO use connect_async so we can service bg tasks & check for ctrl-c during
174177
// connect
175178
int result = cyw43_arch_wifi_connect_timeout_ms((const char *)ssid, (const char *)password, CYW43_AUTH_WPA2_AES_PSK, timeout_ms);
179+
bindings_cyw43_wifi_enforce_pm();
176180
switch (result) {
177181
case 0:
178182
return WIFI_RADIO_ERROR_NONE;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy