10000 Merge pull request #6960 from jepler/picow-server · adafruit/circuitpython@fcf7cfe · GitHub
[go: up one dir, main page]

Skip to content

Commit fcf7cfe

Browse files
authored
Merge pull request #6960 from jepler/picow-server
Pico W: implement more things
2 parents 39e524f + 0912889 commit fcf7cfe

File tree

11 files changed

+203
-28
lines changed

11 files changed

+203
-28
lines changed

conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ def autoapi_prepare_jinja_env(jinja_env):
213213
"ports/nrf/peripherals",
214214
"ports/nrf/usb",
215215
"ports/raspberrypi/sdk",
216+
"ports/raspberrypi/lib",
216217
"ports/stm/st_driver",
217218
"ports/stm/packages",
218219
"ports/stm/peripherals",

ports/raspberrypi/Makefile

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ INC_CYW43 := \
6565
-isystem sdk/src/rp2_common/pico_cyw43_arch/include/ \
6666
-isystem sdk/src/rp2_common/pico_lwip/include/ \
6767

68-
CFLAGS_CYW43 := -DCYW43_LWIP=1 -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_USE_SPI -DIGNORE_GPIO25 -DCYW43_LOGIC_DEBUG=0
68+
CFLAGS_CYW43 := -DCYW43_LWIP=1 -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_USE_SPI -DIGNORE_GPIO25 -DIGNORE_GPIO23 -DCYW43_LOGIC_DEBUG=0
6969
SRC_SDK_CYW43 := \
7070
src/common/pico_sync/sem.c \
7171
src/rp2_common/cyw43_driver/cyw43_bus_pio_spi.c \
@@ -110,21 +110,6 @@ $(BUILD)/cyw43_resource.o: lib/cyw43-driver/firmware/$(CYW43_FIRMWARE_BIN)
110110
--redefine-sym _binary_lib_cyw43_driver_firmware_43439A0_7_95_49_00_combined_end=fw_43439A0_7_95_49_00_end \
111111
$< $@
112112
OBJ_CYW43 := $(BUILD)/cyw43_resource.o
113-
# need to do the equivalent of this in cmake
114-
### # cyw43_resource.o contains the WiFi and BT firmware as a binary blob
115-
### add_custom_command(
116-
### OUTPUT ${CYW43_FIRMWARE_OBJ}
117-
### DEPENDS ${PICO_CYW43_DRIVER_PATH}/firmware/${CYW43_FIRMWARE_BIN}
118-
### WORKING_DIRECTORY ${PICO_CYW43_DRIVER_PATH}/firmware
119-
### COMMAND ${CMAKE_OBJCOPY} -I binary -O elf32-littlearm -B arm
120-
### --readonly-text
121-
### --rename-section .data=${RESOURCE_SECNAME},${RESOURCE_SECFLAGS}
122-
### --redefine-sym _binary_${CYW43_FIRMWARE_BIN_}_start=${CYW43_FIRMWARE_PRETTY}_start
123-
### --redefine-sym _binary_${CYW43_FIRMWARE_BIN_}_end=${CYW43_FIRMWARE_PRETTY}_end
124-
### --redefine-sym _binary_${CYW43_FIRMWARE_BIN_}_size=${CYW43_FIRMWARE_PRETTY}_size
125-
### ${CYW43_FIRMWARE_BIN} ${CYW43_FIRMWARE_OBJ}
126-
### )
127-
###
128113
else
129114
INC_CYW43 :=
130115
CFLAGS_CYW43 :=

ports/raspberrypi/bindings/cyw43/__init__.c

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

35+
//| class CywPin:
36+
//| """A class that represents a GPIO pin attached to the wifi chip.
37+
//|
38+
//| Cannot be constructed at runtime, but may be the type of a pin object
39+
//| in :py:mod:`board`. A `CywPin` can be used as a DigitalInOut, but not with other
40+
//| peripherals such as `PWMOut`."""
3541
const mp_obj_type_t cyw43_pin_type = {
3642
{ &mp_type_type },
3743
.flags = MP_TYPE_FLAG_EXTENDED,
@@ -42,6 +48,22 @@ const mp_obj_type_t cyw43_pin_type = {
4248
)
4349
};
4450

