Skip to content

Commit a9c402e

Browse files
authored
Merge branch 'micropython:master' into samd_i2c
2 parents 333a91b + 69ffd2a commit a9c402e

File tree

34 files changed

+773
-279
lines changed

34 files changed

+773
-279
lines changed

docs/library/machine.Pin.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,13 @@ The following methods are not part of the core Pin API and only implemented on c
209209

210210
Set pin to "0" output level.
211211

212-
Availability: nrf, rp2, stm32 ports.
212+
Availability: mimxrt, nrf, renesas-ra, rp2, samd, stm32 ports.
213213

214214
.. method:: Pin.high()
215215

216216
Set pin to "1" output level.
217217

218-
Availability: nrf, rp2, stm32 ports.
218+
Availability: mimxrt, nrf, renesas-ra, rp2, samd, stm32 ports.
219219

220220
.. method:: Pin.mode([mode])
221221

@@ -242,7 +242,7 @@ The following methods are not part of the core Pin API and only implemented on c
242242

243243
Toggle output pin from "0" to "1" or vice-versa.
244244

245-
Availability: mimxrt, samd, rp2 ports.
245+
Availability: cc3200, esp32, esp8266, mimxrt, rp2, samd ports.
246246

247247
Constants
248248
---------

extmod/vfs_rom.c

Lines changed: 90 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#define ROMFS_RECORD_KIND_DATA_POINTER (3)
9292
#define ROMFS_RECORD_KIND_DIRECTORY (4)
9393
#define ROMFS_RECORD_KIND_FILE (5)
94+
#define ROMFS_RECORD_KIND_FILESYSTEM (0x14a6b1)
9495

9596
typedef mp_uint_t record_kind_t;
9697

@@ -101,34 +102,72 @@ struct _mp_obj_vfs_rom_t {
101102
const uint8_t *filesystem_end;
102103
};
103104

