Skip to content

Commit 4fe2f03

Browse files
committed
Add support for Yoto Mini and Yoto Player V3
There were a bunch of changes to enable the boards: * Add web workflow for sdioio cards. Adds the "native" access. * Introduce `i2cioexpander` for native I2C expander support. * Introduce DigitalInOut protocol so that IOPins can be used where DigitalInOut would be traditionally. * Add mp_errno_t for clarifying what APIs return errno. * DigitalInOut protocol uses it to pass through I2C issues. * Switch `bitbangio` and `fourwire` to DigitalInOutProtocol. * Support the Mini's GC9306 display with CS and DC over IOPin. * DigitalInOutProtocol can fall back to Python-level access if not natively supported. * Make board.I2C() speed configurable to speed up IOExpander access. * Update codespell to work with Python 3.14. * Make static web workflow responses cachable by the browser for 1 day.
1 parent 57aec3a commit 4fe2f03

File tree

77 files changed

+3083
-370
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+3083
-370
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ repos:
2828
lib/mbedtls_errors/generate_errors.diff
2929
)
3030
- repo: https://github.com/codespell-project/codespell
31-
rev: v2.2.4
31+
rev: v2.4.1
3232
hooks:
3333
- id: codespell
3434
args: [-w]

extmod/vfs_blockdev.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,16 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
6363
#endif
6464
#if CIRCUITPY_SDIOIO
6565
if (mp_obj_get_type(bdev) == &sdioio_SDCard_type) {
66-
// TODO: Enable native blockdev for SDIO too.
66+
self->flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL;
67+
self->readblocks[0] = mp_const_none;
68+
self->readblocks[1] = bdev;
69+
self->readblocks[2] = (mp_obj_t)sdioio_sdcard_readblocks; // native version
70+
self->writeblocks[0] = mp_const_none;
71+
self->writeblocks[1] = bdev;
72+
self->writeblocks[2] = (mp_obj_t)sdioio_sdcard_writeblocks; // native version
73+
self->u.ioctl[0] = mp_const_none;
74+
self->u.ioctl[1] = bdev;
75+
self->u.ioctl[2] = (mp_obj_t)sdioio_sdcard_ioctl; // native version
6776
}
6877
#endif
6978
if (self->u.ioctl[0] != MP_OBJ_NULL) {

locale/circuitpython.pot

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ msgstr ""
119119
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
120120
#: ports/raspberrypi/common-hal/usb_host/Port.c
121121
#: shared-bindings/digitalio/DigitalInOut.c
122-
#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c
122+
#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c
123+
#: shared-module/max3421e/Max3421E.c
123124
msgid "%q in use"
124125
msgstr ""
125126

@@ -132,7 +133,7 @@ msgid "%q indices must be integers, not %s"
132133
msgstr ""
133134

134135
#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c
135-
#: shared-module/bitbangio/SPI.c
136+
#: shared-bindings/digitalio/DigitalInOutProtocol.c
136137
msgid "%q init failed"
137138
msgstr ""
138139

@@ -235,6 +236,14 @@ msgstr ""
235236
msgid "%q must be power of 2"
236237
msgstr ""
237238

239+
#: shared-bindings/digitalio/DigitalInOutProtocol.c
240+
msgid "%q object missing '%q' attribute"
241+
msgstr ""
242+
243+
#: shared-bindings/digitalio/DigitalInOutProtocol.c
244+
msgid "%q object missing '%q' method"
245+
msgstr ""
246+
238247
#: shared-bindings/wifi/Monitor.c
239248
msgid "%q out of bounds"
240249
msgstr ""
@@ -766,6 +775,10 @@ msgstr ""
766775
msgid "Cannot create a new Adapter; use _bleio.adapter;"
767776
msgstr ""
768777

778+
#: shared-module/i2cioexpander/IOExpander.c
779+
msgid "Cannot deinitialize board IOExpander"
780+
msgstr ""
781+
769782
#: shared-bindings/displayio/Bitmap.c
770783
#: shared-bindings/memorymonitor/AllocationSize.c
771784
#: shared-bindings/pulseio/PulseIn.c
@@ -800,6 +813,7 @@ msgid "Cannot remount path when visible via USB."
800813
msgstr ""
801814

802815
#: shared-bindings/digitalio/DigitalInOut.c
816+
#: shared-bindings/i2cioexpander/IOPin.c
803817
msgid "Cannot set value when direction is input."
804818
msgstr ""
805819

@@ -939,6 +953,7 @@ msgid "Done"
939953
msgstr ""
940954

941955
#: shared-bindings/digitalio/DigitalInOut.c
956+
#: shared-bindings/i2cioexpander/IOPin.c
942957
msgid "Drive mode not used when direction is input."
943958
msgstr ""
944959

@@ -1277,8 +1292,8 @@ msgstr ""
12771292
#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c
12781293
#: shared-bindings/digitalio/DigitalInOut.c
12791294
#: shared-bindings/epaperdisplay/EPaperDisplay.c
1280-
#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c
1281-
#: shared-bindings/supervisor/__init__.c
1295+
#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c
1296+
#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c
12821297
#: shared-module/aurora_epaper/aurora_framebuffer.c
12831298
#: shared-module/lvfontio/OnDiskFont.c
12841299
msgid "Invalid %q"
@@ -1880,6 +1895,7 @@ msgid "Publishers can only be created from a parent node"
18801895
msgstr ""
18811896

18821897
#: shared-bindings/digitalio/DigitalInOut.c
1898+
#: shared-bindings/i2cioexpander/IOPin.c
18831899
msgid "Pull not used when direction is output."
18841900
msgstr ""
18851901

@@ -2539,6 +2555,10 @@ msgstr ""
25392555
msgid "a bytes-like object is required"
25402556
msgstr ""
25412557

2558+
#: shared-bindings/i2cioexpander/IOExpander.c
2559+
msgid "address out of range"
2560+
msgstr ""
2561+
25422562
#: shared-bindings/i2ctarget/I2CTarget.c
25432563
msgid "addresses is empty"
25442564
msgstr ""
@@ -3814,6 +3834,10 @@ msgstr ""
38143834
msgid "not supported for input types"
38153835
msgstr ""
38163836

3837+
#: shared-bindings/i2cioexpander/IOExpander.c
3838+
msgid "num_pins must be 8 or 16"
3839+
msgstr ""
3840+
38173841
#: extmod/ulab/code/numpy/create.c
38183842
msgid "number of points must be at least 2"
38193843
msgstr ""
@@ -3827,6 +3851,10 @@ msgstr ""
38273851
msgid "object '%s' isn't a tuple or list"
38283852
msgstr ""
38293853

3854+
#: shared-bindings/digitalio/DigitalInOutProtocol.c
3855+
msgid "object does not support DigitalInOut protocol"
3856+
msgstr ""
3857+
38303858
#: py/obj.c
38313859
msgid "object doesn't support item assignment"
38323860
msgstr ""

ports/analog/common-hal/busio/I2C.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
187187
}
188188