51+
//| def set_power_management(value: int) -> None:
52+
//| """Set the power management register
53+
//|
54+
//| According to Raspberry Pi documentation, the value 0xa11140
55+
//| increases responsiveness at the cost of higher power usage.
56+
//|
57+
//| Besides this value, there appears to be no other public documentation
58+
//| of the values that can be used.
59+
//| """
60+
STATIC mp_obj_t cyw43_set_power_management(const mp_obj_t value_in) {
61+
mp_int_t value = mp_obj_get_int(value_in);
62+
cyw43_wifi_pm(&cyw43_state, value);
63+
return mp_const_none;
64+
}
65+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(cyw43_set_power_management_obj, cyw43_set_power_management);
66+
4567
const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj) {
4668
if (!mp_obj_is_type(obj, &mcu_pin_type) && !mp_obj_is_type(obj, &cyw43_pin_type)) {
4769
mp_raise_TypeError_varg(translate("Expected a %q or %q"), mcu_pin_type.name, cyw43_pin_type.name);
@@ -58,6 +80,7 @@ const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj) {
5880
STATIC const mp_rom_map_elem_t cyw43_module_globals_table[] = {
5981
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cyw43) },
6082
{ MP_ROM_QSTR(MP_QSTR_CywPin), MP_ROM_QSTR(MP_QSTR_CywPin) },
83+
{ MP_ROM_QSTR(MP_QSTR_set_power_management), &cyw43_set_power_management_obj },
6184
};
6285

6386
STATIC MP_DEFINE_CONST_DICT(cyw43_module_globals, cyw43_module_globals_table);

ports/raspberrypi/boards/raspberry_pi_pico_w/pins.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
2727
{ MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) },
2828
{ MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) },
2929

30-
{ MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) },
31-
{ MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) },
30+
{ MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_CYW1) },
31+
{ MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_CYW1) },
3232

3333
{ MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24) },
3434
{ MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) },

ports/raspberrypi/common-hal/digitalio/DigitalInOut.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ void common_hal_digitalio_digitalinout_set_value(
140140

141141
bool common_hal_digitalio_digitalinout_get_value(
142142
digitalio_digitalinout_obj_t *self) {
143+
#if CIRCUITPY_CYW43
144+
if (IS_CYW(self)) {
145+
return cyw43_arch_gpio_get(self->pin->number);
146+
}
147+
#endif
143148
return gpio_get(self->pin->number);
144149
}
145150

ports/raspberrypi/common-hal/microcontroller/__init__.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = {
173173
{ MP_ROM_QSTR(MP_QSTR_GPIO20), MP_ROM_PTR(&pin_GPIO20) },
174174
{ MP_ROM_QSTR(MP_QSTR_GPIO21), MP_ROM_PTR(&pin_GPIO21) },
175175
{ MP_ROM_QSTR(MP_QSTR_GPIO22), MP_ROM_PTR(&pin_GPIO22) },
176+
#if !defined(IGNORE_GPIO23)
176177
{ MP_ROM_QSTR(MP_QSTR_GPIO23), MP_ROM_PTR(&pin_GPIO23) },
178+
#endif
177179
{ MP_ROM_QSTR(MP_QSTR_GPIO24), MP_ROM_PTR(&pin_GPIO24) },
178180
#if !defined(IGNORE_GPIO25)
179181
{ MP_ROM_QSTR(MP_QSTR_GPIO25), MP_ROM_PTR(&pin_GPIO25) },
@@ -184,6 +186,7 @@ const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = {
184186
{ MP_ROM_QSTR(MP_QSTR_GPIO29), MP_ROM_PTR(&pin_GPIO29) },
185187
#if CIRCUITPY_CYW43
186188
{ MP_ROM_QSTR(MP_QSTR_CYW0), MP_ROM_PTR(&pin_CYW0) },
189+
{ MP_ROM_QSTR(MP_QSTR_CYW1), MP_ROM_PTR(&pin_CYW1) },
187190
#endif
188191
};
189192
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table);

ports/raspberrypi/common-hal/socketpool/Socket.c

Lines changed: 140 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "py/stream.h"
3838
#include "shared-bindings/socketpool/SocketPool.h"
3939
#include "shared/runtime/interrupt_char.h"
40+
#include "shared/netutils/netutils.h"
4041
#include "supervisor/port.h"
4142
#include "supervisor/shared/tick.h"
4243
#include "supervisor/workflow.h"
@@ -115,6 +116,10 @@ static inline void poll_sockets(void) {
115116
#ifdef MICROPY_EVENT_POLL_HOOK
116117
MICROPY_EVENT_POLL_HOOK;
117118
#else
119+
RUN_BACKGROUND_TASKS;
120+
if (MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) {
121+
mp_handle_pending(true);
122+
}
118123
mp_hal_delay_ms(1);
119124
#endif
120125
}
@@ -739,14 +744,117 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_
739744
return -MP_EBADF;
740745
}
741746

