Skip to content

Commit 80ededb

Browse files
committed
Experimental: PINT module bindings.
P.I.N.T Python Implementation of Network Transports.
1 parent 3b03a30 commit 80ededb

File tree

12 files changed

+635
-0
lines changed

12 files changed

+635
-0
lines changed

.github/workflows/micropython.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ jobs:
2323
board: RPI_PICO_USB
2424
- name: picow
2525
board: RPI_PICO_W
26+
- name: pico_pint
27+
board: RPI_PICO_PINT
2628
- name: tiny2040_8mb
2729
board: PIMORONI_TINY2040
2830
- name: picolipo_4mb
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"deploy": [
3+
"../deploy.md"
4+
],
5+
"docs": "",
6+
"features": [
7+
"Breadboard friendly",
8+
"Castellated Pads",
9+
"Micro USB"
10+
],
11+
"id": "rp2-pico",
12+
"images": [
13+
"rp2-pico.jpg"
14+
],
15+
"mcu": "rp2040",
16+
"product": "Pico",
17+
"thumbnail": "",
18+
"url": "https://www.raspberrypi.com/products/raspberry-pi-pico/",
19+
"vendor": "Raspberry Pi"
20+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
include("$(PORT_DIR)/boards/manifest.py")
2+
3+
require("bundle-networking")
4+
5+
include("../manifest_pico.py")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# cmake file for Raspberry Pi Pico
2+
set(PICO_BOARD "pico")
3+
4+
# Board specific version of the frozen manifest
5+
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
6+
7+
set(MICROPY_C_HEAP_SIZE 4096)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Board and hardware specific configuration
2+
#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico"
3+
#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024)
4+
5+
// Enable networking.
6+
#define MICROPY_PY_NETWORK 1
7+
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico"
8+
9+
extern const struct _mp_obj_type_t mod_network_nic_type_pint;
10+
#define MICROPY_HW_NIC_PINT { MP_ROM_QSTR(MP_QSTR_PINT), MP_ROM_PTR(&mod_network_nic_type_pint) },
11+
12+
#define MICROPY_BOARD_NETWORK_INTERFACES \
13+
MICROPY_HW_NIC_PINT
14+
15+
#define MICROPY_PY_SOCKET_EXTENDED_STATE 1
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
GP0,GPIO0
2+
GP1,GPIO1
3+
GP2,GPIO2
4+
GP3,GPIO3
5+
GP4,GPIO4
6+
GP5,GPIO5
7+
GP6,GPIO6
8+
GP7,GPIO7
9+
GP8,GPIO8
10+
GP9,GPIO9
11+
GP10,GPIO10
12+
GP11,GPIO11
13+
GP12,GPIO12
14+
GP13,GPIO13
15+
GP14,GPIO14
16+
GP15,GPIO15
17+
GP16,GPIO16
18+
GP17,GPIO17
19+
GP18,GPIO18
20+
GP19,GPIO19
21+
GP20,GPIO20
22+
GP21,GPIO21
23+
GP22,GPIO22
24+
GP25,GPIO25
25+
GP26,GPIO26
26+
GP27,GPIO27
27+
GP28,GPIO28
28+
LED,GPIO25
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
include_directories(${CMAKE_CURRENT_LIST_DIR}/../../)
2+
3+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
4+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
5+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../")
6+
7+
set(CMAKE_C_STANDARD 11)
8+
set(CMAKE_CXX_STANDARD 17)
9+
10+
include(micropython-common)
11+
include(pint/micropython)
12+
13+
# C++ Magic Memory
14+
include(cppmem/micropython)

