Skip to content

Commit 8cf85c4

Browse files
microdev1Neradoc
andcommitted
allow multiple board buses
Co-authored-by: Neradoc <[email protected]>
1 parent 932131b commit 8cf85c4

File tree

8 files changed

+234
-174
lines changed

8 files changed

+234
-174
lines changed

ports/atmel-samd/boards/hallowing_m0_express/board.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ uint8_t display_init_sequence[] = {
7171
void board_init(void) {
7272
displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus;
7373
bus->base.type = &displayio_fourwire_type;
74-
busio_spi_obj_t *spi = common_hal_board_create_spi();
74+
busio_spi_obj_t *spi = common_hal_board_create_spi(0);
7575
common_hal_busio_spi_never_reset(spi);
7676
common_hal_displayio_fourwire_construct(bus,
7777
spi,

ports/atmel-samd/boards/ugame10/board.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ uint8_t display_init_sequence[] = {
7272
void board_init(void) {
7373
displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus;
7474
bus->base.type = &displayio_fourwire_type;
75-
busio_spi_obj_t *spi = common_hal_board_create_spi();
75+
busio_spi_obj_t *spi = common_hal_board_create_spi(0);
7676
common_hal_displayio_fourwire_construct(bus,
7777
spi,
7878
&pin_PA09, // Command or data

py/circuitpy_mpconfig.h

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -254,23 +254,38 @@ typedef long mp_off_t;
254254
#error No *_FLASH_FILESYSTEM set!
255255
#endif
256256

257-
// These CIRCUITPY_xxx values should all be defined in the *.mk files as being on or off.
258-
// So if any are not defined in *.mk, they'll throw an error here.
257+
// Default board buses.
258+
259+
#ifndef CIRCUITPY_BOARD_I2C
260+
#if defined(DEFAULT_I2C_BUS_SCL) && defined(DEFAULT_I2C_BUS_SDA)
261+
#define CIRCUITPY_BOARD_I2C (1)
262+
#define CIRCUITPY_BOARD_I2C_PIN {DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA}
263+
#else
264+
#define CIRCUITPY_BOARD_I2C (0)
265+
#endif
266+
#endif
259267

260-
#if CIRCUITPY_BOARD
261-
#define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL))
262-
#define BOARD_SPI (defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MISO) && defined(DEFAULT_SPI_BUS_MOSI))
263-
#define BOARD_UART (defined(DEFAULT_UART_BUS_RX) && defined(DEFAULT_UART_BUS_TX))
264-
// I2C and SPI are always allocated off the heap.
265-
#if BOARD_UART
266-
#define BOARD_UART_ROOT_POINTER mp_obj_t shared_uart_bus;
268+
#ifndef CIRCUITPY_BOARD_SPI
269+
#if defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MOSI) && defined(DEFAULT_SPI_BUS_MISO)
270+
#define CIRCUITPY_BOARD_SPI (1)
271+
#define CIRCUITPY_BOARD_SPI_PIN {DEFAULT_SPI_BUS_SCK, DEFAULT_SPI_BUS_MOSI, DEFAULT_SPI_BUS_MISO}
267272
#else
268-
#define BOARD_UART_ROOT_POINTER
273+
#define CIRCUITPY_BOARD_SPI (0)
269274
#endif
275+
#endif
276+
277+
#ifndef CIRCUITPY_BOARD_UART
278+
#if defined(DEFAULT_UART_BUS_TX) && defined(DEFAULT_UART_BUS_RX)
279+
#define CIRCUITPY_BOARD_UART (1)
280+
#define CIRCUITPY_BOARD_UART_PIN {DEFAULT_UART_BUS_TX, DEFAULT_UART_BUS_RX, NULL, NULL}
270281
#else
271-
#define BOARD_UART_ROOT_POINTER
282+
#define CIRCUITPY_BOARD_UART (0)
283+
#endif
272284
#endif
273285

286+
// These CIRCUITPY_xxx values should all be defined in the *.mk files as being on or off.
287+
// So if any are not defined in *.mk, they'll throw an error here.
288+
274289
#if CIRCUITPY_DISPLAYIO
275290
#ifndef CIRCUITPY_DISPLAY_LIMIT
276291
#define CIRCUITPY_DISPLAY_LIMIT (1)
@@ -460,7 +475,6 @@ struct _supervisor_allocation_node;
460475
FLASH_ROOT_POINTERS \
461476
KEYPAD_ROOT_POINTERS \
462477
GAMEPAD_ROOT_POINTERS \
463-
BOARD_UART_ROOT_POINTER \
464478
WIFI_MONITOR_ROOT_POINTERS \
465479
MEMORYMONITOR_ROOT_POINTERS \
466480
vstr_t *repl_line; \

shared-bindings/board/__init__.c

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,15 @@
2828
#include "py/runtime.h"
2929

3030
#include "shared-bindings/board/__init__.h"
31-
#if BOARD_I2C
31+
#if CIRCUITPY_BOARD_I2C
3232
#include "shared-bindings/busio/I2C.h"
3333
#endif
34-
#if BOARD_SPI
34+
#if CIRCUITPY_BOARD_SPI
3535
#include "shared-bindings/busio/SPI.h"
3636
#endif
37+
#if CIRCUITPY_BOARD_UART
38+
#include "shared-bindings/busio/UART.h"
39+
#endif
3740

3841
//| """Board specific pin names
3942
//|
@@ -47,84 +50,85 @@
4750
//| """Board ID string. The unique identifier for the board model in
4851
//| circuitpython, as well as on circuitpython.org.
4952
//| Example: "hallowing_m0_express"."""
50-
//|
5153

52-
//| def I2C() -> busio.I2C:
53-
//| """Returns the `busio.I2C` object for the board designated SDA and SCL pins. It is a singleton."""
54+
#if CIRCUITPY_BOARD_I2C || CIRCUITPY_BOARD_SPI || CIRCUITPY_BOARD_UART
55+
STATIC mp_int_t board_get_instance(size_t n_args, const mp_obj_t *args, const mp_int_t bus_in) {
56+
if (n_args == 0) {
57+
return 0;
58+
}
59+
const mp_int_t instance = mp_obj_get_int(args[0]);
60+
if (instance >= bus_in || instance < 0) {
61+
mp_raise_ValueError_varg(translate("No default %q bus"), MP_QSTR_UART);
62+
}
63+
return instance;
64+
}
65+
#endif
66+
67+
//| def I2C(instance: Optional[int] = 0) -> busio.I2C:
68+
//| """Returns the `busio.I2C` object for the board's designated I2C bus(es). It is a singleton.
69+
//| The object created uses the default parameter values for `busio.I2C`."""
5470
//| ...
5571
//|
56-
57-
#if BOARD_I2C
58-
mp_obj_t board_i2c(void) {
59-
mp_obj_t singleton = common_hal_board_get_i2c();
72+
#if CIRCUITPY_BOARD_I2C
73+
mp_obj_t board_i2c(size_t n_args, const mp_obj_t *args) {
74+
const mp_int_t instance = board_get_instance(n_args, args, CIRCUITPY_BOARD_I2C);
75+
const mp_obj_t singleton = common_hal_board_get_i2c(instance);
6076
if (singleton != NULL && !common_hal_busio_i2c_deinited(singleton)) {
6177
return singleton;
6278
}
63-
assert_pin_free(DEFAULT_I2C_BUS_SDA);
64-
assert_pin_free(DEFAULT_I2C_BUS_SCL);
65-
return common_hal_board_create_i2c();
79+
return common_hal_board_create_i2c(instance);
6680
}
6781
#else
68-
mp_obj_t board_i2c(void) {
82+
mp_obj_t board_i2c(size_t n_args, const mp_obj_t *args) {
6983
mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_I2C);
7084
return NULL;
7185
}
7286
#endif
73-
MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c);
74-
87+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(board_i2c_obj, 0, 1, board_i2c);
7588

76-
//| def SPI() -> busio.SPI:
77-
//| """Returns the `busio.SPI` object for the board designated SCK, MOSI and MISO pins. It is a
78-
//| singleton."""
89+
//| def SPI(instance: Optional[int] = 0) -> busio.SPI:
90+
//| """Returns the `busio.SPI` object for the board's designated SPI bus(es). It is a singleton.
91+
//| The object created uses the default parameter values for `busio.SPI`."""
7992
//| ...
8093
//|
81-
#if BOARD_SPI
82-
mp_obj_t board_spi(void) {
83-
mp_obj_t singleton = common_hal_board_get_spi();
94+
#if CIRCUITPY_BOARD_SPI
95+
mp_obj_t board_spi(size_t n_args, const mp_obj_t *args) {
96+
const mp_int_t instance = board_get_instance(n_args, args, CIRCUITPY_BOARD_SPI);
97+
const mp_obj_t singleton = common_hal_board_get_spi(instance);
8498
if (singleton != NULL && !common_hal_busio_spi_deinited(singleton)) {
8599
return singleton;
86100
}
87-
assert_pin_free(DEFAULT_SPI_BUS_SCK);
88-
assert_pin_free(DEFAULT_SPI_BUS_MOSI);
89-
assert_pin_free(DEFAULT_SPI_BUS_MISO);
90-
return common_hal_board_create_spi();
101+
return common_hal_board_create_spi(instance);
91102
}
92103
#else
93-
mp_obj_t board_spi(void) {
104+
mp_obj_t board_spi(size_t n_args, const mp_obj_t *args) {
94105
mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_SPI);
95106
return NULL;
96107
}
97108
#endif
98-
MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);
109+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(board_spi_obj, 0, 1, board_spi);
99110

100-
//| def UART() -> busio.UART:
101-
//| """Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton.
102-
//|
103-
//| The object created uses the default parameter values for `busio.UART`. If you need to set
104-
//| parameters that are not changeable after creation, such as ``receiver_buffer_size``,
105-
//| do not use `board.UART()`; instead create a `busio.UART` object explicitly with the
106-
//| desired parameters."""
111+
//| def UART(instance: Optional[int] = 0) -> busio.UART:
112+
//| """Returns the `busio.UART` object for the board's designated UART bus(es). It is a singleton.
113+
//| The object created uses the default parameter values for `busio.UART`."""
107114
//| ...
108115
//|
109-
#if BOARD_UART
110-
mp_obj_t board_uart(void) {
111-
mp_obj_t singleton = common_hal_board_get_uart();
112-
if (singleton != NULL) {
116+
#if CIRCUITPY_BOARD_UART
117+
mp_obj_t board_uart(size_t n_args, const mp_obj_t *args) {
118+
const mp_int_t instance = board_get_instance(n_args, args, CIRCUITPY_BOARD_UART);
119+
const mp_obj_t singleton = common_hal_board_get_uart(instance);
120+
if (singleton != NULL && !common_hal_busio_uart_deinited(singleton)) {
113121
return singleton;
114122
}
115-
116-
assert_pin_free(DEFAULT_UART_BUS_RX);
117-
assert_pin_free(DEFAULT_UART_BUS_TX);
118-
119-
return common_hal_board_create_uart();
123+
return common_hal_board_create_uart(instance);
120124
}
121125
#else
122-
mp_obj_t board_uart(void) {
126+
mp_obj_t board_uart(size_t n_args, const mp_obj_t *args) {
123127
mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_UART);
124128
return NULL;
125129
}
126130
#endif
127-
MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart);
131+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(board_uart_obj, 0, 1, board_uart);
128132

129133
const mp_obj_module_t board_module = {
130134
.base = { &mp_type_module },

shared-bindings/board/__init__.h

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,30 @@
3535
extern const mp_obj_dict_t board_module_globals;
3636
STATIC const MP_DEFINE_STR_OBJ(board_module_id_obj, CIRCUITPY_BOARD_ID);
3737

38-
mp_obj_t common_hal_board_get_i2c(void);
39-
mp_obj_t common_hal_board_create_i2c(void);
40-
MP_DECLARE_CONST_FUN_OBJ_0(board_i2c_obj);
38+
bool common_hal_board_is_i2c(mp_obj_t obj);
39+
mp_obj_t common_hal_board_get_i2c(const mp_int_t insatnce);
40+
mp_obj_t common_hal_board_create_i2c(const mp_int_t instance);
41+
mp_obj_t board_i2c(size_t n_args, const mp_obj_t *args);
42+
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(board_i2c_obj);
4143

42-
mp_obj_t common_hal_board_get_spi(void);
43-
mp_obj_t common_hal_board_create_spi(void);
44-
MP_DECLARE_CONST_FUN_OBJ_0(board_spi_obj);
44+
bool common_hal_board_is_spi(mp_obj_t obj);
45+
mp_obj_t common_hal_board_get_spi(const mp_int_t insatnce);
46+
mp_obj_t common_hal_board_create_spi(const mp_int_t instance);
47+
mp_obj_t board_spi(size_t n_args, const mp_obj_t *args);
48+
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(board_spi_obj);
4549

46-
mp_obj_t common_hal_board_get_uart(void);
47-
mp_obj_t common_hal_board_create_uart(void);
48-
MP_DECLARE_CONST_FUN_OBJ_0(board_uart_obj);
50+
bool common_hal_board_is_uart(mp_obj_t obj);
51+
mp_obj_t common_hal_board_get_uart(const mp_int_t insatnce);
52+
mp_obj_t common_hal_board_create_uart(const mp_int_t instance);
53+
mp_obj_t board_uart(size_t n_args, const mp_obj_t *args);
54+
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(board_uart_obj);
4955

50-
mp_obj_t board_i2c(void);
51-
mp_obj_t board_spi(void);
52-
mp_obj_t board_uart(void);
56+
#define CIRCUITPY_BOARD_BUS_SINGLETON(name, bus, instance) \
57+
STATIC mp_obj_t board_##name(void) { \
58+
const mp_obj_t inst = mp_obj_new_int_from_uint(instance); \
59+
return board_##bus(1, &inst); \
60+
} \
61+
MP_DEFINE_CONST_FUN_OBJ_0(board_##name##_obj, board_##name);
5362

5463
#define CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS \
5564
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_board) }, \

0 commit comments

Comments
 (0)