Skip to content

Commit 0611127

Browse files
committed
Add W55RP20-EVB-Pico, W6300-EVB-Pico2
1 parent 0707e28 commit 0611127

23 files changed

Lines changed: 1636 additions & 0 deletions

ports/raspberrypi/Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,32 @@ SRC_CYW43 :=
8484
SRC_LWIP :=
8585
endif
8686

87+
ifeq ($(CIRCUITPY_WIZNET), 1)
88+
INC_WIZNET := \
89+
-isystem common-hal/wiznet \
90+
91+
SRC_WIZNET := \
92+
common-hal/wiznet/wizchip_pio_spi.c \
93+
94+
WIZNET_PIOASM = $(BUILD)/pioasm/pioasm/pioasm
95+
.PHONY: pioasmBuild
96+
pioasmBuild: $(WIZNET_PIOASM)
97+
98+
$(WIZNET_PIOASM):
99+
$(Q)cmake -S pioasm -B $(BUILD)/pioasm
100+
$(MAKE) -C $(BUILD)/pioasm pioasmBuild
101+
102+
$(BUILD)/wizchip_pio_spi.pio.h: common-hal/wiznet/wizchip_pio_spi.pio $(WIZNET_PIOASM)
103+
$(Q)$(WIZNET_PIOASM) -o c-sdk $< $@
104+
$(BUILD)/common-hal/wiznet/wizchip_pio_spi.o: $(BUILD)/wizchip_pio_spi.pio.h
105+
106+
$(BUILD)/genhdr/qstr.i.last: $(BUILD)/wizchip_pio_spi.pio.h
107+
108+
else
109+
INC_WIZNET :=
110+
SRC_WIZNET :=
111+
endif
112+
87113
CHIP_VARIANT_LOWER = $(shell echo $(CHIP_VARIANT) | tr '[:upper:]' '[:lower:]')
88114