104-
static record_kind_t extract_record(const uint8_t **fs, const uint8_t **fs_next) {
105-
record_kind_t record_kind = mp_decode_uint(fs);
106-
mp_uint_t record_len = mp_decode_uint(fs);
105+
// Returns 0 for success, -1 for failure.
106+
static int mp_decode_uint_checked(const uint8_t **ptr, const uint8_t *ptr_max, mp_uint_t *value_out) {
107+
mp_uint_t unum = 0;
108+
byte val;
109+
const uint8_t *p = *ptr;
110+
do {
111+
if (p >= ptr_max) {
112+
return -1;
113+
}
114+
val = *p++;
115+
unum = (unum << 7) | (val & 0x7f);
116+
} while ((val & 0x80) != 0);
117+
*ptr = p;
118+
*value_out = unum;
119+
return 0;
120+
}
121+
122+
static record_kind_t extract_record(const uint8_t **fs, const uint8_t **fs_next, const uint8_t *fs_max) {
123+
mp_uint_t record_kind;
124+
if (mp_decode_uint_checked(fs, fs_max, &record_kind) != 0) {
125+
return ROMFS_RECORD_KIND_UNUSED;
126+
}
127+
mp_uint_t record_len;
128+
if (mp_decode_uint_checked(fs, fs_max, &record_len) != 0) {
129+
return ROMFS_RECORD_KIND_UNUSED;
130+
}
107131
*fs_next = *fs + record_len;
108132
return record_kind;
109133
}
110134

111-
static void extract_data(mp_obj_vfs_rom_t *self, const uint8_t *fs, const uint8_t *fs_top, size_t *size_out, const uint8_t **data_out) {
112-
*size_out = 0;
113-
*data_out = NULL;
135+
// Returns 0 for success, a negative integer for failure.
136+
static int extract_data(mp_obj_vfs_rom_t *self, const uint8_t *fs, const uint8_t *fs_top, size_t *size_out, const uint8_t **data_out) {
114137
while (fs < fs_top) {
115138
const uint8_t *fs_next;
116-
record_kind_t record_kind = extract_record(&fs, &fs_next);
117-
if (record_kind == ROMFS_RECORD_KIND_DATA_VERBATIM) {
118-
// Verbatim data.
119-
*size_out = fs_next - fs;
120-
*data_out = fs;
139+
record_kind_t record_kind = extract_record(&fs, &fs_next, fs_top);
140+
if (record_kind == ROMFS_RECORD_KIND_UNUSED) {
141+
// Corrupt filesystem.
121142
break;
143+
} else if (record_kind == ROMFS_RECORD_KIND_DATA_VERBATIM) {
144+
// Verbatim data.
145+
if (size_out != NULL) {
146+
*size_out = fs_next - fs;
147+
*data_out = fs;
148+
}
149+
return 0;
122150
} else if (record_kind == ROMFS_RECORD_KIND_DATA_POINTER) {
123151
// Pointer to data.
124-
*size_out = mp_decode_uint(&fs);
125-
*data_out = self->filesystem + mp_decode_uint(&fs);
126-
break;
152+
mp_uint_t size;
153+
if (mp_decode_uint_checked(&fs, fs_next, &size) != 0) {
154+
break;
155+
}
156+
mp_uint_t offset;
157+
if (mp_decode_uint_checked(&fs, fs_next, &offset) != 0) {
158+
break;
159+
}
160+
if (size_out != NULL) {
161+
*size_out = size;
162+
*data_out = self->filesystem + offset;
163+
}
164+
return 0;
127165
} else {
128166
// Skip this record.
129167
fs = fs_next;
130168
}
131169
}
170+
return -MP_EIO;
132171
}
133172

134173
// Searches for `path` in the filesystem.
@@ -144,10 +183,17 @@ mp_import_stat_t mp_vfs_rom_search_filesystem(mp_obj_vfs_rom_t *self, const char
144183
}
145184
while (path_len > 0 && fs < fs_top) {
146185
const uint8_t *fs_next;
147-
record_kind_t record_kind = extract_record(&fs, &fs_next);
148-
if (record_kind == ROMFS_RECORD_KIND_DIRECTORY || record_kind == ROMFS_RECORD_KIND_FILE) {
186+
record_kind_t record_kind = extract_record(&fs, &fs_next, fs_top);
187+
if (record_kind == ROMFS_RECORD_KIND_UNUSED) {
188+
// Corrupt filesystem.
189+
return MP_IMPORT_STAT_NO_EXIST;
190+
} else if (record_kind == ROMFS_RECORD_KIND_DIRECTORY || record_kind == ROMFS_RECORD_KIND_FILE) {
149191
// A directory or file record.
150-
mp_uint_t name_len = mp_decode_uint(&fs);
192+
mp_uint_t name_len;
193+
if (mp_decode_uint_checked(&fs, fs_next, &name_len) != 0) {
194+
// Corrupt filesystem.
195+
return MP_IMPORT_STAT_NO_EXIST;
196+
}
151197
if ((name_len == path_len
152198
|| (name_len < path_len && path[name_len] == '/'))
153199
&& memcmp(path, fs, name_len) == 0) {
@@ -167,8 +213,9 @@ mp_import_stat_t mp_vfs_rom_search_filesystem(mp_obj_vfs_rom_t *self, const char
167213
if (path_len != 0) {
168214
return MP_IMPORT_STAT_NO_EXIST;
169215
}
170-
if (size_out != NULL) {
171-
extract_data(self, fs, fs_top, size_out, data_out);
216+
if (extract_data(self, fs, fs_top, size_out, data_out) != 0) {
217+
// Corrupt filesystem.
218+
return MP_IMPORT_STAT_NO_EXIST;
172219
}
173220
return MP_IMPORT_STAT_FILE;
174221
}
@@ -214,7 +261,15 @@ static mp_obj_t vfs_rom_make_new(const mp_obj_type_t *type, size_t n_args, size_
214261
}
215262

216263
// The ROMFS is a record itself, so enter into it and compute its limit.
217-
extract_record(&self->filesystem, &self->filesystem_end);
264+
record_kind_t record_kind = extract_record(&self->filesystem, &self->filesystem_end, self->filesystem + bufinfo.len);
265+
if (record_kind != ROMFS_RECORD_KIND_FILESYSTEM) {
266+
mp_raise_OSError(MP_ENODEV);
267+
}
268+
269+
// Check the filesystem is within the limits of the input buffer.
270+
if (self->filesystem_end > (const uint8_t *)bufinfo.buf + bufinfo.len) {
271+
mp_raise_OSError(MP_ENODEV);
272+
}
218273

219274
return MP_OBJ_FROM_PTR(self);
220275
}
@@ -259,13 +314,21 @@ static mp_obj_t vfs_rom_ilistdir_it_iternext(mp_obj_t self_in) {
259314

260315
while (self->index < self->index_top) {
261316
const uint8_t *index_next;
262-
record_kind_t record_kind = extract_record(&self->index, &index_next);
317+
record_kind_t record_kind = extract_record(&self->index, &index_next, self->index_top);
263318
uint32_t type;
264319
mp_uint_t name_len;
265320
size_t data_len;
266-
if (record_kind == ROMFS_RECORD_KIND_DIRECTORY || record_kind == ROMFS_RECORD_KIND_FILE) {
321+
if (record_kind == ROMFS_RECORD_KIND_UNUSED) {
322+
// Corrupt filesystem.
323+
self->index = self->index_top;
324+
break;
325+
} else if (record_kind == ROMFS_RECORD_KIND_DIRECTORY || record_kind == ROMFS_RECORD_KIND_FILE) {
267326
// A directory or file record.
268-
name_len = mp_decode_uint(&self->index);
327+
if (mp_decode_uint_checked(&self->index, index_next, &name_len) != 0) {
328+
// Corrupt filesystem.
329+
self->index = self->index_top;
330+
break;
331+
}
269332
if (record_kind == ROMFS_RECORD_KIND_DIRECTORY) {
270333
// A directory.
271334
type = MP_S_IFDIR;
@@ -274,7 +337,10 @@ static mp_obj_t vfs_rom_ilistdir_it_iternext(mp_obj_t self_in) {
274337
// A file.
275338
type = MP_S_IFREG;
276339
const uint8_t *data_value;
277-
extract_data(self->vfs_rom, self->index + name_len, index_next, &data_len, &data_value);
340+
if (extract_data(self->vfs_rom, self->index + name_len, index_next, &data_len, &data_value) != 0) {
341+
// Corrupt filesystem.
342+
break;
343+
}
278344
}
279345
} else {
280346
// Skip this record.

lib/pico-sdk

Submodule pico-sdk updated 138 files

ports/cc3200/mods/pybpin.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,20 @@ static mp_obj_t pin_value(size_t n_args, const mp_obj_t *args) {
680680
}
681681
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
682682

683+
// pin.toggle()
684+
static mp_obj_t pin_toggle(mp_obj_t self_in) {
685+
pin_obj_t *self = self_in;
686+
if (self->value) {
687+
self->value = 0;
688+
MAP_GPIOPinWrite(self->port, self->bit, 0);
689+
} else {
690+
self->value = 1;
691+
MAP_GPIOPinWrite(self->port, self->bit, self->bit);
692+
}
693+
return mp_const_none;
694+
}
695+
static MP_DEFINE_CONST_FUN_OBJ_1(pin_toggle_obj, pin_toggle);
696+
683697
static mp_obj_t pin_id(mp_obj_t self_in) {
684698
pin_obj_t *self = self_in;
685699
return MP_OBJ_NEW_QSTR(self->name);
@@ -902,6 +916,7 @@ static const mp_rom_map_elem_t pin_locals_dict_table[] = {
902916
// instance methods
903917
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pin_init_obj) },
904918
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&pin_value_obj) },
919+
{ MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&pin_toggle_obj) },
905920
{ MP_ROM_QSTR(MP_QSTR_id), MP_ROM_PTR(&pin_id_obj) },
906921
{ MP_ROM_QSTR(MP_QSTR_mode), MP_ROM_PTR(&pin_mode_obj) },
907922
{ MP_ROM_QSTR(MP_QSTR_pull), MP_ROM_PTR(&pin_pull_obj) },

ports/esp32/README.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ This is a port of MicroPython to the Espressif ESP32 series of
55
microcontrollers. It uses the ESP-IDF framework and MicroPython runs as
66
a task under FreeRTOS.
77

8+
Currently supports ESP32, ESP32-C3, ESP32-C6, ESP32-S2 and ESP32-S3
9+
(ESP8266 is supported by a separate MicroPython port).
10+
811
Supported features include:
912
- REPL (Python prompt) over UART0.
1013
- 16k stack for the MicroPython task and approximately 100k Python heap.
@@ -67,12 +70,16 @@ After you've cloned and checked out the IDF to the correct version, run the
6770

6871
```bash
6972
$ cd esp-idf
70-
$ ./install.sh # (or install.bat on Windows)
73+
$ ./install.sh esp32 # (or install.bat on Windows)
7174
$ source export.sh # (or export.bat on Windows)
7275
```
7376

74-
The `install.sh` step only needs to be done once. You will need to source
75-
`export.sh` for every new session.
77+
The `install.sh` step only needs to be done once. Change `esp32` if you are
78+
targeting other chip. Use comma-separated list like `esp32,esp32s2` to
79+
install for multiple chips. Or omit the chip to install for all Espressif
80+
chips (which is slower).
81+
82+
You will need to source `export.sh` for every new session.
7683

7784
Building the firmware
7885
---------------------
@@ -85,7 +92,7 @@ this repository):
8592
$ make -C mpy-cross
8693
```
8794

88-
Then to build MicroPython for the ESP32 run:
95+
Then to build MicroPython for ESP32 run:
8996

9097
```bash
9198
$ cd ports/esp32
@@ -106,7 +113,7 @@ rebooting or logging out and in again. (Note: on some distributions this may
106113
be the `uucp` group, run `ls -la /dev/ttyUSB0` to check.)
107114

108115
```bash
109-
$ sudo adduser <username> dialout
116+
$ sudo usermod -aG dialout <username>
110117
```
111118

112119
If you are installing MicroPython to your module for the first time, or
@@ -141,7 +148,7 @@ $ idf.py -D MICROPY_BOARD=ESP32_GENERIC build
141148
$ idf.py flash
142149
```
143150

144-
Some boards also support "variants", which are allow for small variations of
151+
Some boards also support "variants", which allow for small variations of
145152
an otherwise similar board. For example different flash sizes or features. For
146153
example to build the `OTA` variant of `ESP32_GENERIC`.
147154

@@ -173,7 +180,7 @@ or
173180
$ miniterm.py /dev/ttyUSB0 115200
174181
```
175182

176-
You can also use `idf.py monitor`.
183+
You can also use `idf.py monitor` or `mpremote`.
177184

178185
Configuring the WiFi and using the board
179186
----------------------------------------

ports/esp32/esp32_common.cmake

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,13 @@ list(APPEND IDF_COMPONENTS
178178
vfs
179179
)
180180

181+
# Provide the default LD fragment if not set
182+
if (MICROPY_USER_LDFRAGMENTS)
183+
set(MICROPY_LDFRAGMENTS ${MICROPY_USER_LDFRAGMENTS})
184+
else()
185+
set(MICROPY_LDFRAGMENTS linker.lf)
186+
endif()
187+
181188
# Register the main IDF component.
182189
idf_component_register(
183190
SRCS
@@ -197,7 +204,7 @@ idf_component_register(
197204
${MICROPY_BOARD_DIR}
198205
${CMAKE_BINARY_DIR}
199206
LDFRAGMENTS
200-
linker.lf
207+
${MICROPY_LDFRAGMENTS}
201208
REQUIRES
202209
${IDF_COMPONENTS}
203210
)

ports/esp32/machine_i2c.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,15 @@ static void machine_hw_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_p
146146
}
147147

148148
mp_obj_t machine_hw_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
149-
MP_MACHINE_I2C_CHECK_FOR_LEGACY_SOFTI2C_CONSTRUCTION(n_args, n_kw, all_args);
149+
// Create a SoftI2C instance if no id is specified (or is -1) but other arguments are given
150+
if (n_args != 0) {
151+
MP_MACHINE_I2C_CHECK_FOR_LEGACY_SOFTI2C_CONSTRUCTION(n_args, n_kw, all_args);
152+
}
150153

151154
// Parse args
152155
enum { ARG_id, ARG_scl, ARG_sda, ARG_freq, ARG_timeout };
153156
static const mp_arg_t allowed_args[] = {
154-
{ MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
157+
{ MP_QSTR_id, MP_ARG_INT, {.u_int = I2C_NUM_0} },
155158
{ MP_QSTR_scl, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
156159
{ MP_QSTR_sda, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
157160
{ MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
@@ -161,7 +164,9 @@ mp_obj_t machine_hw_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_
161164
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
162165

163166
// Get I2C bus
164-
mp_int_t i2c_id = mp_obj_get_int(args[ARG_id].u_obj);
167+
mp_int_t i2c_id = args[ARG_id].u_int;
168+
169+
// Check if the I2C bus is valid
165170
if (!(I2C_NUM_0 <= i2c_id && i2c_id < I2C_NUM_MAX)) {
166171
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id);
167172
}

ports/esp32/machine_pin.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,15 @@ static mp_obj_t machine_pin_on(mp_obj_t self_in) {
287287
}
288288
static MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_on_obj, machine_pin_on);
289289

290+
// pin.toggle()
291+
static mp_obj_t machine_pin_toggle(mp_obj_t self_in) {
292+
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
293+
gpio_num_t index = PIN_OBJ_PTR_INDEX(self);
294+
gpio_set_level(index, 1 - mp_hal_pin_read_output(index));
295+
return mp_const_none;
296+
}
297+
static MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle);
298+
290299
// pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING)
291300
static mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
292301
enum { ARG_handler, ARG_trigger, ARG_wake };
@@ -366,6 +375,7 @@ static const mp_rom_map_elem_t machine_pin_locals_dict_table[] = {
366375
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) },
367376
{ MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_off_obj) },
368377
{ MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_on_obj) },
378+
{ MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_pin_toggle_obj) },
369379
{ MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) },
370380

371381
// class attributes

0 commit comments

Comments
 (0)