742-
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self,
747+
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *socket,
743748
uint8_t *ip, uint32_t *port) {
744-
mp_raise_NotImplementedError(NULL);
749+
if (socket->type != MOD_NETWORK_SOCK_STREAM) {
750+
mp_raise_OSError(MP_EOPNOTSUPP);
751+
}
752+
753+
// Create new socket object, do it here because we must not raise an out-of-memory
754+
// exception when the LWIP concurrency lock is held
755+
socketpool_socket_obj_t *socket2 = m_new_ll_obj_with_finaliser(socketpool_socket_obj_t);
756+
socket2->base.type = &socketpool_socket_type;
757+
758+
MICROPY_PY_LWIP_ENTER
759+
760+
if (socket->pcb.tcp == NULL) {
761+
MICROPY_PY_LWIP_EXIT
762+
m_del_obj(socketpool_socket_obj_t, socket2);
763+
mp_raise_OSError(MP_EBADF);
764+
}
765+
766+
// I need to do this because "tcp_accepted", later, is a macro.
767+
struct tcp_pcb *listener = socket->pcb.tcp;
768+
if (listener->state != LISTEN) {
769+
MICROPY_PY_LWIP_EXIT
770+
m_del_obj(socketpool_socket_obj_t, socket2);
771+
mp_raise_OSError(MP_EINVAL);
772+
}
773+
774+
// accept incoming connection
775+
struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(socket)[socket->incoming.connection.iget];
776+
if (*incoming_connection == NULL) {
777+
if (socket->timeout == 0) {
778+
MICROPY_PY_LWIP_EXIT
779+
m_del_obj(socketpool_socket_obj_t, socket2);
780+
mp_raise_OSError(MP_EAGAIN);
781+
} else if (socket->timeout != -1) {
782+
mp_uint_t retries = socket->timeout / 100;
783+
while (*incoming_connection == NULL) {
784+
MICROPY_PY_LWIP_EXIT
785+
if (retries-- == 0) {
786+
m_del_obj(socketpool_socket_obj_t, socket2);
787+
mp_raise_OSError(MP_ETIMEDOUT);
788+
}
789+
mp_hal_delay_ms(100);
790+
MICROPY_PY_LWIP_REENTER
791+
}
792+
} else {
793+
while (*incoming_connection == NULL) {
794+
MICROPY_PY_LWIP_EXIT
795+
poll_sockets();
796+
MICROPY_PY_LWIP_REENTER
797+
}
798+
}
799+
}
800+
801+
// We get a new pcb handle...
802+
socket2->pcb.tcp = *incoming_connection;
803+
if (++socket->incoming.connection.iget >= socket->incoming.connection.alloc) {
804+
socket->incoming.connection.iget = 0;
805+
}
806+
*incoming_connection = NULL;
807+
808+
// ...and set up the new socket for it.
809+
socket2->domain = MOD_NETWORK_AF_INET;
810+
socket2->type = MOD_NETWORK_SOCK_STREAM;
811+
socket2->incoming.pbuf = NULL;
812+
socket2->timeout = socket->timeout;
813+
socket2->state = STATE_CONNECTED;
814+
socket2->recv_offset = 0;
815+
socket2->callback = MP_OBJ_NULL;
816+
tcp_arg(socket2->pcb.tcp, (void *)socket2);
817+
tcp_err(socket2->pcb.tcp, _lwip_tcp_error);
818+
tcp_recv(socket2->pcb.tcp, _lwip_tcp_recv);
819+
820+
tcp_accepted(listener);
821+
822+
MICROPY_PY_LWIP_EXIT
823+
824+
// output values
825+
memcpy(ip, &(socket2->pcb.tcp->remote_ip), NETUTILS_IPV4ADDR_BUFSIZE);
826+
*port = (mp_uint_t)socket2->pcb.tcp->remote_port;
827+
return MP_OBJ_FROM_PTR(socket2);
745828
}
746829