189189
// Write data to the device selected by address
190-
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
190+
mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
191191
const uint8_t *data, size_t len) {
192192

193193
int ret;
@@ -202,14 +202,14 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
202202
};
203203
ret = MXC_I2C_MasterTransaction(&wr_req);
204204
if (ret) {
205-
return MP_EIO;
205+
return -MP_EIO;
206206
}
207207

208208
return 0;
209209
}
210210

211211
// Read into buffer from the device selected by address
212-
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self,
212+
mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self,
213213
uint16_t addr,
214214
uint8_t *data, size_t len) {
215215

@@ -226,14 +226,14 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self,
226226
ret = MXC_I2C_MasterTransaction(&rd_req);
227227
if (ret) {
228228
// Return I/O error
229-
return MP_EIO;
229+
return -MP_EIO;
230230
}
231231

232232
return 0;
233233
}
234234

235235
// Write the bytes from out_data to the device selected by address
236-
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
236+
mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
237237
uint8_t *out_data, size_t out_len,
238238
uint8_t *in_data, size_t in_len) {
239239

@@ -249,7 +249,7 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
249249
};
250250
ret = MXC_I2C_MasterTransaction(&wr_rd_req);
251251
if (ret) {
252-
return MP_EIO;
252+
return -MP_EIO;
253253
}
254254

255255
return 0;

ports/atmel-samd/common-hal/busio/I2C.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
176176
self->has_lock = false;
177177
}
178178

179-
static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
179+
static mp_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
180180
const uint8_t *data, size_t len, bool transmit_stop_bit) {
181181

182182
uint16_t attempts = ATTEMPTS;
@@ -197,17 +197,17 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
197197
if (status == I2C_OK) {
198198
return 0;
199199
} else if (status == I2C_ERR_BAD_ADDRESS) {
200-
return MP_ENODEV;
200+
return -MP_ENODEV;
201201
}
202-
return MP_EIO;
202+
return -MP_EIO;
203203
}
204204

205-
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
205+
mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
206206
const uint8_t *data, size_t len) {
207207
return _common_hal_busio_i2c_write(self, addr, data, len, true);
208208
}
209209

