summaryrefslogtreecommitdiffstatshomepage
path: root/extmod
diff options
context:
space:
mode:
Diffstat (limited to 'extmod')
-rw-r--r--extmod/fsusermount.c3
-rw-r--r--extmod/machine_i2c.c150
-rw-r--r--extmod/machine_pulse.c2
-rw-r--r--extmod/machine_spi.c86
-rw-r--r--extmod/machine_spi.h15
-rw-r--r--extmod/modbtree.c5
-rw-r--r--extmod/modframebuf.c1
-rw-r--r--extmod/modlwip.c49
-rw-r--r--extmod/modubinascii.c5
-rw-r--r--extmod/moductypes.c3
-rw-r--r--extmod/moduhashlib.c1
-rw-r--r--extmod/moduheapq.c1
-rw-r--r--extmod/modujson.c108
-rw-r--r--extmod/modurandom.c1
-rw-r--r--extmod/modure.c1
-rw-r--r--extmod/modussl_axtls.c5
-rw-r--r--extmod/modussl_mbedtls.c303
-rw-r--r--extmod/moduzlib.c16
-rw-r--r--extmod/modwebrepl.c3
-rw-r--r--extmod/modwebsocket.c1
-rw-r--r--extmod/utime_mphal.c89
-rw-r--r--extmod/utime_mphal.h36
-rw-r--r--extmod/uzlib/tinf.h1
-rw-r--r--extmod/uzlib/tinfgzip.c110
-rw-r--r--extmod/uzlib/tinflate.c3
-rw-r--r--extmod/vfs_fat.c84
-rw-r--r--extmod/vfs_fat_file.c47
-rw-r--r--extmod/vfs_fat_misc.c4
28 files changed, 904 insertions, 229 deletions
diff --git a/extmod/fsusermount.c b/extmod/fsusermount.c
index cbc1e36220..5882aba991 100644
--- a/extmod/fsusermount.c
+++ b/extmod/fsusermount.c
@@ -31,6 +31,7 @@
#include "py/nlr.h"
#include "py/runtime.h"
+#include "py/mperrno.h"
#include "lib/fatfs/ff.h"
#include "extmod/fsusermount.h"
@@ -183,7 +184,7 @@ mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in) {
}
if (i == MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL)));
+ mp_raise_OSError(MP_EINVAL);
}
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c
index ceddf0730e..e201b23990 100644
--- a/extmod/machine_i2c.c
+++ b/extmod/machine_i2c.c
@@ -34,6 +34,9 @@
#if MICROPY_PY_MACHINE_I2C
+// Clock stretching limit, so that we don't get stuck.
+#define I2C_STRETCH_LIMIT 255
+
typedef struct _machine_i2c_obj_t {
mp_obj_base_t base;
uint32_t us_delay;
@@ -53,6 +56,11 @@ STATIC void mp_hal_i2c_scl_low(machine_i2c_obj_t *self) {
STATIC void mp_hal_i2c_scl_release(machine_i2c_obj_t *self) {
mp_hal_pin_od_high(self->scl);
+ mp_hal_i2c_delay(self);
+ // For clock stretching, wait for the SCL pin to be released, with timeout.
+ for (int count = I2C_STRETCH_LIMIT; mp_hal_pin_read(self->scl) == 0 && count; --count) {
+ mp_hal_delay_us_fast(1);
+ }
}
STATIC void mp_hal_i2c_sda_low(machine_i2c_obj_t *self) {
@@ -71,7 +79,6 @@ STATIC void mp_hal_i2c_start(machine_i2c_obj_t *self) {
mp_hal_i2c_sda_release(self);
mp_hal_i2c_delay(self);
mp_hal_i2c_scl_release(self);
- mp_hal_i2c_delay(self);
mp_hal_i2c_sda_low(self);
mp_hal_i2c_delay(self);
}
@@ -81,7 +88,6 @@ STATIC void mp_hal_i2c_stop(machine_i2c_obj_t *self) {
mp_hal_i2c_sda_low(self);
mp_hal_i2c_delay(self);
mp_hal_i2c_scl_release(self);
- mp_hal_i2c_delay(self);
mp_hal_i2c_sda_release(self);
mp_hal_i2c_delay(self);
}
@@ -108,14 +114,12 @@ STATIC int mp_hal_i2c_write_byte(machine_i2c_obj_t *self, uint8_t val) {
}
mp_hal_i2c_delay(self);
mp_hal_i2c_scl_release(self);
- mp_hal_i2c_delay(self);
mp_hal_i2c_scl_low(self);
}
mp_hal_i2c_sda_release(self);
mp_hal_i2c_delay(self);
mp_hal_i2c_scl_release(self);
- mp_hal_i2c_delay(self);
int ret = mp_hal_i2c_sda_read(self);
mp_hal_i2c_delay(self);
@@ -124,24 +128,6 @@ STATIC int mp_hal_i2c_write_byte(machine_i2c_obj_t *self, uint8_t val) {
return !ret;
}
-STATIC void mp_hal_i2c_write(machine_i2c_obj_t *self, uint8_t addr, uint8_t *data, size_t len) {
- mp_hal_i2c_start(self);
- if (!mp_hal_i2c_write_byte(self, addr << 1)) {
- goto er;
- }
- while (len--) {
- if (!mp_hal_i2c_write_byte(self, *data++)) {
- goto er;
- }
- }
- mp_hal_i2c_stop(self);
- return;
-
-er:
- mp_hal_i2c_stop(self);
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
-}
-
STATIC int mp_hal_i2c_read_byte(machine_i2c_obj_t *self, uint8_t *val, int nack) {
mp_hal_i2c_delay(self);
mp_hal_i2c_scl_low(self);
@@ -150,7 +136,6 @@ STATIC int mp_hal_i2c_read_byte(machine_i2c_obj_t *self, uint8_t *val, int nack)
uint8_t data = 0;
for (int i = 7; i >= 0; i--) {
mp_hal_i2c_scl_release(self);
- mp_hal_i2c_delay(self);
data = (data << 1) | mp_hal_i2c_sda_read(self);
mp_hal_i2c_scl_low(self);
mp_hal_i2c_delay(self);
@@ -163,40 +148,33 @@ STATIC int mp_hal_i2c_read_byte(machine_i2c_obj_t *self, uint8_t *val, int nack)
}
mp_hal_i2c_delay(self);
mp_hal_i2c_scl_release(self);
- mp_hal_i2c_delay(self);
mp_hal_i2c_scl_low(self);
mp_hal_i2c_sda_release(self);
return 1; // success
}
-STATIC void mp_hal_i2c_read(machine_i2c_obj_t *self, uint8_t addr, uint8_t *data, size_t len) {
- mp_hal_i2c_start(self);
- if (!mp_hal_i2c_write_byte(self, (addr << 1) | 1)) {
- goto er;
+// addr is the device address, memaddr is a memory address sent big-endian
+STATIC int mp_hal_i2c_write_addresses(machine_i2c_obj_t *self, uint8_t addr,
+ uint32_t memaddr, uint8_t addrsize) {
+ if (!mp_hal_i2c_write_byte(self, addr << 1)) {
+ return 0; // error
}
- while (len--) {
- if (!mp_hal_i2c_read_byte(self, data++, len == 0)) {
- goto er;
+ for (int16_t i = addrsize - 8; i >= 0; i -= 8) {
+ if (!mp_hal_i2c_write_byte(self, memaddr >> i)) {
+ return 0; // error
}
}
- mp_hal_i2c_stop(self);
- return;
-
-er:
- mp_hal_i2c_stop(self);
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
+ return 1; // success
}
-STATIC void mp_hal_i2c_write_mem(machine_i2c_obj_t *self, uint8_t addr, uint16_t memaddr, const uint8_t *src, size_t len) {
+STATIC void mp_hal_i2c_write_mem(machine_i2c_obj_t *self, uint8_t addr,
+ uint32_t memaddr, uint8_t addrsize, const uint8_t *src, size_t len) {
// start the I2C transaction
mp_hal_i2c_start(self);
// write the slave address and the memory address within the slave
- if (!mp_hal_i2c_write_byte(self, addr << 1)) {
- goto er;
- }
- if (!mp_hal_i2c_write_byte(self, memaddr)) {
+ if (!mp_hal_i2c_write_addresses(self, addr, memaddr, addrsize)) {
goto er;
}
@@ -216,20 +194,30 @@ er:
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
}
-STATIC void mp_hal_i2c_read_mem(machine_i2c_obj_t *self, uint8_t addr, uint16_t memaddr, uint8_t *dest, size_t len) {
+STATIC void mp_hal_i2c_read_mem(machine_i2c_obj_t *self, uint8_t addr,
+ uint32_t memaddr, uint8_t addrsize, uint8_t *dest, size_t len) {
// start the I2C transaction
mp_hal_i2c_start(self);
- // write the slave address and the memory address within the slave
- if (!mp_hal_i2c_write_byte(self, addr << 1)) {
- goto er;
+ if (addrsize) {
+ // write the slave address and the memory address within the slave
+ if (!mp_hal_i2c_write_addresses(self, addr, memaddr, addrsize)) {
+ goto er;
+ }
+
+ // i2c_read will do a repeated start, and then read the I2C memory
+ mp_hal_i2c_start(self);
}
- if (!mp_hal_i2c_write_byte(self, memaddr)) {
+
+ if (!mp_hal_i2c_write_byte(self, (addr << 1) | 1)) {
goto er;
}
-
- // i2c_read will do a repeated start, and then read the I2C memory
- mp_hal_i2c_read(self, addr, dest, len);
+ while (len--) {
+ if (!mp_hal_i2c_read_byte(self, dest++, len == 0)) {
+ goto er;
+ }
+ }
+ mp_hal_i2c_stop(self);
return;
er:
@@ -237,6 +225,14 @@ er:
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
}
+STATIC void mp_hal_i2c_write(machine_i2c_obj_t *self, uint8_t addr, const uint8_t *src, size_t len) {
+ mp_hal_i2c_write_mem(self, addr, 0, 0, src, len);
+}
+
+STATIC void mp_hal_i2c_read(machine_i2c_obj_t *self, uint8_t addr, uint8_t *dest, size_t len) {
+ mp_hal_i2c_read_mem(self, addr, 0, 0, dest, len);
+}
+
/******************************************************************************/
// MicroPython bindings for I2C
@@ -276,7 +272,7 @@ STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
for (int addr = 0x08; addr < 0x78; ++addr) {
mp_hal_i2c_start(self);
- int ack = mp_hal_i2c_write_byte(self, (addr << 1) | 1);
+ int ack = mp_hal_i2c_write_byte(self, (addr << 1));
if (ack) {
mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr));
}
@@ -365,68 +361,64 @@ STATIC mp_obj_t machine_i2c_writeto(mp_obj_t self_in, mp_obj_t addr_in, mp_obj_t
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(machine_i2c_writeto_obj, machine_i2c_writeto);
+STATIC const mp_arg_t machine_i2c_mem_allowed_args[] = {
+ { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
+ { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
+ { MP_QSTR_arg, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
+};
+
STATIC mp_obj_t machine_i2c_readfrom_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_addr, ARG_memaddr, ARG_n, ARG_addrsize };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
- { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
- { MP_QSTR_n, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
- //{ MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, TODO
- };
machine_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+ mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
+ MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
// create the buffer to store data into
vstr_t vstr;
- vstr_init_len(&vstr, args[ARG_n].u_int);
+ vstr_init_len(&vstr, mp_obj_get_int(args[ARG_n].u_obj));
// do the transfer
- mp_hal_i2c_read_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int, (uint8_t*)vstr.buf, vstr.len);
+ mp_hal_i2c_read_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int,
+ args[ARG_addrsize].u_int, (uint8_t*)vstr.buf, vstr.len);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_obj, 1, machine_i2c_readfrom_mem);
+
STATIC mp_obj_t machine_i2c_readfrom_mem_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_addr, ARG_memaddr, ARG_buf, ARG_addrsize };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
- { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
- { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
- //{ MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, TODO
- };
machine_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+ mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
+ MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
// get the buffer to store data into
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_WRITE);
// do the transfer
- mp_hal_i2c_read_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int, bufinfo.buf, bufinfo.len);
+ mp_hal_i2c_read_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int,
+ args[ARG_addrsize].u_int, bufinfo.buf, bufinfo.len);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_into_obj, 1, machine_i2c_readfrom_mem_into);
STATIC mp_obj_t machine_i2c_writeto_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_addr, ARG_memaddr, ARG_buf, ARG_addrsize };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
- { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
- { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
- //{ MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, TODO
- };
machine_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+ mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
+ MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
// get the buffer to write the data from
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_READ);
// do the transfer
- mp_hal_i2c_write_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int, bufinfo.buf, bufinfo.len);
+ mp_hal_i2c_write_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int,
+ args[ARG_addrsize].u_int, bufinfo.buf, bufinfo.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_writeto_mem_obj, 1, machine_i2c_writeto_mem);
diff --git a/extmod/machine_pulse.c b/extmod/machine_pulse.c
index 8c8bff510c..b2a78d72ee 100644
--- a/extmod/machine_pulse.c
+++ b/extmod/machine_pulse.c
@@ -58,7 +58,7 @@ STATIC mp_obj_t machine_time_pulse_us_(size_t n_args, const mp_obj_t *args) {
}
mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us);
if (us == (mp_uint_t)-1) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT)));
+ mp_raise_OSError(MP_ETIMEDOUT);
}
return mp_obj_new_int(us);
}
diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c
index 6b6202a221..e3d72ab588 100644
--- a/extmod/machine_spi.c
+++ b/extmod/machine_spi.c
@@ -25,26 +25,85 @@
*/
#include <stdio.h>
+#include <string.h>
#include "py/runtime.h"
#include "extmod/machine_spi.h"
#if MICROPY_PY_MACHINE_SPI
-STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t slen, const uint8_t *src, size_t dlen, uint8_t *dest) {
+void mp_machine_soft_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
+ mp_machine_soft_spi_obj_t *self = (mp_machine_soft_spi_obj_t*)self_in;
+ uint32_t delay_half = self->delay_half;
+
+ // only MSB transfer is implemented
+
+ // If a port defines MICROPY_PY_MACHINE_SPI_MIN_DELAY, and the configured
+ // delay_half is equal to this value, then the software SPI implementation
+ // will run as fast as possible, limited only by CPU speed and GPIO time.
+ #ifdef MICROPY_PY_MACHINE_SPI_MIN_DELAY
+ if (delay_half == MICROPY_PY_MACHINE_SPI_MIN_DELAY) {
+ for (size_t i = 0; i < len; ++i) {
+ uint8_t data_out = src[i];
+ uint8_t data_in = 0;
+ for (int j = 0; j < 8; ++j, data_out <<= 1) {
+ mp_hal_pin_write(self->mosi, (data_out >> 7) & 1);
+ mp_hal_pin_write(self->sck, 1 - self->polarity);
+ data_in = (data_in << 1) | mp_hal_pin_read(self->miso);
+ mp_hal_pin_write(self->sck, self->polarity);
+ }
+ if (dest != NULL) {
+ dest[i] = data_in;
+ }
+ }
+ return;
+ }
+ #endif
+
+ for (size_t i = 0; i < len; ++i) {
+ uint8_t data_out = src[i];
+ uint8_t data_in = 0;
+ for (int j = 0; j < 8; ++j, data_out <<= 1) {
+ mp_hal_pin_write(self->mosi, (data_out >> 7) & 1);
+ if (self->phase == 0) {
+ mp_hal_delay_us_fast(delay_half);
+ mp_hal_pin_write(self->sck, 1 - self->polarity);
+ } else {
+ mp_hal_pin_write(self->sck, 1 - self->polarity);
+ mp_hal_delay_us_fast(delay_half);
+ }
+ data_in = (data_in << 1) | mp_hal_pin_read(self->miso);
+ if (self->phase == 0) {
+ mp_hal_delay_us_fast(delay_half);
+ mp_hal_pin_write(self->sck, self->polarity);
+ } else {
+ mp_hal_pin_write(self->sck, self->polarity);
+ mp_hal_delay_us_fast(delay_half);
+ }
+ }
+ if (dest != NULL) {
+ dest[i] = data_in;
+ }
+
+ // Some ports need a regular callback, but probably we don't need
+ // to do this every byte, or even at all.
+ #ifdef MICROPY_EVENT_POLL_HOOK
+ MICROPY_EVENT_POLL_HOOK;
+ #endif
+ }
+}
+
+STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) {
mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(self);
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
- spi_p->transfer(s, slen, src, dlen, dest);
+ spi_p->transfer(s, len, src, dest);
}
STATIC mp_obj_t mp_machine_spi_read(size_t n_args, const mp_obj_t *args) {
- uint8_t write_byte = 0;
- if (n_args == 3) {
- write_byte = mp_obj_get_int(args[2]);
- }
vstr_t vstr;
vstr_init_len(&vstr, mp_obj_get_int(args[1]));
- mp_machine_spi_transfer(args[0], 1, &write_byte, vstr.len, (uint8_t*)vstr.buf);
+ memset(vstr.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, vstr.len);
+ mp_machine_spi_transfer(args[0], vstr.len, vstr.buf, vstr.buf);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_spi_read);
@@ -52,11 +111,8 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_sp
STATIC mp_obj_t mp_machine_spi_readinto(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
- uint8_t write_byte = 0;
- if (n_args == 3) {
- write_byte = mp_obj_get_int(args[2]);
- }
- mp_machine_spi_transfer(args[0], 1, &write_byte, bufinfo.len, (uint8_t*)bufinfo.buf);
+ memset(bufinfo.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, bufinfo.len);
+ mp_machine_spi_transfer(args[0], bufinfo.len, bufinfo.buf, bufinfo.buf);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj, 2, 3, mp_machine_spi_readinto);
@@ -64,7 +120,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj, 2, 3, mp_machin
STATIC mp_obj_t mp_machine_spi_write(mp_obj_t self, mp_obj_t wr_buf) {
mp_buffer_info_t src;
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
- mp_machine_spi_transfer(self, src.len, (const uint8_t*)src.buf, 0, NULL);
+ mp_machine_spi_transfer(self, src.len, (const uint8_t*)src.buf, NULL);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_machine_spi_write_obj, mp_machine_spi_write);
@@ -75,9 +131,9 @@ STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp
mp_buffer_info_t dest;
mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE);
if (src.len != dest.len) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "buffers must be the same length"));
+ mp_raise_ValueError("buffers must be the same length");
}
- mp_machine_spi_transfer(self, src.len, (const uint8_t*)src.buf, dest.len, (uint8_t*)dest.buf);
+ mp_machine_spi_transfer(self, src.len, src.buf, dest.buf);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_3(mp_machine_spi_write_readinto_obj, mp_machine_spi_write_readinto);
diff --git a/extmod/machine_spi.h b/extmod/machine_spi.h
index 26d716fc11..316d06646e 100644
--- a/extmod/machine_spi.h
+++ b/extmod/machine_spi.h
@@ -28,12 +28,25 @@
#define MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
#include "py/obj.h"
+#include "py/mphal.h"
// SPI protocol
typedef struct _mp_machine_spi_p_t {
- void (*transfer)(mp_obj_base_t *obj, size_t slen, const uint8_t *src, size_t dlen, uint8_t *dest);
+ void (*transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest);
} mp_machine_spi_p_t;
+typedef struct _mp_machine_soft_spi_obj_t {
+ mp_obj_base_t base;
+ uint32_t delay_half; // microsecond delay for half SCK period
+ uint8_t polarity;
+ uint8_t phase;
+ mp_hal_pin_obj_t sck;
+ mp_hal_pin_obj_t mosi;
+ mp_hal_pin_obj_t miso;
+} mp_machine_soft_spi_obj_t;
+
+void mp_machine_soft_spi_transfer(mp_obj_base_t *self, size_t len, const uint8_t *src, uint8_t *dest);
+
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_read_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_readinto_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_write_obj);
diff --git a/extmod/modbtree.c b/extmod/modbtree.c
index ea2ea582c8..f5ec5bfca1 100644
--- a/extmod/modbtree.c
+++ b/extmod/modbtree.c
@@ -58,7 +58,7 @@ STATIC const mp_obj_type_t btree_type;
#define CHECK_ERROR(res) \
if (res == RET_ERROR) { \
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno))); \
+ mp_raise_OSError(errno); \
}
void __dbpanic(DB *db) {
@@ -370,7 +370,7 @@ STATIC mp_obj_t mod_btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t
DB *db = __bt_open(pos_args[0], &btree_stream_fvtable, &openinfo, /*dflags*/0);
if (db == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno)));
+ mp_raise_OSError(errno);
}
return MP_OBJ_FROM_PTR(btree_new(db));
}
@@ -387,7 +387,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_btree_globals, mp_module_btree_globals_tab
const mp_obj_module_t mp_module_btree = {
.base = { &mp_type_module },
- .name = MP_QSTR_btree,
.globals = (mp_obj_dict_t*)&mp_module_btree_globals,
};
diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c
index 3c884c6898..cd7f1c5e4b 100644
--- a/extmod/modframebuf.c
+++ b/extmod/modframebuf.c
@@ -213,7 +213,6 @@ STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_tab
const mp_obj_module_t mp_module_framebuf = {
.base = { &mp_type_module },
- .name = MP_QSTR_framebuf,
.globals = (mp_obj_dict_t*)&framebuf_module_globals,
};
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index 80df662647..11ba6e4231 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -598,11 +598,11 @@ STATIC mp_obj_t lwip_socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args
case MOD_NETWORK_SOCK_STREAM: socket->pcb.tcp = tcp_new(); break;
case MOD_NETWORK_SOCK_DGRAM: socket->pcb.udp = udp_new(); break;
//case MOD_NETWORK_SOCK_RAW: socket->pcb.raw = raw_new(); break;
- default: nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINVAL)));
+ default: mp_raise_OSError(MP_EINVAL);
}
if (socket->pcb.tcp == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ENOMEM)));
+ mp_raise_OSError(MP_ENOMEM);
}
switch (socket->type) {
@@ -686,7 +686,7 @@ STATIC mp_obj_t lwip_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
}
if (err != ERR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(error_lookup_table[-err])));
+ mp_raise_OSError(error_lookup_table[-err]);
}
return mp_const_none;
@@ -698,15 +698,15 @@ STATIC mp_obj_t lwip_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) {
mp_int_t backlog = mp_obj_get_int(backlog_in);
if (socket->pcb.tcp == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF)));
+ mp_raise_OSError(MP_EBADF);
}
if (socket->type != MOD_NETWORK_SOCK_STREAM) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EOPNOTSUPP)));
+ mp_raise_OSError(MP_EOPNOTSUPP);
}
struct tcp_pcb *new_pcb = tcp_listen_with_backlog(socket->pcb.tcp, (u8_t)backlog);
if (new_pcb == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ENOMEM)));
+ mp_raise_OSError(MP_ENOMEM);
}
socket->pcb.tcp = new_pcb;
tcp_accept(new_pcb, _lwip_tcp_accept);
@@ -719,15 +719,15 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
lwip_socket_obj_t *socket = self_in;
if (socket->pcb.tcp == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF)));
+ mp_raise_OSError(MP_EBADF);
}
if (socket->type != MOD_NETWORK_SOCK_STREAM) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EOPNOTSUPP)));
+ mp_raise_OSError(MP_EOPNOTSUPP);
}
// I need to do this because "tcp_accepted", later, is a macro.
struct tcp_pcb *listener = socket->pcb.tcp;
if (listener->state != LISTEN) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINVAL)));
+ mp_raise_OSError(MP_EINVAL);
}
// accept incoming connection
@@ -738,7 +738,7 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
if (socket->incoming.connection != NULL) break;
}
if (socket->incoming.connection == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT)));
+ mp_raise_OSError(MP_ETIMEDOUT);
}
} else {
while (socket->incoming.connection == NULL) {
@@ -785,7 +785,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
lwip_socket_obj_t *socket = self_in;
if (socket->pcb.tcp == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF)));
+ mp_raise_OSError(MP_EBADF);
}
// get address
@@ -800,9 +800,9 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
case MOD_NETWORK_SOCK_STREAM: {
if (socket->state != STATE_NEW) {
if (socket->state == STATE_CONNECTED) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EALREADY)));
+ mp_raise_OSError(MP_EALREADY);
} else {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINPROGRESS)));
+ mp_raise_OSError(MP_EINPROGRESS);
}
}
// Register our recieve callback.
@@ -811,7 +811,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
err = tcp_connect(socket->pcb.tcp, &dest, port, _lwip_tcp_connected);
if (err != ERR_OK) {
socket->state = STATE_NEW;
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(error_lookup_table[-err])));
+ mp_raise_OSError(error_lookup_table[-err]);
}
socket->peer_port = (mp_uint_t)port;
memcpy(socket->peer, &dest, sizeof(socket->peer));
@@ -822,7 +822,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
if (socket->state != STATE_CONNECTING) break;
}
if (socket->state == STATE_CONNECTING) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT)));
+ mp_raise_OSError(MP_ETIMEDOUT);
}
} else {
while (socket->state == STATE_CONNECTING) {
@@ -843,7 +843,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
}
if (err != ERR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(error_lookup_table[-err])));
+ mp_raise_OSError(error_lookup_table[-err]);
}
return mp_const_none;
@@ -855,7 +855,7 @@ STATIC void lwip_socket_check_connected(lwip_socket_obj_t *socket) {
// not connected
int _errno = error_lookup_table[-socket->state];
socket->state = _ERR_BADF;
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+ mp_raise_OSError(_errno);
}
}
@@ -880,7 +880,7 @@ STATIC mp_obj_t lwip_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
}
}
if (ret == -1) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+ mp_raise_OSError(_errno);
}
return mp_obj_new_int_from_uint(ret);
@@ -909,7 +909,7 @@ STATIC mp_obj_t lwip_socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
}
}
if (ret == -1) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+ mp_raise_OSError(_errno);
}
if (ret == 0) {
@@ -944,7 +944,7 @@ STATIC mp_obj_t lwip_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t
}
}
if (ret == -1) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+ mp_raise_OSError(_errno);
}
return mp_obj_new_int_from_uint(ret);
@@ -977,7 +977,7 @@ STATIC mp_obj_t lwip_socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
}
}
if (ret == -1) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+ mp_raise_OSError(_errno);
}
mp_obj_t tuple[2];
@@ -1010,7 +1010,7 @@ STATIC mp_obj_t lwip_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) {
// most useful behavior is: check whether we will be able to send all of input
// data without EAGAIN, and if won't be, raise it without sending any.
if (bufinfo.len > tcp_sndbuf(socket->pcb.tcp)) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EAGAIN)));
+ mp_raise_OSError(MP_EAGAIN);
}
}
// TODO: In CPython3.5, socket timeout should apply to the
@@ -1018,7 +1018,7 @@ STATIC mp_obj_t lwip_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) {
while (bufinfo.len != 0) {
ret = lwip_tcp_send(socket, bufinfo.buf, bufinfo.len, &_errno);
if (ret == -1) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+ mp_raise_OSError(_errno);
}
bufinfo.len -= ret;
bufinfo.buf = (char*)bufinfo.buf + ret;
@@ -1259,7 +1259,7 @@ STATIC mp_obj_t lwip_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
if (state.status < 0) {
// TODO: CPython raises gaierror, we raise with native lwIP negative error
// values, to differentiate from normal errno's at least in such way.
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(state.status)));
+ mp_raise_OSError(state.status);
}
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
@@ -1309,7 +1309,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table
const mp_obj_module_t mp_module_lwip = {
.base = { &mp_type_module },
- .name = MP_QSTR_lwip,
.globals = (mp_obj_dict_t*)&mp_module_lwip_globals,
};
diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c
index 562c754b52..2ef1a6f21d 100644
--- a/extmod/modubinascii.c
+++ b/extmod/modubinascii.c
@@ -208,9 +208,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64);
mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
- uint32_t crc = (n_args > 1) ? mp_obj_get_int(args[1]) : 0;
+ uint32_t crc = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 0;
crc = uzlib_crc32(bufinfo.buf, bufinfo.len, crc ^ 0xffffffff);
- return MP_OBJ_NEW_SMALL_INT(crc ^ 0xffffffff);
+ return mp_obj_new_int_from_uint(crc ^ 0xffffffff);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_binascii_crc32);
#endif
@@ -232,7 +232,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globa
const mp_obj_module_t mp_module_ubinascii = {
.base = { &mp_type_module },
- .name = MP_QSTR_ubinascii,
.globals = (mp_obj_dict_t*)&mp_module_binascii_globals,
};
diff --git a/extmod/moductypes.c b/extmod/moductypes.c
index a3071af987..6249a49406 100644
--- a/extmod/moductypes.c
+++ b/extmod/moductypes.c
@@ -125,7 +125,7 @@ STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args
mp_arg_check_num(n_args, n_kw, 2, 3, false);
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
o->base.type = type;
- o->addr = (void*)(uintptr_t)mp_obj_get_int(args[0]);
+ o->addr = (void*)(uintptr_t)mp_obj_int_get_truncated(args[0]);
o->desc = args[1];
o->flags = LAYOUT_NATIVE;
if (n_args == 3) {
@@ -710,7 +710,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uctypes_globals, mp_module_uctypes_globals
const mp_obj_module_t mp_module_uctypes = {
.base = { &mp_type_module },
- .name = MP_QSTR_uctypes,
.globals = (mp_obj_dict_t*)&mp_module_uctypes_globals,
};
diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c
index 6cd690a676..13525cc3fa 100644
--- a/extmod/moduhashlib.c
+++ b/extmod/moduhashlib.c
@@ -151,7 +151,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_hashlib_globals, mp_module_hashlib_globals
const mp_obj_module_t mp_module_uhashlib = {
.base = { &mp_type_module },
- .name = MP_QSTR_uhashlib,
.globals = (mp_obj_dict_t*)&mp_module_hashlib_globals,
};
diff --git a/extmod/moduheapq.c b/extmod/moduheapq.c
index 84ffe54f98..567ee83da6 100644
--- a/extmod/moduheapq.c
+++ b/extmod/moduheapq.c
@@ -116,7 +116,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uheapq_globals, mp_module_uheapq_globals_t
const mp_obj_module_t mp_module_uheapq = {
.base = { &mp_type_module },
- .name = MP_QSTR_uheapq,
.globals = (mp_obj_dict_t*)&mp_module_uheapq_globals,
};
diff --git a/extmod/modujson.c b/extmod/modujson.c
index 4e080c9756..ca4e6df104 100644
--- a/extmod/modujson.c
+++ b/extmod/modujson.c
@@ -1,9 +1,9 @@
/*
- * This file is part of the Micro Python project, http://micropython.org/
+ * This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
- * Copyright (c) 2014 Damien P. George
+ * Copyright (c) 2014-2016 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -28,8 +28,10 @@
#include "py/nlr.h"
#include "py/objlist.h"
+#include "py/objstringio.h"
#include "py/parsenum.h"
#include "py/runtime.h"
+#include "py/stream.h"
#if MICROPY_PY_UJSON
@@ -42,7 +44,7 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
-// This function implements a simple non-recursive JSON parser.
+// The function below implements a simple non-recursive JSON parser.
//
// The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt
// The parser here will parse any valid JSON and return the correct
@@ -52,13 +54,35 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
// input is outside it's specs.
//
// Most of the work is parsing the primitives (null, false, true, numbers,
-// strings). It does 1 pass over the input string and so is easily extended to
-// being able to parse from a non-seekable stream. It tries to be fast and
+// strings). It does 1 pass over the input stream. It tries to be fast and
// small in code size, while not using more RAM than necessary.
-STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
- mp_uint_t len;
- const char *s = mp_obj_str_get_data(obj, &len);
- const char *top = s + len;
+
+typedef struct _ujson_stream_t {
+ mp_obj_t stream_obj;
+ mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
+ int errcode;
+ byte cur;
+} ujson_stream_t;
+
+#define S_EOF (0) // null is not allowed in json stream so is ok as EOF marker
+#define S_END(s) ((s).cur == S_EOF)
+#define S_CUR(s) ((s).cur)
+#define S_NEXT(s) (ujson_stream_next(&(s)))
+
+STATIC byte ujson_stream_next(ujson_stream_t *s) {
+ mp_uint_t ret = s->read(s->stream_obj, &s->cur, 1, &s->errcode);
+ if (s->errcode != 0) {
+ mp_raise_OSError(s->errcode);
+ }
+ if (ret == 0) {
+ s->cur = S_EOF;
+ }
+ return s->cur;
+}
+
+STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
+ const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ);
+ ujson_stream_t s = {stream_obj, stream_p->read, 0, 0};
vstr_t vstr;
vstr_init(&vstr, 8);
mp_obj_list_t stack; // we use a list as a simple stack for nested JSON
@@ -67,41 +91,43 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
mp_obj_t stack_top = MP_OBJ_NULL;
mp_obj_type_t *stack_top_type = NULL;
mp_obj_t stack_key = MP_OBJ_NULL;
+ S_NEXT(s);
for (;;) {
cont:
- if (s == top) {
+ if (S_END(s)) {
break;
}
mp_obj_t next = MP_OBJ_NULL;
bool enter = false;
- switch (*s) {
+ byte cur = S_CUR(s);
+ S_NEXT(s);
+ switch (cur) {
case ',':
case ':':
case ' ':
case '\t':
case '\n':
case '\r':
- s += 1;
goto cont;
case 'n':
- if (s + 3 < top && s[1] == 'u' && s[2] == 'l' && s[3] == 'l') {
- s += 4;
+ if (S_CUR(s) == 'u' && S_NEXT(s) == 'l' && S_NEXT(s) == 'l') {
+ S_NEXT(s);
next = mp_const_none;
} else {
goto fail;
}
break;
case 'f':
- if (s + 4 < top && s[1] == 'a' && s[2] == 'l' && s[3] == 's' && s[4] == 'e') {
- s += 5;
+ if (S_CUR(s) == 'a' && S_NEXT(s) == 'l' && S_NEXT(s) == 's' && S_NEXT(s) == 'e') {
+ S_NEXT(s);
next = mp_const_false;
} else {
goto fail;
}
break;
case 't':
- if (s + 3 < top && s[1] == 'r' && s[2] == 'u' && s[3] == 'e') {
- s += 4;
+ if (S_CUR(s) == 'r' && S_NEXT(s) == 'u' && S_NEXT(s) == 'e') {
+ S_NEXT(s);
next = mp_const_true;
} else {
goto fail;
@@ -109,11 +135,10 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
break;
case '"':
vstr_reset(&vstr);
- for (s++; s < top && *s != '"';) {
- byte c = *s;
+ for (; !S_END(s) && S_CUR(s) != '"';) {
+ byte c = S_CUR(s);
if (c == '\\') {
- s++;
- c = *s;
+ c = S_NEXT(s);
switch (c) {
case 'b': c = 0x08; break;
case 'f': c = 0x0c; break;
@@ -121,10 +146,9 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
case 'r': c = 0x0d; break;
case 't': c = 0x09; break;
case 'u': {
- if (s + 4 >= top) { goto fail; }
mp_uint_t num = 0;
for (int i = 0; i < 4; i++) {
- c = (*++s | 0x20) - '0';
+ c = (S_NEXT(s) | 0x20) - '0';
if (c > 9) {
c -= ('a' - ('9' + 1));
}
@@ -137,27 +161,29 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
}
vstr_add_byte(&vstr, c);
str_cont:
- s++;
+ S_NEXT(s);
}
- if (s == top) {
+ if (S_END(s)) {
goto fail;
}
- s++;
+ S_NEXT(s);
next = mp_obj_new_str(vstr.buf, vstr.len, false);
break;
case '-':
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {
bool flt = false;
vstr_reset(&vstr);
- for (; s < top; s++) {
- if (*s == '.' || *s == 'E' || *s == 'e') {
+ for (;;) {
+ vstr_add_byte(&vstr, cur);
+ cur = S_CUR(s);
+ if (cur == '.' || cur == 'E' || cur == 'e') {
flt = true;
- } else if (*s == '-' || unichar_isdigit(*s)) {
+ } else if (cur == '-' || unichar_isdigit(cur)) {
// pass
} else {
break;
}
- vstr_add_byte(&vstr, *s);
+ S_NEXT(s);
}
if (flt) {
next = mp_parse_num_decimal(vstr.buf, vstr.len, false, false, NULL);
@@ -169,16 +195,13 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
case '[':
next = mp_obj_new_list(0, NULL);
enter = true;
- s += 1;
break;
case '{':
next = mp_obj_new_dict(0);
enter = true;
- s += 1;
break;
case '}':
case ']': {
- s += 1;
if (stack_top == MP_OBJ_NULL) {
// no object at all
goto fail;
@@ -231,10 +254,10 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
}
success:
// eat trailing whitespace
- while (s < top && unichar_isspace(*s)) {
- s++;
+ while (unichar_isspace(S_CUR(s))) {
+ S_NEXT(s);
}
- if (s < top) {
+ if (!S_END(s)) {
// unexpected chars
goto fail;
}
@@ -248,11 +271,21 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
fail:
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "syntax error in JSON"));
}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
+
+STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
+ mp_uint_t len;
+ const char *buf = mp_obj_str_get_data(obj, &len);
+ vstr_t vstr = {len, len, (char*)buf, true};
+ mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0};
+ return mod_ujson_load(MP_OBJ_FROM_PTR(&sio));
+}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads);
STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) },
{ MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) },
+ { MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) },
{ MP_ROM_QSTR(MP_QSTR_loads), MP_ROM_PTR(&mod_ujson_loads_obj) },
};
@@ -260,7 +293,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_ujson_globals, mp_module_ujson_globals_tab
const mp_obj_module_t mp_module_ujson = {
.base = { &mp_type_module },
- .name = MP_QSTR_ujson,
.globals = (mp_obj_dict_t*)&mp_module_ujson_globals,
};
diff --git a/extmod/modurandom.c b/extmod/modurandom.c
index 27d7177207..995b0a2665 100644
--- a/extmod/modurandom.c
+++ b/extmod/modurandom.c
@@ -215,7 +215,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_urandom_globals, mp_module_urandom_globals
const mp_obj_module_t mp_module_urandom = {
.base = { &mp_type_module },
- .name = MP_QSTR_urandom,
.globals = (mp_obj_dict_t*)&mp_module_urandom_globals,
};
diff --git a/extmod/modure.c b/extmod/modure.c
index 9821e235a6..b8c242429b 100644
--- a/extmod/modure.c
+++ b/extmod/modure.c
@@ -237,7 +237,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table);
const mp_obj_module_t mp_module_ure = {
.base = { &mp_type_module },
- .name = MP_QSTR_ure,
.globals = (mp_obj_dict_t*)&mp_module_re_globals,
};
diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c
index ce86263c2c..5bc69fe261 100644
--- a/extmod/modussl_axtls.c
+++ b/extmod/modussl_axtls.c
@@ -56,7 +56,7 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, bool server_side) {
uint32_t options = SSL_SERVER_VERIFY_LATER;
if ((o->ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL)));
+ mp_raise_OSError(MP_EINVAL);
}
if (server_side) {
@@ -69,7 +69,7 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, bool server_side) {
if ((res = ssl_handshake_status(o->ssl_sock)) != SSL_OK) {
printf("ssl_handshake_status: %d\n", res);
ssl_display_error(res);
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EIO)));
+ mp_raise_OSError(MP_EIO);
}
}
@@ -196,7 +196,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table);
const mp_obj_module_t mp_module_ussl = {
.base = { &mp_type_module },
- .name = MP_QSTR_ussl,
.globals = (mp_obj_dict_t*)&mp_module_ssl_globals,
};
diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c
new file mode 100644
index 0000000000..5a7a745d82
--- /dev/null
+++ b/extmod/modussl_mbedtls.c
@@ -0,0 +1,303 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Linaro Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/mpconfig.h"
+#if MICROPY_PY_USSL && MICROPY_SSL_MBEDTLS
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "py/nlr.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+
+// mbedtls_time_t
+#include "mbedtls/platform.h"
+#include "mbedtls/net.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/pk.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/debug.h"
+
+typedef struct _mp_obj_ssl_socket_t {
+ mp_obj_base_t base;
+ mp_obj_t sock;
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctr_drbg;
+ mbedtls_ssl_context ssl;
+ mbedtls_ssl_config conf;
+ mbedtls_x509_crt cacert;
+ mbedtls_x509_crt cert;
+ mbedtls_pk_context pkey;
+} mp_obj_ssl_socket_t;
+
+struct ssl_args {
+ mp_arg_val_t key;
+ mp_arg_val_t cert;
+ mp_arg_val_t server_side;
+ mp_arg_val_t server_hostname;
+};
+
+STATIC const mp_obj_type_t ussl_socket_type;
+
+static void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) {
+ printf("DBG:%s:%04d: %s\n", file, line, str);
+}
+
+// TODO: FIXME!
+int null_entropy_func(void *data, unsigned char *output, size_t len) {
+ // enjoy random bytes
+ return 0;
+}
+
+int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) {
+ mp_obj_t sock = *(mp_obj_t*)ctx;
+
+ const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_WRITE);
+ int err;
+
+ int out_sz = sock_stream->write(sock, buf, len, &err);
+ if (out_sz == MP_STREAM_ERROR) {
+ return -err;
+ } else {
+ return out_sz;
+ }
+}
+
+int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) {
+ mp_obj_t sock = *(mp_obj_t*)ctx;
+
+ const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_READ);
+ int err;
+
+ int out_sz = sock_stream->read(sock, buf, len, &err);
+ if (out_sz == MP_STREAM_ERROR) {
+ return -err;
+ } else {
+ return out_sz;
+ }
+}
+
+
+STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
+ mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t);
+ o->base.type = &ussl_socket_type;
+
+ int ret;
+ mbedtls_ssl_init(&o->ssl);
+ mbedtls_ssl_config_init(&o->conf);
+ mbedtls_x509_crt_init(&o->cacert);
+ mbedtls_x509_crt_init(&o->cert);
+ mbedtls_pk_init(&o->pkey);
+ mbedtls_ctr_drbg_init(&o->ctr_drbg);
+ // Debug level (0-4)
+ mbedtls_debug_set_threshold(0);
+
+ mbedtls_entropy_init(&o->entropy);
+ const byte seed[] = "upy";
+ ret = mbedtls_ctr_drbg_seed(&o->ctr_drbg, null_entropy_func/*mbedtls_entropy_func*/, &o->entropy, seed, sizeof(seed));
+ if (ret != 0) {
+ printf("ret=%d\n", ret);
+ assert(0);
+ }
+
+ ret = mbedtls_ssl_config_defaults(&o->conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT);
+ if (ret != 0) {
+ assert(0);
+ }
+
+ mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE);
+ mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg);
+ mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL);
+
+ ret = mbedtls_ssl_setup(&o->ssl, &o->conf);
+ if (ret != 0) {
+ assert(0);
+ }
+
+ if (args->server_hostname.u_obj != mp_const_none) {
+ const char *sni = mp_obj_str_get_str(args->server_hostname.u_obj);
+ ret = mbedtls_ssl_set_hostname(&o->ssl, sni);
+ if (ret != 0) {
+ assert(0);
+ }
+ }
+
+ o->sock = sock;
+ mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL);
+
+ if (args->key.u_obj != MP_OBJ_NULL) {
+ mp_uint_t key_len;
+ const byte *key = (const byte*)mp_obj_str_get_data(args->key.u_obj, &key_len);
+ // len should include terminating null
+ ret = mbedtls_pk_parse_key(&o->pkey, key, key_len + 1, NULL, 0);
+ assert(ret == 0);
+
+ mp_uint_t cert_len;
+ const byte *cert = (const byte*)mp_obj_str_get_data(args->cert.u_obj, &cert_len);
+ // len should include terminating null
+ ret = mbedtls_x509_crt_parse(&o->cert, cert, cert_len + 1);
+ assert(ret == 0);
+
+ ret = mbedtls_ssl_conf_own_cert(&o->conf, &o->cert, &o->pkey);
+ assert(ret == 0);
+ }
+
+ if (args->server_side.u_bool) {
+ assert(0);
+ } else {
+ while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) {
+ if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ //assert(0);
+ printf("mbedtls_ssl_handshake error: -%x\n", -ret);
+ mp_raise_OSError(MP_EIO);
+ }
+ }
+ }
+
+ return o;
+}
+
+STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ (void)kind;
+ mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_printf(print, "<_SSLSocket %p>", self);
+}
+
+STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
+ mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
+
+ int ret = mbedtls_ssl_read(&o->ssl, buf, size);
+ if (ret >= 0) {
+ return ret;
+ }
+ *errcode = ret;
+ return MP_STREAM_ERROR;
+}
+
+STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
+ mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
+
+ int ret = mbedtls_ssl_write(&o->ssl, buf, size);
+ if (ret >= 0) {
+ return ret;
+ }
+ *errcode = ret;
+ return MP_STREAM_ERROR;
+}
+
+STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
+ // Currently supports only blocking mode
+ (void)self_in;
+ if (!mp_obj_is_true(flag_in)) {
+ mp_not_implemented("");
+ }
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
+
+STATIC mp_obj_t socket_close(mp_obj_t self_in) {
+ mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mbedtls_x509_crt_free(&self->cacert);
+ mbedtls_ssl_free(&self->ssl);
+ mbedtls_ssl_config_free(&self->conf);
+ mbedtls_ctr_drbg_free(&self->ctr_drbg);
+ mbedtls_entropy_free(&self->entropy);
+
+ mp_obj_t dest[2];
+ mp_load_method(self->sock, MP_QSTR_close, dest);
+ return mp_call_method_n_kw(0, 0, dest);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close);
+
+STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readall), MP_ROM_PTR(&mp_stream_readall_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
+ { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
+ { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
+
+STATIC const mp_stream_p_t ussl_socket_stream_p = {
+ .read = socket_read,
+ .write = socket_write,
+};
+
+STATIC const mp_obj_type_t ussl_socket_type = {
+ { &mp_type_type },
+ // Save on qstr's, reuse same as for module
+ .name = MP_QSTR_ussl,
+ .print = socket_print,
+ .getiter = NULL,
+ .iternext = NULL,
+ .protocol = &ussl_socket_stream_p,
+ .locals_dict = (void*)&ussl_socket_locals_dict,
+};
+
+STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ // TODO: Implement more args
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ // TODO: Check that sock implements stream protocol
+ mp_obj_t sock = pos_args[0];
+
+ struct ssl_args args;
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
+ MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args);
+
+ return MP_OBJ_FROM_PTR(socket_new(sock, &args));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket);
+
+STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ussl) },
+ { MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&mod_ssl_wrap_socket_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table);
+
+const mp_obj_module_t mp_module_ussl = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&mp_module_ssl_globals,
+};
+
+#endif // MICROPY_PY_USSL
diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c
index 65cbc5eb01..c5d4c48120 100644
--- a/extmod/moduzlib.c
+++ b/extmod/moduzlib.c
@@ -59,7 +59,7 @@ STATIC unsigned char read_src_stream(TINF_DATA *data) {
byte c;
mp_uint_t out_sz = stream->read(self->src_stream, &c, 1, &err);
if (out_sz == MP_STREAM_ERROR) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(err)));
+ mp_raise_OSError(err);
}
if (out_sz == 0) {
nlr_raise(mp_obj_new_exception(&mp_type_EOFError));
@@ -81,10 +81,18 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size
if (n_args > 1) {
dict_opt = mp_obj_get_int(args[1]);
}
- if (dict_opt >= 0) {
+
+ if (dict_opt >= 16) {
+ int st = uzlib_gzip_parse_header(&o->decomp);
+ if (st != TINF_OK) {
+ goto header_error;
+ }
+ dict_sz = 1 << (dict_opt - 16);
+ } else if (dict_opt >= 0) {
dict_opt = uzlib_zlib_parse_header(&o->decomp);
if (dict_opt < 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "zlib header"));
+header_error:
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "compression header"));
}
dict_sz = 1 << dict_opt;
} else {
@@ -204,7 +212,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uzlib_globals, mp_module_uzlib_globals_tab
const mp_obj_module_t mp_module_uzlib = {
.base = { &mp_type_module },
- .name = MP_QSTR_uzlib,
.globals = (mp_obj_dict_t*)&mp_module_uzlib_globals,
};
@@ -213,6 +220,7 @@ const mp_obj_module_t mp_module_uzlib = {
#include "uzlib/tinflate.c"
#include "uzlib/tinfzlib.c"
+#include "uzlib/tinfgzip.c"
#include "uzlib/adler32.c"
#include "uzlib/crc32.c"
diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c
index 858d2c1c0b..8e05809662 100644
--- a/extmod/modwebrepl.c
+++ b/extmod/modwebrepl.c
@@ -340,7 +340,7 @@ STATIC const mp_obj_type_t webrepl_type = {
};
STATIC const mp_map_elem_t webrepl_module_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_websocket) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR__webrepl) },
{ MP_OBJ_NEW_QSTR(MP_QSTR__webrepl), (mp_obj_t)&webrepl_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_password), (mp_obj_t)&webrepl_set_password_obj },
};
@@ -349,7 +349,6 @@ STATIC MP_DEFINE_CONST_DICT(webrepl_module_globals, webrepl_module_globals_table
const mp_obj_module_t mp_module_webrepl = {
.base = { &mp_type_module },
- .name = MP_QSTR__webrepl,
.globals = (mp_obj_dict_t*)&webrepl_module_globals,
};
diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c
index f46dac1773..8200ea708a 100644
--- a/extmod/modwebsocket.c
+++ b/extmod/modwebsocket.c
@@ -313,7 +313,6 @@ STATIC MP_DEFINE_CONST_DICT(websocket_module_globals, websocket_module_globals_t
const mp_obj_module_t mp_module_websocket = {
.base = { &mp_type_module },
- .name = MP_QSTR_websocket,
.globals = (mp_obj_dict_t*)&websocket_module_globals,
};
diff --git a/extmod/utime_mphal.c b/extmod/utime_mphal.c
new file mode 100644
index 0000000000..3ecdc94469
--- /dev/null
+++ b/extmod/utime_mphal.c
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2016 Damien P. George
+ * Copyright (c) 2016 Paul Sokolovsky
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/mpconfig.h"
+#if MICROPY_PY_UTIME_MP_HAL
+
+#include <string.h>
+
+#include "py/obj.h"
+#include "py/mphal.h"
+#include "py/smallint.h"
+#include "extmod/utime_mphal.h"
+
+STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
+ #if MICROPY_PY_BUILTINS_FLOAT
+ mp_hal_delay_ms(1000 * mp_obj_get_float(seconds_o));
+ #else
+ mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o));
+ #endif
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_obj, time_sleep);
+
+STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) {
+ mp_int_t ms = mp_obj_get_int(arg);
+ if (ms > 0) {
+ mp_hal_delay_ms(ms);
+ }
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_ms_obj, time_sleep_ms);
+
+STATIC mp_obj_t time_sleep_us(mp_obj_t arg) {
+ mp_int_t us = mp_obj_get_int(arg);
+ if (us > 0) {
+ mp_hal_delay_us(us);
+ }
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_us_obj, time_sleep_us);
+
+STATIC mp_obj_t time_ticks_ms(void) {
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK);
+}
+MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_ms_obj, time_ticks_ms);
+
+STATIC mp_obj_t time_ticks_us(void) {
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & MP_SMALL_INT_POSITIVE_MASK);
+}
+MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_us_obj, time_ticks_us);
+
+STATIC mp_obj_t time_ticks_cpu(void) {
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & MP_SMALL_INT_POSITIVE_MASK);
+}
+MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_cpu_obj, time_ticks_cpu);
+
+STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) {
+ // we assume that the arguments come from ticks_xx so are small ints
+ uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
+ uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
+ return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
+}
+MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj, time_ticks_diff);
+
+#endif // MICROPY_PY_UTIME_MP_HAL
diff --git a/extmod/utime_mphal.h b/extmod/utime_mphal.h
new file mode 100644
index 0000000000..4f2395a090
--- /dev/null
+++ b/extmod/utime_mphal.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2016 Damien P. George
+ * Copyright (c) 2016 Paul Sokolovsky
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/obj.h"
+
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_ms_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_us_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_ms_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_us_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_cpu_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_diff_obj);
diff --git a/extmod/uzlib/tinf.h b/extmod/uzlib/tinf.h
index 3545bbd883..106203a099 100644
--- a/extmod/uzlib/tinf.h
+++ b/extmod/uzlib/tinf.h
@@ -32,6 +32,7 @@ extern "C" {
#define TINF_DONE 1
#define TINF_DATA_ERROR (-3)
#define TINF_CHKSUM_ERROR (-4)
+#define TINF_DICT_ERROR (-5)
/* checksum types */
#define TINF_CHKSUM_NONE 0
diff --git a/extmod/uzlib/tinfgzip.c b/extmod/uzlib/tinfgzip.c
new file mode 100644
index 0000000000..f1afdd0b8d
--- /dev/null
+++ b/extmod/uzlib/tinfgzip.c
@@ -0,0 +1,110 @@
+/*
+ * tinfgzip - tiny gzip decompressor
+ *
+ * Copyright (c) 2003 by Joergen Ibsen / Jibz
+ * All Rights Reserved
+ *
+ * http://www.ibsensoftware.com/
+ *
+ * Copyright (c) 2014-2016 by Paul Sokolovsky
+ *
+ * This software is provided 'as-is', without any express
+ * or implied warranty. In no event will the authors be
+ * held liable for any damages arising from the use of
+ * this software.
+ *
+ * Permission is granted to anyone to use this software
+ * for any purpose, including commercial applications,
+ * and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The origin of this software must not be
+ * misrepresented; you must not claim that you
+ * wrote the original software. If you use this
+ * software in a product, an acknowledgment in
+ * the product documentation would be appreciated
+ * but is not required.
+ *
+ * 2. Altered source versions must be plainly marked
+ * as such, and must not be misrepresented as
+ * being the original software.
+ *
+ * 3. This notice may not be removed or altered from
+ * any source distribution.
+ */
+
+#include "tinf.h"
+
+#define FTEXT 1
+#define FHCRC 2
+#define FEXTRA 4
+#define FNAME 8
+#define FCOMMENT 16
+
+void tinf_skip_bytes(TINF_DATA *d, int num);
+uint16_t tinf_get_uint16(TINF_DATA *d);
+
+void tinf_skip_bytes(TINF_DATA *d, int num)
+{
+ while (num--) uzlib_get_byte(d);
+}
+
+uint16_t tinf_get_uint16(TINF_DATA *d)
+{
+ unsigned int v = uzlib_get_byte(d);
+ v = (uzlib_get_byte(d) << 8) | v;
+ return v;
+}
+
+int uzlib_gzip_parse_header(TINF_DATA *d)
+{
+ unsigned char flg;
+
+ /* -- check format -- */
+
+ /* check id bytes */
+ if (uzlib_get_byte(d) != 0x1f || uzlib_get_byte(d) != 0x8b) return TINF_DATA_ERROR;
+
+ /* check method is deflate */
+ if (uzlib_get_byte(d) != 8) return TINF_DATA_ERROR;
+
+ /* get flag byte */
+ flg = uzlib_get_byte(d);
+
+ /* check that reserved bits are zero */
+ if (flg & 0xe0) return TINF_DATA_ERROR;
+
+ /* -- find start of compressed data -- */
+
+ /* skip rest of base header of 10 bytes */
+ tinf_skip_bytes(d, 6);
+
+ /* skip extra data if present */
+ if (flg & FEXTRA)
+ {
+ unsigned int xlen = tinf_get_uint16(d);
+ tinf_skip_bytes(d, xlen);
+ }
+
+ /* skip file name if present */
+ if (flg & FNAME) { while (uzlib_get_byte(d)); }
+
+ /* skip file comment if present */
+ if (flg & FCOMMENT) { while (uzlib_get_byte(d)); }
+
+ /* check header crc if present */
+ if (flg & FHCRC)
+ {
+ /*unsigned int hcrc =*/ tinf_get_uint16(d);
+
+ // TODO: Check!
+// if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff))
+// return TINF_DATA_ERROR;
+ }
+
+ /* initialize for crc32 checksum */
+ d->checksum_type = TINF_CHKSUM_CRC;
+ d->checksum = ~0;
+
+ return TINF_OK;
+}
diff --git a/extmod/uzlib/tinflate.c b/extmod/uzlib/tinflate.c
index 0e53f7f072..58850eb4a2 100644
--- a/extmod/uzlib/tinflate.c
+++ b/extmod/uzlib/tinflate.c
@@ -361,6 +361,9 @@ static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
/* possibly get more bits from distance code */
offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
if (d->dict_ring) {
+ if (offs > d->dict_size) {
+ return TINF_DICT_ERROR;
+ }
d->lzOff = d->dict_idx - offs;
if (d->lzOff < 0) {
d->lzOff += d->dict_size;
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index eea075f6b0..6e827fc664 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -31,6 +31,7 @@
#include <string.h>
#include "py/nlr.h"
#include "py/runtime.h"
+#include "py/mperrno.h"
#include "lib/fatfs/ff.h"
#include "lib/fatfs/diskio.h"
#include "extmod/vfs_fat_file.h"
@@ -76,25 +77,42 @@ STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_listdir_obj, 1, 2, fat_vfs_listdir_func);
-STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) {
- (void)vfs_in;
+STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t path_in, mp_int_t attr) {
const char *path = mp_obj_str_get_str(path_in);
- // TODO check that path is actually a file before trying to unlink it
- FRESULT res = f_unlink(path);
- if (res == FR_OK) {
+
+ FILINFO fno;
+#if _USE_LFN
+ fno.lfname = NULL;
+ fno.lfsize = 0;
+#endif
+ FRESULT res = f_stat(path, &fno);
+
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
+
+ // check if path is a file or directory
+ if ((fno.fattrib & AM_DIR) == attr) {
+ res = f_unlink(path);
+
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
return mp_const_none;
} else {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
- MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(attr ? MP_ENOTDIR : MP_EISDIR);
}
}
+
+STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) {
+ (void)vfs_in;
+ return fat_vfs_remove_internal(path_in, 0); // 0 == file attribute
+}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_remove_obj, fat_vfs_remove);
STATIC mp_obj_t fat_vfs_rmdir(mp_obj_t vfs_in, mp_obj_t path_in) {
- // TODO: Currently just redirects to fat_vfs_remove(), which are
- // backed by the same underlying FatFs function. Should at least
- // check that path is actually a dir.
- return fat_vfs_remove(vfs_in, path_in);
+ (void) vfs_in;
+ return fat_vfs_remove_internal(path_in, AM_DIR);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir);
@@ -106,8 +124,7 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
if (res == FR_OK) {
return mp_const_none;
} else {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
- MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
}
@@ -120,8 +137,7 @@ STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) {
if (res == FR_OK) {
return mp_const_none;
} else {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
- MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir);
@@ -139,8 +155,7 @@ STATIC mp_obj_t fat_vfs_chdir(mp_obj_t vfs_in, mp_obj_t path_in) {
}
if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
- MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
return mp_const_none;
@@ -154,7 +169,7 @@ STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
FRESULT res = f_getcwd(buf, sizeof buf);
if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
return mp_obj_new_str(buf, strlen(buf), false);
@@ -215,8 +230,7 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
res = f_stat(path, &fno);
}
if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
- MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
}
@@ -250,6 +264,35 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_stat_obj, fat_vfs_stat);
+// Get the status of a VFS.
+STATIC mp_obj_t fat_vfs_statvfs(mp_obj_t vfs_in, mp_obj_t path_in) {
+ (void)vfs_in;
+ const char *path = mp_obj_str_get_str(path_in);
+
+ FATFS *fatfs;
+ DWORD nclst;
+ FRESULT res = f_getfree(path, &nclst, &fatfs);
+ if (FR_OK != res) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
+
+ mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
+
+ t->items[0] = MP_OBJ_NEW_SMALL_INT(fatfs->csize * fatfs->ssize); // f_bsize
+ t->items[1] = t->items[0]; // f_frsize
+ t->items[2] = MP_OBJ_NEW_SMALL_INT((fatfs->n_fatent - 2) * fatfs->csize); // f_blocks
+ t->items[3] = MP_OBJ_NEW_SMALL_INT(nclst); // f_bfree
+ t->items[4] = t->items[3]; // f_bavail
+ t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // f_files
+ t->items[6] = MP_OBJ_NEW_SMALL_INT(0); // f_ffree
+ t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // f_favail
+ t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // f_flags
+ t->items[9] = MP_OBJ_NEW_SMALL_INT(_MAX_LFN); // f_namemax
+
+ return MP_OBJ_FROM_PTR(t);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_statvfs_obj, fat_vfs_statvfs);
+
// Unmount the filesystem
STATIC mp_obj_t fat_vfs_umount(mp_obj_t vfs_in) {
fatfs_umount(((fs_user_mount_t *)vfs_in)->readblocks[1]);
@@ -268,6 +311,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&fat_vfs_remove_obj) },
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&fat_vfs_rename_obj) },
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&fat_vfs_stat_obj) },
+ { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&fat_vfs_statvfs_obj) },
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) },
};
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index 0cd61e4605..ecc9ed70f9 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -35,6 +35,7 @@
#include "py/nlr.h"
#include "py/runtime.h"
#include "py/stream.h"
+#include "py/mperrno.h"
#include "lib/fatfs/ff.h"
#include "extmod/vfs_fat_file.h"
@@ -49,25 +50,25 @@ extern const mp_obj_type_t mp_type_textio;
// this table converts from FRESULT to POSIX errno
const byte fresult_to_errno_table[20] = {
[FR_OK] = 0,
- [FR_DISK_ERR] = EIO,
- [FR_INT_ERR] = EIO,
- [FR_NOT_READY] = EBUSY,
- [FR_NO_FILE] = ENOENT,
- [FR_NO_PATH] = ENOENT,
- [FR_INVALID_NAME] = EINVAL,
- [FR_DENIED] = EACCES,
- [FR_EXIST] = EEXIST,
- [FR_INVALID_OBJECT] = EINVAL,
- [FR_WRITE_PROTECTED] = EROFS,
- [FR_INVALID_DRIVE] = ENODEV,
- [FR_NOT_ENABLED] = ENODEV,
- [FR_NO_FILESYSTEM] = ENODEV,
- [FR_MKFS_ABORTED] = EIO,
- [FR_TIMEOUT] = EIO,
- [FR_LOCKED] = EIO,
- [FR_NOT_ENOUGH_CORE] = ENOMEM,
- [FR_TOO_MANY_OPEN_FILES] = EMFILE,
- [FR_INVALID_PARAMETER] = EINVAL,
+ [FR_DISK_ERR] = MP_EIO,
+ [FR_INT_ERR] = MP_EIO,
+ [FR_NOT_READY] = MP_EBUSY,
+ [FR_NO_FILE] = MP_ENOENT,
+ [FR_NO_PATH] = MP_ENOENT,
+ [FR_INVALID_NAME] = MP_EINVAL,
+ [FR_DENIED] = MP_EACCES,
+ [FR_EXIST] = MP_EEXIST,
+ [FR_INVALID_OBJECT] = MP_EINVAL,
+ [FR_WRITE_PROTECTED] = MP_EROFS,
+ [FR_INVALID_DRIVE] = MP_ENODEV,
+ [FR_NOT_ENABLED] = MP_ENODEV,
+ [FR_NO_FILESYSTEM] = MP_ENODEV,
+ [FR_MKFS_ABORTED] = MP_EIO,
+ [FR_TIMEOUT] = MP_EIO,
+ [FR_LOCKED] = MP_EIO,
+ [FR_NOT_ENOUGH_CORE] = MP_ENOMEM,
+ [FR_TOO_MANY_OPEN_FILES] = MP_EMFILE,
+ [FR_INVALID_PARAMETER] = MP_EINVAL,
};
typedef struct _pyb_file_obj_t {
@@ -101,7 +102,7 @@ STATIC mp_uint_t file_obj_write(mp_obj_t self_in, const void *buf, mp_uint_t siz
}
if (sz_out != size) {
// The FatFS documentation says that this means disk full.
- *errcode = ENOSPC;
+ *errcode = MP_ENOSPC;
return MP_STREAM_ERROR;
}
return sz_out;
@@ -140,7 +141,7 @@ STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg,
case 1: // SEEK_CUR
if (s->offset != 0) {
- *errcode = ENOTSUP;
+ *errcode = MP_EOPNOTSUPP;
return MP_STREAM_ERROR;
}
// no-operation
@@ -155,7 +156,7 @@ STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg,
return 0;
} else {
- *errcode = EINVAL;
+ *errcode = MP_EINVAL;
return MP_STREAM_ERROR;
}
}
@@ -208,7 +209,7 @@ STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) {
FRESULT res = f_open(&o->fp, fname, mode);
if (res != FR_OK) {
m_del_obj(pyb_file_obj_t, o);
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
// for 'a' mode, we must begin at the end of the file
diff --git a/extmod/vfs_fat_misc.c b/extmod/vfs_fat_misc.c
index 23fe4be88d..d3507a85f3 100644
--- a/extmod/vfs_fat_misc.c
+++ b/extmod/vfs_fat_misc.c
@@ -54,9 +54,7 @@ mp_obj_t fat_vfs_listdir(const char *path, bool is_str_type) {
res = f_opendir(&dir, path); /* Open the directory */
if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
- MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
-
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
mp_obj_t dir_list = mp_obj_new_list(0, NULL);