747-
bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *self,
830+
bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *socket,
748831
const char *host, size_t hostlen, uint32_t port) {
749-
mp_raise_NotImplementedError(NULL);
832+
uint8_t ip[NETUTILS_IPV4ADDR_BUFSIZE];
833+
834+
// get address
835+
ip_addr_t bind_addr;
836+
int error = socketpool_resolve_host(socket->pool, host, &bind_addr);
837+
if (error != 0) {
838+
mp_raise_OSError(EHOSTUNREACH);
839+
}
840+
841+
err_t err = ERR_ARG;
842+
switch (socket->type) {
843+
case MOD_NETWORK_SOCK_STREAM: {
844+
err = tcp_bind(socket->pcb.tcp, &bind_addr, port);
845+
break;
846+
}
847+
case MOD_NETWORK_SOCK_DGRAM: {
848+
err = udp_bind(socket->pcb.udp, &bind_addr, port);
849+
break;
850+
}
851+
}
852+
853+
if (err != ERR_OK) {
854+
mp_raise_OSError(error_lookup_table[-err]);
855+
}
856+
857+
return mp_const_none;
750858
}
751859

752860
STATIC err_t _lwip_tcp_close_poll(void *arg, struct tcp_pcb *pcb) {
@@ -891,8 +999,34 @@ bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *socket)
891999
return socket->state == STATE_CONNECTED;
8921000
}
8931001

894-
bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int backlog) {
895-
mp_raise_NotImplementedError(NULL);
1002+
bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *socket, int backlog) {
1003+
if (socket->type != MOD_NETWORK_SOCK_STREAM) {
1004+
mp_raise_OSError(MP_EOPNOTSUPP);
1005+
}
1006+
1007+
struct tcp_pcb *new_pcb = tcp_listen_with_backlog(socket->pcb.tcp, (u8_t)backlog);
1008+
if (new_pcb == NULL) {
1009+
mp_raise_OSError(MP_ENOMEM);
1010+
}
1011+
socket->pcb.tcp = new_pcb;
1012+
1013+
// Allocate memory for the backlog of connections
1014+
if (backlog <= 1) {
1015+
socket->incoming.connection.alloc = 0;
1016+
socket->incoming.connection.tcp.item = NULL;
1017+
} else {
1018+
socket->incoming.connection.alloc = backlog;
1019+
socket->incoming.connection.tcp.array = m_new0(struct tcp_pcb *, backlog);
1020+
}
1021+
socket->incoming.connection.iget = 0;
1022+
socket->incoming.connection.iput = 0;
1023+
1024+
tcp_accept(new_pcb, _lwip_tcp_accept);
1025+
1026+
// Socket is no longer considered "new" for purposes of polling
1027+
socket->state = STATE_LISTENING;
1028+
1029+
return mp_const_none;
8961030
}
8971031