89115
INC += \
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
// TODO: wiznet.PIO_SPI class.
8+
// This file contains all of the Python API definitions for the
9+
// wiznet.PIO_SPI class.
10+
11+
#include <string.h>
12+
13+
#include "shared-bindings/microcontroller/Pin.h"
14+
#include "bindings/wiznet/PIO_SPI.h"
15+
#include "shared-bindings/util.h"
16+
17+
#include "shared/runtime/buffer_helper.h"
18+
#include "shared/runtime/context_manager_helpers.h"
19+
#include "py/binary.h"
20+
#include "py/mperrno.h"
21+
#include "py/objproperty.h"
22+
#include "py/runtime.h"
23+
24+
25+
// TODO: class WIZNET_PIO_SPI
26+
27+
28+
static mp_obj_t wiznet_pio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
29+
#if CIRCUITPY_WIZNET
30+
wiznet_pio_spi_obj_t *self = mp_obj_malloc(wiznet_pio_spi_obj_t, &wiznet_pio_spi_type);
31+
#if CIRCUITPY_WIZNET_W6300
32+
enum { ARG_clock, ARG_quad_io0, ARG_quad_io1, ARG_quad_io2, ARG_quad_io3, ARG_half_duplex, ARG_quad_spi };
33+
static const mp_arg_t allowed_args[] = {
34+
{ MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ },
35+
{ MP_QSTR_quad_io0, MP_ARG_OBJ, {.u_obj = mp_const_none} },
36+
{ MP_QSTR_quad_io1, MP_ARG_OBJ, {.u_obj = mp_const_none} },
37+
{ MP_QSTR_quad_io2, MP_ARG_OBJ, {.u_obj = mp_const_none} },
38+
{ MP_QSTR_quad_io3, MP_ARG_OBJ, {.u_obj = mp_const_none} },
39+
{ MP_QSTR_half_duplex, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
40+
};
41+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
42+
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
43+
44+
const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock);
45+
const mcu_pin_obj_t *quad_io0 = validate_obj_is_free_pin_or_none(args[ARG_quad_io0].u_obj, MP_QSTR_quad_io0);
46+
const mcu_pin_obj_t *quad_io1 = validate_obj_is_free_pin_or_none(args[ARG_quad_io1].u_obj, MP_QSTR_quad_io1);
47+
const mcu_pin_obj_t *quad_io2 = validate_obj_is_free_pin_or_none(args[ARG_quad_io2].u_obj, MP_QSTR_quad_io2);
48+
const mcu_pin_obj_t *quad_io3 = validate_obj_is_free_pin_or_none(args[ARG_quad_io3].u_obj, MP_QSTR_quad_io3);
49+
50+
if (!quad_io0 || !quad_io1 || !quad_io2 || !quad_io3) {
51+
mp_raise_ValueError(MP_ERROR_TEXT("Must provide all quad_io pins for QSPI"));
52+
}
53+
54+
common_hal_wiznet_pio_qspi_construct(self, clock, quad_io0, quad_io1, quad_io2, quad_io3, args[ARG_half_duplex].u_bool);
55+
56+
#else // W55RP20
57+
enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_half_duplex };
58+
static const mp_arg_t allowed_args[] = {
59+
{ MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ },
60+
{ MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} },
61+
{ MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} },
62+
{ MP_QSTR_half_duplex, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
63+
};
64+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
65+
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
66+
67+
const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock);
68+
const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj, MP_QSTR_mosi);
69+
const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj, MP_QSTR_miso);
70+
71+
if (!miso && !mosi) {
72+
mp_raise_ValueError(MP_ERROR_TEXT("Must provide MISO or MOSI pin"));
73+
}
74+
75+
common_hal_wiznet_pio_spi_construct(self, clock, mosi, miso, args[ARG_half_duplex].u_bool);
76+
#endif
77+
return MP_OBJ_FROM_PTR(self);
78+
#else
79+
mp_raise_NotImplementedError(NULL);
80+
#endif // CIRCUITPY_WIZNET
81+
}
82+
83+
#if CIRCUITPY_WIZNET
84+
85+
// TODO: def deinit
86+
87+
static mp_obj_t wiznet_pio_spi_obj_deinit(mp_obj_t self_in) {
88+
wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
89+
common_hal_wiznet_pio_spi_deinit(self);
90+
return mp_const_none;
91+
}
92+
MP_DEFINE_CONST_FUN_OBJ_1(wiznet_pio_spi_deinit_obj, wiznet_pio_spi_obj_deinit);
93+
94+
// TODO: def __enter__
95+
96+
// TODO: def __exit__
97+
98+
static void check_lock(wiznet_pio_spi_obj_t *self) {
99+
asm ("");
100+
if (!common_hal_wiznet_pio_spi_has_lock(self)) {
101+
mp_raise_RuntimeError(MP_ERROR_TEXT("Function requires lock"));
102+
}
103+
}
104+
105+
static void check_for_deinit(wiznet_pio_spi_obj_t *self) {
106+
if (common_hal_wiznet_pio_spi_deinited(self)) {
107+
raise_deinited_error();
108+
}
109+
}
110+
111+
// TODO: def configure
112+
113+
static mp_obj_t wiznet_pio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
114+
enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits };
115+
static const mp_arg_t allowed_args[] = {
116+
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} },
117+
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
118+
{ MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
119+
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
120+
};
121+
wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
122+
check_for_deinit(self);
123+
check_lock(self);
124+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
125+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
126+
127+
uint8_t polarity = (uint8_t)mp_arg_validate_int_range(args[ARG_polarity].u_int, 0, 1, MP_QSTR_polarity);
128+
uint8_t phase = (uint8_t)mp_arg_validate_int_range(args[ARG_phase].u_int, 0, 1, MP_QSTR_phase);
129+
uint8_t bits = (uint8_t)mp_arg_validate_int_range(args[ARG_bits].u_int, 8, 9, MP_QSTR_bits);
130+
131+
if (!common_hal_wiznet_pio_spi_configure(self, args[ARG_baudrate].u_int,
132+
polarity, phase, bits)) {
133+
mp_raise_OSError(MP_EIO);
134+
}
135+
return mp_const_none;
136+
}
137+
MP_DEFINE_CONST_FUN_OBJ_KW(wiznet_pio_spi_configure_obj, 1, wiznet_pio_spi_configure);
138+
139+
// TODO: def try_lock
140+
141+
static mp_obj_t wiznet_pio_spi_obj_try_lock(mp_obj_t self_in) {
142+
wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
143+
return mp_obj_new_bool(common_hal_wiznet_pio_spi_try_lock(self));
144+
}
145+
MP_DEFINE_CONST_FUN_OBJ_1(wiznet_pio_spi_try_lock_obj, wiznet_pio_spi_obj_try_lock);
146+
147+
// TODO: def unlock
148+
149+
static mp_obj_t wiznet_pio_spi_obj_unlock(mp_obj_t self_in) {
150+
wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
151+
check_for_deinit(self);
152+
common_hal_wiznet_pio_spi_unlock(self);
153+
return mp_const_none;
154+
}
155+
MP_DEFINE_CONST_FUN_OBJ_1(wiznet_pio_spi_unlock_obj, wiznet_pio_spi_obj_unlock);
156+
157+
// TODO: def write
158+
159+
static mp_obj_t wiznet_pio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
160+
enum { ARG_buffer, ARG_start, ARG_end };
161+
static const mp_arg_t allowed_args[] = {
162+
{ MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
163+
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
164+
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
165+
};
166+
167+
wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
168+
check_for_deinit(self);
169+
check_lock(self);
170+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
171+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
172+
173+
mp_buffer_info_t bufinfo;
174+
mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ);
175+
// Compute bounds in terms of elements, not bytes.
176+
int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL);
177+
int32_t start = args[ARG_start].u_int;
178+
size_t length = bufinfo.len / stride_in_bytes;
179+
normalize_buffer_bounds(&start, args[ARG_end].u_int, &length);
180+
181+
// Treat start and length in terms of bytes from now on.
182+
start *= stride_in_bytes;
183+
length *= stride_in_bytes;
184+
185+
if (length == 0) {
186+
return mp_const_none;
187+
}
188+
189+
bool ok = common_hal_wiznet_pio_spi_write(self, ((uint8_t *)bufinfo.buf) + start, length);
190+
191+
if (!ok) {
192+
mp_raise_OSError(MP_EIO);
193+
}
194+
return mp_const_none;
195+
}
196+
MP_DEFINE_CONST_FUN_OBJ_KW(wiznet_pio_spi_write_obj, 1, wiznet_pio_spi_write);
197+
198+
// TODO: def readinto
199+
200+
static mp_obj_t wiznet_pio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
201+
enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value };
202+
static const mp_arg_t allowed_args[] = {
203+
{ MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
204+
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
205+
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
206+
{ MP_QSTR_write_value, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
207+
};
208+
wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
209+
check_for_deinit(self);
210+
check_lock(self);
211+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
212+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
213+
214+
mp_buffer_info_t bufinfo;
215+
mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE);
216+
// Compute bounds in terms of elements, not bytes.
217+
int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL);
218+
int32_t start = args[ARG_start].u_int;
219+
size_t length = bufinfo.len / stride_in_bytes;
220+
normalize_buffer_bounds(&start, args[ARG_end].u_int, &length);
221+
222+
// Treat start and length in terms of bytes from now on.
223+
start *= stride_in_bytes;
224+
length *= stride_in_bytes;
225+
226+
if (length == 0) {
227+
return mp_const_none;
228+
}
229+
230+
bool ok = common_hal_wiznet_pio_spi_read(self, ((uint8_t *)bufinfo.buf) + start, length, args[ARG_write_value].u_int);
231+
if (!ok) {
232+
mp_raise_OSError(MP_EIO);
233+
}
234+
return mp_const_none;
235+
}
236+
MP_DEFINE_CONST_FUN_OBJ_KW(wiznet_pio_spi_readinto_obj, 1, wiznet_pio_spi_readinto);
237+
238+
#endif // CIRCUITPY_WIZNET
239+
240+
static const mp_rom_map_elem_t wiznet_pio_spi_locals_dict_table[] = {
241+
#if CIRCUITPY_WIZNET
242+
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&wiznet_pio_spi_deinit_obj) },
243+
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
244+
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) },
245+
246+
{ MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&wiznet_pio_spi_configure_obj) },
247+
{ MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&wiznet_pio_spi_try_lock_obj) },
248+
{ MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&wiznet_pio_spi_unlock_obj) },
249+
250+
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&wiznet_pio_spi_readinto_obj) },
251+
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&wiznet_pio_spi_write_obj) },
252+
253+
#endif // CIRCUITPY_WIZNET
254+
};
255+
static MP_DEFINE_CONST_DICT(wiznet_pio_spi_locals_dict, wiznet_pio_spi_locals_dict_table);
256+
257+
MP_DEFINE_CONST_OBJ_TYPE(
258+
wiznet_pio_spi_type,
259+
MP_QSTR_PIO_SPI,
260+
MP_TYPE_FLAG_NONE,
261+
make_new, wiznet_pio_spi_make_new,
262+
locals_dict, &wiznet_pio_spi_locals_dict
263+
);
264+
265+
wiznet_pio_spi_obj_t *validate_obj_is_wiznet_pio_spi_bus(mp_obj_t obj, qstr arg_name) {
266+
return mp_arg_validate_type(obj, &wiznet_pio_spi_type, arg_name);
267+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#pragma once
8+
9+
#include "py/obj.h"
10+
11+
#include "common-hal/microcontroller/Pin.h"
12+
#include "common-hal/wiznet/PIO_SPI.h"
13+
14+
// Type object used in Python. Should be shared between ports.
15+
extern const mp_obj_type_t wiznet_pio_spi_type;
16+
17+
#if CIRCUITPY_WIZNET_W6300
18+
19+
extern void common_hal_wiznet_pio_qspi_construct(wiznet_pio_spi_obj_t *self,
20+
const mcu_pin_obj_t *clock, const mcu_pin_obj_t *quad_io0,
21+
const mcu_pin_obj_t *quad_io1, const mcu_pin_obj_t *quad_io2,
22+
const mcu_pin_obj_t *quad_io3, bool half_duplex);
23+
24+
#else // W55RP20
25+
// Construct an underlying SPI object.
26+
extern void common_hal_wiznet_pio_spi_construct(wiznet_pio_spi_obj_t *self,
27+
const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi,
28+
const mcu_pin_obj_t *miso, bool half_duplex);
29+
30+
#endif
31+
32+
extern void common_hal_wiznet_pio_spi_deinit(wiznet_pio_spi_obj_t *self);
33+
extern bool common_hal_wiznet_pio_spi_deinited(wiznet_pio_spi_obj_t *self);
34+
35+
extern bool common_hal_wiznet_pio_spi_configure(wiznet_pio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits);
36+
37+
extern bool common_hal_wiznet_pio_spi_try_lock(wiznet_pio_spi_obj_t *self);
38+
extern bool common_hal_wiznet_pio_spi_has_lock(wiznet_pio_spi_obj_t *self);
39+
extern void common_hal_wiznet_pio_spi_unlock(wiznet_pio_spi_obj_t *self);
40+
41+
// Writes out the given data.
42+
extern bool common_hal_wiznet_pio_spi_write(wiznet_pio_spi_obj_t *self, const uint8_t *data, size_t len);
43+
44+
// Reads in len bytes while outputting the byte write_value.
45+
extern bool common_hal_wiznet_pio_spi_read(wiznet_pio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value);
46+
47+
extern wiznet_pio_spi_obj_t *validate_obj_is_wiznet_pio_spi_bus(mp_obj_t obj_in, qstr arg_name);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#include <stdint.h>
8+
9+
#include "py/obj.h"
10+
#include "py/runtime.h"
11+
12+
#include "shared-bindings/microcontroller/Pin.h"
13+
#include "bindings/wiznet/PIO_SPI.h"
14+
15+
#include "py/runtime.h"
16+
17+
static const mp_rom_map_elem_t wiznet_module_globals_table[] = {
18+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wiznet) },
19+
{ MP_ROM_QSTR(MP_QSTR_PIO_SPI), MP_ROM_PTR(&wiznet_pio_spi_type) },
20+
};
21+
22+
static MP_DEFINE_CONST_DICT(wiznet_module_globals, wiznet_module_globals_table);
23+
24+
const mp_obj_module_t wiznet_module = {
25+
.base = { &mp_type_module },
26+
.globals = (mp_obj_dict_t *)&wiznet_module_globals,
27+
};
28+
29+
MP_REGISTER_MODULE(MP_QSTR_wiznet, wiznet_module);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#pragma once
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#include "supervisor/board.h"
8+
9+
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.

0 commit comments

Comments
 (0)