micropython/modules/pint/README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# P.I.N.T
2+
3+
### Python Implementation of Network Transports.
4+
5+
Want to glue your esoteric network device into MicroPython without delving
6+
into C or trying to figure out lwIP? PINT is just the refreshment you need.
7+
8+
### Reference Implementation
9+
10+
PINT uses a Python class to implement a socket-based networking driver.
11+
12+
How you implement these functions is down to you- but you must expect/return
13+
the correct data. Here's the basic skeleton:
14+
15+
```python
16+
class PINT_Socket():
17+
"""An arbitrary structure for storing data about your sockets.
18+
19+
Does not have to be a class, you could just return an int with the
20+
socket ID of your target device.
21+
"""
22+
def __init__(self):
23+
pass
24+
25+
26+
class PINT_NIC:
27+
"""The actual NIC implementation.
28+
29+
Most of the heavy lifting is sockets based, you might want to implement
30+
the socket_ methods on your socket class and simply delegate to them.
31+
"""
32+
def __init__(self) -> None:
33+
pass
34+
35+
def __del__(self) -> None:
36+
pass
37+
38+
def gethostbyname(self, name: str) -> tuple[int, int, int, int]:
39+
return (127, 0, 0, 1)
40+
41+
def socket_socket(self) -> PINT_Socket:
42+
return PINT_Socket()
43+
44+
def socket_close(self, socket: PINT_Socket) -> None:
45+
pass
46+
47+
def socket_bind(self, socket: PINT_Socket, ip: tuple[int, int, int, int], port: int) -> bool:
48+
return True
49+
50+
def socket_listen(self, socket: PINT_Socket, backlog: int) -> bool:
51+
return True
52+
53+
def socket_accept(self, socket: PINT_Socket, socket2: PINT_Socket, ip: tuple[int, int, int, int], port: int) -> bool:
54+
return True
55+
56+
def socket_connect(self, socket: PINT_Socket, ip: tuple[int, int, int, int], port) -> bool:
57+
return True
58+
59+
def socket_send(self, socket: PINT_Socket, buf: bytearray) -> int:
60+
return 0
61+
62+
def socket_recv(self, socket: PINT_Socket, buf: bytearray) -> int:
63+
"""Buf is provided as a mutable bytearray, you must write into it."""
64+
return 0
65+
66+
def socket_sendto(self, socket: PINT_Socket, buf: bytearray, ip, port) -> int:
67+
return 0
68+
69+
def socket_recvfrom(self, socket: PINT_Socket, buf: bytearray, ip, port) -> int:
70+
"""Buf is provided as a mutable bytearray, you must write into it."""
71+
return 0
72+
73+
def socket_setsockopt(self, socket: PINT_Socket, level: int, opt: int, val: bytearray) -> bool:
74+
return True
75+
76+
def socket_settimeout(self, socket: PINT_Socket, timeout_ms: int) -> bool:
77+
return True
78+
79+
def socket_ioctl(self, socket: PINT_Socket, request: int, arg: int) -> bool:
80+
return True
81+
82+
```
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
set(MOD_NAME pint)
2+
string(TOUPPER ${MOD_NAME} MOD_NAME_UPPER)
3+
add_library(usermod_${MOD_NAME} INTERFACE)
4+
5+
target_sources(usermod_${MOD_NAME} INTERFACE
6+
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c
7+
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp
8+
)
9+
10+
target_include_directories(usermod_${MOD_NAME} INTERFACE
11+
${CMAKE_CURRENT_LIST_DIR}
12+
)
13+
14+
target_compile_definitions(usermod_${MOD_NAME} INTERFACE
15+
MODULE_PINT_ENABLED=1
16+
)
17+
18+
target_link_libraries(usermod INTERFACE usermod_${MOD_NAME})

micropython/modules/pint/pint.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "pint.h"
2+
3+
MP_DEFINE_CONST_FUN_OBJ_1(network_pint__del__obj, network_pint__del__);
4+
5+
static const mod_network_nic_protocol_t mod_network_nic_protocol_pint = {
6+
.gethostbyname = network_pint_gethostbyname,
7+
.deinit = network_pint_deinit,
8+
.socket = network_pint_socket_socket,
9+
.close = network_pint_socket_close,
10+
.bind = network_pint_socket_bind,
11+
.listen = network_pint_socket_listen,
12+
.accept = network_pint_socket_accept,
13+
.connect = network_pint_socket_connect,
14+
.send = network_pint_socket_send,
15+
.recv = network_pint_socket_recv,
16+
.sendto = network_pint_socket_sendto,
17+
.recvfrom = network_pint_socket_recvfrom,
18+
.setsockopt = network_pint_socket_setsockopt,
19+
.settimeout = network_pint_socket_settimeout,
20+
.ioctl = network_pint_socket_ioctl,
21+
};
22+
23+
static const mp_rom_map_elem_t pint_locals_dict_table[] = {
24+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&network_pint__del__obj) },
25+
};
26+
27+
static MP_DEFINE_CONST_DICT(pint_locals_dict, pint_locals_dict_table);
28+
29+
MP_DEFINE_CONST_OBJ_TYPE(
30+
mod_network_nic_type_pint,
31+
MP_QSTR_pint,
32+
MP_TYPE_FLAG_NONE,
33+
make_new, network_pint_make_new,
34+
locals_dict, &pint_locals_dict,
35+
protocol, &mod_network_nic_protocol_pint
36+
);
37+
38+
#ifdef NETWORK_PINT_MODULE
39+
static const mp_map_elem_t pint_globals_table[] = {
40+
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pint) },
41+
{ MP_OBJ_NEW_QSTR(MP_QSTR_PINT), (mp_obj_t)&mod_network_nic_type_pint },
42+
};
43+
44+
static MP_DEFINE_CONST_DICT(mp_module_pint_globals, pint_globals_table);
45+
46+
const mp_obj_module_t pint_user_cmodule = {
47+
.base = { &mp_type_module },
48+
.globals = (mp_obj_dict_t*)&mp_module_pint_globals,
49+
};
50+
51+
MP_REGISTER_MODULE(MP_QSTR_pint, pint_user_cmodule);
52+
#endif

0 commit comments

Comments
 (0)