8981032
mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *socket,

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@
5959
#define NETIF_STA (&cyw43_state.netif[CYW43_ITF_STA])
6060
#define NETIF_AP (&cyw43_state.netif[CYW43_ITF_AP])
6161

62+
static inline uint32_t nw_get_le32(const uint8_t *buf) {
63+
return buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24;
64+
}
65+
66+
static inline void nw_put_le32(uint8_t *buf, uint32_t x) {
67+
buf[0] = x;
68+
buf[1] = x >> 8;
69+
buf[2] = x >> 16;
70+
buf[3] = x >> 24;
71+
}
72+
6273
NORETURN static void ro_attribute(int attr) {
6374
mp_raise_msg_varg(&mp_type_AttributeError, MP_ERROR_TEXT("'%s' object has no attribute '%q'"), "Radio", attr);
6475
}
@@ -81,7 +92,10 @@ mp_obj_t common_hal_wifi_radio_get_hostname(wifi_radio_obj_t *self) {
8192
}
8293

8394
void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *hostname) {
84-
ro_attribute(MP_QSTR_hostname);
95+
assert(strlen(hostname) < MP_ARRAY_SIZE(self->hostname));
96+
memcpy(self->hostname, hostname, strlen(hostname));
97+
netif_set_hostname(NETIF_STA, self->hostname);
98+
netif_set_hostname(NETIF_AP, self->hostname);
8599
}
86100

87101
mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) {
@@ -93,12 +107,19 @@ void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const uint8_t
93107
}
94108

95109
mp_float_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self) {
96-
return MICROPY_FLOAT_CONST(0.);
110+
uint8_t buf[13];
111+
memcpy(buf, "qtxpower\x00\x00\x00\x00\x00", 13);
112+
cyw43_ioctl(&cyw43_state, CYW43_IOCTL_GET_VAR, 13, buf, CYW43_ITF_STA);
113+
return nw_get_le32(buf) * MICROPY_FLOAT_CONST(0.25);
97114
}
98115

99116
void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const mp_float_t tx_power) {
100-
ro_attribute(MP_QSTR_tx_power);
101-
117+
mp_int_t dbm_times_four = (int)(4 * tx_power);
118+
uint8_t buf[9 + 4];
119+
memcpy(buf, "qtxpower\x00", 9);
120+
nw_put_le32(buf + 9, dbm_times_four);
121+
cyw43_ioctl(&cyw43_state, CYW43_IOCTL_SET_VAR, 9 + 4, buf, CYW43_ITF_STA);
122+
cyw43_ioctl(&cyw43_state, CYW43_IOCTL_SET_VAR, 9 + 4, buf, CYW43_ITF_AP);
102123
}
103124

104125
mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
typedef struct {
3535
mp_obj_base_t base;
36+
char hostname[254]; // hostname max is 253 chars, + 1 for trailing NUL
3637
wifi_scannednetworks_obj_t *current_scan;
3738
} wifi_radio_obj_t;
3839

ports/raspberrypi/peripherals/pins.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,5 @@ PIN(28);
7575
PIN(29);
7676
#if CIRCUITPY_CYW43
7777
CYW_PIN(0);
78+
CYW_PIN(1);
7879
#endif

ports/raspberrypi/peripherals/pins.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ extern const mcu_pin_obj_t pin_GPIO29;
7272

7373
#if CIRCUITPY_CYW43
7474
extern const mcu_pin_obj_t pin_CYW0;
75+
extern const mcu_pin_obj_t pin_CYW1;
7576
#endif
7677

7778
#endif // MICROPY_INCLUDED_RASPBERRYPI_PERIPHERALS_PINS_H

0 commit comments

Comments
 (0)
0