210-
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
210+
mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
211211
uint8_t *data, size_t len) {
212212

213213
uint16_t attempts = ATTEMPTS;
@@ -228,14 +228,14 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
228228
if (status == ERR_NONE) {
229229
return 0;
230230
} else if (status == I2C_ERR_BAD_ADDRESS) {
231-
return MP_ENODEV;
231+
return -MP_ENODEV;
232232
}
233-
return MP_EIO;
233+
return -MP_EIO;
234234
}
235235

236-
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
236+
mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
237237
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
238-
uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
238+
mp_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
239239
if (result != 0) {
240240
return result;
241241
}

ports/atmel-samd/common-hal/sdioio/SDCard.c

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "py/runtime.h"
1010

1111
#include "common-hal/microcontroller/Pin.h"
12+
#include "extmod/vfs.h"
1213
#include "shared-bindings/sdioio/SDCard.h"
1314
#include "shared-bindings/microcontroller/Pin.h"
1415
#include "shared-bindings/microcontroller/__init__.h"
@@ -170,43 +171,85 @@ static void debug_print_state(sdioio_sdcard_obj_t *self, const char *what, sd_mm
170171
#endif
171172
}
172173

173-
int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
174-
check_for_deinit(self);
175-
check_whole_block(bufinfo);
174+
mp_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf,
175+
uint32_t start_block, uint32_t num_blocks) {
176+
sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in);
176177
wait_write_complete(self);
177178
self->state_programming = true;
178-
sd_mmc_err_t r = sd_mmc_init_write_blocks(0, start_block, bufinfo->len / 512);
179+
sd_mmc_err_t r = sd_mmc_init_write_blocks(0, start_block, num_blocks);
179180
if (r != SD_MMC_OK) {
180181
debug_print_state(self, "sd_mmc_init_write_blocks", r);
181-
return -EIO;
182+
return -MP_EIO;
182183
}
183-
r = sd_mmc_start_write_blocks(bufinfo->buf, bufinfo->len / 512);
184+
r = sd_mmc_start_write_blocks(buf, num_blocks);
184185
if (r != SD_MMC_OK) {
185186
debug_print_state(self, "sd_mmc_start_write_blocks", r);
186-
return -EIO;
187+
return -MP_EIO;
187188
}
188-
// debug_print_state(self, "after writeblocks OK");
189189
return 0;
190190
}
191191

192-
int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
192+
mp_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
193193
check_for_deinit(self);
194194
check_whole_block(bufinfo);
195+
196+
uint32_t num_blocks = bufinfo->len / 512;
197+
return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf,
198+
start_block, num_blocks);
199+
}
200+
201+
mp_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf,
202+
uint32_t start_block, uint32_t num_blocks) {
203+
sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in);
195204
wait_write_complete(self);
196-
sd_mmc_err_t r = sd_mmc_init_read_blocks(0, start_block, bufinfo->len / 512);
205+
sd_mmc_err_t r = sd_mmc_init_read_blocks(0, start_block, num_blocks);
197206
if (r != SD_MMC_OK) {
198207
debug_print_state(self, "sd_mmc_init_read_blocks", r);
199-
return -EIO;
208+
return -MP_EIO;
200209
}
201-
r = sd_mmc_start_read_blocks(bufinfo->buf, bufinfo->len / 512);
210+
r = sd_mmc_start_read_blocks(buf, num_blocks);
202211
if (r != SD_MMC_OK) {
203212
debug_print_state(self, "sd_mmc_start_read_blocks", r);
204-
return -EIO;
213+
return -MP_EIO;
205214
}
206215
sd_mmc_wait_end_of_write_blocks(0);
207216
return 0;
208217
}
209218

219+
mp_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
220+
check_for_deinit(self);
221+
check_whole_block(bufinfo);
222+
223+
uint32_t num_blocks = bufinfo->len / 512;
224+
return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf,
225+
start_block, num_blocks);
226+
}
227+
228+
// Native function for VFS blockdev layer
229+
bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg,
230+
mp_int_t *out_value) {
231+
sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in);
232+
*out_value = 0;
233+
234+
switch (cmd) {
235+
case MP_BLOCKDEV_IOCTL_DEINIT:
236+
case MP_BLOCKDEV_IOCTL_SYNC:
237+
// SDIO operations are synchronous, no action needed
238+
return true;
239+
240+
case MP_BLOCKDEV_IOCTL_BLOCK_COUNT:
241+
*out_value = common_hal_sdioio_sdcard_get_count(self);
242+
return true;
243+
244+
case MP_BLOCKDEV_IOCTL_BLOCK_SIZE:
245+
*out_value = 512; // SD cards use 512-byte sectors
246+
return true;
247+
248+
default:
249+
return false; // Unsupported command
250+
}
251+
}
252+
210253
bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) {
211254
check_for_deinit(self);
212255
return true;

0 commit comments

Comments
 (0)