summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--extmod/machine_i2c.c12
-rw-r--r--extmod/machine_mem.c2
-rw-r--r--extmod/machine_spi.c12
-rw-r--r--extmod/modframebuf.c2
-rw-r--r--extmod/modubinascii.c8
-rw-r--r--extmod/moductypes.c12
-rw-r--r--extmod/moduhashlib.c4
-rw-r--r--extmod/moduheapq.c6
-rw-r--r--extmod/modujson.c4
-rw-r--r--extmod/modure.c4
-rw-r--r--extmod/modussl_axtls.c6
-rw-r--r--extmod/modutimeq.c8
-rw-r--r--extmod/moduzlib.c4
-rw-r--r--extmod/uos_dupterm.c4
-rw-r--r--extmod/vfs_posix.c1
-rw-r--r--extmod/vfs_posix_file.c3
-rw-r--r--lib/netutils/netutils.c3
-rw-r--r--lib/utils/interrupt_char.c5
-rw-r--r--lib/utils/interrupt_char.h3
-rw-r--r--locale/circuitpython.pot786
-rw-r--r--locale/en_US.po786
-rw-r--r--locale/es.po786
-rw-r--r--locale/fr.po2281
-rwxr-xr-xmain.c43
-rw-r--r--[-rwxr-xr-x]ports/atmel-samd/Makefile2
-rw-r--r--ports/atmel-samd/audio_dma.c5
-rw-r--r--ports/atmel-samd/bindings/samd/Clock.c4
-rw-r--r--ports/atmel-samd/board_busses.c7
-rw-r--r--ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/common-hal/analogio/AnalogOut.c2
-rw-r--r--ports/atmel-samd/common-hal/audiobusio/PDMIn.c3
-rw-r--r--ports/atmel-samd/common-hal/audioio/AudioOut.c4
-rw-r--r--ports/atmel-samd/common-hal/busio/I2C.c44
-rw-r--r--ports/atmel-samd/common-hal/busio/I2C.h3
-rw-r--r--ports/atmel-samd/common-hal/busio/SPI.c2
-rw-r--r--ports/atmel-samd/common-hal/i2cslave/I2CSlave.c252
-rw-r--r--ports/atmel-samd/common-hal/i2cslave/I2CSlave.h45
-rw-r--r--ports/atmel-samd/common-hal/i2cslave/__init__.c1
-rw-r--r--ports/atmel-samd/external_flash/devices.h16
-rw-r--r--ports/atmel-samd/mpconfigport.h8
m---------ports/atmel-samd/peripherals0
-rw-r--r--ports/esp8266/common-hal/analogio/AnalogIn.c3
-rw-r--r--ports/esp8266/common-hal/analogio/AnalogOut.c7
-rw-r--r--ports/esp8266/common-hal/busio/SPI.c3
-rw-r--r--ports/esp8266/common-hal/busio/UART.c7
-rw-r--r--ports/esp8266/common-hal/digitalio/DigitalInOut.c9
-rw-r--r--ports/esp8266/common-hal/microcontroller/__init__.c5
-rw-r--r--ports/esp8266/common-hal/pulseio/PWMOut.c13
-rw-r--r--ports/esp8266/common-hal/pulseio/PulseIn.c9
-rw-r--r--ports/esp8266/common-hal/storage/__init__.c5
-rw-r--r--ports/esp8266/esp8266.ld2
-rw-r--r--ports/esp8266/esp_mphal.c3
-rw-r--r--ports/esp8266/machine_adc.c3
-rw-r--r--ports/esp8266/machine_hspi.c5
-rw-r--r--ports/esp8266/machine_pin.c10
-rw-r--r--ports/esp8266/machine_pwm.c3
-rw-r--r--ports/esp8266/machine_rtc.c9
-rw-r--r--ports/esp8266/machine_uart.c9
-rw-r--r--ports/esp8266/makeimg.py1
-rw-r--r--ports/esp8266/modesp.c9
-rw-r--r--ports/esp8266/modmachine.c3
-rw-r--r--ports/esp8266/modnetwork.c37
-rw-r--r--ports/nrf/common-hal/analogio/AnalogIn.c3
-rw-r--r--ports/nrf/common-hal/analogio/AnalogOut.c8
-rw-r--r--ports/nrf/common-hal/busio/I2C.c3
-rw-r--r--ports/nrf/common-hal/busio/UART.c19
-rw-r--r--ports/nrf/common-hal/digitalio/DigitalInOut.c3
-rw-r--r--ports/nrf/common-hal/microcontroller/Processor.c3
-rw-r--r--ports/nrf/common-hal/pulseio/PWMOut.c8
-rw-r--r--ports/nrf/common-hal/usb_hid/Device.c8
-rw-r--r--ports/nrf/drivers/bluetooth/ble_drv.c49
-rw-r--r--ports/nrf/modules/ubluepy/ubluepy_characteristic.c3
-rw-r--r--ports/nrf/modules/ubluepy/ubluepy_service.c7
-rw-r--r--ports/nrf/modules/ubluepy/ubluepy_uuid.c5
-rw-r--r--ports/unix/Makefile2
-rw-r--r--ports/unix/file.c3
-rw-r--r--ports/unix/modffi.c12
-rw-r--r--ports/unix/modmachine.c4
-rw-r--r--ports/unix/modusocket.c4
-rw-r--r--py/compile.c4
-rw-r--r--py/emitinlinextensa.c22
-rw-r--r--py/emitnative.c36
-rw-r--r--py/makeqstrdata.py171
-rw-r--r--py/modbuiltins.c2
-rw-r--r--py/moduerrno.c32
-rw-r--r--py/mperrno.h2
-rw-r--r--py/obj.c24
-rw-r--r--py/obj.h15
-rw-r--r--py/objexcept.c29
-rw-r--r--py/parsenum.c10
-rw-r--r--py/py.mk2
-rwxr-xr-xpy/qstr.c2
-rw-r--r--py/runtime.c22
-rw-r--r--py/runtime.h22
-rw-r--r--py/vm.c6
-rw-r--r--shared-bindings/audiobusio/PDMIn.c2
-rw-r--r--shared-bindings/i2cslave/I2CSlave.c450
-rw-r--r--shared-bindings/i2cslave/I2CSlave.h60
-rw-r--r--shared-bindings/i2cslave/__init__.c117
-rw-r--r--shared-bindings/index.rst1
-rw-r--r--shared-bindings/os/__init__.c2
-rw-r--r--shared-module/audioio/WaveFile.c6
-rwxr-xr-xsupervisor/shared/memory.c2
-rw-r--r--supervisor/shared/translate.c51
-rw-r--r--supervisor/shared/translate.h11
m---------tools/huffman0
111 files changed, 6083 insertions, 515 deletions
diff --git a/.gitmodules b/.gitmodules
index 1aa29a30b..c0a3446b9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -80,3 +80,6 @@
path = lib/tinyusb
url = https://github.com/hathach/tinyusb.git
branch = develop
+[submodule "tools/huffman"]
+ path = tools/huffman
+ url = https://github.com/tannewt/huffman.git
diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c
index 5d441b1ba..b91f1a1eb 100644
--- a/extmod/machine_i2c.c
+++ b/extmod/machine_i2c.c
@@ -33,6 +33,8 @@
#include "py/runtime.h"
#include "extmod/machine_i2c.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_MACHINE_I2C
typedef mp_machine_soft_i2c_obj_t machine_i2c_obj_t;
@@ -294,7 +296,7 @@ STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, s
extern mp_obj_t MICROPY_PY_MACHINE_I2C_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
return MICROPY_PY_MACHINE_I2C_MAKE_NEW(type, n_args, n_kw, args);
#else
- mp_raise_ValueError("invalid I2C peripheral");
+ mp_raise_ValueError(translate("invalid I2C peripheral"));
#endif
}
--n_args;
@@ -335,7 +337,7 @@ STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
if (i2c_p->start == NULL) {
- mp_raise_msg(&mp_type_OSError, "I2C operation not supported");
+ mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
int ret = i2c_p->start(self);
if (ret != 0) {
@@ -349,7 +351,7 @@ STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
if (i2c_p->stop == NULL) {
- mp_raise_msg(&mp_type_OSError, "I2C operation not supported");
+ mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
int ret = i2c_p->stop(self);
if (ret != 0) {
@@ -363,7 +365,7 @@ STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
if (i2c_p->read == NULL) {
- mp_raise_msg(&mp_type_OSError, "I2C operation not supported");
+ mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
// get the buffer to read into
@@ -387,7 +389,7 @@ STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
if (i2c_p->write == NULL) {
- mp_raise_msg(&mp_type_OSError, "I2C operation not supported");
+ mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
// get the buffer to write from
diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c
index b9f16507c..e0649290e 100644
--- a/extmod/machine_mem.c
+++ b/extmod/machine_mem.c
@@ -42,7 +42,7 @@
STATIC uintptr_t machine_mem_get_addr(mp_obj_t addr_o, uint align) {
uintptr_t addr = mp_obj_int_get_truncated(addr_o);
if ((addr & (align - 1)) != 0) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("address %08x is not aligned to %d bytes"), addr, align));
}
return addr;
}
diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c
index f0c4896c2..3bbab2824 100644
--- a/extmod/machine_spi.c
+++ b/extmod/machine_spi.c
@@ -30,6 +30,8 @@
#include "py/runtime.h"
#include "extmod/machine_spi.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_MACHINE_SPI
// if a port didn't define MSB/LSB constants then provide them
@@ -52,7 +54,7 @@ mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
extern mp_obj_t MICROPY_PY_MACHINE_SPI_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
return MICROPY_PY_MACHINE_SPI_MAKE_NEW(type, n_args, n_kw, args);
#else
- mp_raise_ValueError("invalid SPI peripheral");
+ mp_raise_ValueError(translate("invalid SPI peripheral"));
#endif
}
--n_args;
@@ -119,7 +121,7 @@ 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) {
- mp_raise_ValueError("buffers must be the same length");
+ mp_raise_ValueError(translate("buffers must be the same length"));
}
mp_machine_spi_transfer(self, src.len, src.buf, dest.buf);
return mp_const_none;
@@ -202,15 +204,15 @@ STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n
self->spi.polarity = args[ARG_polarity].u_int;
self->spi.phase = args[ARG_phase].u_int;
if (args[ARG_bits].u_int != 8) {
- mp_raise_ValueError("bits must be 8");
+ mp_raise_ValueError(translate("bits must be 8"));
}
if (args[ARG_firstbit].u_int != MICROPY_PY_MACHINE_SPI_MSB) {
- mp_raise_ValueError("firstbit must be MSB");
+ mp_raise_ValueError(translate("firstbit must be MSB"));
}
if (args[ARG_sck].u_obj == MP_OBJ_NULL
|| args[ARG_mosi].u_obj == MP_OBJ_NULL
|| args[ARG_miso].u_obj == MP_OBJ_NULL) {
- mp_raise_ValueError("must specify all of sck/mosi/miso");
+ mp_raise_ValueError(translate("must specify all of sck/mosi/miso"));
}
self->spi.sck = mp_hal_get_pin_obj(args[ARG_sck].u_obj);
self->spi.mosi = mp_hal_get_pin_obj(args[ARG_mosi].u_obj);
diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c
index a7f6ba905..413540540 100644
--- a/extmod/modframebuf.c
+++ b/extmod/modframebuf.c
@@ -296,7 +296,7 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
case FRAMEBUF_GS8:
break;
default:
- mp_raise_ValueError("invalid format");
+ mp_raise_ValueError(translate("invalid format"));
}
return MP_OBJ_FROM_PTR(o);
diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c
index ba4af54f2..0f64b2715 100644
--- a/extmod/modubinascii.c
+++ b/extmod/modubinascii.c
@@ -35,7 +35,7 @@
static void check_not_unicode(const mp_obj_t arg) {
#if MICROPY_CPYTHON_COMPAT
if (MP_OBJ_IS_STR(arg)) {
- mp_raise_TypeError("a bytes-like object is required");
+ mp_raise_TypeError(translate("a bytes-like object is required"));
}
#endif
}
@@ -87,7 +87,7 @@ mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
if ((bufinfo.len & 1) != 0) {
- mp_raise_ValueError("odd-length string");
+ mp_raise_ValueError(translate("odd-length string"));
}
vstr_t vstr;
vstr_init_len(&vstr, bufinfo.len / 2);
@@ -98,7 +98,7 @@ mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
if (unichar_isxdigit(hex_ch)) {
hex_byte += unichar_xdigit_value(hex_ch);
} else {
- mp_raise_ValueError("non-hex digit found");
+ mp_raise_ValueError(translate("non-hex digit found"));
}
if (i & 1) {
hex_byte <<= 4;
@@ -166,7 +166,7 @@ mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) {
}
if (nbits) {
- mp_raise_ValueError("incorrect padding");
+ mp_raise_ValueError(translate("incorrect padding"));
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
diff --git a/extmod/moductypes.c b/extmod/moductypes.c
index b0f28331e..e627cd146 100644
--- a/extmod/moductypes.c
+++ b/extmod/moductypes.c
@@ -32,6 +32,8 @@
#include "py/objtuple.h"
#include "py/binary.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_UCTYPES
/// \module uctypes - Access data structures in memory
@@ -117,7 +119,7 @@ typedef struct _mp_obj_uctypes_struct_t {
} mp_obj_uctypes_struct_t;
STATIC NORETURN void syntax_error(void) {
- mp_raise_TypeError("syntax error in uctypes descriptor");
+ mp_raise_TypeError(translate("syntax error in uctypes descriptor"));
}
STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
@@ -214,7 +216,7 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_
// but scalar structure field is lowered into native Python int, so all
// type info is lost. So, we cannot say if it's scalar type description,
// or such lowered scalar.
- mp_raise_TypeError("Cannot unambiguously get sizeof scalar");
+ mp_raise_TypeError(translate("Cannot unambiguously get sizeof scalar"));
}
syntax_error();
}
@@ -392,7 +394,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
// TODO: Support at least OrderedDict in addition
if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)) {
- mp_raise_TypeError("struct: no fields");
+ mp_raise_TypeError(translate("struct: no fields"));
}
mp_obj_t deref = mp_obj_dict_get(self->desc, MP_OBJ_NEW_QSTR(attr));
@@ -525,7 +527,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob
} else {
// load / store
if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) {
- mp_raise_TypeError("struct: cannot index");
+ mp_raise_TypeError(translate("struct: cannot index"));
}
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc);
@@ -539,7 +541,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob
uint val_type = GET_TYPE(arr_sz, VAL_TYPE_BITS);
arr_sz &= VALUE_MASK(VAL_TYPE_BITS);
if (index >= arr_sz) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "struct: index out of range"));
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, translate("struct: index out of range")));
}
if (t->len == 2) {
diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c
index 5e14fc8d4..1618594e9 100644
--- a/extmod/moduhashlib.c
+++ b/extmod/moduhashlib.c
@@ -29,6 +29,8 @@
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_UHASHLIB
#if MICROPY_PY_UHASHLIB_SHA256
@@ -97,7 +99,7 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) {
static void check_not_unicode(const mp_obj_t arg) {
#if MICROPY_CPYTHON_COMPAT
if (MP_OBJ_IS_STR(arg)) {
- mp_raise_TypeError("a bytes-like object is required");
+ mp_raise_TypeError(translate("a bytes-like object is required"));
}
#endif
}
diff --git a/extmod/moduheapq.c b/extmod/moduheapq.c
index 71c15368b..db17e8ca2 100644
--- a/extmod/moduheapq.c
+++ b/extmod/moduheapq.c
@@ -27,13 +27,15 @@
#include "py/objlist.h"
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_UHEAPQ
// the algorithm here is modelled on CPython's heapq.py
STATIC mp_obj_list_t *get_heap(mp_obj_t heap_in) {
if (!MP_OBJ_IS_TYPE(heap_in, &mp_type_list)) {
- mp_raise_TypeError("heap must be a list");
+ mp_raise_TypeError(translate("heap must be a list"));
}
return MP_OBJ_TO_PTR(heap_in);
}
@@ -81,7 +83,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_uheapq_heappush_obj, mod_uheapq_heappush);
STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) {
mp_obj_list_t *heap = get_heap(heap_in);
if (heap->len == 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap"));
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, translate("empty heap")));
}
mp_obj_t item = heap->items[0];
heap->len -= 1;
diff --git a/extmod/modujson.c b/extmod/modujson.c
index 830b588fd..ea6c8b40f 100644
--- a/extmod/modujson.c
+++ b/extmod/modujson.c
@@ -32,6 +32,8 @@
#include "py/runtime.h"
#include "py/stream.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_UJSON
STATIC mp_obj_t mod_ujson_dump(mp_obj_t obj, mp_obj_t stream) {
@@ -276,7 +278,7 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
return stack_top;
fail:
- mp_raise_ValueError("syntax error in JSON");
+ mp_raise_ValueError(translate("syntax error in JSON"));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
diff --git a/extmod/modure.c b/extmod/modure.c
index 31c2b9864..1a7027026 100644
--- a/extmod/modure.c
+++ b/extmod/modure.c
@@ -158,7 +158,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
mp_obj_t s = mp_obj_new_str_of_type(str_type, (const byte*)subj.begin, caps[0] - subj.begin);
mp_obj_list_append(retval, s);
if (self->re.sub > 0) {
- mp_raise_NotImplementedError("Splitting with sub-captures");
+ mp_raise_NotImplementedError(translate("Splitting with sub-captures"));
}
subj.begin = caps[1];
if (maxsplit > 0 && --maxsplit == 0) {
@@ -204,7 +204,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
int error = re1_5_compilecode(&o->re, re_str);
if (error != 0) {
error:
- mp_raise_ValueError("Error in regex");
+ mp_raise_ValueError(translate("Error in regex"));
}
if (flags & FLAG_DEBUG) {
re1_5_dumpcode(&o->re);
diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c
index 475d3f0ea..cfa652585 100644
--- a/extmod/modussl_axtls.c
+++ b/extmod/modussl_axtls.c
@@ -30,6 +30,8 @@
#include "py/runtime.h"
#include "py/stream.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_USSL && MICROPY_SSL_AXTLS
#include "ssl.h"
@@ -76,13 +78,13 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
const byte *data = (const byte*)mp_obj_str_get_data(args->key.u_obj, &len);
int res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_RSA_KEY, data, len, NULL);
if (res != SSL_OK) {
- mp_raise_ValueError("invalid key");
+ mp_raise_ValueError(translate("invalid key"));
}
data = (const byte*)mp_obj_str_get_data(args->cert.u_obj, &len);
res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_X509_CERT, data, len, NULL);
if (res != SSL_OK) {
- mp_raise_ValueError("invalid cert");
+ mp_raise_ValueError(translate("invalid cert"));
}
}
diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c
index 28bbcc521..614820443 100644
--- a/extmod/modutimeq.c
+++ b/extmod/modutimeq.c
@@ -31,6 +31,8 @@
#include "py/runtime.h"
#include "py/smallint.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_UTIMEQ
#define MODULO MICROPY_PY_UTIME_TICKS_PERIOD
@@ -126,7 +128,7 @@ STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) {
mp_obj_t heap_in = args[0];
mp_obj_utimeq_t *heap = get_heap(heap_in);
if (heap->len == heap->alloc) {
- mp_raise_IndexError("queue overflow");
+ mp_raise_IndexError(translate("queue overflow"));
}
mp_uint_t l = heap->len;
heap->items[l].time = MP_OBJ_SMALL_INT_VALUE(args[1]);
@@ -142,7 +144,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_utimeq_heappush_obj, 4, 4, mod_ut
STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) {
mp_obj_utimeq_t *heap = get_heap(heap_in);
if (heap->len == 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap"));
+ mp_raise_IndexError(translate("empty heap"));
}
mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref);
if (!MP_OBJ_IS_TYPE(list_ref, &mp_type_list) || ret->len < 3) {
@@ -167,7 +169,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_utimeq_heappop_obj, mod_utimeq_heappop);
STATIC mp_obj_t mod_utimeq_peektime(mp_obj_t heap_in) {
mp_obj_utimeq_t *heap = get_heap(heap_in);
if (heap->len == 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap"));
+ mp_raise_IndexError(translate("empty heap"));
}
struct qentry *item = &heap->items[0];
diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c
index 0d2366bea..f70ecd92c 100644
--- a/extmod/moduzlib.c
+++ b/extmod/moduzlib.c
@@ -31,6 +31,8 @@
#include "py/stream.h"
#include "py/mperrno.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_UZLIB
#include "../../lib/uzlib/src/tinf.h"
@@ -92,7 +94,7 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size
dict_opt = uzlib_zlib_parse_header(&o->decomp);
if (dict_opt < 0) {
header_error:
- mp_raise_ValueError("compression header");
+ mp_raise_ValueError(translate("compression header"));
}
dict_sz = 1 << dict_opt;
} else {
diff --git a/extmod/uos_dupterm.c b/extmod/uos_dupterm.c
index cc6d97f41..781ec0d46 100644
--- a/extmod/uos_dupterm.c
+++ b/extmod/uos_dupterm.c
@@ -34,6 +34,8 @@
#include "py/stream.h"
#include "lib/utils/interrupt_char.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PY_OS_DUPTERM
void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc) {
@@ -115,7 +117,7 @@ STATIC mp_obj_t mp_uos_dupterm(size_t n_args, const mp_obj_t *args) {
}
if (idx < 0 || idx >= MICROPY_PY_OS_DUPTERM) {
- mp_raise_ValueError("invalid dupterm index");
+ mp_raise_ValueError(translate("invalid dupterm index"));
}
mp_obj_t previous_obj = MP_STATE_VM(dupterm_objs[idx]);
diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c
index 9ee4900ee..39e197f29 100644
--- a/extmod/vfs_posix.c
+++ b/extmod/vfs_posix.c
@@ -31,6 +31,7 @@
#if defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX
+#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c
index d3ed4fe21..3eca47eb4 100644
--- a/extmod/vfs_posix_file.c
+++ b/extmod/vfs_posix_file.c
@@ -27,6 +27,7 @@
#include "py/runtime.h"
#include "py/stream.h"
#include "extmod/vfs_posix.h"
+#include "supervisor/shared/translate.h"
#if defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX
@@ -44,7 +45,7 @@ typedef struct _mp_obj_vfs_posix_file_t {
#ifdef MICROPY_CPYTHON_COMPAT
STATIC void check_fd_is_open(const mp_obj_vfs_posix_file_t *o) {
if (o->fd < 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "I/O operation on closed file"));
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, translate("I/O operation on closed file")));
}
}
#else
diff --git a/lib/netutils/netutils.c b/lib/netutils/netutils.c
index 073f46b19..03418d7e6 100644
--- a/lib/netutils/netutils.c
+++ b/lib/netutils/netutils.c
@@ -31,6 +31,7 @@
#include "py/runtime.h"
#include "lib/netutils/netutils.h"
+#include "supervisor/shared/translate.h"
// Takes an array with a raw IPv4 address and returns something like '192.168.0.1'.
mp_obj_t netutils_format_ipv4_addr(uint8_t *ip, netutils_endian_t endian) {
@@ -79,7 +80,7 @@ void netutils_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian
} else if (i > 0 && s < s_top && *s == '.') {
s++;
} else {
- mp_raise_ValueError("invalid arguments");
+ mp_raise_ValueError(translate("invalid arguments"));
}
}
}
diff --git a/lib/utils/interrupt_char.c b/lib/utils/interrupt_char.c
index fca0f95b5..91ee5c80e 100644
--- a/lib/utils/interrupt_char.c
+++ b/lib/utils/interrupt_char.c
@@ -47,4 +47,9 @@ void mp_keyboard_interrupt(void) {
#endif
}
+// Check to see if we've been CTRL-C'ed by autoreload or the user.
+bool mp_hal_is_interrupted(void) {
+ return MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception));
+}
+
#endif
diff --git a/lib/utils/interrupt_char.h b/lib/utils/interrupt_char.h
index ca50d4d56..e0b1db529 100644
--- a/lib/utils/interrupt_char.h
+++ b/lib/utils/interrupt_char.h
@@ -26,8 +26,11 @@
#ifndef MICROPY_INCLUDED_LIB_UTILS_INTERRUPT_CHAR_H
#define MICROPY_INCLUDED_LIB_UTILS_INTERRUPT_CHAR_H
+#include <stdbool.h>
+
extern int mp_interrupt_char;
void mp_hal_set_interrupt_char(int c);
void mp_keyboard_interrupt(void);
+bool mp_hal_is_interrupted(void);
#endif // MICROPY_INCLUDED_LIB_UTILS_INTERRUPT_CHAR_H
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index 1f4f43ec6..4434a0018 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-08-09 14:14-0700\n"
+"POT-Creation-Date: 2018-08-20 09:37-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,90 +17,242 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: extmod/vfs_fat.c:426 py/moduerrno.c:115
+#: extmod/machine_i2c.c:299
+msgid "invalid I2C peripheral"
+msgstr ""
+
+#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368
+#: extmod/machine_i2c.c:392
+msgid "I2C operation not supported"
+msgstr ""
+
+#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53
+#, c-format
+msgid "address %08x is not aligned to %d bytes"
+msgstr ""
+
+#: extmod/machine_spi.c:57
+msgid "invalid SPI peripheral"
+msgstr ""
+
+#: extmod/machine_spi.c:124
+msgid "buffers must be the same length"
+msgstr ""
+
+#: extmod/machine_spi.c:207
+msgid "bits must be 8"
+msgstr ""
+
+#: extmod/machine_spi.c:210
+msgid "firstbit must be MSB"
+msgstr ""
+
+#: extmod/machine_spi.c:215
+msgid "must specify all of sck/mosi/miso"
+msgstr ""
+
+#: extmod/modframebuf.c:299
+msgid "invalid format"
+msgstr ""
+
+#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102
+msgid "a bytes-like object is required"
+msgstr ""
+
+#: extmod/modubinascii.c:90
+msgid "odd-length string"
+msgstr ""
+
+#: extmod/modubinascii.c:101
+msgid "non-hex digit found"
+msgstr ""
+
+#: extmod/modubinascii.c:169
+msgid "incorrect padding"
+msgstr ""
+
+#: extmod/moductypes.c:122
+msgid "syntax error in uctypes descriptor"
+msgstr ""
+
+#: extmod/moductypes.c:219
+msgid "Cannot unambiguously get sizeof scalar"
+msgstr ""
+
+#: extmod/moductypes.c:397
+msgid "struct: no fields"
+msgstr ""
+
+#: extmod/moductypes.c:530
+msgid "struct: cannot index"
+msgstr ""
+
+#: extmod/moductypes.c:544
+msgid "struct: index out of range"
+msgstr ""
+
+#: extmod/moduheapq.c:38
+msgid "heap must be a list"
+msgstr ""
+
+#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172
+msgid "empty heap"
+msgstr ""
+
+#: extmod/modujson.c:281
+msgid "syntax error in JSON"
+msgstr ""
+
+#: extmod/modure.c:161
+msgid "Splitting with sub-captures"
+msgstr ""
+
+#: extmod/modure.c:207
+msgid "Error in regex"
+msgstr ""
+
+#: extmod/modussl_axtls.c:81
+msgid "invalid key"
+msgstr ""
+
+#: extmod/modussl_axtls.c:87
+msgid "invalid cert"
+msgstr ""
+
+#: extmod/modutimeq.c:131
+msgid "queue overflow"
+msgstr ""
+
+#: extmod/moduzlib.c:97
+msgid "compression header"
+msgstr ""
+
+#: extmod/uos_dupterm.c:120
+msgid "invalid dupterm index"
+msgstr ""
+
+#: extmod/vfs_fat.c:426 py/moduerrno.c:150
msgid "Read-only filesystem"
msgstr ""
+#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43
+msgid "I/O operation on closed file"
+msgstr ""
+
#: lib/embed/abort_.c:8
msgid "abort() called"
msgstr ""
+#: lib/netutils/netutils.c:83
+msgid "invalid arguments"
+msgstr ""
+
#: lib/utils/pyexec.c:97 py/builtinimport.c:253
msgid "script compilation not supported"
msgstr ""
-#: main.c:137
+#: main.c:143
msgid " output:\n"
msgstr ""
-#: main.c:148 main.c:221
+#: main.c:157 main.c:230
msgid ""
"Auto-reload is on. Simply save files over USB to run them or enter REPL to "
"disable.\n"
msgstr ""
-#: main.c:150
+#: main.c:159
msgid "Running in safe mode! Auto-reload is off.\n"
msgstr ""
-#: main.c:152 main.c:223
+#: main.c:161 main.c:232
msgid "Auto-reload is off.\n"
msgstr ""
-#: main.c:166
+#: main.c:175
msgid "Running in safe mode! Not running saved code.\n"
msgstr ""
-#: main.c:182
+#: main.c:191
msgid "WARNING: Your code filename has two extensions\n"
msgstr ""
-#: main.c:230
+#: main.c:239
msgid "You requested starting safe mode by "
msgstr ""
-#: main.c:233
+#: main.c:242
msgid "To exit, please reset the board without "
msgstr ""
-#: main.c:240
+#: main.c:249
msgid ""
"You are running in safe mode which means something really bad happened.\n"
msgstr ""
-#: main.c:242
+#: main.c:251
msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n"
msgstr ""
-#: main.c:243
+#: main.c:252
msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n"
msgstr ""
-#: main.c:246
+#: main.c:255
msgid ""
"The microcontroller's power dipped. Please make sure your power supply "
"provides\n"
msgstr ""
-#: main.c:247
+#: main.c:256
msgid ""
"enough power for the whole circuit and press reset (after ejecting "
"CIRCUITPY).\n"
msgstr ""
-#: main.c:251
+#: main.c:260
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
-#: main.c:406
+#: main.c:415
msgid "soft reboot\n"
msgstr ""
+#: ports/atmel-samd/audio_dma.c:285
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361
+msgid "All sync event channels in use"
+msgstr ""
+
+#: ports/atmel-samd/bindings/samd/Clock.c:135
+msgid "calibration is read only"
+msgstr ""
+
+#: ports/atmel-samd/bindings/samd/Clock.c:137
+msgid "calibration is out of range"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:39
+msgid "No default I2C bus"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:64
+msgid "No default SPI bus"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:91
+msgid "No default UART bus"
+msgstr ""
+
#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63
+#: ports/nrf/common-hal/analogio/AnalogIn.c:39
msgid "Pin does not have ADC capabilities"
msgstr ""
-#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:53
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49
+msgid "No DAC on chip"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56
msgid "AnalogOut not supported on given pin"
msgstr ""
@@ -139,12 +291,12 @@ msgid "Too many channels in sample."
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305
-#: ports/atmel-samd/common-hal/audioio/AudioOut.c:322
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:326
msgid "No DMA channel found"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308
-#: ports/atmel-samd/common-hal/audioio/AudioOut.c:324
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:328
msgid "Unable to allocate buffers for signed conversion"
msgstr ""
@@ -192,20 +344,27 @@ msgstr ""
msgid "All timers in use"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:45
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:215
+msgid "All event channels in use"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/I2C.c:71
msgid "Not enough pins available"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:76
+#: ports/atmel-samd/common-hal/busio/I2C.c:78
+#: ports/atmel-samd/common-hal/busio/SPI.c:132
#: ports/atmel-samd/common-hal/busio/UART.c:119
+#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45
+#: ports/nrf/common-hal/busio/I2C.c:58
msgid "Invalid pins"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:99
+#: ports/atmel-samd/common-hal/busio/I2C.c:101
msgid "SDA or SCL needs a pull up"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:119
+#: ports/atmel-samd/common-hal/busio/I2C.c:121
msgid "Unsupported baudrate"
msgstr ""
@@ -234,15 +393,18 @@ msgid "No TX pin"
msgstr ""
#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:168
+#: ports/nrf/common-hal/digitalio/DigitalInOut.c:158
msgid "Cannot get pull while in output mode"
msgstr ""
#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74
+#: ports/esp8266/common-hal/microcontroller/__init__.c:64
msgid "Cannot reset into bootloader because no bootloader is present."
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120
#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:366
+#: ports/nrf/common-hal/pulseio/PWMOut.c:227
msgid "Invalid PWM frequency"
msgstr ""
@@ -259,15 +421,18 @@ msgid "EXTINT channel already in use"
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:86
#, c-format
msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:203
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:151
msgid "pop from an empty PulseIn"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:235 py/obj.c:404
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:235
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420
msgid "index out of range"
msgstr ""
@@ -296,18 +461,365 @@ msgid "No free GCLKs"
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:78
+#: ports/nrf/common-hal/usb_hid/Device.c:45
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:82
+#: ports/nrf/common-hal/usb_hid/Device.c:53
msgid "USB Busy"
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:82
+#: ports/nrf/common-hal/usb_hid/Device.c:59
msgid "USB Error"
msgstr ""
+#: ports/esp8266/common-hal/analogio/AnalogIn.c:43
+msgid "Pin %q does not have ADC capabilities"
+msgstr ""
+
+#: ports/esp8266/common-hal/analogio/AnalogOut.c:39
+msgid "No hardware support for analog out."
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/SPI.c:72
+msgid "Pins not valid for SPI"
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:45
+msgid "Only tx supported on UART1 (GPIO2)."
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108
+msgid "invalid data bits"
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144
+msgid "invalid stop bits"
+msgstr ""
+
+#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200
+msgid "ESP8266 does not support pull down."
+msgstr ""
+
+#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210
+msgid "GPIO16 does not support pull up."
+msgstr ""
+
+#: ports/esp8266/common-hal/microcontroller/__init__.c:66
+msgid "ESP8226 does not support safe mode."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:54
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:113
+#, c-format
+msgid "Maximum PWM frequency is %dhz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:57
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:116
+msgid "Minimum PWM frequency is 1hz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:68
+#, c-format
+msgid "Multiple PWM frequencies not supported. PWM already set to %dhz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70
+#, c-format
+msgid "PWM not supported on pin %d"
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:78
+msgid "No PulseIn support for %q"
+msgstr ""
+
+#: ports/esp8266/common-hal/storage/__init__.c:34
+msgid "Unable to remount filesystem"
+msgstr ""
+
+#: ports/esp8266/common-hal/storage/__init__.c:38
+msgid "Use esptool to erase flash and re-upload Python instead"
+msgstr ""
+
+#: ports/esp8266/esp_mphal.c:154
+msgid "C-level assert"
+msgstr ""
+
+#: ports/esp8266/machine_adc.c:57
+#, c-format
+msgid "not a valid ADC Channel: %d"
+msgstr ""
+
+#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137
+msgid "impossible baudrate"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:129
+msgid "expecting a pin"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:284
+msgid "Pin(16) doesn't support pull"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:323
+msgid "invalid pin"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:389
+msgid "pin does not have IRQ capabilities"
+msgstr ""
+
+#: ports/esp8266/machine_rtc.c:185
+msgid "buffer too long"
+msgstr ""
+
+#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223
+#: ports/esp8266/machine_rtc.c:246
+msgid "invalid alarm"
+msgstr ""
+
+#: ports/esp8266/machine_uart.c:169
+#, c-format
+msgid "UART(%d) does not exist"
+msgstr ""
+
+#: ports/esp8266/machine_uart.c:219
+msgid "UART(1) can't read"
+msgstr ""
+
+#: ports/esp8266/modesp.c:119
+msgid "len must be multiple of 4"
+msgstr ""
+
+#: ports/esp8266/modesp.c:274
+#, c-format
+msgid "memory allocation failed, allocating %u bytes for native code"
+msgstr ""
+
+#: ports/esp8266/modesp.c:317
+msgid "flash location must be below 1MByte"
+msgstr ""
+
+#: ports/esp8266/modmachine.c:63
+msgid "frequency can only be either 80Mhz or 160MHz"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:61
+msgid "STA required"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:61
+msgid "AP required"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:87
+msgid "Cannot update i/f status"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:142
+msgid "Cannot set STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:144
+msgid "Cannot connect to AP"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:152
+msgid "Cannot disconnect from AP"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:173
+msgid "unknown status param"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:222
+msgid "STA must be active"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:239
+msgid "scan failed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:306
+msgid "wifi_set_ip_info() failed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:319
+msgid "either pos or kw args are allowed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:329
+msgid "can't get STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:331
+msgid "can't get AP config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:346
+msgid "invalid buffer length"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:405
+msgid "can't set STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:407
+msgid "can't set AP config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:416
+msgid "can query only one param"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:469
+msgid "unknown config param"
+msgstr ""
+
+#: ports/nrf/common-hal/analogio/AnalogOut.c:37
+msgid "AnalogOut functionality not supported"
+msgstr ""
+
+#: ports/nrf/common-hal/busio/UART.c:45 ports/nrf/common-hal/busio/UART.c:49
+#: ports/nrf/common-hal/busio/UART.c:53 ports/nrf/common-hal/busio/UART.c:62
+#: ports/nrf/common-hal/busio/UART.c:68 ports/nrf/common-hal/busio/UART.c:73
+#: ports/nrf/common-hal/busio/UART.c:78 ports/nrf/common-hal/busio/UART.c:83
+#: ports/nrf/common-hal/busio/UART.c:88
+msgid "busio.UART not yet implemented"
+msgstr ""
+
+#: ports/nrf/common-hal/microcontroller/Processor.c:49
+#, c-format
+msgid "Can not get temperature. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:199
+msgid "Cannot apply GAP parameters."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:213
+msgid "Cannot set PPCP parameters."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:245
+msgid "Can not query for the device address."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:264
+msgid "Can not add Vendor Specific 128-bit UUID."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:284
+#: ports/nrf/drivers/bluetooth/ble_drv.c:298
+msgid "Can not add Service."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:373
+msgid "Can not add Characteristic."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:400
+msgid "Can not apply device name in the stack."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:464
+#: ports/nrf/drivers/bluetooth/ble_drv.c:514
+msgid "Can not encode UUID, to check length."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:470
+#: ports/nrf/drivers/bluetooth/ble_drv.c:520
+msgid "Can encode UUID into the advertisment packet."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:545
+msgid "Can not fit data into the advertisment packet."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:558
+#: ports/nrf/drivers/bluetooth/ble_drv.c:604
+#, c-format
+msgid "Can not apply advertisment data. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:614
+#, c-format
+msgid "Can not start advertisment. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:631
+#, c-format
+msgid "Can not stop advertisment. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:650
+#: ports/nrf/drivers/bluetooth/ble_drv.c:726
+#, c-format
+msgid "Can not read attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:667
+#: ports/nrf/drivers/bluetooth/ble_drv.c:756
+#, c-format
+msgid "Can not write attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:691
+#, c-format
+msgid "Can not notify attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:784
+#, c-format
+msgid "Can not start scanning. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:829
+#, c-format
+msgid "Can not connect. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:80
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:132
+#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137
+msgid "Invalid UUID parameter"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:73
+msgid "Invalid Service type"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127
+msgid "Invalid UUID string length"
+msgstr ""
+
+#: ports/unix/modffi.c:138
+msgid "Unknown type"
+msgstr ""
+
+#: ports/unix/modffi.c:207 ports/unix/modffi.c:265
+msgid "Error in ffi_prep_cif"
+msgstr ""
+
+#: ports/unix/modffi.c:270
+msgid "ffi_prep_closure_loc"
+msgstr ""
+
+#: ports/unix/modffi.c:413
+msgid "Don't know how to pass object to native function"
+msgstr ""
+
+#: ports/unix/modusocket.c:474
+#, c-format
+msgid "[addrinfo error %d]"
+msgstr ""
+
#: py/argcheck.c:44
msgid "function does not take keyword arguments"
msgstr ""
@@ -549,14 +1061,111 @@ msgstr ""
msgid "'data' requires integer arguments"
msgstr ""
+#: py/emitinlinextensa.c:86
+msgid "can only have up to 4 parameters to Xtensa assembly"
+msgstr ""
+
+#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96
+msgid "parameters must be registers in sequence a2 to a5"
+msgstr ""
+
+#: py/emitinlinextensa.c:162
+#, c-format
+msgid "'%s' expects a register"
+msgstr ""
+
+#: py/emitinlinextensa.c:169
+#, c-format
+msgid "'%s' expects an integer"
+msgstr ""
+
+#: py/emitinlinextensa.c:174
+#, c-format
+msgid "'%s' integer %d is not within range %d..%d"
+msgstr ""
+
+#: py/emitinlinextensa.c:182
+#, c-format
+msgid "'%s' expects a label"
+msgstr ""
+
+#: py/emitinlinextensa.c:193
+msgid "label '%q' not defined"
+msgstr ""
+
+#: py/emitinlinextensa.c:327
+#, c-format
+msgid "unsupported Xtensa instruction '%s' with %d arguments"
+msgstr ""
+
+#: py/emitnative.c:183
+msgid "unknown type '%q'"
+msgstr ""
+
+#: py/emitnative.c:260
+msgid "Viper functions don't currently support more than 4 arguments"
+msgstr ""
+
#: py/emitnative.c:742
msgid "conversion to object"
msgstr ""
+#: py/emitnative.c:921
+msgid "local '%q' used before type known"
+msgstr ""
+
+#: py/emitnative.c:1118 py/emitnative.c:1156
+msgid "can't load from '%q'"
+msgstr ""
+
+#: py/emitnative.c:1128
+msgid "can't load with '%q' index"
+msgstr ""
+
+#: py/emitnative.c:1188
+msgid "local '%q' has type '%q' but source is '%q'"
+msgstr ""
+
+#: py/emitnative.c:1289 py/emitnative.c:1379
+msgid "can't store '%q'"
+msgstr ""
+
+#: py/emitnative.c:1358 py/emitnative.c:1419
+msgid "can't store to '%q'"
+msgstr ""
+
+#: py/emitnative.c:1369
+msgid "can't store with '%q' index"
+msgstr ""
+
+#: py/emitnative.c:1540
+msgid "can't implicitly convert '%q' to 'bool'"
+msgstr ""
+
+#: py/emitnative.c:1774
+msgid "unary op %q not implemented"
+msgstr ""
+
+#: py/emitnative.c:1930
+msgid "binary op %q not implemented"
+msgstr ""
+
+#: py/emitnative.c:1951
+msgid "can't do binary op between '%q' and '%q'"
+msgstr ""
+
#: py/emitnative.c:2126
msgid "casting"
msgstr ""
+#: py/emitnative.c:2173
+msgid "return expected '%q' but got '%q'"
+msgstr ""
+
+#: py/emitnative.c:2191
+msgid "must raise an object"
+msgstr ""
+
#: py/emitnative.c:2201
msgid "native yield"
msgstr ""
@@ -617,140 +1226,140 @@ msgstr ""
msgid "expecting a dict for keyword args"
msgstr ""
-#: py/moduerrno.c:108 py/moduerrno.c:111
+#: py/moduerrno.c:143 py/moduerrno.c:146
msgid "Permission denied"
msgstr ""
-#: py/moduerrno.c:109
+#: py/moduerrno.c:144
msgid "No such file/directory"
msgstr ""
-#: py/moduerrno.c:110
+#: py/moduerrno.c:145
msgid "Input/output error"
msgstr ""
-#: py/moduerrno.c:112
+#: py/moduerrno.c:147
msgid "File exists"
msgstr ""
-#: py/moduerrno.c:113
+#: py/moduerrno.c:148
msgid "Unsupported operation"
msgstr ""
-#: py/moduerrno.c:114
+#: py/moduerrno.c:149
msgid "Invalid argument"
msgstr ""
-#: py/obj.c:89
+#: py/obj.c:90
msgid "Traceback (most recent call last):\n"
msgstr ""
-#: py/obj.c:92
+#: py/obj.c:94
msgid " File \"%q\", line %d"
msgstr ""
-#: py/obj.c:94
+#: py/obj.c:96
msgid " File \"%q\""
msgstr ""
-#: py/obj.c:101
+#: py/obj.c:100
msgid ", in %q\n"
msgstr ""
-#: py/obj.c:241
+#: py/obj.c:257
msgid "can't convert to int"
msgstr ""
-#: py/obj.c:244
+#: py/obj.c:260
#, c-format
msgid "can't convert %s to int"
msgstr ""
-#: py/obj.c:304
+#: py/obj.c:320
msgid "can't convert to float"
msgstr ""
-#: py/obj.c:307
+#: py/obj.c:323
#, c-format
msgid "can't convert %s to float"
msgstr ""
-#: py/obj.c:337
+#: py/obj.c:353
msgid "can't convert to complex"
msgstr ""
-#: py/obj.c:340
+#: py/obj.c:356
#, c-format
msgid "can't convert %s to complex"
msgstr ""
-#: py/obj.c:355
+#: py/obj.c:371
msgid "expected tuple/list"
msgstr ""
-#: py/obj.c:358
+#: py/obj.c:374
#, c-format
msgid "object '%s' is not a tuple or list"
msgstr ""
-#: py/obj.c:369
+#: py/obj.c:385
msgid "tuple/list has wrong length"
msgstr ""
-#: py/obj.c:371
+#: py/obj.c:387
#, c-format
msgid "requested length %d but object has length %d"
msgstr ""
-#: py/obj.c:384
+#: py/obj.c:400
msgid "indices must be integers"
msgstr ""
-#: py/obj.c:387
+#: py/obj.c:403
msgid "%q indices must be integers, not %s"
msgstr ""
-#: py/obj.c:407
+#: py/obj.c:423
msgid "%q index out of range"
msgstr ""
-#: py/obj.c:439
+#: py/obj.c:455
msgid "object has no len"
msgstr ""
-#: py/obj.c:442
+#: py/obj.c:458
#, c-format
msgid "object of type '%s' has no len()"
msgstr ""
-#: py/obj.c:480
+#: py/obj.c:496
msgid "object does not support item deletion"
msgstr ""
-#: py/obj.c:483
+#: py/obj.c:499
#, c-format
msgid "'%s' object does not support item deletion"
msgstr ""
-#: py/obj.c:487
+#: py/obj.c:503
msgid "object is not subscriptable"
msgstr ""
-#: py/obj.c:490
+#: py/obj.c:506
#, c-format
msgid "'%s' object is not subscriptable"
msgstr ""
-#: py/obj.c:494
+#: py/obj.c:510
msgid "object does not support item assignment"
msgstr ""
-#: py/obj.c:497
+#: py/obj.c:513
#, c-format
msgid "'%s' object does not support item assignment"
msgstr ""
-#: py/obj.c:528
+#: py/obj.c:544
msgid "object with buffer protocol required"
msgstr ""
@@ -795,7 +1404,7 @@ msgstr ""
msgid "dict update sequence has wrong length"
msgstr ""
-#: py/objfloat.c:308
+#: py/objfloat.c:308 py/parsenum.c:331
msgid "complex values not supported"
msgstr ""
@@ -1043,10 +1652,6 @@ msgstr ""
msgid "can't convert '%q' object to %q implicitly"
msgstr ""
-#: py/objstringio.c:43
-msgid "I/O operation on closed file"
-msgstr ""
-
#: py/objstrunicode.c:134
#, c-format
msgid "string indices must be integers, not %s"
@@ -1142,6 +1747,23 @@ msgstr ""
msgid "int() arg 2 must be >= 2 and <= 36"
msgstr ""
+#: py/parsenum.c:151
+msgid "invalid syntax for integer"
+msgstr ""
+
+#: py/parsenum.c:155
+#, c-format
+msgid "invalid syntax for integer with base %d"
+msgstr ""
+
+#: py/parsenum.c:339
+msgid "invalid syntax for number"
+msgstr ""
+
+#: py/parsenum.c:342
+msgid "decimal numbers not supported"
+msgstr ""
+
#: py/persistentcode.c:223
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@@ -1253,6 +1875,18 @@ msgstr ""
msgid "stream operation not supported"
msgstr ""
+#: py/vm.c:255
+msgid "local variable referenced before assignment"
+msgstr ""
+
+#: py/vm.c:1142
+msgid "no active exception to reraise"
+msgstr ""
+
+#: py/vm.c:1284
+msgid "byte code not implemented"
+msgstr ""
+
#: shared-bindings/_stage/Layer.c:71
msgid "graphic must be 2048 bytes long"
msgstr ""
@@ -1298,6 +1932,10 @@ msgstr ""
msgid "destination_length must be an int >= 0"
msgstr ""
+#: shared-bindings/audiobusio/PDMIn.c:199
+msgid "Cannot record to a file"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c:202
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -1392,6 +2030,18 @@ msgstr ""
msgid "expected a DigitalInOut"
msgstr ""
+#: shared-bindings/i2cslave/I2CSlave.c:98
+msgid "can't convert address to int"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c:101
+msgid "address out of bounds"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c:107
+msgid "addresses is empty"
+msgstr ""
+
#: shared-bindings/microcontroller/Pin.c:89
#: shared-bindings/neopixel_write/__init__.c:67
#: shared-bindings/pulseio/PulseOut.c:75
@@ -1426,6 +2076,10 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
+#: shared-bindings/os/__init__.c:200
+msgid "No hardware random available"
+msgstr ""
+
#: shared-bindings/pulseio/PWMOut.c:164
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
@@ -1546,6 +2200,14 @@ msgstr ""
msgid "Invalid file"
msgstr ""
+#: shared-module/audioio/WaveFile.c:117
+msgid "Couldn't allocate first buffer"
+msgstr ""
+
+#: shared-module/audioio/WaveFile.c:123
+msgid "Couldn't allocate second buffer"
+msgstr ""
+
#: shared-module/bitbangio/I2C.c:58
msgid "Clock stretch too long"
msgstr ""
diff --git a/locale/en_US.po b/locale/en_US.po
index 7eec87dc7..256278256 100644
--- a/locale/en_US.po
+++ b/locale/en_US.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-08-09 13:43-0700\n"
+"POT-Creation-Date: 2018-08-20 09:37-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -17,90 +17,242 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.1.1\n"
-#: extmod/vfs_fat.c:426 py/moduerrno.c:115
+#: extmod/machine_i2c.c:299
+msgid "invalid I2C peripheral"
+msgstr ""
+
+#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368
+#: extmod/machine_i2c.c:392
+msgid "I2C operation not supported"
+msgstr ""
+
+#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53
+#, c-format
+msgid "address %08x is not aligned to %d bytes"
+msgstr ""
+
+#: extmod/machine_spi.c:57
+msgid "invalid SPI peripheral"
+msgstr ""
+
+#: extmod/machine_spi.c:124
+msgid "buffers must be the same length"
+msgstr ""
+
+#: extmod/machine_spi.c:207
+msgid "bits must be 8"
+msgstr ""
+
+#: extmod/machine_spi.c:210
+msgid "firstbit must be MSB"
+msgstr ""
+
+#: extmod/machine_spi.c:215
+msgid "must specify all of sck/mosi/miso"
+msgstr ""
+
+#: extmod/modframebuf.c:299
+msgid "invalid format"
+msgstr ""
+
+#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102
+msgid "a bytes-like object is required"
+msgstr ""
+
+#: extmod/modubinascii.c:90
+msgid "odd-length string"
+msgstr ""
+
+#: extmod/modubinascii.c:101
+msgid "non-hex digit found"
+msgstr ""
+
+#: extmod/modubinascii.c:169
+msgid "incorrect padding"
+msgstr ""
+
+#: extmod/moductypes.c:122
+msgid "syntax error in uctypes descriptor"
+msgstr ""
+
+#: extmod/moductypes.c:219
+msgid "Cannot unambiguously get sizeof scalar"
+msgstr ""
+
+#: extmod/moductypes.c:397
+msgid "struct: no fields"
+msgstr ""
+
+#: extmod/moductypes.c:530
+msgid "struct: cannot index"
+msgstr ""
+
+#: extmod/moductypes.c:544
+msgid "struct: index out of range"
+msgstr ""
+
+#: extmod/moduheapq.c:38
+msgid "heap must be a list"
+msgstr ""
+
+#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172
+msgid "empty heap"
+msgstr ""
+
+#: extmod/modujson.c:281
+msgid "syntax error in JSON"
+msgstr ""
+
+#: extmod/modure.c:161
+msgid "Splitting with sub-captures"
+msgstr ""
+
+#: extmod/modure.c:207
+msgid "Error in regex"
+msgstr ""
+
+#: extmod/modussl_axtls.c:81
+msgid "invalid key"
+msgstr ""
+
+#: extmod/modussl_axtls.c:87
+msgid "invalid cert"
+msgstr ""
+
+#: extmod/modutimeq.c:131
+msgid "queue overflow"
+msgstr ""
+
+#: extmod/moduzlib.c:97
+msgid "compression header"
+msgstr ""
+
+#: extmod/uos_dupterm.c:120
+msgid "invalid dupterm index"
+msgstr ""
+
+#: extmod/vfs_fat.c:426 py/moduerrno.c:150
msgid "Read-only filesystem"
msgstr ""
+#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43
+msgid "I/O operation on closed file"
+msgstr ""
+
#: lib/embed/abort_.c:8
msgid "abort() called"
msgstr ""
+#: lib/netutils/netutils.c:83
+msgid "invalid arguments"
+msgstr ""
+
#: lib/utils/pyexec.c:97 py/builtinimport.c:253
msgid "script compilation not supported"
msgstr ""
-#: main.c:137
+#: main.c:143
msgid " output:\n"
msgstr ""
-#: main.c:148 main.c:221
+#: main.c:157 main.c:230
msgid ""
"Auto-reload is on. Simply save files over USB to run them or enter REPL to "
"disable.\n"
msgstr ""
-#: main.c:150
+#: main.c:159
msgid "Running in safe mode! Auto-reload is off.\n"
msgstr ""
-#: main.c:152 main.c:223
+#: main.c:161 main.c:232
msgid "Auto-reload is off.\n"
msgstr ""
-#: main.c:166
+#: main.c:175
msgid "Running in safe mode! Not running saved code.\n"
msgstr ""
-#: main.c:182
+#: main.c:191
msgid "WARNING: Your code filename has two extensions\n"
msgstr ""
-#: main.c:230
+#: main.c:239
msgid "You requested starting safe mode by "
msgstr ""
-#: main.c:233
+#: main.c:242
msgid "To exit, please reset the board without "
msgstr ""
-#: main.c:240
+#: main.c:249
msgid ""
"You are running in safe mode which means something really bad happened.\n"
msgstr ""
-#: main.c:242
+#: main.c:251
msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n"
msgstr ""
-#: main.c:243
+#: main.c:252
msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n"
msgstr ""
-#: main.c:246
+#: main.c:255
msgid ""
"The microcontroller's power dipped. Please make sure your power supply "
"provides\n"
msgstr ""
-#: main.c:247
+#: main.c:256
msgid ""
"enough power for the whole circuit and press reset (after ejecting "
"CIRCUITPY).\n"
msgstr ""
-#: main.c:251
+#: main.c:260
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
-#: main.c:406
+#: main.c:415
msgid "soft reboot\n"
msgstr ""
+#: ports/atmel-samd/audio_dma.c:285
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361
+msgid "All sync event channels in use"
+msgstr ""
+
+#: ports/atmel-samd/bindings/samd/Clock.c:135
+msgid "calibration is read only"
+msgstr ""
+
+#: ports/atmel-samd/bindings/samd/Clock.c:137
+msgid "calibration is out of range"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:39
+msgid "No default I2C bus"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:64
+msgid "No default SPI bus"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:91
+msgid "No default UART bus"
+msgstr ""
+
#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63
+#: ports/nrf/common-hal/analogio/AnalogIn.c:39
msgid "Pin does not have ADC capabilities"
msgstr ""
-#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:53
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49
+msgid "No DAC on chip"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56
msgid "AnalogOut not supported on given pin"
msgstr ""
@@ -139,12 +291,12 @@ msgid "Too many channels in sample."
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305
-#: ports/atmel-samd/common-hal/audioio/AudioOut.c:322
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:326
msgid "No DMA channel found"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308
-#: ports/atmel-samd/common-hal/audioio/AudioOut.c:324
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:328
msgid "Unable to allocate buffers for signed conversion"
msgstr ""
@@ -192,20 +344,27 @@ msgstr ""
msgid "All timers in use"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:45
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:215
+msgid "All event channels in use"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/I2C.c:71
msgid "Not enough pins available"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:76
+#: ports/atmel-samd/common-hal/busio/I2C.c:78
+#: ports/atmel-samd/common-hal/busio/SPI.c:132
#: ports/atmel-samd/common-hal/busio/UART.c:119
+#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45
+#: ports/nrf/common-hal/busio/I2C.c:58
msgid "Invalid pins"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:99
+#: ports/atmel-samd/common-hal/busio/I2C.c:101
msgid "SDA or SCL needs a pull up"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:119
+#: ports/atmel-samd/common-hal/busio/I2C.c:121
msgid "Unsupported baudrate"
msgstr ""
@@ -234,15 +393,18 @@ msgid "No TX pin"
msgstr ""
#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:168
+#: ports/nrf/common-hal/digitalio/DigitalInOut.c:158
msgid "Cannot get pull while in output mode"
msgstr ""
#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74
+#: ports/esp8266/common-hal/microcontroller/__init__.c:64
msgid "Cannot reset into bootloader because no bootloader is present."
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120
#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:366
+#: ports/nrf/common-hal/pulseio/PWMOut.c:227
msgid "Invalid PWM frequency"
msgstr ""
@@ -259,15 +421,18 @@ msgid "EXTINT channel already in use"
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:86
#, c-format
msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:203
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:151
msgid "pop from an empty PulseIn"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:235 py/obj.c:404
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:235
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420
msgid "index out of range"
msgstr ""
@@ -296,18 +461,365 @@ msgid "No free GCLKs"
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:78
+#: ports/nrf/common-hal/usb_hid/Device.c:45
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:82
+#: ports/nrf/common-hal/usb_hid/Device.c:53
msgid "USB Busy"
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:82
+#: ports/nrf/common-hal/usb_hid/Device.c:59
msgid "USB Error"
msgstr ""
+#: ports/esp8266/common-hal/analogio/AnalogIn.c:43
+msgid "Pin %q does not have ADC capabilities"
+msgstr ""
+
+#: ports/esp8266/common-hal/analogio/AnalogOut.c:39
+msgid "No hardware support for analog out."
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/SPI.c:72
+msgid "Pins not valid for SPI"
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:45
+msgid "Only tx supported on UART1 (GPIO2)."
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108
+msgid "invalid data bits"
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144
+msgid "invalid stop bits"
+msgstr ""
+
+#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200
+msgid "ESP8266 does not support pull down."
+msgstr ""
+
+#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210
+msgid "GPIO16 does not support pull up."
+msgstr ""
+
+#: ports/esp8266/common-hal/microcontroller/__init__.c:66
+msgid "ESP8226 does not support safe mode."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:54
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:113
+#, c-format
+msgid "Maximum PWM frequency is %dhz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:57
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:116
+msgid "Minimum PWM frequency is 1hz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:68
+#, c-format
+msgid "Multiple PWM frequencies not supported. PWM already set to %dhz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70
+#, c-format
+msgid "PWM not supported on pin %d"
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:78
+msgid "No PulseIn support for %q"
+msgstr ""
+
+#: ports/esp8266/common-hal/storage/__init__.c:34
+msgid "Unable to remount filesystem"
+msgstr ""
+
+#: ports/esp8266/common-hal/storage/__init__.c:38
+msgid "Use esptool to erase flash and re-upload Python instead"
+msgstr ""
+
+#: ports/esp8266/esp_mphal.c:154
+msgid "C-level assert"
+msgstr ""
+
+#: ports/esp8266/machine_adc.c:57
+#, c-format
+msgid "not a valid ADC Channel: %d"
+msgstr ""
+
+#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137
+msgid "impossible baudrate"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:129
+msgid "expecting a pin"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:284
+msgid "Pin(16) doesn't support pull"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:323
+msgid "invalid pin"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:389
+msgid "pin does not have IRQ capabilities"
+msgstr ""
+
+#: ports/esp8266/machine_rtc.c:185
+msgid "buffer too long"
+msgstr ""
+
+#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223
+#: ports/esp8266/machine_rtc.c:246
+msgid "invalid alarm"
+msgstr ""
+
+#: ports/esp8266/machine_uart.c:169
+#, c-format
+msgid "UART(%d) does not exist"
+msgstr ""
+
+#: ports/esp8266/machine_uart.c:219
+msgid "UART(1) can't read"
+msgstr ""
+
+#: ports/esp8266/modesp.c:119
+msgid "len must be multiple of 4"
+msgstr ""
+
+#: ports/esp8266/modesp.c:274
+#, c-format
+msgid "memory allocation failed, allocating %u bytes for native code"
+msgstr ""
+
+#: ports/esp8266/modesp.c:317
+msgid "flash location must be below 1MByte"
+msgstr ""
+
+#: ports/esp8266/modmachine.c:63
+msgid "frequency can only be either 80Mhz or 160MHz"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:61
+msgid "STA required"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:61
+msgid "AP required"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:87
+msgid "Cannot update i/f status"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:142
+msgid "Cannot set STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:144
+msgid "Cannot connect to AP"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:152
+msgid "Cannot disconnect from AP"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:173
+msgid "unknown status param"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:222
+msgid "STA must be active"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:239
+msgid "scan failed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:306
+msgid "wifi_set_ip_info() failed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:319
+msgid "either pos or kw args are allowed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:329
+msgid "can't get STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:331
+msgid "can't get AP config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:346
+msgid "invalid buffer length"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:405
+msgid "can't set STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:407
+msgid "can't set AP config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:416
+msgid "can query only one param"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:469
+msgid "unknown config param"
+msgstr ""
+
+#: ports/nrf/common-hal/analogio/AnalogOut.c:37
+msgid "AnalogOut functionality not supported"
+msgstr ""
+
+#: ports/nrf/common-hal/busio/UART.c:45 ports/nrf/common-hal/busio/UART.c:49
+#: ports/nrf/common-hal/busio/UART.c:53 ports/nrf/common-hal/busio/UART.c:62
+#: ports/nrf/common-hal/busio/UART.c:68 ports/nrf/common-hal/busio/UART.c:73
+#: ports/nrf/common-hal/busio/UART.c:78 ports/nrf/common-hal/busio/UART.c:83
+#: ports/nrf/common-hal/busio/UART.c:88
+msgid "busio.UART not yet implemented"
+msgstr ""
+
+#: ports/nrf/common-hal/microcontroller/Processor.c:49
+#, c-format
+msgid "Can not get temperature. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:199
+msgid "Cannot apply GAP parameters."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:213
+msgid "Cannot set PPCP parameters."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:245
+msgid "Can not query for the device address."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:264
+msgid "Can not add Vendor Specific 128-bit UUID."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:284
+#: ports/nrf/drivers/bluetooth/ble_drv.c:298
+msgid "Can not add Service."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:373
+msgid "Can not add Characteristic."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:400
+msgid "Can not apply device name in the stack."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:464
+#: ports/nrf/drivers/bluetooth/ble_drv.c:514
+msgid "Can not encode UUID, to check length."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:470
+#: ports/nrf/drivers/bluetooth/ble_drv.c:520
+msgid "Can encode UUID into the advertisment packet."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:545
+msgid "Can not fit data into the advertisment packet."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:558
+#: ports/nrf/drivers/bluetooth/ble_drv.c:604
+#, c-format
+msgid "Can not apply advertisment data. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:614
+#, c-format
+msgid "Can not start advertisment. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:631
+#, c-format
+msgid "Can not stop advertisment. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:650
+#: ports/nrf/drivers/bluetooth/ble_drv.c:726
+#, c-format
+msgid "Can not read attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:667
+#: ports/nrf/drivers/bluetooth/ble_drv.c:756
+#, c-format
+msgid "Can not write attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:691
+#, c-format
+msgid "Can not notify attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:784
+#, c-format
+msgid "Can not start scanning. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:829
+#, c-format
+msgid "Can not connect. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:80
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:132
+#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137
+msgid "Invalid UUID parameter"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:73
+msgid "Invalid Service type"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127
+msgid "Invalid UUID string length"
+msgstr ""
+
+#: ports/unix/modffi.c:138
+msgid "Unknown type"
+msgstr ""
+
+#: ports/unix/modffi.c:207 ports/unix/modffi.c:265
+msgid "Error in ffi_prep_cif"
+msgstr ""
+
+#: ports/unix/modffi.c:270
+msgid "ffi_prep_closure_loc"
+msgstr ""
+
+#: ports/unix/modffi.c:413
+msgid "Don't know how to pass object to native function"
+msgstr ""
+
+#: ports/unix/modusocket.c:474
+#, c-format
+msgid "[addrinfo error %d]"
+msgstr ""
+
#: py/argcheck.c:44
msgid "function does not take keyword arguments"
msgstr ""
@@ -549,14 +1061,111 @@ msgstr ""
msgid "'data' requires integer arguments"
msgstr ""
+#: py/emitinlinextensa.c:86
+msgid "can only have up to 4 parameters to Xtensa assembly"
+msgstr ""
+
+#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96
+msgid "parameters must be registers in sequence a2 to a5"
+msgstr ""
+
+#: py/emitinlinextensa.c:162
+#, c-format
+msgid "'%s' expects a register"
+msgstr ""
+
+#: py/emitinlinextensa.c:169
+#, c-format
+msgid "'%s' expects an integer"
+msgstr ""
+
+#: py/emitinlinextensa.c:174
+#, c-format
+msgid "'%s' integer %d is not within range %d..%d"
+msgstr ""
+
+#: py/emitinlinextensa.c:182
+#, c-format
+msgid "'%s' expects a label"
+msgstr ""
+
+#: py/emitinlinextensa.c:193
+msgid "label '%q' not defined"
+msgstr ""
+
+#: py/emitinlinextensa.c:327
+#, c-format
+msgid "unsupported Xtensa instruction '%s' with %d arguments"
+msgstr ""
+
+#: py/emitnative.c:183
+msgid "unknown type '%q'"
+msgstr ""
+
+#: py/emitnative.c:260
+msgid "Viper functions don't currently support more than 4 arguments"
+msgstr ""
+
#: py/emitnative.c:742
msgid "conversion to object"
msgstr ""
+#: py/emitnative.c:921
+msgid "local '%q' used before type known"
+msgstr ""
+
+#: py/emitnative.c:1118 py/emitnative.c:1156
+msgid "can't load from '%q'"
+msgstr ""
+
+#: py/emitnative.c:1128
+msgid "can't load with '%q' index"
+msgstr ""
+
+#: py/emitnative.c:1188
+msgid "local '%q' has type '%q' but source is '%q'"
+msgstr ""
+
+#: py/emitnative.c:1289 py/emitnative.c:1379
+msgid "can't store '%q'"
+msgstr ""
+
+#: py/emitnative.c:1358 py/emitnative.c:1419
+msgid "can't store to '%q'"
+msgstr ""
+
+#: py/emitnative.c:1369
+msgid "can't store with '%q' index"
+msgstr ""
+
+#: py/emitnative.c:1540
+msgid "can't implicitly convert '%q' to 'bool'"
+msgstr ""
+
+#: py/emitnative.c:1774
+msgid "unary op %q not implemented"
+msgstr ""
+
+#: py/emitnative.c:1930
+msgid "binary op %q not implemented"
+msgstr ""
+
+#: py/emitnative.c:1951
+msgid "can't do binary op between '%q' and '%q'"
+msgstr ""
+
#: py/emitnative.c:2126
msgid "casting"
msgstr ""
+#: py/emitnative.c:2173
+msgid "return expected '%q' but got '%q'"
+msgstr ""
+
+#: py/emitnative.c:2191
+msgid "must raise an object"
+msgstr ""
+
#: py/emitnative.c:2201
msgid "native yield"
msgstr ""
@@ -617,140 +1226,140 @@ msgstr ""
msgid "expecting a dict for keyword args"
msgstr ""
-#: py/moduerrno.c:108 py/moduerrno.c:111
+#: py/moduerrno.c:143 py/moduerrno.c:146
msgid "Permission denied"
msgstr ""
-#: py/moduerrno.c:109
+#: py/moduerrno.c:144
msgid "No such file/directory"
msgstr ""
-#: py/moduerrno.c:110
+#: py/moduerrno.c:145
msgid "Input/output error"
msgstr ""
-#: py/moduerrno.c:112
+#: py/moduerrno.c:147
msgid "File exists"
msgstr ""
-#: py/moduerrno.c:113
+#: py/moduerrno.c:148
msgid "Unsupported operation"
msgstr ""
-#: py/moduerrno.c:114
+#: py/moduerrno.c:149
msgid "Invalid argument"
msgstr ""
-#: py/obj.c:89
+#: py/obj.c:90
msgid "Traceback (most recent call last):\n"
msgstr ""
-#: py/obj.c:92
+#: py/obj.c:94
msgid " File \"%q\", line %d"
msgstr ""
-#: py/obj.c:94
+#: py/obj.c:96
msgid " File \"%q\""
msgstr ""
-#: py/obj.c:101
+#: py/obj.c:100
msgid ", in %q\n"
msgstr ""
-#: py/obj.c:241
+#: py/obj.c:257
msgid "can't convert to int"
msgstr ""
-#: py/obj.c:244
+#: py/obj.c:260
#, c-format
msgid "can't convert %s to int"
msgstr ""
-#: py/obj.c:304
+#: py/obj.c:320
msgid "can't convert to float"
msgstr ""
-#: py/obj.c:307
+#: py/obj.c:323
#, c-format
msgid "can't convert %s to float"
msgstr ""
-#: py/obj.c:337
+#: py/obj.c:353
msgid "can't convert to complex"
msgstr ""
-#: py/obj.c:340
+#: py/obj.c:356
#, c-format
msgid "can't convert %s to complex"
msgstr ""
-#: py/obj.c:355
+#: py/obj.c:371
msgid "expected tuple/list"
msgstr ""
-#: py/obj.c:358
+#: py/obj.c:374
#, c-format
msgid "object '%s' is not a tuple or list"
msgstr ""
-#: py/obj.c:369
+#: py/obj.c:385
msgid "tuple/list has wrong length"
msgstr ""
-#: py/obj.c:371
+#: py/obj.c:387
#, c-format
msgid "requested length %d but object has length %d"
msgstr ""
-#: py/obj.c:384
+#: py/obj.c:400
msgid "indices must be integers"
msgstr ""
-#: py/obj.c:387
+#: py/obj.c:403
msgid "%q indices must be integers, not %s"
msgstr ""
-#: py/obj.c:407
+#: py/obj.c:423
msgid "%q index out of range"
msgstr ""
-#: py/obj.c:439
+#: py/obj.c:455
msgid "object has no len"
msgstr ""
-#: py/obj.c:442
+#: py/obj.c:458
#, c-format
msgid "object of type '%s' has no len()"
msgstr ""
-#: py/obj.c:480
+#: py/obj.c:496
msgid "object does not support item deletion"
msgstr ""
-#: py/obj.c:483
+#: py/obj.c:499
#, c-format
msgid "'%s' object does not support item deletion"
msgstr ""
-#: py/obj.c:487
+#: py/obj.c:503
msgid "object is not subscriptable"
msgstr ""
-#: py/obj.c:490
+#: py/obj.c:506
#, c-format
msgid "'%s' object is not subscriptable"
msgstr ""
-#: py/obj.c:494
+#: py/obj.c:510
msgid "object does not support item assignment"
msgstr ""
-#: py/obj.c:497
+#: py/obj.c:513
#, c-format
msgid "'%s' object does not support item assignment"
msgstr ""
-#: py/obj.c:528
+#: py/obj.c:544
msgid "object with buffer protocol required"
msgstr ""
@@ -795,7 +1404,7 @@ msgstr ""
msgid "dict update sequence has wrong length"
msgstr ""
-#: py/objfloat.c:308
+#: py/objfloat.c:308 py/parsenum.c:331
msgid "complex values not supported"
msgstr ""
@@ -1043,10 +1652,6 @@ msgstr ""
msgid "can't convert '%q' object to %q implicitly"
msgstr ""
-#: py/objstringio.c:43
-msgid "I/O operation on closed file"
-msgstr ""
-
#: py/objstrunicode.c:134
#, c-format
msgid "string indices must be integers, not %s"
@@ -1142,6 +1747,23 @@ msgstr ""
msgid "int() arg 2 must be >= 2 and <= 36"
msgstr ""
+#: py/parsenum.c:151
+msgid "invalid syntax for integer"
+msgstr ""
+
+#: py/parsenum.c:155
+#, c-format
+msgid "invalid syntax for integer with base %d"
+msgstr ""
+
+#: py/parsenum.c:339
+msgid "invalid syntax for number"
+msgstr ""
+
+#: py/parsenum.c:342
+msgid "decimal numbers not supported"
+msgstr ""
+
#: py/persistentcode.c:223
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@@ -1253,6 +1875,18 @@ msgstr ""
msgid "stream operation not supported"
msgstr ""
+#: py/vm.c:255
+msgid "local variable referenced before assignment"
+msgstr ""
+
+#: py/vm.c:1142
+msgid "no active exception to reraise"
+msgstr ""
+
+#: py/vm.c:1284
+msgid "byte code not implemented"
+msgstr ""
+
#: shared-bindings/_stage/Layer.c:71
msgid "graphic must be 2048 bytes long"
msgstr ""
@@ -1298,6 +1932,10 @@ msgstr ""
msgid "destination_length must be an int >= 0"
msgstr ""
+#: shared-bindings/audiobusio/PDMIn.c:199
+msgid "Cannot record to a file"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c:202
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -1392,6 +2030,18 @@ msgstr ""
msgid "expected a DigitalInOut"
msgstr ""
+#: shared-bindings/i2cslave/I2CSlave.c:98
+msgid "can't convert address to int"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c:101
+msgid "address out of bounds"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c:107
+msgid "addresses is empty"
+msgstr ""
+
#: shared-bindings/microcontroller/Pin.c:89
#: shared-bindings/neopixel_write/__init__.c:67
#: shared-bindings/pulseio/PulseOut.c:75
@@ -1426,6 +2076,10 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
+#: shared-bindings/os/__init__.c:200
+msgid "No hardware random available"
+msgstr ""
+
#: shared-bindings/pulseio/PWMOut.c:164
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
@@ -1546,6 +2200,14 @@ msgstr ""
msgid "Invalid file"
msgstr ""
+#: shared-module/audioio/WaveFile.c:117
+msgid "Couldn't allocate first buffer"
+msgstr ""
+
+#: shared-module/audioio/WaveFile.c:123
+msgid "Couldn't allocate second buffer"
+msgstr ""
+
#: shared-module/bitbangio/I2C.c:58
msgid "Clock stretch too long"
msgstr ""
diff --git a/locale/es.po b/locale/es.po
index 7eec87dc7..256278256 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-08-09 13:43-0700\n"
+"POT-Creation-Date: 2018-08-20 09:37-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -17,90 +17,242 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.1.1\n"
-#: extmod/vfs_fat.c:426 py/moduerrno.c:115
+#: extmod/machine_i2c.c:299
+msgid "invalid I2C peripheral"
+msgstr ""
+
+#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368
+#: extmod/machine_i2c.c:392
+msgid "I2C operation not supported"
+msgstr ""
+
+#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53
+#, c-format
+msgid "address %08x is not aligned to %d bytes"
+msgstr ""
+
+#: extmod/machine_spi.c:57
+msgid "invalid SPI peripheral"
+msgstr ""
+
+#: extmod/machine_spi.c:124
+msgid "buffers must be the same length"
+msgstr ""
+
+#: extmod/machine_spi.c:207
+msgid "bits must be 8"
+msgstr ""
+
+#: extmod/machine_spi.c:210
+msgid "firstbit must be MSB"
+msgstr ""
+
+#: extmod/machine_spi.c:215
+msgid "must specify all of sck/mosi/miso"
+msgstr ""
+
+#: extmod/modframebuf.c:299
+msgid "invalid format"
+msgstr ""
+
+#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102
+msgid "a bytes-like object is required"
+msgstr ""
+
+#: extmod/modubinascii.c:90
+msgid "odd-length string"
+msgstr ""
+
+#: extmod/modubinascii.c:101
+msgid "non-hex digit found"
+msgstr ""
+
+#: extmod/modubinascii.c:169
+msgid "incorrect padding"
+msgstr ""
+
+#: extmod/moductypes.c:122
+msgid "syntax error in uctypes descriptor"
+msgstr ""
+
+#: extmod/moductypes.c:219
+msgid "Cannot unambiguously get sizeof scalar"
+msgstr ""
+
+#: extmod/moductypes.c:397
+msgid "struct: no fields"
+msgstr ""
+
+#: extmod/moductypes.c:530
+msgid "struct: cannot index"
+msgstr ""
+
+#: extmod/moductypes.c:544
+msgid "struct: index out of range"
+msgstr ""
+
+#: extmod/moduheapq.c:38
+msgid "heap must be a list"
+msgstr ""
+
+#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172
+msgid "empty heap"
+msgstr ""
+
+#: extmod/modujson.c:281
+msgid "syntax error in JSON"
+msgstr ""
+
+#: extmod/modure.c:161
+msgid "Splitting with sub-captures"
+msgstr ""
+
+#: extmod/modure.c:207
+msgid "Error in regex"
+msgstr ""
+
+#: extmod/modussl_axtls.c:81
+msgid "invalid key"
+msgstr ""
+
+#: extmod/modussl_axtls.c:87
+msgid "invalid cert"
+msgstr ""
+
+#: extmod/modutimeq.c:131
+msgid "queue overflow"
+msgstr ""
+
+#: extmod/moduzlib.c:97
+msgid "compression header"
+msgstr ""
+
+#: extmod/uos_dupterm.c:120
+msgid "invalid dupterm index"
+msgstr ""
+
+#: extmod/vfs_fat.c:426 py/moduerrno.c:150
msgid "Read-only filesystem"
msgstr ""
+#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43
+msgid "I/O operation on closed file"
+msgstr ""
+
#: lib/embed/abort_.c:8
msgid "abort() called"
msgstr ""
+#: lib/netutils/netutils.c:83
+msgid "invalid arguments"
+msgstr ""
+
#: lib/utils/pyexec.c:97 py/builtinimport.c:253
msgid "script compilation not supported"
msgstr ""
-#: main.c:137
+#: main.c:143
msgid " output:\n"
msgstr ""
-#: main.c:148 main.c:221
+#: main.c:157 main.c:230
msgid ""
"Auto-reload is on. Simply save files over USB to run them or enter REPL to "
"disable.\n"
msgstr ""
-#: main.c:150
+#: main.c:159
msgid "Running in safe mode! Auto-reload is off.\n"
msgstr ""
-#: main.c:152 main.c:223
+#: main.c:161 main.c:232
msgid "Auto-reload is off.\n"
msgstr ""
-#: main.c:166
+#: main.c:175
msgid "Running in safe mode! Not running saved code.\n"
msgstr ""
-#: main.c:182
+#: main.c:191
msgid "WARNING: Your code filename has two extensions\n"
msgstr ""
-#: main.c:230
+#: main.c:239
msgid "You requested starting safe mode by "
msgstr ""
-#: main.c:233
+#: main.c:242
msgid "To exit, please reset the board without "
msgstr ""
-#: main.c:240
+#: main.c:249
msgid ""
"You are running in safe mode which means something really bad happened.\n"
msgstr ""
-#: main.c:242
+#: main.c:251
msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n"
msgstr ""
-#: main.c:243
+#: main.c:252
msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n"
msgstr ""
-#: main.c:246
+#: main.c:255
msgid ""
"The microcontroller's power dipped. Please make sure your power supply "
"provides\n"
msgstr ""
-#: main.c:247
+#: main.c:256
msgid ""
"enough power for the whole circuit and press reset (after ejecting "
"CIRCUITPY).\n"
msgstr ""
-#: main.c:251
+#: main.c:260
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
-#: main.c:406
+#: main.c:415
msgid "soft reboot\n"
msgstr ""
+#: ports/atmel-samd/audio_dma.c:285
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361
+msgid "All sync event channels in use"
+msgstr ""
+
+#: ports/atmel-samd/bindings/samd/Clock.c:135
+msgid "calibration is read only"
+msgstr ""
+
+#: ports/atmel-samd/bindings/samd/Clock.c:137
+msgid "calibration is out of range"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:39
+msgid "No default I2C bus"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:64
+msgid "No default SPI bus"
+msgstr ""
+
+#: ports/atmel-samd/board_busses.c:91
+msgid "No default UART bus"
+msgstr ""
+
#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63
+#: ports/nrf/common-hal/analogio/AnalogIn.c:39
msgid "Pin does not have ADC capabilities"
msgstr ""
-#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:53
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49
+msgid "No DAC on chip"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56
msgid "AnalogOut not supported on given pin"
msgstr ""
@@ -139,12 +291,12 @@ msgid "Too many channels in sample."
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305
-#: ports/atmel-samd/common-hal/audioio/AudioOut.c:322
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:326
msgid "No DMA channel found"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308
-#: ports/atmel-samd/common-hal/audioio/AudioOut.c:324
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:328
msgid "Unable to allocate buffers for signed conversion"
msgstr ""
@@ -192,20 +344,27 @@ msgstr ""
msgid "All timers in use"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:45
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:215
+msgid "All event channels in use"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/I2C.c:71
msgid "Not enough pins available"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:76
+#: ports/atmel-samd/common-hal/busio/I2C.c:78
+#: ports/atmel-samd/common-hal/busio/SPI.c:132
#: ports/atmel-samd/common-hal/busio/UART.c:119
+#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45
+#: ports/nrf/common-hal/busio/I2C.c:58
msgid "Invalid pins"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:99
+#: ports/atmel-samd/common-hal/busio/I2C.c:101
msgid "SDA or SCL needs a pull up"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c:119
+#: ports/atmel-samd/common-hal/busio/I2C.c:121
msgid "Unsupported baudrate"
msgstr ""
@@ -234,15 +393,18 @@ msgid "No TX pin"
msgstr ""
#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:168
+#: ports/nrf/common-hal/digitalio/DigitalInOut.c:158
msgid "Cannot get pull while in output mode"
msgstr ""
#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74
+#: ports/esp8266/common-hal/microcontroller/__init__.c:64
msgid "Cannot reset into bootloader because no bootloader is present."
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120
#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:366
+#: ports/nrf/common-hal/pulseio/PWMOut.c:227
msgid "Invalid PWM frequency"
msgstr ""
@@ -259,15 +421,18 @@ msgid "EXTINT channel already in use"
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:86
#, c-format
msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:203
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:151
msgid "pop from an empty PulseIn"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:235 py/obj.c:404
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:235
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420
msgid "index out of range"
msgstr ""
@@ -296,18 +461,365 @@ msgid "No free GCLKs"
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:78
+#: ports/nrf/common-hal/usb_hid/Device.c:45
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:82
+#: ports/nrf/common-hal/usb_hid/Device.c:53
msgid "USB Busy"
msgstr ""
#: ports/atmel-samd/common-hal/usb_hid/Device.c:82
+#: ports/nrf/common-hal/usb_hid/Device.c:59
msgid "USB Error"
msgstr ""
+#: ports/esp8266/common-hal/analogio/AnalogIn.c:43
+msgid "Pin %q does not have ADC capabilities"
+msgstr ""
+
+#: ports/esp8266/common-hal/analogio/AnalogOut.c:39
+msgid "No hardware support for analog out."
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/SPI.c:72
+msgid "Pins not valid for SPI"
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:45
+msgid "Only tx supported on UART1 (GPIO2)."
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108
+msgid "invalid data bits"
+msgstr ""
+
+#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144
+msgid "invalid stop bits"
+msgstr ""
+
+#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200
+msgid "ESP8266 does not support pull down."
+msgstr ""
+
+#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210
+msgid "GPIO16 does not support pull up."
+msgstr ""
+
+#: ports/esp8266/common-hal/microcontroller/__init__.c:66
+msgid "ESP8226 does not support safe mode."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:54
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:113
+#, c-format
+msgid "Maximum PWM frequency is %dhz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:57
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:116
+msgid "Minimum PWM frequency is 1hz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:68
+#, c-format
+msgid "Multiple PWM frequencies not supported. PWM already set to %dhz."
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70
+#, c-format
+msgid "PWM not supported on pin %d"
+msgstr ""
+
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:78
+msgid "No PulseIn support for %q"
+msgstr ""
+
+#: ports/esp8266/common-hal/storage/__init__.c:34
+msgid "Unable to remount filesystem"
+msgstr ""
+
+#: ports/esp8266/common-hal/storage/__init__.c:38
+msgid "Use esptool to erase flash and re-upload Python instead"
+msgstr ""
+
+#: ports/esp8266/esp_mphal.c:154
+msgid "C-level assert"
+msgstr ""
+
+#: ports/esp8266/machine_adc.c:57
+#, c-format
+msgid "not a valid ADC Channel: %d"
+msgstr ""
+
+#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137
+msgid "impossible baudrate"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:129
+msgid "expecting a pin"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:284
+msgid "Pin(16) doesn't support pull"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:323
+msgid "invalid pin"
+msgstr ""
+
+#: ports/esp8266/machine_pin.c:389
+msgid "pin does not have IRQ capabilities"
+msgstr ""
+
+#: ports/esp8266/machine_rtc.c:185
+msgid "buffer too long"
+msgstr ""
+
+#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223
+#: ports/esp8266/machine_rtc.c:246
+msgid "invalid alarm"
+msgstr ""
+
+#: ports/esp8266/machine_uart.c:169
+#, c-format
+msgid "UART(%d) does not exist"
+msgstr ""
+
+#: ports/esp8266/machine_uart.c:219
+msgid "UART(1) can't read"
+msgstr ""
+
+#: ports/esp8266/modesp.c:119
+msgid "len must be multiple of 4"
+msgstr ""
+
+#: ports/esp8266/modesp.c:274
+#, c-format
+msgid "memory allocation failed, allocating %u bytes for native code"
+msgstr ""
+
+#: ports/esp8266/modesp.c:317
+msgid "flash location must be below 1MByte"
+msgstr ""
+
+#: ports/esp8266/modmachine.c:63
+msgid "frequency can only be either 80Mhz or 160MHz"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:61
+msgid "STA required"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:61
+msgid "AP required"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:87
+msgid "Cannot update i/f status"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:142
+msgid "Cannot set STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:144
+msgid "Cannot connect to AP"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:152
+msgid "Cannot disconnect from AP"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:173
+msgid "unknown status param"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:222
+msgid "STA must be active"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:239
+msgid "scan failed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:306
+msgid "wifi_set_ip_info() failed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:319
+msgid "either pos or kw args are allowed"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:329
+msgid "can't get STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:331
+msgid "can't get AP config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:346
+msgid "invalid buffer length"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:405
+msgid "can't set STA config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:407
+msgid "can't set AP config"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:416
+msgid "can query only one param"
+msgstr ""
+
+#: ports/esp8266/modnetwork.c:469
+msgid "unknown config param"
+msgstr ""
+
+#: ports/nrf/common-hal/analogio/AnalogOut.c:37
+msgid "AnalogOut functionality not supported"
+msgstr ""
+
+#: ports/nrf/common-hal/busio/UART.c:45 ports/nrf/common-hal/busio/UART.c:49
+#: ports/nrf/common-hal/busio/UART.c:53 ports/nrf/common-hal/busio/UART.c:62
+#: ports/nrf/common-hal/busio/UART.c:68 ports/nrf/common-hal/busio/UART.c:73
+#: ports/nrf/common-hal/busio/UART.c:78 ports/nrf/common-hal/busio/UART.c:83
+#: ports/nrf/common-hal/busio/UART.c:88
+msgid "busio.UART not yet implemented"
+msgstr ""
+
+#: ports/nrf/common-hal/microcontroller/Processor.c:49
+#, c-format
+msgid "Can not get temperature. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:199
+msgid "Cannot apply GAP parameters."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:213
+msgid "Cannot set PPCP parameters."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:245
+msgid "Can not query for the device address."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:264
+msgid "Can not add Vendor Specific 128-bit UUID."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:284
+#: ports/nrf/drivers/bluetooth/ble_drv.c:298
+msgid "Can not add Service."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:373
+msgid "Can not add Characteristic."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:400
+msgid "Can not apply device name in the stack."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:464
+#: ports/nrf/drivers/bluetooth/ble_drv.c:514
+msgid "Can not encode UUID, to check length."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:470
+#: ports/nrf/drivers/bluetooth/ble_drv.c:520
+msgid "Can encode UUID into the advertisment packet."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:545
+msgid "Can not fit data into the advertisment packet."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:558
+#: ports/nrf/drivers/bluetooth/ble_drv.c:604
+#, c-format
+msgid "Can not apply advertisment data. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:614
+#, c-format
+msgid "Can not start advertisment. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:631
+#, c-format
+msgid "Can not stop advertisment. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:650
+#: ports/nrf/drivers/bluetooth/ble_drv.c:726
+#, c-format
+msgid "Can not read attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:667
+#: ports/nrf/drivers/bluetooth/ble_drv.c:756
+#, c-format
+msgid "Can not write attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:691
+#, c-format
+msgid "Can not notify attribute value. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:784
+#, c-format
+msgid "Can not start scanning. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:829
+#, c-format
+msgid "Can not connect. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:80
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:132
+#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137
+msgid "Invalid UUID parameter"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:73
+msgid "Invalid Service type"
+msgstr ""
+
+#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127
+msgid "Invalid UUID string length"
+msgstr ""
+
+#: ports/unix/modffi.c:138
+msgid "Unknown type"
+msgstr ""
+
+#: ports/unix/modffi.c:207 ports/unix/modffi.c:265
+msgid "Error in ffi_prep_cif"
+msgstr ""
+
+#: ports/unix/modffi.c:270
+msgid "ffi_prep_closure_loc"
+msgstr ""
+
+#: ports/unix/modffi.c:413
+msgid "Don't know how to pass object to native function"
+msgstr ""
+
+#: ports/unix/modusocket.c:474
+#, c-format
+msgid "[addrinfo error %d]"
+msgstr ""
+
#: py/argcheck.c:44
msgid "function does not take keyword arguments"
msgstr ""
@@ -549,14 +1061,111 @@ msgstr ""
msgid "'data' requires integer arguments"
msgstr ""
+#: py/emitinlinextensa.c:86
+msgid "can only have up to 4 parameters to Xtensa assembly"
+msgstr ""
+
+#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96
+msgid "parameters must be registers in sequence a2 to a5"
+msgstr ""
+
+#: py/emitinlinextensa.c:162
+#, c-format
+msgid "'%s' expects a register"
+msgstr ""
+
+#: py/emitinlinextensa.c:169
+#, c-format
+msgid "'%s' expects an integer"
+msgstr ""
+
+#: py/emitinlinextensa.c:174
+#, c-format
+msgid "'%s' integer %d is not within range %d..%d"
+msgstr ""
+
+#: py/emitinlinextensa.c:182
+#, c-format
+msgid "'%s' expects a label"
+msgstr ""
+
+#: py/emitinlinextensa.c:193
+msgid "label '%q' not defined"
+msgstr ""
+
+#: py/emitinlinextensa.c:327
+#, c-format
+msgid "unsupported Xtensa instruction '%s' with %d arguments"
+msgstr ""
+
+#: py/emitnative.c:183
+msgid "unknown type '%q'"
+msgstr ""
+
+#: py/emitnative.c:260
+msgid "Viper functions don't currently support more than 4 arguments"
+msgstr ""
+
#: py/emitnative.c:742
msgid "conversion to object"
msgstr ""
+#: py/emitnative.c:921
+msgid "local '%q' used before type known"
+msgstr ""
+
+#: py/emitnative.c:1118 py/emitnative.c:1156
+msgid "can't load from '%q'"
+msgstr ""
+
+#: py/emitnative.c:1128
+msgid "can't load with '%q' index"
+msgstr ""
+
+#: py/emitnative.c:1188
+msgid "local '%q' has type '%q' but source is '%q'"
+msgstr ""
+
+#: py/emitnative.c:1289 py/emitnative.c:1379
+msgid "can't store '%q'"
+msgstr ""
+
+#: py/emitnative.c:1358 py/emitnative.c:1419
+msgid "can't store to '%q'"
+msgstr ""
+
+#: py/emitnative.c:1369
+msgid "can't store with '%q' index"
+msgstr ""
+
+#: py/emitnative.c:1540
+msgid "can't implicitly convert '%q' to 'bool'"
+msgstr ""
+
+#: py/emitnative.c:1774
+msgid "unary op %q not implemented"
+msgstr ""
+
+#: py/emitnative.c:1930
+msgid "binary op %q not implemented"
+msgstr ""
+
+#: py/emitnative.c:1951
+msgid "can't do binary op between '%q' and '%q'"
+msgstr ""
+
#: py/emitnative.c:2126
msgid "casting"
msgstr ""
+#: py/emitnative.c:2173
+msgid "return expected '%q' but got '%q'"
+msgstr ""
+
+#: py/emitnative.c:2191
+msgid "must raise an object"
+msgstr ""
+
#: py/emitnative.c:2201
msgid "native yield"
msgstr ""
@@ -617,140 +1226,140 @@ msgstr ""
msgid "expecting a dict for keyword args"
msgstr ""
-#: py/moduerrno.c:108 py/moduerrno.c:111
+#: py/moduerrno.c:143 py/moduerrno.c:146
msgid "Permission denied"
msgstr ""
-#: py/moduerrno.c:109
+#: py/moduerrno.c:144
msgid "No such file/directory"
msgstr ""
-#: py/moduerrno.c:110
+#: py/moduerrno.c:145
msgid "Input/output error"
msgstr ""
-#: py/moduerrno.c:112
+#: py/moduerrno.c:147
msgid "File exists"
msgstr ""
-#: py/moduerrno.c:113
+#: py/moduerrno.c:148
msgid "Unsupported operation"
msgstr ""
-#: py/moduerrno.c:114
+#: py/moduerrno.c:149
msgid "Invalid argument"
msgstr ""
-#: py/obj.c:89
+#: py/obj.c:90
msgid "Traceback (most recent call last):\n"
msgstr ""
-#: py/obj.c:92
+#: py/obj.c:94
msgid " File \"%q\", line %d"
msgstr ""
-#: py/obj.c:94
+#: py/obj.c:96
msgid " File \"%q\""
msgstr ""
-#: py/obj.c:101
+#: py/obj.c:100
msgid ", in %q\n"
msgstr ""
-#: py/obj.c:241
+#: py/obj.c:257
msgid "can't convert to int"
msgstr ""
-#: py/obj.c:244
+#: py/obj.c:260
#, c-format
msgid "can't convert %s to int"
msgstr ""
-#: py/obj.c:304
+#: py/obj.c:320
msgid "can't convert to float"
msgstr ""
-#: py/obj.c:307
+#: py/obj.c:323
#, c-format
msgid "can't convert %s to float"
msgstr ""
-#: py/obj.c:337
+#: py/obj.c:353
msgid "can't convert to complex"
msgstr ""
-#: py/obj.c:340
+#: py/obj.c:356
#, c-format
msgid "can't convert %s to complex"
msgstr ""
-#: py/obj.c:355
+#: py/obj.c:371
msgid "expected tuple/list"
msgstr ""
-#: py/obj.c:358
+#: py/obj.c:374
#, c-format
msgid "object '%s' is not a tuple or list"
msgstr ""
-#: py/obj.c:369
+#: py/obj.c:385
msgid "tuple/list has wrong length"
msgstr ""
-#: py/obj.c:371
+#: py/obj.c:387
#, c-format
msgid "requested length %d but object has length %d"
msgstr ""
-#: py/obj.c:384
+#: py/obj.c:400
msgid "indices must be integers"
msgstr ""
-#: py/obj.c:387
+#: py/obj.c:403
msgid "%q indices must be integers, not %s"
msgstr ""
-#: py/obj.c:407
+#: py/obj.c:423
msgid "%q index out of range"
msgstr ""
-#: py/obj.c:439
+#: py/obj.c:455
msgid "object has no len"
msgstr ""
-#: py/obj.c:442
+#: py/obj.c:458
#, c-format
msgid "object of type '%s' has no len()"
msgstr ""
-#: py/obj.c:480
+#: py/obj.c:496
msgid "object does not support item deletion"
msgstr ""
-#: py/obj.c:483
+#: py/obj.c:499
#, c-format
msgid "'%s' object does not support item deletion"
msgstr ""
-#: py/obj.c:487
+#: py/obj.c:503
msgid "object is not subscriptable"
msgstr ""
-#: py/obj.c:490
+#: py/obj.c:506
#, c-format
msgid "'%s' object is not subscriptable"
msgstr ""
-#: py/obj.c:494
+#: py/obj.c:510
msgid "object does not support item assignment"
msgstr ""
-#: py/obj.c:497
+#: py/obj.c:513
#, c-format
msgid "'%s' object does not support item assignment"
msgstr ""
-#: py/obj.c:528
+#: py/obj.c:544
msgid "object with buffer protocol required"
msgstr ""
@@ -795,7 +1404,7 @@ msgstr ""
msgid "dict update sequence has wrong length"
msgstr ""
-#: py/objfloat.c:308
+#: py/objfloat.c:308 py/parsenum.c:331
msgid "complex values not supported"
msgstr ""
@@ -1043,10 +1652,6 @@ msgstr ""
msgid "can't convert '%q' object to %q implicitly"
msgstr ""
-#: py/objstringio.c:43
-msgid "I/O operation on closed file"
-msgstr ""
-
#: py/objstrunicode.c:134
#, c-format
msgid "string indices must be integers, not %s"
@@ -1142,6 +1747,23 @@ msgstr ""
msgid "int() arg 2 must be >= 2 and <= 36"
msgstr ""
+#: py/parsenum.c:151
+msgid "invalid syntax for integer"
+msgstr ""
+
+#: py/parsenum.c:155
+#, c-format
+msgid "invalid syntax for integer with base %d"
+msgstr ""
+
+#: py/parsenum.c:339
+msgid "invalid syntax for number"
+msgstr ""
+
+#: py/parsenum.c:342
+msgid "decimal numbers not supported"
+msgstr ""
+
#: py/persistentcode.c:223
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@@ -1253,6 +1875,18 @@ msgstr ""
msgid "stream operation not supported"
msgstr ""
+#: py/vm.c:255
+msgid "local variable referenced before assignment"
+msgstr ""
+
+#: py/vm.c:1142
+msgid "no active exception to reraise"
+msgstr ""
+
+#: py/vm.c:1284
+msgid "byte code not implemented"
+msgstr ""
+
#: shared-bindings/_stage/Layer.c:71
msgid "graphic must be 2048 bytes long"
msgstr ""
@@ -1298,6 +1932,10 @@ msgstr ""
msgid "destination_length must be an int >= 0"
msgstr ""
+#: shared-bindings/audiobusio/PDMIn.c:199
+msgid "Cannot record to a file"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c:202
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -1392,6 +2030,18 @@ msgstr ""
msgid "expected a DigitalInOut"
msgstr ""
+#: shared-bindings/i2cslave/I2CSlave.c:98
+msgid "can't convert address to int"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c:101
+msgid "address out of bounds"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c:107
+msgid "addresses is empty"
+msgstr ""
+
#: shared-bindings/microcontroller/Pin.c:89
#: shared-bindings/neopixel_write/__init__.c:67
#: shared-bindings/pulseio/PulseOut.c:75
@@ -1426,6 +2076,10 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
+#: shared-bindings/os/__init__.c:200
+msgid "No hardware random available"
+msgstr ""
+
#: shared-bindings/pulseio/PWMOut.c:164
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
@@ -1546,6 +2200,14 @@ msgstr ""
msgid "Invalid file"
msgstr ""
+#: shared-module/audioio/WaveFile.c:117
+msgid "Couldn't allocate first buffer"
+msgstr ""
+
+#: shared-module/audioio/WaveFile.c:123
+msgid "Couldn't allocate second buffer"
+msgstr ""
+
#: shared-module/bitbangio/I2C.c:58
msgid "Clock stretch too long"
msgstr ""
diff --git a/locale/fr.po b/locale/fr.po
new file mode 100644
index 000000000..4438e90b5
--- /dev/null
+++ b/locale/fr.po
@@ -0,0 +1,2281 @@
+# French translation.
+# Copyright (C) 2018
+# This file is distributed under the same license as the PACKAGE package.
+# Pierrick Couturier <arofarn@arofarn.info>, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2018-08-20 09:37-0700\n"
+"PO-Revision-Date: 2018-08-14 11:01+0200\n"
+"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
+"Language-Team: fr\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: extmod/machine_i2c.c:299
+msgid "invalid I2C peripheral"
+msgstr "périphérique I2C invalide"
+
+#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368
+#: extmod/machine_i2c.c:392
+msgid "I2C operation not supported"
+msgstr "opération sur I2C non supportée"
+
+#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53
+#, c-format
+msgid "address %08x is not aligned to %d bytes"
+msgstr "l'adresse %08x n'est pas alignée sur %d octets"
+
+#: extmod/machine_spi.c:57
+msgid "invalid SPI peripheral"
+msgstr "périphérique SPI invalide"
+
+#: extmod/machine_spi.c:124
+msgid "buffers must be the same length"
+msgstr "les tampons doivent être de la même longueur"
+
+#: extmod/machine_spi.c:207
+msgid "bits must be 8"
+msgstr "les bits doivent être 8"
+
+#: extmod/machine_spi.c:210
+msgid "firstbit must be MSB"
+msgstr "le 1er bit doit être le MSB"
+
+#: extmod/machine_spi.c:215
+msgid "must specify all of sck/mosi/miso"
+msgstr "SCK, MOSI et MISO doivent tous être spécifiés"
+
+#: extmod/modframebuf.c:299
+msgid "invalid format"
+msgstr "format invalide"
+
+#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102
+msgid "a bytes-like object is required"
+msgstr "un objet 'bytes-like' est requis"
+
+#: extmod/modubinascii.c:90
+msgid "odd-length string"
+msgstr "chaîne de longueur impaire"
+
+#: extmod/modubinascii.c:101
+msgid "non-hex digit found"
+msgstr "digit non-héxadécimale trouvé"
+
+#: extmod/modubinascii.c:169
+msgid "incorrect padding"
+msgstr "espacement incorrect"
+
+#: extmod/moductypes.c:122
+msgid "syntax error in uctypes descriptor"
+msgstr "erreur de syntaxe dans le descripteur d'uctypes"
+
+#: extmod/moductypes.c:219
+msgid "Cannot unambiguously get sizeof scalar"
+msgstr "Impossible d'obtenir la taille du scalaire sans ambigüité"
+
+#: extmod/moductypes.c:397
+msgid "struct: no fields"
+msgstr "struct: aucun champs"
+
+#: extmod/moductypes.c:530
+msgid "struct: cannot index"
+msgstr "struct: indexage impossible"
+
+#: extmod/moductypes.c:544
+msgid "struct: index out of range"
+msgstr "struct: index hors limite"
+
+#: extmod/moduheapq.c:38
+msgid "heap must be a list"
+msgstr "'heap' doit être une liste"
+
+#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172
+msgid "empty heap"
+msgstr "'heap' vide"
+
+#: extmod/modujson.c:281
+msgid "syntax error in JSON"
+msgstr "erreur de syntaxe dans le JSON"
+
+#: extmod/modure.c:161
+msgid "Splitting with sub-captures"
+msgstr "Fractionnement avec des captures 'sub'"
+
+#: extmod/modure.c:207
+msgid "Error in regex"
+msgstr "Erreur dans l'expression régulière"
+
+#: extmod/modussl_axtls.c:81
+msgid "invalid key"
+msgstr "clé invalide"
+
+#: extmod/modussl_axtls.c:87
+msgid "invalid cert"
+msgstr "certificat invalide"
+
+#: extmod/modutimeq.c:131
+msgid "queue overflow"
+msgstr "dépassement de file"
+
+#: extmod/moduzlib.c:97
+msgid "compression header"
+msgstr "entête de compression"
+
+#: extmod/uos_dupterm.c:120
+msgid "invalid dupterm index"
+msgstr "index invalide pour dupterm"
+
+#: extmod/vfs_fat.c:426 py/moduerrno.c:150
+msgid "Read-only filesystem"
+msgstr "Système de fichier en lecture seule"
+
+#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43
+msgid "I/O operation on closed file"
+msgstr "opération d'E/S sur un fichier fermé"
+
+#: lib/embed/abort_.c:8
+msgid "abort() called"
+msgstr "abort() appelé"
+
+#: lib/netutils/netutils.c:83
+msgid "invalid arguments"
+msgstr "arguments invalides"
+
+#: lib/utils/pyexec.c:97 py/builtinimport.c:253
+msgid "script compilation not supported"
+msgstr "compilation du script non supporté"
+
+#: main.c:143
+msgid " output:\n"
+msgstr " sortie:\n"
+
+#: main.c:157 main.c:230
+msgid ""
+"Auto-reload is on. Simply save files over USB to run them or enter REPL to "
+"disable.\n"
+msgstr ""
+"Auto-chargement activé. Copiez simplement les fichiers en USB pour les "
+"lancer ou entrez sur REPL pour le désactiver.\n"
+
+#: main.c:159
+msgid "Running in safe mode! Auto-reload is off.\n"
+msgstr "Mode sans-échec. Auto-rechargement désactivé.\n"
+
+#: main.c:161 main.c:232
+msgid "Auto-reload is off.\n"
+msgstr "Auto-rechargement désactivé.\n"
+
+#: main.c:175
+msgid "Running in safe mode! Not running saved code.\n"
+msgstr "Mode sans-échec! Le code sauvegardé ne s'éxecute pas.\n"
+
+#: main.c:191
+msgid "WARNING: Your code filename has two extensions\n"
+msgstr "ATTENTION: le nom de fichier de votre code a deux extensions\n"
+
+#: main.c:239
+msgid "You requested starting safe mode by "
+msgstr "Vous avez demandé à démarrer en mode sans-échec par "
+
+#: main.c:242
+msgid "To exit, please reset the board without "
+msgstr "Pour quitter, redémarrez la carte SVP sans "
+
+#: main.c:249
+msgid ""
+"You are running in safe mode which means something really bad happened.\n"
+msgstr ""
+"Vous êtes en mode sans-échec ce qui signifie que quelque chose demauvais est "
+"arrivé.\n"
+
+#: main.c:251
+msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n"
+msgstr "Il semblerait que votre code CircuitPython a durement planté. Oups!\n"
+
+#: main.c:252
+msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n"
+msgstr "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n"
+
+#: main.c:255
+msgid ""
+"The microcontroller's power dipped. Please make sure your power supply "
+"provides\n"
+msgstr ""
+"L'alimentation du microcontroleur a chuté. Merci de vérifier que votre "
+"alimentation fournit\n"
+
+#: main.c:256
+msgid ""
+"enough power for the whole circuit and press reset (after ejecting "
+"CIRCUITPY).\n"
+msgstr ""
+"assez de puissance pour l'ensemble du circuit et appuyez sur 'reset' (après "
+"avoir éjecter CIRCUITPY).\n"
+
+#: main.c:260
+msgid "Press any key to enter the REPL. Use CTRL-D to reload."
+msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger."
+
+#: main.c:415
+msgid "soft reboot\n"
+msgstr "redémarrage logiciel\n"
+
+#: ports/atmel-samd/audio_dma.c:285
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361
+msgid "All sync event channels in use"
+msgstr "Tous les canaux d'événements de synchro sont utilisés"
+
+#: ports/atmel-samd/bindings/samd/Clock.c:135
+msgid "calibration is read only"
+msgstr "la calibration est en lecture seule"
+
+#: ports/atmel-samd/bindings/samd/Clock.c:137
+msgid "calibration is out of range"
+msgstr "la calibration est hors gamme"
+
+#: ports/atmel-samd/board_busses.c:39
+msgid "No default I2C bus"
+msgstr "Pas de bus I2C par défaut"
+
+#: ports/atmel-samd/board_busses.c:64
+msgid "No default SPI bus"
+msgstr "Pas de bus SPI par défaut"
+
+#: ports/atmel-samd/board_busses.c:91
+msgid "No default UART bus"
+msgstr "Pas de bus UART par défaut"
+
+#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63
+#: ports/nrf/common-hal/analogio/AnalogIn.c:39
+msgid "Pin does not have ADC capabilities"
+msgstr "la broche ne peut être utilisé pour l'ADC"
+
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49
+msgid "No DAC on chip"
+msgstr "Pas de DAC sur la puce"
+
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56
+msgid "AnalogOut not supported on given pin"
+msgstr "AnalogOut n'est pas supporté sur cette broche"
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150
+msgid "Invalid bit clock pin"
+msgstr "Broche invalide pour 'bit clock'"
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153
+msgid "Bit clock and word select must share a clock unit"
+msgstr "'bit clock' et 'word select' doivent partagé une horloge"
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130
+msgid "Invalid data pin"
+msgstr "Broche de données invalide"
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:169
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:174
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150
+msgid "Serializer in use"
+msgstr "Sérialiseur en cours d'utilisation"
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230
+msgid "Clock unit in use"
+msgstr "Horloge en cours d'utilisation"
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172
+msgid "Unable to find free GCLK"
+msgstr "Impossible de trouver un GCLK libre"
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254
+msgid "Too many channels in sample."
+msgstr "Trop de canaux dans l'échantillon."
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:326
+msgid "No DMA channel found"
+msgstr "Aucun canal DMA trouvé"
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:328
+msgid "Unable to allocate buffers for signed conversion"
+msgstr "Impossible d'allouer des tampons pour une conversion signée"
+
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:109
+msgid "Invalid clock pin"
+msgstr "Broche d'horloge invalide"
+
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134
+msgid "Only 8 or 16 bit mono with "
+msgstr "Uniquement 8 ou 16 bit mono avec "
+
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167
+msgid "sampling rate out of range"
+msgstr "taux d'échantillonage hors gamme"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69
+msgid "DAC already in use"
+msgstr "DAC déjà utilisé"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73
+msgid "Right channel unsupported"
+msgstr "Canal droit non supporté"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76
+#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c:65
+msgid "Invalid pin"
+msgstr "Broche invalide"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84
+msgid "Invalid pin for left channel"
+msgstr "Broche invalide pour le canal gauche"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88
+msgid "Invalid pin for right channel"
+msgstr "Broche invalide pour le canal droit"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91
+msgid "Cannot output both channels on the same pin"
+msgstr "On ne peut mettre les deux canaux sur la même broche"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:173
+#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:186
+#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110
+msgid "All timers in use"
+msgstr "Tous les timers sont utilisés"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c:215
+msgid "All event channels in use"
+msgstr "Tous les canaux d'événements sont utilisés"
+
+#: ports/atmel-samd/common-hal/busio/I2C.c:71
+msgid "Not enough pins available"
+msgstr "Pas assez de broches disponibles"
+
+#: ports/atmel-samd/common-hal/busio/I2C.c:78
+#: ports/atmel-samd/common-hal/busio/SPI.c:132
+#: ports/atmel-samd/common-hal/busio/UART.c:119
+#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45
+#: ports/nrf/common-hal/busio/I2C.c:58
+msgid "Invalid pins"
+msgstr "Broche invalide"
+
+#: ports/atmel-samd/common-hal/busio/I2C.c:101
+msgid "SDA or SCL needs a pull up"
+msgstr "SDA ou SCL a besoin d'une résistance de tirage ('pull up')"
+
+#: ports/atmel-samd/common-hal/busio/I2C.c:121
+msgid "Unsupported baudrate"
+msgstr "Débit non supporté"
+
+#: ports/atmel-samd/common-hal/busio/UART.c:66
+msgid "bytes > 8 bits not supported"
+msgstr "octets > 8 bits non supporté"
+
+#: ports/atmel-samd/common-hal/busio/UART.c:72
+msgid "tx and rx cannot both be None"
+msgstr "TX et RX ne peuvent être None tous les deux"
+
+#: ports/atmel-samd/common-hal/busio/UART.c:139
+msgid "Failed to allocate RX buffer"
+msgstr "Echec de l'allocation du tampon RX"
+
+#: ports/atmel-samd/common-hal/busio/UART.c:147
+msgid "Could not initialize UART"
+msgstr "L'UART n'a pu être initialisé"
+
+#: ports/atmel-samd/common-hal/busio/UART.c:234
+msgid "No RX pin"
+msgstr "Pas de broche RX"
+
+#: ports/atmel-samd/common-hal/busio/UART.c:284
+msgid "No TX pin"
+msgstr "Pas de broche TX"
+
+#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:168
+#: ports/nrf/common-hal/digitalio/DigitalInOut.c:158
+msgid "Cannot get pull while in output mode"
+msgstr "Ne peux être tirer ('pull') en mode 'output'"
+
+#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74
+#: ports/esp8266/common-hal/microcontroller/__init__.c:64
+msgid "Cannot reset into bootloader because no bootloader is present."
+msgstr ""
+"Ne peut être redémarré vers le bootloader car il n'y a pas de bootloader."
+
+#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120
+#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:366
+#: ports/nrf/common-hal/pulseio/PWMOut.c:227
+msgid "Invalid PWM frequency"
+msgstr "Fréquence de PWM invalide"
+
+#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:184
+msgid "All timers for this pin are in use"
+msgstr "Tous les timers pour cette broche sont utilisés"
+
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110
+msgid "No hardware support on pin"
+msgstr "Pas de support matériel pour cette broche"
+
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113
+msgid "EXTINT channel already in use"
+msgstr "Canal EXTINT déjà utilisé"
+
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:86
+#, c-format
+msgid "Failed to allocate RX buffer of %d bytes"
+msgstr "Echec de l'allocation de %d octets du tampon RX"
+
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:203
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:151
+msgid "pop from an empty PulseIn"
+msgstr "'pop' d'une entrée PulseIn vide"
+
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:235
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420
+msgid "index out of range"
+msgstr "index hors gamme"
+
+#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178
+msgid "Another send is already active"
+msgstr "Un autre envoi est déjà actif"
+
+#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38
+msgid "Both pins must support hardware interrupts"
+msgstr "Les deux entrées doivent supporter les interruptions"
+
+#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:46
+msgid "A hardware interrupt channel is already in use"
+msgstr "Un canal d'interruptions est déjà utilisé"
+
+#: ports/atmel-samd/common-hal/rtc/RTC.c:101
+msgid "calibration value out of range +/-127"
+msgstr "valeur de calibration hors gamme +/-127"
+
+#: ports/atmel-samd/common-hal/storage/__init__.c:48
+msgid "Cannot remount '/' when USB is active."
+msgstr "'/' ne peut être remonté quand l'USB est actif."
+
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c:75
+msgid "No free GCLKs"
+msgstr "Pas de GCLK libre"
+
+#: ports/atmel-samd/common-hal/usb_hid/Device.c:78
+#: ports/nrf/common-hal/usb_hid/Device.c:45
+#, c-format
+msgid "Buffer incorrect size. Should be %d bytes."
+msgstr "Tampon de taille incorrect. Devrait être de %d octets."
+
+#: ports/atmel-samd/common-hal/usb_hid/Device.c:82
+#: ports/nrf/common-hal/usb_hid/Device.c:53
+msgid "USB Busy"
+msgstr "USB occupé"
+
+#: ports/atmel-samd/common-hal/usb_hid/Device.c:82
+#: ports/nrf/common-hal/usb_hid/Device.c:59
+msgid "USB Error"
+msgstr "Erreur USB"
+
+#: ports/esp8266/common-hal/analogio/AnalogIn.c:43
+msgid "Pin %q does not have ADC capabilities"
+msgstr "La broche %q n'a pas de convertisseur analogique-digital"
+
+#: ports/esp8266/common-hal/analogio/AnalogOut.c:39
+msgid "No hardware support for analog out."
+msgstr "Pas de support matériel pour une sortie analogique"
+
+#: ports/esp8266/common-hal/busio/SPI.c:72
+msgid "Pins not valid for SPI"
+msgstr "Broche invalide pour le SPI"
+
+#: ports/esp8266/common-hal/busio/UART.c:45
+msgid "Only tx supported on UART1 (GPIO2)."
+msgstr "Seul le TX est supporté sur l'UART1 (GPIO2)."
+
+#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108
+msgid "invalid data bits"
+msgstr "bits de données invalides"
+
+#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144
+msgid "invalid stop bits"
+msgstr "bits d'arrêt invalides"
+
+#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200
+msgid "ESP8266 does not support pull down."
+msgstr "L'ESP8266 ne supporte pas le rappel (pull-down)"
+
+#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210
+msgid "GPIO16 does not support pull up."
+msgstr "le GPIO16 ne supporte pas le tirage (pull-up)"
+
+#: ports/esp8266/common-hal/microcontroller/__init__.c:66
+msgid "ESP8226 does not support safe mode."
+msgstr "l'ESP8266 ne supporte pas le mode sans-échec"
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:54
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:113
+#, c-format
+msgid "Maximum PWM frequency is %dhz."
+msgstr "La fréquence de PWM maximale est %dHz"
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:57
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:116
+msgid "Minimum PWM frequency is 1hz."
+msgstr "La fréquence de PWM minimale est 1Hz"
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:68
+#, c-format
+msgid "Multiple PWM frequencies not supported. PWM already set to %dhz."
+msgstr ""
+"Les fréquences multiples de PWM ne sont pas supportées. Déjà réglé à %dHz"
+
+#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70
+#, c-format
+msgid "PWM not supported on pin %d"
+msgstr "La broche %d ne supporte pas le PWM"
+
+#: ports/esp8266/common-hal/pulseio/PulseIn.c:78
+msgid "No PulseIn support for %q"
+msgstr "Pas de support de PulseIn pour %q"
+
+#: ports/esp8266/common-hal/storage/__init__.c:34
+msgid "Unable to remount filesystem"
+msgstr "Impossible de remonter le système de fichiers"
+
+#: ports/esp8266/common-hal/storage/__init__.c:38
+msgid "Use esptool to erase flash and re-upload Python instead"
+msgstr ""
+"Utilisez 'esptool' pour effacer la flash et rechargez Python à la place"
+
+#: ports/esp8266/esp_mphal.c:154
+msgid "C-level assert"
+msgstr ""
+
+#: ports/esp8266/machine_adc.c:57
+#, c-format
+msgid "not a valid ADC Channel: %d"
+msgstr "canal ADC non valide : %d"
+
+#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137
+msgid "impossible baudrate"
+msgstr "débit impossible"
+
+#: ports/esp8266/machine_pin.c:129
+msgid "expecting a pin"
+msgstr "une broche (Pin) est attendue"
+
+#: ports/esp8266/machine_pin.c:284
+msgid "Pin(16) doesn't support pull"
+msgstr "Pin(16) ne supporte pas le tirage (pull)"
+
+#: ports/esp8266/machine_pin.c:323
+msgid "invalid pin"
+msgstr "broche invalide"
+
+#: ports/esp8266/machine_pin.c:389
+msgid "pin does not have IRQ capabilities"
+msgstr "la broche n'a pas de capacité d'interruption (IRQ)"
+
+#: ports/esp8266/machine_rtc.c:185
+msgid "buffer too long"
+msgstr "tampon trop long"
+
+#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223
+#: ports/esp8266/machine_rtc.c:246
+msgid "invalid alarm"
+msgstr "alarme invalide"
+
+#: ports/esp8266/machine_uart.c:169
+#, c-format
+msgid "UART(%d) does not exist"
+msgstr "UART(%d) n'existe pas"
+
+#: ports/esp8266/machine_uart.c:219
+msgid "UART(1) can't read"
+msgstr "UART(1) ne peut pas lire"
+
+#: ports/esp8266/modesp.c:119
+msgid "len must be multiple of 4"
+msgstr "'len' doit être un multiple de 4"
+
+#: ports/esp8266/modesp.c:274
+#, c-format
+msgid "memory allocation failed, allocating %u bytes for native code"
+msgstr ""
+"l'allocation de mémoire a échoué en allouant %u octets pour un code natif"
+
+#: ports/esp8266/modesp.c:317
+msgid "flash location must be below 1MByte"
+msgstr "l'emplacement en mémoire flash doit être inférieure à 1Mo"
+
+#: ports/esp8266/modmachine.c:63
+msgid "frequency can only be either 80Mhz or 160MHz"
+msgstr "la fréquence doit être soit 80MHz soit 160MHz"
+
+#: ports/esp8266/modnetwork.c:61
+msgid "STA required"
+msgstr "'STA' requis"
+
+#: ports/esp8266/modnetwork.c:61
+msgid "AP required"
+msgstr "'AP' requis"
+
+#: ports/esp8266/modnetwork.c:87
+msgid "Cannot update i/f status"
+msgstr "le status i/f ne peut être mis à jour"
+
+#: ports/esp8266/modnetwork.c:142
+msgid "Cannot set STA config"
+msgstr "Impossible de configurer STA"
+
+#: ports/esp8266/modnetwork.c:144
+msgid "Cannot connect to AP"
+msgstr "Impossible de se connecter à 'AP'"
+
+#: ports/esp8266/modnetwork.c:152
+msgid "Cannot disconnect from AP"
+msgstr "Impossible de se déconnecter de 'AP'"
+
+#: ports/esp8266/modnetwork.c:173
+msgid "unknown status param"
+msgstr "paramètre de status inconnu"
+
+#: ports/esp8266/modnetwork.c:222
+msgid "STA must be active"
+msgstr "'STA' doit être actif"
+
+#: ports/esp8266/modnetwork.c:239
+msgid "scan failed"
+msgstr "échec du scan"
+
+#: ports/esp8266/modnetwork.c:306
+msgid "wifi_set_ip_info() failed"
+msgstr "wifi_set_ip_info() a échoué"
+
+#: ports/esp8266/modnetwork.c:319
+msgid "either pos or kw args are allowed"
+msgstr "seuls les arguments 'pos' ou 'kw' sont autorisés"
+
+#: ports/esp8266/modnetwork.c:329
+msgid "can't get STA config"
+msgstr "impossible de récupérer de la config de 'STA'"
+
+#: ports/esp8266/modnetwork.c:331
+msgid "can't get AP config"
+msgstr "impossible de récupérer de la config de 'AP'"
+
+#: ports/esp8266/modnetwork.c:346
+msgid "invalid buffer length"
+msgstr "longueur de tampon invalide"
+
+#: ports/esp8266/modnetwork.c:405
+msgid "can't set STA config"
+msgstr "impossible de régler la config de 'STA'"
+
+#: ports/esp8266/modnetwork.c:407
+msgid "can't set AP config"
+msgstr "impossible de régler la config de 'AP'"
+
+#: ports/esp8266/modnetwork.c:416
+msgid "can query only one param"
+msgstr "ne peut demander qu'un seul paramètre"
+
+#: ports/esp8266/modnetwork.c:469
+msgid "unknown config param"
+msgstr "paramètre de config. inconnu"
+
+#: ports/nrf/common-hal/analogio/AnalogOut.c:37
+msgid "AnalogOut functionality not supported"
+msgstr "AnalogOut non supporté"
+
+#: ports/nrf/common-hal/busio/UART.c:45 ports/nrf/common-hal/busio/UART.c:49
+#: ports/nrf/common-hal/busio/UART.c:53 ports/nrf/common-hal/busio/UART.c:62
+#: ports/nrf/common-hal/busio/UART.c:68 ports/nrf/common-hal/busio/UART.c:73
+#: ports/nrf/common-hal/busio/UART.c:78 ports/nrf/common-hal/busio/UART.c:83
+#: ports/nrf/common-hal/busio/UART.c:88
+msgid "busio.UART not yet implemented"
+msgstr "busio.UART pas encore implémenté"
+
+#: ports/nrf/common-hal/microcontroller/Processor.c:49
+#, c-format
+msgid "Can not get temperature. status: 0x%02x"
+msgstr "Impossible de lire la température. status: 0x%02x"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:199
+msgid "Cannot apply GAP parameters."
+msgstr "Impossible d'appliquer les paramètres GAP"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:213
+msgid "Cannot set PPCP parameters."
+msgstr "Impossible d'appliquer les paramètres PPCP"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:245
+msgid "Can not query for the device address."
+msgstr "Impossible d'obtenir l'adresse du périphérique"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:264
+msgid "Can not add Vendor Specific 128-bit UUID."
+msgstr "Impossible d'ajouter l'UUID 128bits Vendor Specific"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:284
+#: ports/nrf/drivers/bluetooth/ble_drv.c:298
+msgid "Can not add Service."
+msgstr "Impossible d'ajouter le Service"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:373
+msgid "Can not add Characteristic."
+msgstr "Impossible d'ajouter la Characteristic."
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:400
+msgid "Can not apply device name in the stack."
+msgstr "Impossible d'appliquer le nom de périphérique dans la pile"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:464
+#: ports/nrf/drivers/bluetooth/ble_drv.c:514
+msgid "Can not encode UUID, to check length."
+msgstr "Impossible d'encoder l'UUID pour vérifier la longueur."
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:470
+#: ports/nrf/drivers/bluetooth/ble_drv.c:520
+msgid "Can encode UUID into the advertisment packet."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:545
+msgid "Can not fit data into the advertisment packet."
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:558
+#: ports/nrf/drivers/bluetooth/ble_drv.c:604
+#, c-format
+msgid "Can not apply advertisment data. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:614
+#, c-format
+msgid "Can not start advertisment. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:631
+#, c-format
+msgid "Can not stop advertisment. status: 0x%02x"
+msgstr ""
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:650
+#: ports/nrf/drivers/bluetooth/ble_drv.c:726
+#, c-format
+msgid "Can not read attribute value. status: 0x%02x"
+msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:667
+#: ports/nrf/drivers/bluetooth/ble_drv.c:756
+#, c-format
+msgid "Can not write attribute value. status: 0x%02x"
+msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:691
+#, c-format
+msgid "Can not notify attribute value. status: 0x%02x"
+msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%02x"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:784
+#, c-format
+msgid "Can not start scanning. status: 0x%02x"
+msgstr "Impossible de commencer à scanner. status: 0x%02x"
+
+#: ports/nrf/drivers/bluetooth/ble_drv.c:829
+#, c-format
+msgid "Can not connect. status: 0x%02x"
+msgstr "Connection impossible. status: 0x%02x"
+
+#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:80
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:132
+#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137
+msgid "Invalid UUID parameter"
+msgstr "Paramètre UUID invalide"
+
+#: ports/nrf/modules/ubluepy/ubluepy_service.c:73
+msgid "Invalid Service type"
+msgstr "Type de service invalide"
+
+#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127
+msgid "Invalid UUID string length"
+msgstr "Longeur de chaîne UUID invalide"
+
+#: ports/unix/modffi.c:138
+msgid "Unknown type"
+msgstr "Type inconnu"
+
+#: ports/unix/modffi.c:207 ports/unix/modffi.c:265
+msgid "Error in ffi_prep_cif"
+msgstr "Erreur dans ffi_prep_cif"
+
+#: ports/unix/modffi.c:270
+msgid "ffi_prep_closure_loc"
+msgstr ""
+
+#: ports/unix/modffi.c:413
+msgid "Don't know how to pass object to native function"
+msgstr "Ne sais pas comment passer un objet à une fonction native"
+
+#: ports/unix/modusocket.c:474
+#, c-format
+msgid "[addrinfo error %d]"
+msgstr ""
+
+#: py/argcheck.c:44
+msgid "function does not take keyword arguments"
+msgstr "la fonction ne prend pas d'arguments nommés"
+
+#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104
+#, c-format
+msgid "function takes %d positional arguments but %d were given"
+msgstr "la fonction prend %d argument(s) mais %d ont été donné(s)"
+
+#: py/argcheck.c:64
+#, c-format
+msgid "function missing %d required positional arguments"
+msgstr "il manque %d arguments obligatoires à la fonction"
+
+#: py/argcheck.c:72
+#, c-format
+msgid "function expected at most %d arguments, got %d"
+msgstr "la fonction attendait au plus %d arguments, reçu %d"
+
+#: py/argcheck.c:97
+msgid "'%q' argument required"
+msgstr "'%q' argument requis"
+
+#: py/argcheck.c:122
+msgid "extra positional arguments given"
+msgstr "argument positionnel donné en plus"
+
+#: py/argcheck.c:130
+msgid "extra keyword arguments given"
+msgstr "argument nommé donné en plus"
+
+#: py/argcheck.c:142
+msgid "argument num/types mismatch"
+msgstr "argument num/types ne correspond pas"
+
+#: py/argcheck.c:147
+msgid "keyword argument(s) not yet implemented - use normal args instead"
+msgstr ""
+"argument(s) nommé(s) pas encore implémenté - utilisez les arguments normaux"
+
+#: py/bc.c:88 py/objnamedtuple.c:108
+msgid "%q() takes %d positional arguments but %d were given"
+msgstr "%q() prend %d arguments mais %d ont été donnés"
+
+#: py/bc.c:197 py/bc.c:215
+msgid "unexpected keyword argument"
+msgstr "argument nommé imprévu"
+
+#: py/bc.c:199
+msgid "keywords must be strings"
+msgstr "les noms doivent être des chaînes de caractère"
+
+#: py/bc.c:206 py/objnamedtuple.c:138
+msgid "function got multiple values for argument '%q'"
+msgstr "la fonction a reçu plusieurs valeurs pour l'argument '%q'"
+
+#: py/bc.c:218 py/objnamedtuple.c:130
+msgid "unexpected keyword argument '%q'"
+msgstr "argument nommé '%q' imprévu"
+
+#: py/bc.c:244
+#, c-format
+msgid "function missing required positional argument #%d"
+msgstr "il manque l'argument obligatoire #%d"
+
+#: py/bc.c:260
+msgid "function missing required keyword argument '%q'"
+msgstr "il manque l'argument nommé obligatoire '%q'"
+
+#: py/bc.c:269
+msgid "function missing keyword-only argument"
+msgstr "il manque l'argument nommé obligatoire"
+
+#: py/binary.c:112
+msgid "bad typecode"
+msgstr "mauvais code type"
+
+#: py/builtinevex.c:99
+msgid "bad compile mode"
+msgstr "mauvais mode de compilation"
+
+#: py/builtinimport.c:338
+msgid "cannot perform relative import"
+msgstr "ne peut pas réaliser un import relatif"
+
+#: py/builtinimport.c:422 py/builtinimport.c:534
+msgid "module not found"
+msgstr "module introuvable"
+
+#: py/builtinimport.c:425 py/builtinimport.c:537
+msgid "no module named '%q'"
+msgstr "pas de module '%q'"
+
+#: py/builtinimport.c:512
+msgid "relative import"
+msgstr "import relatif"
+
+#: py/compile.c:397 py/compile.c:542
+msgid "can't assign to expression"
+msgstr "ne peut pas assigner à l'expression"
+
+#: py/compile.c:416
+msgid "multiple *x in assignment"
+msgstr "*x multiple dans l'assignement"
+
+#: py/compile.c:642
+msgid "non-default argument follows default argument"
+msgstr "un argument sans valeur par défaut suit un argument avec défaut"
+
+#: py/compile.c:771 py/compile.c:789
+msgid "invalid micropython decorator"
+msgstr "décorateur micropython invalide"
+
+#: py/compile.c:943
+msgid "can't delete expression"
+msgstr "ne peut pas supprimer l'expression"
+
+#: py/compile.c:955
+msgid "'break' outside loop"
+msgstr "'break' en dehors d'une boucle"
+
+#: py/compile.c:958
+msgid "'continue' outside loop"
+msgstr "'continue' en dehors d'une boucle"
+
+#: py/compile.c:969
+msgid "'return' outside function"
+msgstr "'return' en dehors d'une fonction"
+
+#: py/compile.c:1169
+msgid "identifier redefined as global"
+msgstr "identifiant redéfini comme global"
+
+#: py/compile.c:1185
+msgid "no binding for nonlocal found"
+msgstr "pas de lien trouvé pour nonlocal"
+
+#: py/compile.c:1188
+msgid "identifier redefined as nonlocal"
+msgstr "identifiant redéfini comme nonlocal"
+
+#: py/compile.c:1197
+msgid "can't declare nonlocal in outer code"
+msgstr "ne peut déclarer de nonlocal dans un code externe"
+
+#: py/compile.c:1542
+msgid "default 'except' must be last"
+msgstr "l''except' par défaut doit être le dernier"
+
+#: py/compile.c:2095
+msgid "*x must be assignment target"
+msgstr "*x doit être la cible de l'assignement"
+
+#: py/compile.c:2193
+msgid "super() can't find self"
+msgstr "super() ne peut pas trouver self"
+
+#: py/compile.c:2256
+msgid "can't have multiple *x"
+msgstr "il ne peut y avoir de *x multiples"
+
+#: py/compile.c:2263
+msgid "can't have multiple **x"
+msgstr "il ne peut y avoir de **x multiples"
+
+#: py/compile.c:2271
+msgid "LHS of keyword arg must be an id"
+msgstr "La partie gauche de l'argument nommé doit être un identifiant"
+
+#: py/compile.c:2287
+msgid "non-keyword arg after */**"
+msgstr "argument non-nommé après */**"
+
+#: py/compile.c:2291
+msgid "non-keyword arg after keyword arg"
+msgstr "argument non-nommé après argument nommé"
+
+#: py/compile.c:2463 py/compile.c:2473 py/compile.c:2712 py/compile.c:2742
+#: py/parse.c:1176
+msgid "invalid syntax"
+msgstr "syntaxe invalide"
+
+#: py/compile.c:2465
+msgid "expecting key:value for dict"
+msgstr "couple clef:valeur attendu pour un objet dict"
+
+#: py/compile.c:2475
+msgid "expecting just a value for set"
+msgstr "une simple valeur est attendu pour set"
+
+#: py/compile.c:2600
+msgid "'yield' outside function"
+msgstr "'yield' en dehors d'une fonction"
+
+#: py/compile.c:2619
+msgid "'await' outside function"
+msgstr "'await' en dehors d'une fonction"
+
+#: py/compile.c:2774
+msgid "name reused for argument"
+msgstr "nom réutilisé comme argument"
+
+#: py/compile.c:2827
+msgid "parameter annotation must be an identifier"
+msgstr "l'annotation du paramètre doit être un identifiant"
+
+#: py/compile.c:2969 py/compile.c:3137
+msgid "return annotation must be an identifier"
+msgstr "l'annotation de return doit être un identifiant"
+
+#: py/compile.c:3097
+msgid "inline assembler must be a function"
+msgstr "l'assembleur en ligne doit être une fonction"
+
+#: py/compile.c:3134
+msgid "unknown type"
+msgstr "type inconnu"
+
+#: py/compile.c:3154
+msgid "expecting an assembler instruction"
+msgstr "une instruction assembleur est attendue"
+
+#: py/compile.c:3184
+msgid "'label' requires 1 argument"
+msgstr "'label' nécessite 1 argument"
+
+#: py/compile.c:3190
+msgid "label redefined"
+msgstr "label redéfini"
+
+#: py/compile.c:3196
+msgid "'align' requires 1 argument"
+msgstr "'align' nécessite 1 argument"
+
+#: py/compile.c:3205
+msgid "'data' requires at least 2 arguments"
+msgstr "'data' nécessite au moins 2 arguments"
+
+#: py/compile.c:3212
+msgid "'data' requires integer arguments"
+msgstr "'data' nécessite des arguments entiers"
+
+#: py/emitinlinextensa.c:86
+msgid "can only have up to 4 parameters to Xtensa assembly"
+msgstr ""
+
+#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96
+msgid "parameters must be registers in sequence a2 to a5"
+msgstr "les paramètres doivent être des registres dans la séquence a2 à a5"
+
+#: py/emitinlinextensa.c:162
+#, c-format
+msgid "'%s' expects a register"
+msgstr "'%s' attend un registre"
+
+#: py/emitinlinextensa.c:169
+#, c-format
+msgid "'%s' expects an integer"
+msgstr "'%s' attend un entier"
+
+#: py/emitinlinextensa.c:174
+#, c-format
+msgid "'%s' integer %d is not within range %d..%d"
+msgstr "'%s' l'entier %d n'est pas dans la gamme %d..%d"
+
+#: py/emitinlinextensa.c:182
+#, c-format
+msgid "'%s' expects a label"
+msgstr "'%s' attend un label"
+
+#: py/emitinlinextensa.c:193
+msgid "label '%q' not defined"
+msgstr "label '%q' non supporté"
+
+#: py/emitinlinextensa.c:327
+#, c-format
+msgid "unsupported Xtensa instruction '%s' with %d arguments"
+msgstr "instruction Xtensa '%s' non supportée avec %d arguments"
+
+#: py/emitnative.c:183
+msgid "unknown type '%q'"
+msgstr "type '%q' inconnu"
+
+#: py/emitnative.c:260
+msgid "Viper functions don't currently support more than 4 arguments"
+msgstr "les fonctions Viper ne supportent pas plus de 4 arguments actuellement"
+
+#: py/emitnative.c:742
+msgid "conversion to object"
+msgstr "conversion en objet"
+
+#: py/emitnative.c:921
+msgid "local '%q' used before type known"
+msgstr "'%q' local utilisé avant d'en connaitre le type"
+
+#: py/emitnative.c:1118 py/emitnative.c:1156
+msgid "can't load from '%q'"
+msgstr "impossible de charger depuis '%q'"
+
+#: py/emitnative.c:1128
+msgid "can't load with '%q' index"
+msgstr "impossible de charger avec l'index '%q'"
+
+#: py/emitnative.c:1188
+msgid "local '%q' has type '%q' but source is '%q'"
+msgstr "la variable locale '%q' a le type '%q' mais la source est '%q'"
+
+#: py/emitnative.c:1289 py/emitnative.c:1379
+msgid "can't store '%q'"
+msgstr "impossible de stocker '%q'"
+
+#: py/emitnative.c:1358 py/emitnative.c:1419
+msgid "can't store to '%q'"
+msgstr "imposible de stocker vers '%q'"
+
+#: py/emitnative.c:1369
+msgid "can't store with '%q' index"
+msgstr "impossible de stocker avec un index '%q'"
+
+#: py/emitnative.c:1540
+msgid "can't implicitly convert '%q' to 'bool'"
+msgstr "impossible de convertir implicitement '%q' en 'bool'"
+
+#: py/emitnative.c:1774
+msgid "unary op %q not implemented"
+msgstr "opération unaire '%q' non implémentée"
+
+#: py/emitnative.c:1930
+msgid "binary op %q not implemented"
+msgstr "opération binaire '%q' non implémentée"
+
+#: py/emitnative.c:1951
+msgid "can't do binary op between '%q' and '%q'"
+msgstr "opération binaire impossible entre '%q' et '%q'"
+
+#: py/emitnative.c:2126
+msgid "casting"
+msgstr "typage"
+
+#: py/emitnative.c:2173
+msgid "return expected '%q' but got '%q'"
+msgstr "return attendait '%q' mais a reçu '%q'"
+
+#: py/emitnative.c:2191
+msgid "must raise an object"
+msgstr "doit lever un objet"
+
+#: py/emitnative.c:2201
+msgid "native yield"
+msgstr "native yield"
+
+#: py/lexer.c:345
+msgid "unicode name escapes"
+msgstr "échappement pour nom unicode"
+
+#: py/modbuiltins.c:162
+msgid "chr() arg not in range(0x110000)"
+msgstr "argument de chr() hors de la gamme range(0x11000)"
+
+#: py/modbuiltins.c:171
+msgid "chr() arg not in range(256)"
+msgstr "argument de chr() hors de la gamme range(256)"
+
+#: py/modbuiltins.c:285
+msgid "arg is an empty sequence"
+msgstr "l'argument est une séquence vide"
+
+#: py/modbuiltins.c:350
+msgid "ord expects a character"
+msgstr "ord attend un caractère"
+
+#: py/modbuiltins.c:353
+#, c-format
+msgid "ord() expected a character, but string of length %d found"
+msgstr "ord() attend un caractère mais une chaîne de longueur %d a été trouvée"
+
+#: py/modbuiltins.c:363
+msgid "3-arg pow() not supported"
+msgstr "pow() avec 3 arguments non supporté"
+
+#: py/modbuiltins.c:517
+msgid "must use keyword argument for key function"
+msgstr "il faut utiliser un argument nommé pour une fonction key"
+
+#: py/modmath.c:41 shared-bindings/math/__init__.c:53
+msgid "math domain error"
+msgstr "erreur de domaine math"
+
+#: py/modmath.c:196 py/objfloat.c:270 py/objint_longlong.c:222
+#: py/objint_mpz.c:230 py/runtime.c:619 shared-bindings/math/__init__.c:346
+msgid "division by zero"
+msgstr "division par zéro"
+
+#: py/modmicropython.c:155
+msgid "schedule stack full"
+msgstr "pile de plannification pleine"
+
+#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244
+#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145
+#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175
+msgid "buffer too small"
+msgstr "tampon trop petit"
+
+#: py/modthread.c:240
+msgid "expecting a dict for keyword args"
+msgstr "un dict est attendu pour les arguments nommés"
+
+#: py/moduerrno.c:143 py/moduerrno.c:146
+msgid "Permission denied"
+msgstr "Permission refusée"
+
+#: py/moduerrno.c:144
+msgid "No such file/directory"
+msgstr "Fichier/dossier introuvable"
+
+#: py/moduerrno.c:145
+msgid "Input/output error"
+msgstr "Erreur d'entrée/sortie"
+
+#: py/moduerrno.c:147
+msgid "File exists"
+msgstr "Le fichier existe"
+
+#: py/moduerrno.c:148
+msgid "Unsupported operation"
+msgstr "Opération non supportée"
+
+#: py/moduerrno.c:149
+msgid "Invalid argument"
+msgstr "Argument invalide"
+
+#: py/obj.c:90
+msgid "Traceback (most recent call last):\n"
+msgstr "Trace (appels les plus récents en dernier):\n"
+
+#: py/obj.c:94
+msgid " File \"%q\", line %d"
+msgstr " Fichier \"%q\", ligne %d"
+
+#: py/obj.c:96
+msgid " File \"%q\""
+msgstr " Fichier \"%q\""
+
+#: py/obj.c:100
+msgid ", in %q\n"
+msgstr ", dans %q\n"
+
+#: py/obj.c:257
+msgid "can't convert to int"
+msgstr "ne peut convertir en entier int"
+
+#: py/obj.c:260
+#, c-format
+msgid "can't convert %s to int"
+msgstr "ne peut convertir %s en entier int"
+
+#: py/obj.c:320
+msgid "can't convert to float"
+msgstr "ne peut convertir en nombre à virgule flottante (float)"
+
+#: py/obj.c:323
+#, c-format
+msgid "can't convert %s to float"
+msgstr "ne peut convertir %s en nombre à virgule flottante (float)"
+
+#: py/obj.c:353
+msgid "can't convert to complex"
+msgstr "ne peut convertir en nombre complexe"
+
+#: py/obj.c:356
+#, c-format
+msgid "can't convert %s to complex"
+msgstr "ne peut convertir %s en nombre complexe"
+
+#: py/obj.c:371
+msgid "expected tuple/list"
+msgstr "un tuple ou une liste est attendu"
+
+#: py/obj.c:374
+#, c-format
+msgid "object '%s' is not a tuple or list"
+msgstr "l'objet '%s' n'est pas un tuple ou une liste"
+
+#: py/obj.c:385
+msgid "tuple/list has wrong length"
+msgstr "tuple/liste a une mauvaise longueur"
+
+#: py/obj.c:387
+#, c-format
+msgid "requested length %d but object has length %d"
+msgstr "la longueur requise est %d mais l'objet est long de %d"
+
+#: py/obj.c:400
+msgid "indices must be integers"
+msgstr "les indices doivent être des entiers"
+
+#: py/obj.c:403
+msgid "%q indices must be integers, not %s"
+msgstr "les indices %q doivent être des entiers, pas %s"
+
+#: py/obj.c:423
+msgid "%q index out of range"
+msgstr "index %q hors gamme"
+
+#: py/obj.c:455
+msgid "object has no len"
+msgstr "l'objet n'a pas de len"
+
+#: py/obj.c:458
+#, c-format
+msgid "object of type '%s' has no len()"
+msgstr "l'objet de type '%s' n'a pas de len()"
+
+#: py/obj.c:496
+msgid "object does not support item deletion"
+msgstr "l'objet ne supporte pas la suppression d'éléments"
+
+#: py/obj.c:499
+#, c-format
+msgid "'%s' object does not support item deletion"
+msgstr "l'objet '%s' ne supporte pas la suppression d'éléments"
+
+#: py/obj.c:503
+msgid "object is not subscriptable"
+msgstr "l'objet n'est pas sous-scriptable"
+
+#: py/obj.c:506
+#, c-format
+msgid "'%s' object is not subscriptable"
+msgstr "l'objet '%s' n'est pas sous-scriptable"
+
+#: py/obj.c:510
+msgid "object does not support item assignment"
+msgstr "l'objet ne supporte pas l'assignation d'éléments"
+
+#: py/obj.c:513
+#, c-format
+msgid "'%s' object does not support item assignment"
+msgstr "l'objet '%s' ne supporte pas l'assignation d'éléments"
+
+#: py/obj.c:544
+msgid "object with buffer protocol required"
+msgstr "un objet avec un protocol de tampon est nécessaire"
+
+#: py/objarray.c:413 py/objstr.c:427 py/objstrunicode.c:191 py/objtuple.c:187
+#: shared-bindings/nvm/ByteArray.c:85
+msgid "only slices with step=1 (aka None) are supported"
+msgstr "seuls les slices avec 'step=1' (cad None) sont supportées"
+
+#: py/objarray.c:426
+msgid "lhs and rhs should be compatible"
+msgstr "Les parties gauches et droites doivent être compatibles"
+
+#: py/objarray.c:444 shared-bindings/nvm/ByteArray.c:107
+msgid "array/bytes required on right side"
+msgstr "tableau/octets requis à droite"
+
+#: py/objcomplex.c:203
+msgid "can't do truncated division of a complex number"
+msgstr "on ne peut pas faire de division tronquée d'un nombre complexe"
+
+#: py/objcomplex.c:209
+msgid "complex division by zero"
+msgstr "division complexe par zéro"
+
+#: py/objcomplex.c:237
+msgid "0.0 to a complex power"
+msgstr "0.0 à une puissance complexe"
+
+#: py/objdeque.c:107
+msgid "full"
+msgstr "plein"
+
+#: py/objdeque.c:127
+msgid "empty"
+msgstr "vide"
+
+#: py/objdict.c:314
+msgid "popitem(): dictionary is empty"
+msgstr "popitem(): dictionnaire vide"
+
+#: py/objdict.c:357
+msgid "dict update sequence has wrong length"
+msgstr "la séquence de mise à jour de dict a une mauvaise longueur"
+
+#: py/objfloat.c:308 py/parsenum.c:331
+msgid "complex values not supported"
+msgstr "valeurs complexes non supportées"
+
+#: py/objgenerator.c:108
+msgid "can't send non-None value to a just-started generator"
+msgstr ""
+"on ne peut envoyer une valeur différente de None à un générateur fraîchement "
+"démarré"
+
+#: py/objgenerator.c:126
+msgid "generator already executing"
+msgstr "générateur déjà en cours d'exécution"
+
+#: py/objgenerator.c:229
+msgid "generator ignored GeneratorExit"
+msgstr "le générateur a ignoré GeneratorExit"
+
+#: py/objgenerator.c:251
+msgid "can't pend throw to just-started generator"
+msgstr ""
+
+#: py/objint.c:144
+msgid "can't convert inf to int"
+msgstr "on ne peut convertir inf en int"
+
+#: py/objint.c:146
+msgid "can't convert NaN to int"
+msgstr "on ne peut convertir NaN en int"
+
+#: py/objint.c:163
+msgid "float too big"
+msgstr "nombre flottant trop grand"
+
+#: py/objint.c:328
+msgid "long int not supported in this build"
+msgstr "entier long non supporté dans cette build"
+
+#: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358
+msgid "small int overflow"
+msgstr "dépassement de capacité d'un entier court"
+
+#: py/objint_longlong.c:189 py/objint_mpz.c:283 py/runtime.c:486
+msgid "negative power with no float support"
+msgstr "puissance négative sans support des nombres flottants"
+
+#: py/objint_longlong.c:251
+msgid "ulonglong too large"
+msgstr "ulonglong trop grand"
+
+#: py/objint_mpz.c:267 py/runtime.c:396 py/runtime.c:411
+msgid "negative shift count"
+msgstr "compte de décalage négatif"
+
+#: py/objint_mpz.c:336
+msgid "pow() with 3 arguments requires integers"
+msgstr "pow() avec 3 arguments nécessite des entiers"
+
+#: py/objint_mpz.c:347
+msgid "pow() 3rd argument cannot be 0"
+msgstr "le 3e argument de pow() ne peut être 0"
+
+#: py/objint_mpz.c:415
+msgid "overflow converting long int to machine word"
+msgstr "dépassement de capacité en convertissant un entier long en mot machine"
+
+#: py/objlist.c:273
+msgid "pop from empty list"
+msgstr "pop d'une liste vide"
+
+#: py/objnamedtuple.c:92
+msgid "can't set attribute"
+msgstr "attribut non modifiable"
+
+#: py/objobject.c:55
+msgid "__new__ arg must be a user-type"
+msgstr "l'argument __new__ doit être d'un type défini par l'utilisateur"
+
+#: py/objrange.c:110
+msgid "zero step"
+msgstr "'step' nul"
+
+#: py/objset.c:371
+msgid "pop from an empty set"
+msgstr "pop d'un ensemble set vide"
+
+#: py/objslice.c:66
+msgid "Length must be an int"
+msgstr "La longueur doit être entière"
+
+#: py/objslice.c:71
+msgid "Length must be non-negative"
+msgstr "La longueur ne doit pas être négative"
+
+#: py/objslice.c:86 py/sequence.c:57
+msgid "slice step cannot be zero"
+msgstr "le pas 'step' de slice ne peut être zéro"
+
+#: py/objslice.c:159
+msgid "Cannot subclass slice"
+msgstr "On ne peut faire de subclass de slice"
+
+#: py/objstr.c:261
+msgid "bytes value out of range"
+msgstr "valeur des octets hors gamme"
+
+#: py/objstr.c:270
+msgid "wrong number of arguments"
+msgstr "mauvais nombres d'arguments"
+
+#: py/objstr.c:467
+msgid "join expects a list of str/bytes objects consistent with self object"
+msgstr "join attend une liste d'objets str/bytes cohérent avec l'objet self"
+
+#: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744
+msgid "empty separator"
+msgstr "separateur vide"
+
+#: py/objstr.c:641
+msgid "rsplit(None,n)"
+msgstr "rsplit(None,n)"
+
+#: py/objstr.c:713
+msgid "substring not found"
+msgstr "sous-chaîne non trouvée"
+
+#: py/objstr.c:770
+msgid "start/end indices"
+msgstr "indices de début/fin"
+
+#: py/objstr.c:931
+msgid "bad format string"
+msgstr "chaîne mal-formée"
+
+#: py/objstr.c:953
+msgid "single '}' encountered in format string"
+msgstr "'}' seule rencontrée dans une chaîne de format"
+
+#: py/objstr.c:992
+msgid "bad conversion specifier"
+msgstr "mauvaise spécification de conversion"
+
+#: py/objstr.c:996
+msgid "end of format while looking for conversion specifier"
+msgstr "fin de format en cherchant une spécification de conversion"
+
+#: py/objstr.c:998
+#, c-format
+msgid "unknown conversion specifier %c"
+msgstr "spécification %c de conversion inconnue"
+
+#: py/objstr.c:1029
+msgid "unmatched '{' in format"
+msgstr "'{' sans correspondance dans le format"
+
+#: py/objstr.c:1036
+msgid "expected ':' after format specifier"
+msgstr "':' attendu après la spécification de format"
+
+#: py/objstr.c:1050
+msgid ""
+"can't switch from automatic field numbering to manual field specification"
+msgstr ""
+"impossible de passer d'une énumération auto des champs à une spécification "
+"manuelle"
+
+#: py/objstr.c:1055 py/objstr.c:1083
+msgid "tuple index out of range"
+msgstr "index du tuple hors gamme"
+
+#: py/objstr.c:1071
+msgid "attributes not supported yet"
+msgstr "attribut pas encore supporté"
+
+#: py/objstr.c:1079
+msgid ""
+"can't switch from manual field specification to automatic field numbering"
+msgstr ""
+"impossible de passer d'une spécification manuelle des champs à une "
+"énumération auto"
+
+#: py/objstr.c:1171
+msgid "invalid format specifier"
+msgstr "spécificationde format invalide"
+
+#: py/objstr.c:1192
+msgid "sign not allowed in string format specifier"
+msgstr "signe non autorisé dans les spéc. de formats de chaînes de caractères"
+
+#: py/objstr.c:1200
+msgid "sign not allowed with integer format specifier 'c'"
+msgstr "signe non autorisé avec la spéc. de format d'entier 'c'"
+
+#: py/objstr.c:1259
+#, c-format
+msgid "unknown format code '%c' for object of type '%s'"
+msgstr "code de format '%c' inconnu pour un objet de type '%s'"
+
+#: py/objstr.c:1331
+#, c-format
+msgid "unknown format code '%c' for object of type 'float'"
+msgstr "code de format '%c' inconnu pour un objet de type 'float'"
+
+#: py/objstr.c:1343
+msgid "'=' alignment not allowed in string format specifier"
+msgstr "'=' alignement non autorisé dans la spéc. de format de chaîne"
+
+#: py/objstr.c:1367
+#, c-format
+msgid "unknown format code '%c' for object of type 'str'"
+msgstr "code de format '%c' inconnu pour un objet de type 'str'"
+
+#: py/objstr.c:1415
+msgid "format requires a dict"
+msgstr "le format nécessite un dict"
+
+#: py/objstr.c:1424
+msgid "incomplete format key"
+msgstr "clé de format incomplète"
+
+#: py/objstr.c:1482
+msgid "incomplete format"
+msgstr "format incomplet"
+
+#: py/objstr.c:1490
+msgid "not enough arguments for format string"
+msgstr "pas assez d'argument pour la chaîne de format"
+
+#: py/objstr.c:1500
+#, c-format
+msgid "%%c requires int or char"
+msgstr "%%c nécessite un entier int ou un caractère char"
+
+#: py/objstr.c:1507
+msgid "integer required"
+msgstr "entier requis"
+
+#: py/objstr.c:1570
+#, c-format
+msgid "unsupported format character '%c' (0x%x) at index %d"
+msgstr "caractère de format '%c' (0x%x) non supporté à l'index %d"
+
+#: py/objstr.c:1577
+msgid "not all arguments converted during string formatting"
+msgstr ""
+"tous les arguments n'ont pas été convertis pendant le formatage de la chaîne"
+
+#: py/objstr.c:2102
+msgid "can't convert to str implicitly"
+msgstr "impossible de convertir en str implicitement"
+
+#: py/objstr.c:2106
+msgid "can't convert '%q' object to %q implicitly"
+msgstr "impossible de convertir l'objet '%q' en '%q' implicitement"
+
+#: py/objstrunicode.c:134
+#, c-format
+msgid "string indices must be integers, not %s"
+msgstr "les indices de chaîne de caractère doivent être des entiers, pas %s"
+
+#: py/objstrunicode.c:145 py/objstrunicode.c:164
+msgid "string index out of range"
+msgstr "index de chaîne hors gamme"
+
+#: py/objtype.c:358
+msgid "__init__() should return None"
+msgstr "__init__() doit retourner None"
+
+#: py/objtype.c:360
+#, c-format
+msgid "__init__() should return None, not '%s'"
+msgstr "__init__() doit retourner None, pas '%s'"
+
+#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065
+msgid "unreadable attribute"
+msgstr "attribut illisible"
+
+#: py/objtype.c:868 py/runtime.c:653
+msgid "object not callable"
+msgstr "objet non appelable"
+
+#: py/objtype.c:870 py/runtime.c:655
+#, c-format
+msgid "'%s' object is not callable"
+msgstr "objet '%s' non appelable"
+
+#: py/objtype.c:978
+msgid "type takes 1 or 3 arguments"
+msgstr "le type prend 1 ou 3 arguments"
+
+#: py/objtype.c:989
+msgid "cannot create instance"
+msgstr "ne peut pas créer une instance"
+
+#: py/objtype.c:991
+msgid "cannot create '%q' instances"
+msgstr "ne peut pas créer une instance de '%q'"
+
+#: py/objtype.c:1047
+msgid "can't add special method to already-subclassed class"
+msgstr ""
+"impossible d'ajouter une méthode spécial à une classe déjà sous-classée"
+
+#: py/objtype.c:1091 py/objtype.c:1097
+msgid "type is not an acceptable base type"
+msgstr "le type n'est pas un type de base accepté"
+
+#: py/objtype.c:1100
+msgid "type '%q' is not an acceptable base type"
+msgstr "le type '%q' n'est pas un type de base accepté"
+
+#: py/objtype.c:1137
+msgid "multiple inheritance not supported"
+msgstr "héritage multiple non supporté"
+
+#: py/objtype.c:1164
+msgid "multiple bases have instance lay-out conflict"
+msgstr "de multiple bases ont un conflit de lay-out d'instance"
+
+#: py/objtype.c:1205
+msgid "first argument to super() must be type"
+msgstr "le premier argument de super() doit être un type"
+
+#: py/objtype.c:1370
+msgid "issubclass() arg 2 must be a class or a tuple of classes"
+msgstr ""
+"l'argument 2 de issubclass() doit être une classe ou un tuple de classes"
+
+#: py/objtype.c:1384
+msgid "issubclass() arg 1 must be a class"
+msgstr "l'argument 1 de issubclass() doit être une classe"
+
+#: py/parse.c:726
+msgid "constant must be an integer"
+msgstr "les constantes doivent être des entiers"
+
+#: py/parse.c:868
+msgid "Unable to init parser"
+msgstr "Impossible d'initialiser le parser"
+
+#: py/parse.c:1170
+msgid "unexpected indent"
+msgstr "indentation inattendue"
+
+#: py/parse.c:1173
+msgid "unindent does not match any outer indentation level"
+msgstr "la désindentation ne correspond à aucune indentation"
+
+#: py/parsenum.c:60
+msgid "int() arg 2 must be >= 2 and <= 36"
+msgstr "l'argument 2 de int() doit être >=2 et <=32"
+
+#: py/parsenum.c:151
+msgid "invalid syntax for integer"
+msgstr "syntaxe invalide pour un entier"
+
+#: py/parsenum.c:155
+#, c-format
+msgid "invalid syntax for integer with base %d"
+msgstr "syntaxe invalide pour un entier de base %d"
+
+#: py/parsenum.c:339
+msgid "invalid syntax for number"
+msgstr "syntaxe invalide pour un nombre"
+
+#: py/parsenum.c:342
+msgid "decimal numbers not supported"
+msgstr "nombres décimaux non supportés"
+
+#: py/persistentcode.c:223
+msgid ""
+"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
+"mpy-update for more info."
+msgstr ""
+"Fichier .mpy incompatible. Merci de mettre à jour tous les .mpy. Voir http://"
+"adafru.it/mpy-update pour plus d'informations."
+
+#: py/persistentcode.c:326
+msgid "can only save bytecode"
+msgstr "ne peut sauvegarder que du bytecode"
+
+#: py/runtime.c:206
+msgid "name not defined"
+msgstr "nom non défini"
+
+#: py/runtime.c:209
+msgid "name '%q' is not defined"
+msgstr "nom '%q' non défini"
+
+#: py/runtime.c:304 py/runtime.c:611
+msgid "unsupported type for operator"
+msgstr "type non supporté pour l'opérateur"
+
+#: py/runtime.c:307
+msgid "unsupported type for %q: '%s'"
+msgstr "type non supporté pour %q: '%s'"
+
+#: py/runtime.c:614
+msgid "unsupported types for %q: '%s', '%s'"
+msgstr "type non supporté pour %q: '%s', '%s'"
+
+#: py/runtime.c:881 py/runtime.c:888 py/runtime.c:945
+msgid "wrong number of values to unpack"
+msgstr "mauvais nombre de valeurs à dégrouper"
+
+#: py/runtime.c:883 py/runtime.c:947
+#, c-format
+msgid "need more than %d values to unpack"
+msgstr "nécessite plus de %d valeur à dégrouper"
+
+#: py/runtime.c:890
+#, c-format
+msgid "too many values to unpack (expected %d)"
+msgstr "trop de valeur à dégrouper (%d attendues)"
+
+#: py/runtime.c:984
+msgid "argument has wrong type"
+msgstr "l'argument est d'un mauvais type"
+
+#: py/runtime.c:986
+msgid "argument should be a '%q' not a '%q'"
+msgstr "l'argument devrait être un(e) '%q', pas '%q'"
+
+#: py/runtime.c:1123 py/runtime.c:1197
+msgid "no such attribute"
+msgstr "pas de tel attribut"
+
+#: py/runtime.c:1128
+msgid "type object '%q' has no attribute '%q'"
+msgstr "l'objet de type '%q' n'a pas d'attribut '%q'"
+
+#: py/runtime.c:1132 py/runtime.c:1200
+msgid "'%s' object has no attribute '%q'"
+msgstr "l'objet '%s' n'a pas d'attribut '%q'"
+
+#: py/runtime.c:1238
+msgid "object not iterable"
+msgstr "objet non itérable"
+
+#: py/runtime.c:1241
+#, c-format
+msgid "'%s' object is not iterable"
+msgstr "objet '%s' non itérable"
+
+#: py/runtime.c:1260 py/runtime.c:1296
+msgid "object not an iterator"
+msgstr "l'objet n'est pas un itérateur"
+
+#: py/runtime.c:1262 py/runtime.c:1298
+#, c-format
+msgid "'%s' object is not an iterator"
+msgstr "l'objet '%s' n'est pas un itérateur"
+
+#: py/runtime.c:1401
+msgid "exceptions must derive from BaseException"
+msgstr "les exception doivent dériver de BaseException"
+
+#: py/runtime.c:1430
+msgid "cannot import name %q"
+msgstr "ne peut pas importer le nom %q"
+
+#: py/runtime.c:1535
+msgid "memory allocation failed, heap is locked"
+msgstr "l'allocation de mémoire a échoué, la pile est vérrouillé"
+
+#: py/runtime.c:1539
+#, c-format
+msgid "memory allocation failed, allocating %u bytes"
+msgstr "l'allocation de mémoire a échoué en allouant %u octets"
+
+#: py/runtime.c:1609
+msgid "maximum recursion depth exceeded"
+msgstr "profondeur maximale de récursivité dépassée"
+
+#: py/sequence.c:264
+msgid "object not in sequence"
+msgstr "l'objet n'est pas dans la séquence"
+
+#: py/stream.c:96
+msgid "stream operation not supported"
+msgstr "opération de flux non supportée"
+
+#: py/vm.c:255
+msgid "local variable referenced before assignment"
+msgstr "variable locale référencée avant d'être assignée"
+
+#: py/vm.c:1142
+msgid "no active exception to reraise"
+msgstr "aucune exception active a relevé"
+
+#: py/vm.c:1284
+msgid "byte code not implemented"
+msgstr "bytecode non implémenté"
+
+#: shared-bindings/_stage/Layer.c:71
+msgid "graphic must be 2048 bytes long"
+msgstr "le graphic doit être long de 2048 octets"
+
+#: shared-bindings/_stage/Layer.c:77 shared-bindings/_stage/Text.c:75
+msgid "palette must be 32 bytes long"
+msgstr "la palette doit être longue de 32 octets"
+
+#: shared-bindings/_stage/Layer.c:84
+msgid "map buffer too small"
+msgstr "tampon trop petit"
+
+#: shared-bindings/_stage/Text.c:69
+msgid "font must be 2048 bytes long"
+msgstr "la fonte doit être longue de 2048 octets"
+
+#: shared-bindings/_stage/Text.c:81
+msgid "chars buffer too small"
+msgstr "tampon de caractères trop petit"
+
+#: shared-bindings/analogio/AnalogOut.c:118
+msgid "AnalogOut is only 16 bits. Value must be less than 65536."
+msgstr ""
+"AnalogOut est seulement 16 bits. Les valeurs doivent être inférieures à "
+"65536."
+
+#: shared-bindings/audiobusio/I2SOut.c:225
+#: shared-bindings/audioio/AudioOut.c:223
+msgid "Not playing"
+msgstr "En pause"
+
+#: shared-bindings/audiobusio/PDMIn.c:124
+msgid "Bit depth must be multiple of 8."
+msgstr "La profondeur de bit doit être un multiple de 8."
+
+#: shared-bindings/audiobusio/PDMIn.c:128
+msgid "Oversample must be multiple of 8."
+msgstr "Le sur-échantillonage doit être un multiple de 8."
+
+#: shared-bindings/audiobusio/PDMIn.c:136
+msgid "Microphone startup delay must be in range 0.0 to 1.0"
+msgstr "Le délais au démarrage du micro doit être entre 0.0 et 1.0"
+
+#: shared-bindings/audiobusio/PDMIn.c:193
+msgid "destination_length must be an int >= 0"
+msgstr "destination_length doit être un int >= 0"
+
+#: shared-bindings/audiobusio/PDMIn.c:199
+msgid "Cannot record to a file"
+msgstr "impossible d'enregistrer vers un fichier"
+
+#: shared-bindings/audiobusio/PDMIn.c:202
+msgid "Destination capacity is smaller than destination_length."
+msgstr "La capacité de la cible est plus petite que destination_length."
+
+#: shared-bindings/audiobusio/PDMIn.c:206
+msgid "destination buffer must be an array of type 'H' for bit_depth = 16"
+msgstr ""
+"le tampon de destination doit être un tableau de type 'H' pour bit_depth = 16"
+
+#: shared-bindings/audiobusio/PDMIn.c:208
+msgid ""
+"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
+msgstr ""
+"le tampon de destination doit être un tableau de type 'B' pour bit_depth = 8"
+
+#: shared-bindings/audioio/RawSample.c:98
+msgid ""
+"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
+"'B'"
+msgstr ""
+"le tampon de sample_source doit être un bytearray ou un tableau de type "
+"'h','H', 'b' ou 'B'"
+
+#: shared-bindings/audioio/RawSample.c:104
+msgid "buffer must be a bytes-like object"
+msgstr "le tampon doit être un objet bytes-like"
+
+#: shared-bindings/audioio/WaveFile.c:78
+msgid "file must be a file opened in byte mode"
+msgstr "le fichier doit être un fichier ouvert en mode byte"
+
+#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121
+#: shared-bindings/busio/SPI.c:133
+msgid "Function requires lock"
+msgstr "La fonction nécessite un verrou"
+
+#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210
+msgid "Buffer must be at least length 1"
+msgstr "Le tampon doit être de longueur au moins 1"
+
+#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168
+msgid "Invalid polarity"
+msgstr "Polarité invalide"
+
+#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172
+msgid "Invalid phase"
+msgstr "Phase invalide"
+
+#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176
+msgid "Invalid number of bits"
+msgstr "Nombre de bits invalide"
+
+#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341
+msgid "buffer slices must be of equal length"
+msgstr "les slices de tampon doivent être de longueurs égales"
+
+#: shared-bindings/busio/I2C.c:120
+msgid "Function requires lock."
+msgstr "La fonction nécessite un verrou."
+
+#: shared-bindings/busio/UART.c:98
+msgid "bits must be 7, 8 or 9"
+msgstr "bits doivent être 7, 8 ou 9"
+
+#: shared-bindings/busio/UART.c:110
+msgid "stop must be 1 or 2"
+msgstr "stop doit être 1 ou 2"
+
+#: shared-bindings/digitalio/DigitalInOut.c:211
+msgid "Invalid direction."
+msgstr "Direction invalide"
+
+#: shared-bindings/digitalio/DigitalInOut.c:240
+msgid "Cannot set value when direction is input."
+msgstr "Impossible d'affecter une valeur quand la direction est input."
+
+#: shared-bindings/digitalio/DigitalInOut.c:266
+#: shared-bindings/digitalio/DigitalInOut.c:281
+msgid "Drive mode not used when direction is input."
+msgstr "Le mode Drive n'est pas utilisé quand la direction est 'input'"
+
+#: shared-bindings/digitalio/DigitalInOut.c:314
+#: shared-bindings/digitalio/DigitalInOut.c:331
+msgid "Pull not used when direction is output."
+msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'"
+
+#: shared-bindings/digitalio/DigitalInOut.c:340
+msgid "Unsupported pull value."
+msgstr "Valeur de 'pull' non supportée"
+
+#: shared-bindings/gamepad/GamePad.c:100
+msgid "too many arguments"
+msgstr "trop d'arguments"
+
+#: shared-bindings/gamepad/GamePad.c:104
+msgid "expected a DigitalInOut"
+msgstr "un objet DigitalInOut attendu"
+
+#: shared-bindings/i2cslave/I2CSlave.c:98
+#, fuzzy
+msgid "can't convert address to int"
+msgstr "ne peut convertir %s en entier int"
+
+#: shared-bindings/i2cslave/I2CSlave.c:101
+msgid "address out of bounds"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c:107
+msgid "addresses is empty"
+msgstr ""
+
+#: shared-bindings/microcontroller/Pin.c:89
+#: shared-bindings/neopixel_write/__init__.c:67
+#: shared-bindings/pulseio/PulseOut.c:75
+msgid "Expected a %q"
+msgstr "Attendu : %q"
+
+#: shared-bindings/microcontroller/Pin.c:100
+msgid "%q in use"
+msgstr "%q utilisé"
+
+#: shared-bindings/microcontroller/__init__.c:126
+msgid "Invalid run mode."
+msgstr "Mode de lancement invalide"
+
+#: shared-bindings/multiterminal/__init__.c:68
+msgid "Stream missing readinto() or write() method."
+msgstr "Il manque une méthode readinto() ou write() au flux."
+
+#: shared-bindings/nvm/ByteArray.c:99
+msgid "Slice and value different lengths."
+msgstr "Slice et valeur de tailles différentes"
+
+#: shared-bindings/nvm/ByteArray.c:104
+msgid "Array values should be single bytes."
+msgstr "Les valeurs du tableau doivent être des octets simples 'bytes'"
+
+#: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141
+msgid "Unable to write to nvm."
+msgstr "Impossible d'écrire sur la nvm"
+
+#: shared-bindings/nvm/ByteArray.c:137
+msgid "Bytes must be between 0 and 255."
+msgstr "Les octets 'bytes' doivent être entre 0 et 255"
+
+#: shared-bindings/os/__init__.c:200
+msgid "No hardware random available"
+msgstr "Pas de source matérielle d'aléa disponible"
+
+#: shared-bindings/pulseio/PWMOut.c:164
+msgid ""
+"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
+msgstr ""
+"La valeur de cycle PWM doit être entre 0 et 65535 inclus (résolution de 16 "
+"bits)"
+
+#: shared-bindings/pulseio/PWMOut.c:195
+msgid ""
+"PWM frequency not writeable when variable_frequency is False on construction."
+msgstr ""
+"La fréquence de PWM n'est pas modifiable quand variable_frequency est False "
+"à laconstruction."
+
+#: shared-bindings/pulseio/PulseIn.c:275
+msgid "Cannot delete values"
+msgstr "Impossible de supprimer les valeurs"
+
+#: shared-bindings/pulseio/PulseIn.c:281
+msgid "Slices not supported"
+msgstr "Slices non supportées"
+
+#: shared-bindings/pulseio/PulseIn.c:287
+msgid "index must be int"
+msgstr "l'index doit être un entier"
+
+#: shared-bindings/pulseio/PulseIn.c:293
+msgid "Read-only"
+msgstr "Lecture seule"
+
+#: shared-bindings/pulseio/PulseOut.c:134
+msgid "Array must contain halfwords (type 'H')"
+msgstr "Le tableau doit contenir des halfwords (type 'H')"
+
+#: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100
+msgid "stop not reachable from start"
+msgstr "stop n'est pas accessible de start"
+
+#: shared-bindings/random/__init__.c:111
+msgid "step must be non-zero"
+msgstr "le pas 'step' doit être non nul"
+
+#: shared-bindings/random/__init__.c:114
+msgid "invalid step"
+msgstr "pas invalide"
+
+#: shared-bindings/random/__init__.c:146
+msgid "empty sequence"
+msgstr "séquence vide"
+
+#: shared-bindings/rtc/RTC.c:40 shared-bindings/rtc/RTC.c:44
+#: shared-bindings/time/__init__.c:192
+msgid "RTC is not supported on this board"
+msgstr "RTC non supportée sur cette carte"
+
+#: shared-bindings/rtc/RTC.c:52
+msgid "RTC calibration is not supported on this board"
+msgstr "calibration de la RTC non supportée sur cette carte"
+
+#: shared-bindings/storage/__init__.c:77
+msgid "filesystem must provide mount method"
+msgstr "le system de fichier doit fournir une méthode 'mount'"
+
+#: shared-bindings/supervisor/__init__.c:93
+msgid "Brightness must be between 0 and 255"
+msgstr "La luminosité doit être entre 0 et 255"
+
+#: shared-bindings/supervisor/__init__.c:119
+msgid "Stack size must be at least 256"
+msgstr "La pile doit être au moins de 256"
+
+#: shared-bindings/time/__init__.c:80
+msgid "sleep length must be non-negative"
+msgstr "la longueur de sleep ne doit pas être négative"
+
+#: shared-bindings/time/__init__.c:90
+msgid "time.struct_time() takes exactly 1 argument"
+msgstr "time.struct_time() prend exactement 1 argument"
+
+#: shared-bindings/time/__init__.c:93
+msgid "time.struct_time() takes a 9-sequence"
+msgstr "time.struct_time() prend une séquence de longueur 9"
+
+#: shared-bindings/time/__init__.c:171 shared-bindings/time/__init__.c:252
+msgid "Tuple or struct_time argument required"
+msgstr "Argument de type tuple ou struct_time nécessaire"
+
+#: shared-bindings/time/__init__.c:176 shared-bindings/time/__init__.c:257
+msgid "function takes exactly 9 arguments"
+msgstr "la fonction prend exactement 9 arguments"
+
+#: shared-bindings/time/__init__.c:228 shared-bindings/time/__init__.c:261
+msgid "timestamp out of range for platform time_t"
+msgstr "timestamp hors gamme pour la plateforme time_t"
+
+#: shared-bindings/touchio/TouchIn.c:173
+msgid "threshold must be in the range 0-65536"
+msgstr "le seuil doit être dans la gamme 0-65536"
+
+#: shared-bindings/util.c:38
+msgid ""
+"Object has been deinitialized and can no longer be used. Create a new object."
+msgstr ""
+"L'objet a été désinitialisé et ne peut plus être utilisé. Créez un nouvel "
+"objet."
+
+#: shared-module/audioio/WaveFile.c:61
+msgid "Invalid wave file"
+msgstr "Fichier WAVE invalide"
+
+#: shared-module/audioio/WaveFile.c:69
+msgid "Invalid format chunk size"
+msgstr "Taille de bloc de formatage invalide"
+
+#: shared-module/audioio/WaveFile.c:83
+msgid "Unsupported format"
+msgstr "Format non supporté"
+
+#: shared-module/audioio/WaveFile.c:99
+msgid "Data chunk must follow fmt chunk"
+msgstr "Un bloc de données doit suivre un bloc de format"
+
+#: shared-module/audioio/WaveFile.c:107
+msgid "Invalid file"
+msgstr "Fichier invalide"
+
+#: shared-module/audioio/WaveFile.c:117
+msgid "Couldn't allocate first buffer"
+msgstr "Impossible d'allouer le 1er tampon"
+
+#: shared-module/audioio/WaveFile.c:123
+msgid "Couldn't allocate second buffer"
+msgstr "Impossible d'allouer le 2e tampon"
+
+#: shared-module/bitbangio/I2C.c:58
+msgid "Clock stretch too long"
+msgstr "Période de l'horloge trop longue"
+
+#: shared-module/bitbangio/SPI.c:45
+msgid "Clock pin init failed."
+msgstr "Echec de l'init. de la broche d'horloge"
+
+#: shared-module/bitbangio/SPI.c:51
+msgid "MOSI pin init failed."
+msgstr "Echec de l'init. de la broche MOSI"
+
+#: shared-module/bitbangio/SPI.c:62
+msgid "MISO pin init failed."
+msgstr "Echec de l'init. de la broche MISO"
+
+#: shared-module/bitbangio/SPI.c:122
+msgid "Cannot write without MOSI pin."
+msgstr "Impossible d'écrire sans broche MOSI."
+
+#: shared-module/bitbangio/SPI.c:177
+msgid "Cannot read without MISO pin."
+msgstr "Impossible de lire sans broche MISO."
+
+#: shared-module/bitbangio/SPI.c:241
+msgid "Cannot transfer without MOSI and MISO pins."
+msgstr "Pas de transfert sans broches MOSI et MISO"
+
+#: shared-module/struct/__init__.c:39
+msgid "'S' and 'O' are not supported format types"
+msgstr "'S' et 'O' ne sont pas des types de format supportés"
+
+#: shared-module/struct/__init__.c:83
+msgid "too many arguments provided with the given format"
+msgstr "trop d'arguments fournis avec ce format"
diff --git a/main.c b/main.c
index 4bc9c279f..61d10bc08 100755
--- a/main.c
+++ b/main.c
@@ -128,13 +128,22 @@ const char* first_existing_file_in_list(const char ** filenames) {
return NULL;
}
+void write_compressed(const compressed_string_t* compressed) {
+ char decompressed[compressed->length];
+ decompress(compressed, decompressed);
+ serial_write(decompressed);
+}
+
bool maybe_run_list(const char ** filenames, pyexec_result_t* exec_result) {
const char* filename = first_existing_file_in_list(filenames);
if (filename == NULL) {
return false;
}
mp_hal_stdout_tx_str(filename);
- mp_hal_stdout_tx_str(translate(" output:\n"));
+ const compressed_string_t* compressed = translate(" output:\n");
+ char decompressed[compressed->length];
+ decompress(compressed, decompressed);
+ mp_hal_stdout_tx_str(decompressed);
pyexec_file(filename, exec_result);
return true;
}
@@ -145,11 +154,11 @@ bool run_code_py(safe_mode_t safe_mode) {
if (serial_connected_at_start) {
serial_write("\n");
if (autoreload_is_enabled()) {
- serial_write(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n"));
+ write_compressed(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n"));
} else if (safe_mode != NO_SAFE_MODE) {
- serial_write(translate("Running in safe mode! Auto-reload is off.\n"));
+ write_compressed(translate("Running in safe mode! Auto-reload is off.\n"));
} else if (!autoreload_is_enabled()) {
- serial_write(translate("Auto-reload is off.\n"));
+ write_compressed(translate("Auto-reload is off.\n"));
}
}
#endif
@@ -163,7 +172,7 @@ bool run_code_py(safe_mode_t safe_mode) {
bool found_main = false;
if (safe_mode != NO_SAFE_MODE) {
- serial_write(translate("Running in safe mode! Not running saved code.\n"));
+ write_compressed(translate("Running in safe mode! Not running saved code.\n"));
} else {
new_status_color(MAIN_RUNNING);
@@ -179,7 +188,7 @@ bool run_code_py(safe_mode_t safe_mode) {
if (!found_main){
found_main = maybe_run_list(double_extension_filenames, &result);
if (found_main) {
- serial_write(translate("WARNING: Your code filename has two extensions\n"));
+ write_compressed(translate("WARNING: Your code filename has two extensions\n"));
}
}
stop_mp();
@@ -218,37 +227,37 @@ bool run_code_py(safe_mode_t safe_mode) {
if (!serial_connected_at_start) {
if (autoreload_is_enabled()) {
- serial_write(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n"));
+ write_compressed(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n"));
} else {
- serial_write(translate("Auto-reload is off.\n"));
+ write_compressed(translate("Auto-reload is off.\n"));
}
}
// Output a user safe mode string if its set.
#ifdef BOARD_USER_SAFE_MODE
if (safe_mode == USER_SAFE_MODE) {
serial_write("\n");
- serial_write(translate("You requested starting safe mode by "));
+ write_compressed(translate("You requested starting safe mode by "));
serial_write(BOARD_USER_SAFE_MODE_ACTION);
serial_write("\n");
- serial_write(translate("To exit, please reset the board without "));
+ write_compressed(translate("To exit, please reset the board without "));
serial_write(BOARD_USER_SAFE_MODE_ACTION);
serial_write("\n");
} else
#endif
if (safe_mode != NO_SAFE_MODE) {
serial_write("\n");
- serial_write(translate("You are running in safe mode which means something really bad happened.\n"));
+ write_compressed(translate("You are running in safe mode which means something really bad happened.\n"));
if (safe_mode == HARD_CRASH) {
- serial_write(translate("Looks like our core CircuitPython code crashed hard. Whoops!\n"));
- serial_write(translate("Please file an issue here with the contents of your CIRCUITPY drive:\n"));
+ write_compressed(translate("Looks like our core CircuitPython code crashed hard. Whoops!\n"));
+ write_compressed(translate("Please file an issue here with the contents of your CIRCUITPY drive:\n"));
serial_write("https://github.com/adafruit/circuitpython/issues\n");
} else if (safe_mode == BROWNOUT) {
- serial_write(translate("The microcontroller's power dipped. Please make sure your power supply provides\n"));
- serial_write(translate("enough power for the whole circuit and press reset (after ejecting CIRCUITPY).\n"));
+ write_compressed(translate("The microcontroller's power dipped. Please make sure your power supply provides\n"));
+ write_compressed(translate("enough power for the whole circuit and press reset (after ejecting CIRCUITPY).\n"));
}
}
serial_write("\n");
- serial_write(translate("Press any key to enter the REPL. Use CTRL-D to reload."));
+ write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload."));
}
if (serial_connected_before_animation && !serial_connected()) {
serial_connected_at_start = false;
@@ -403,7 +412,7 @@ int __attribute__((used)) main(void) {
}
if (exit_code == PYEXEC_FORCED_EXIT) {
if (!first_run) {
- serial_write(translate("soft reboot\n"));
+ write_compressed(translate("soft reboot\n"));
}
first_run = false;
skip_repl = run_code_py(safe_mode);
diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile
index 20f3ea46c..e1634a1b9 100755..100644
--- a/ports/atmel-samd/Makefile
+++ b/ports/atmel-samd/Makefile
@@ -308,6 +308,8 @@ SRC_COMMON_HAL = \
busio/UART.c \
digitalio/__init__.c \
digitalio/DigitalInOut.c \
+ i2cslave/__init__.c \
+ i2cslave/I2CSlave.c \
microcontroller/__init__.c \
microcontroller/Pin.c \
microcontroller/Processor.c \
diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c
index 0cd931c2e..45d698c17 100644
--- a/ports/atmel-samd/audio_dma.c
+++ b/ports/atmel-samd/audio_dma.c
@@ -33,6 +33,7 @@
#include "shared-bindings/audioio/WaveFile.h"
#include "py/mpstate.h"
+#include "py/runtime.h"
static audio_dma_t* audio_dma_state[AUDIO_DMA_CHANNEL_COUNT];
@@ -279,6 +280,10 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma,
// We're likely double buffering so set up the block interrupts.
turn_on_event_system();
dma->event_channel = find_sync_event_channel();
+
+ if (dma->event_channel >= EVSYS_SYNCH_NUM) {
+ mp_raise_RuntimeError(translate("All sync event channels in use"));
+ }
init_event_channel_interrupt(dma->event_channel, CORE_GCLK, EVSYS_ID_GEN_DMAC_CH_0 + dma_channel);
// We keep the audio_dma_t for internal use and the sample as a root pointer because it
diff --git a/ports/atmel-samd/bindings/samd/Clock.c b/ports/atmel-samd/bindings/samd/Clock.c
index 28eb7949f..be597c444 100644
--- a/ports/atmel-samd/bindings/samd/Clock.c
+++ b/ports/atmel-samd/bindings/samd/Clock.c
@@ -132,9 +132,9 @@ STATIC mp_obj_t samd_clock_set_calibration(mp_obj_t self_in, mp_obj_t calibratio
samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in);
int ret = clock_set_calibration(self->type, self->index, mp_obj_get_int(calibration));
if (ret == -2)
- mp_raise_AttributeError("calibration is read only");
+ mp_raise_AttributeError(translate("calibration is read only"));
if (ret == -1)
- mp_raise_ValueError("calibration is out of range");
+ mp_raise_ValueError(translate("calibration is out of range"));
return mp_const_none;
}
diff --git a/ports/atmel-samd/board_busses.c b/ports/atmel-samd/board_busses.c
index 4bf1a40fa..e36541ca9 100644
--- a/ports/atmel-samd/board_busses.c
+++ b/ports/atmel-samd/board_busses.c
@@ -29,13 +29,14 @@
#include "shared-bindings/busio/UART.h"
#include "shared-bindings/microcontroller/Pin.h"
+#include "supervisor/shared/translate.h"
#include "mpconfigboard.h"
#include "samd/pins.h"
#include "py/runtime.h"
#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)
STATIC mp_obj_t board_i2c(void) {
- mp_raise_NotImplementedError("No default I2C bus");
+ mp_raise_NotImplementedError(translate("No default I2C bus"));
return NULL;
}
#else
@@ -60,7 +61,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c);
#if !defined(DEFAULT_SPI_BUS_SCK) || !defined(DEFAULT_SPI_BUS_MISO) || !defined(DEFAULT_SPI_BUS_MOSI)
STATIC mp_obj_t board_spi(void) {
- mp_raise_NotImplementedError("No default SPI bus");
+ mp_raise_NotImplementedError(translate("No default SPI bus"));
return NULL;
}
#else
@@ -87,7 +88,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);
#if !defined(DEFAULT_UART_BUS_RX) || !defined(DEFAULT_UART_BUS_TX)
STATIC mp_obj_t board_uart(void) {
- mp_raise_NotImplementedError("No default UART bus");
+ mp_raise_NotImplementedError(translate("No default UART bus"));
return NULL;
}
#else
diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
index 108d67d9f..03d0ba9bd 100644
--- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
@@ -62,3 +62,5 @@
// USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1
+
+#define CIRCUITPY_I2CSLAVE
diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h
index c82395baf..e9e921b4d 100644
--- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h
@@ -47,3 +47,5 @@
// USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1
+
+#define CIRCUITPY_I2CSLAVE
diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h
index 618fbfbe9..34e9ac327 100644
--- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h
@@ -43,7 +43,7 @@
#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES W25Q64JV_IM, \
+#define EXTERNAL_FLASH_DEVICES W25Q64JV_IQ, \
GD25Q64C
#include "external_flash/external_flash.h"
diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
index 135d6ae92..40ef3ce78 100644
--- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
@@ -63,3 +63,5 @@
// USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1
+
+#define CIRCUITPY_I2CSLAVE
diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
index 050f678dd..f1201c8a0 100644
--- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
@@ -48,3 +48,5 @@
// USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1
+
+#define CIRCUITPY_I2CSLAVE
diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c
index 4e50e2827..9be8c3936 100644
--- a/ports/atmel-samd/common-hal/analogio/AnalogOut.c
+++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -46,7 +46,7 @@
void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
const mcu_pin_obj_t *pin) {
#if defined(SAMD21) && !defined(PIN_PA02)
- mp_raise_NotImplementedError("No DAC on chip");
+ mp_raise_NotImplementedError(translate("No DAC on chip"));
#else
if (pin->number != PIN_PA02
#ifdef SAMD51
diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
index 90fbeb9e8..0adc3fb52 100644
--- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
@@ -357,6 +357,9 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
uint16_t* output_buffer, uint32_t output_buffer_length) {
uint8_t dma_channel = find_free_audio_dma_channel();
uint8_t event_channel = find_sync_event_channel();
+ if (event_channel >= EVSYS_SYNCH_NUM) {
+ mp_raise_RuntimeError(translate("All sync event channels in use"));
+ }
// We allocate two buffers on the stack to use for double buffering.
const uint8_t samples_per_buffer = SAMPLES_PER_BUFFER;
diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c
index bef19b2cc..7df328a6a 100644
--- a/ports/atmel-samd/common-hal/audioio/AudioOut.c
+++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c
@@ -211,6 +211,10 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self,
// Find a free event channel. We start at the highest channels because we only need and async
// path.
uint8_t channel = find_async_event_channel();
+ if (channel >= EVSYS_CHANNELS) {
+ mp_raise_RuntimeError(translate("All event channels in use"));
+ }
+
#ifdef SAMD51
connect_event_user_to_channel(EVSYS_ID_USER_DAC_START_1, channel);
#define EVSYS_ID_USER_DAC_START EVSYS_ID_USER_DAC_START_0
diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c
index 8bfa8ddd2..c0643865d 100644
--- a/ports/atmel-samd/common-hal/busio/I2C.c
+++ b/ports/atmel-samd/common-hal/busio/I2C.c
@@ -39,39 +39,41 @@
// Number of times to try to send packet if failed.
#define ATTEMPTS 2
-void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
- const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency, uint32_t timeout) {
- #ifdef PIRKEY_M0
- mp_raise_NotImplementedError(translate("Not enough pins available"));
- return;
- #endif
- Sercom* sercom = NULL;
- uint8_t sercom_index;
- uint32_t sda_pinmux = 0;
- uint32_t scl_pinmux = 0;
+Sercom *samd_i2c_get_sercom(const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda,
+ uint8_t *sercom_index, uint32_t *sda_pinmux, uint32_t *scl_pinmux) {
+ *sda_pinmux = 0;
+ *scl_pinmux = 0;
for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) {
- sercom_index = sda->sercom[i].index;
- if (sercom_index >= SERCOM_INST_NUM) {
+ *sercom_index = sda->sercom[i].index;
+ if (*sercom_index >= SERCOM_INST_NUM) {
continue;
}
- Sercom* potential_sercom = sercom_insts[sercom_index];
+ Sercom* potential_sercom = sercom_insts[*sercom_index];
if (potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 ||
sda->sercom[i].pad != 0) {
continue;
}
- sda_pinmux = PINMUX(sda->number, (i == 0) ? MUX_C : MUX_D);
+ *sda_pinmux = PINMUX(sda->number, (i == 0) ? MUX_C : MUX_D);
for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) {
- if (sercom_index == scl->sercom[j].index &&
+ if (*sercom_index == scl->sercom[j].index &&
scl->sercom[j].pad == 1) {
- scl_pinmux = PINMUX(scl->number, (j == 0) ? MUX_C : MUX_D);
- sercom = potential_sercom;
- break;
+ *scl_pinmux = PINMUX(scl->number, (j == 0) ? MUX_C : MUX_D);
+ return potential_sercom;
}
}
- if (sercom != NULL) {
- break;
- }
}
+ return NULL;
+}
+
+void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
+ const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency, uint32_t timeout) {
+ #ifdef PIRKEY_M0
+ mp_raise_NotImplementedError(translate("Not enough pins available"));
+ return;
+ #endif
+ uint8_t sercom_index;
+ uint32_t sda_pinmux, scl_pinmux;
+ Sercom* sercom = samd_i2c_get_sercom(scl, sda, &sercom_index, &sda_pinmux, &scl_pinmux);
if (sercom == NULL) {
mp_raise_ValueError(translate("Invalid pins"));
}
diff --git a/ports/atmel-samd/common-hal/busio/I2C.h b/ports/atmel-samd/common-hal/busio/I2C.h
index 2401d9247..366c6c469 100644
--- a/ports/atmel-samd/common-hal/busio/I2C.h
+++ b/ports/atmel-samd/common-hal/busio/I2C.h
@@ -41,4 +41,7 @@ typedef struct {
uint8_t sda_pin;
} busio_i2c_obj_t;
+extern Sercom *samd_i2c_get_sercom(const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda,
+ uint8_t *sercom_index, uint32_t *sda_pinmux, uint32_t *scl_pinmux);
+
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_H
diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c
index b372a2f92..fd7f81cc2 100644
--- a/ports/atmel-samd/common-hal/busio/SPI.c
+++ b/ports/atmel-samd/common-hal/busio/SPI.c
@@ -129,7 +129,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
}
#endif
if (sercom == NULL) {
- mp_raise_ValueError("Invalid pins");
+ mp_raise_ValueError(translate("Invalid pins"));
}
// Set up SPI clocks on SERCOM.
diff --git a/ports/atmel-samd/common-hal/i2cslave/I2CSlave.c b/ports/atmel-samd/common-hal/i2cslave/I2CSlave.c
new file mode 100644
index 000000000..f0bbed3d7
--- /dev/null
+++ b/ports/atmel-samd/common-hal/i2cslave/I2CSlave.c
@@ -0,0 +1,252 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Noralf Trønnes
+ *
+ * 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 "shared-bindings/i2cslave/I2CSlave.h"
+#include "common-hal/busio/I2C.h"
+
+#include "lib/utils/interrupt_char.h"
+#include "py/mperrno.h"
+#include "py/mphal.h"
+#include "py/runtime.h"
+
+#include "hal/include/hal_gpio.h"
+#include "peripherals/samd/sercom.h"
+
+void common_hal_i2cslave_i2c_slave_construct(i2cslave_i2c_slave_obj_t *self,
+ const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda,
+ uint8_t *addresses, unsigned int num_addresses, bool smbus) {
+ uint8_t sercom_index;
+ uint32_t sda_pinmux, scl_pinmux;
+ Sercom *sercom = samd_i2c_get_sercom(scl, sda, &sercom_index, &sda_pinmux, &scl_pinmux);
+ if (sercom == NULL) {
+ mp_raise_ValueError(translate("Invalid pins"));
+ }
+ self->sercom = sercom;
+
+ gpio_set_pin_function(sda->number, GPIO_PIN_FUNCTION_OFF);
+ gpio_set_pin_function(scl->number, GPIO_PIN_FUNCTION_OFF);
+ gpio_set_pin_function(sda->number, sda_pinmux);
+ gpio_set_pin_function(scl->number, scl_pinmux);
+
+ self->sda_pin = sda->number;
+ self->scl_pin = scl->number;
+ claim_pin(sda);
+ claim_pin(scl);
+
+ samd_peripherals_sercom_clock_init(sercom, sercom_index);
+
+ sercom->I2CS.CTRLA.bit.SWRST = 1;
+ while (sercom->I2CS.CTRLA.bit.SWRST || sercom->I2CS.SYNCBUSY.bit.SWRST) {}
+
+ sercom->I2CS.CTRLB.bit.AACKEN = 0; // Automatic acknowledge is disabled.
+
+ if (num_addresses == 1) {
+ sercom->I2CS.CTRLB.bit.AMODE = 0x0; // MASK
+ sercom->I2CS.ADDR.bit.ADDR = addresses[0];
+ sercom->I2CS.ADDR.bit.ADDRMASK = 0x00; // Match exact address
+ } else if (num_addresses == 2) {
+ sercom->I2CS.CTRLB.bit.AMODE = 0x1; // 2_ADDRS
+ sercom->I2CS.ADDR.bit.ADDR = addresses[0];
+ sercom->I2CS.ADDR.bit.ADDRMASK = addresses[1];
+ } else {
+ uint32_t combined = 0; // all addresses OR'ed
+ uint32_t differ = 0; // bits that differ between addresses
+ for (unsigned int i = 0; i < num_addresses; i++) {
+ combined |= addresses[i];
+ differ |= addresses[0] ^ addresses[i];
+ }
+ sercom->I2CS.CTRLB.bit.AMODE = 0x0; // MASK
+ sercom->I2CS.ADDR.bit.ADDR = combined;
+ sercom->I2CS.ADDR.bit.ADDRMASK = differ;
+ }
+ self->addresses = addresses;
+ self->num_addresses = num_addresses;
+
+ if (smbus) {
+ sercom->I2CS.CTRLA.bit.LOWTOUTEN = 1; // Errata 12003
+ sercom->I2CS.CTRLA.bit.SEXTTOEN = 1; // Slave SCL Low Extend/Cumulative Time-Out 25ms
+ }
+ sercom->I2CS.CTRLA.bit.SCLSM = 0; // Clock stretch before ack
+ sercom->I2CS.CTRLA.bit.MODE = 0x04; // Slave mode
+ sercom->I2CS.CTRLA.bit.ENABLE = 1;
+}
+
+bool common_hal_i2cslave_i2c_slave_deinited(i2cslave_i2c_slave_obj_t *self) {
+ return self->sda_pin == NO_PIN;
+}
+
+void common_hal_i2cslave_i2c_slave_deinit(i2cslave_i2c_slave_obj_t *self) {
+ if (common_hal_i2cslave_i2c_slave_deinited(self)) {
+ return;
+ }
+
+ self->sercom->I2CS.CTRLA.bit.ENABLE = 0;
+
+ reset_pin(self->sda_pin);
+ reset_pin(self->scl_pin);
+ self->sda_pin = NO_PIN;
+ self->scl_pin = NO_PIN;
+}
+
+static int i2c_slave_check_error(i2cslave_i2c_slave_obj_t *self, bool raise) {
+ if (!self->sercom->I2CS.INTFLAG.bit.ERROR) {
+ return 0;
+ }
+
+ int err = MP_EIO;
+
+ if (self->sercom->I2CS.STATUS.bit.LOWTOUT || self->sercom->I2CS.STATUS.bit.SEXTTOUT) {
+ err = MP_ETIMEDOUT;
+ }
+
+ self->sercom->I2CS.INTFLAG.reg = SERCOM_I2CS_INTFLAG_ERROR; // Clear flag
+
+ if (raise) {
+ mp_raise_OSError(err);
+ }
+ return -err;
+}
+
+int common_hal_i2cslave_i2c_slave_is_addressed(i2cslave_i2c_slave_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart)
+{
+ int err = i2c_slave_check_error(self, false);
+ if (err) {
+ return err;
+ }
+
+ if (!self->sercom->I2CS.INTFLAG.bit.AMATCH) {
+ return 0;
+ }
+
+ self->writing = false;
+
+ *address = self->sercom->I2CS.DATA.reg >> 1;
+ *is_read = self->sercom->I2CS.STATUS.bit.DIR;
+ *is_restart = self->sercom->I2CS.STATUS.bit.SR;
+
+ for (unsigned int i = 0; i < self->num_addresses; i++) {
+ if (*address == self->addresses[i]) {
+ common_hal_i2cslave_i2c_slave_ack(self, true);
+ return 1;
+ }
+ }
+
+ // This should clear AMATCH, but it doesn't...
+ common_hal_i2cslave_i2c_slave_ack(self, false);
+ return 0;
+}
+
+int common_hal_i2cslave_i2c_slave_read_byte(i2cslave_i2c_slave_obj_t *self, uint8_t *data) {
+ for (int t = 0; t < 100 && !self->sercom->I2CS.INTFLAG.reg; t++) {
+ mp_hal_delay_us(10);
+ }
+
+ i2c_slave_check_error(self, true);
+
+ if (!self->sercom->I2CS.INTFLAG.bit.DRDY ||
+ self->sercom->I2CS.INTFLAG.bit.PREC ||
+ self->sercom->I2CS.INTFLAG.bit.AMATCH) {
+ return 0;
+ }
+
+ *data = self->sercom->I2CS.DATA.reg;
+ return 1;
+}
+
+int common_hal_i2cslave_i2c_slave_write_byte(i2cslave_i2c_slave_obj_t *self, uint8_t data) {
+ for (int t = 0; !self->sercom->I2CS.INTFLAG.reg && t < 100; t++) {
+ mp_hal_delay_us(10);
+ }
+
+ i2c_slave_check_error(self, true);
+
+ if (self->sercom->I2CS.INTFLAG.bit.PREC) {
+ return 0;
+ }
+
+ // RXNACK can carry over from the previous transfer
+ if (self->writing && self->sercom->I2CS.STATUS.bit.RXNACK) {
+ return 0;
+ }
+
+ self->writing = true;
+
+ if (!self->sercom->I2CS.INTFLAG.bit.DRDY) {
+ return 0;
+ }
+
+ self->sercom->I2CS.DATA.bit.DATA = data; // Send data
+
+ return 1;
+}
+
+void common_hal_i2cslave_i2c_slave_ack(i2cslave_i2c_slave_obj_t *self, bool ack) {
+ self->sercom->I2CS.CTRLB.bit.ACKACT = !ack;
+ self->sercom->I2CS.CTRLB.bit.CMD = 0x03;
+}
+
+void common_hal_i2cslave_i2c_slave_close(i2cslave_i2c_slave_obj_t *self) {
+ for (int t = 0; !self->sercom->I2CS.INTFLAG.reg && t < 100; t++) {
+ mp_hal_delay_us(10);
+ }
+
+ if (self->sercom->I2CS.INTFLAG.bit.AMATCH || !self->sercom->I2CS.STATUS.bit.CLKHOLD) {
+ return;
+ }
+
+ if (!self->sercom->I2CS.STATUS.bit.DIR) {
+ common_hal_i2cslave_i2c_slave_ack(self, false);
+ } else {
+ int i = 0;
+ while (self->sercom->I2CS.INTFLAG.reg == SERCOM_I2CS_INTFLAG_DRDY) {
+ if (mp_hal_is_interrupted()) {
+ return;
+ }
+
+ self->sercom->I2CS.DATA.bit.DATA = 0xff; // Send dummy byte
+
+ // Wait for a result (if any).
+ // test_byte_word.py::TestWord::test_write_seq leaves us with no INTFLAGs set in some of the tests
+ for (int t = 0; !self->sercom->I2CS.INTFLAG.reg && t < 100; t++) {
+ mp_hal_delay_us(10);
+ }
+
+ if (++i > 1000) { // Avoid getting stuck "forever"
+ mp_raise_OSError(MP_EIO);
+ }
+ }
+ }
+
+ if (self->sercom->I2CS.INTFLAG.bit.AMATCH) {
+ return;
+ }
+
+ if (self->sercom->I2CS.STATUS.bit.CLKHOLD) {
+ // Unable to release the clock.
+ // The slave might have to be re-initialized to get unstuck.
+ mp_raise_OSError(MP_EIO);
+ }
+}
diff --git a/ports/atmel-samd/common-hal/i2cslave/I2CSlave.h b/ports/atmel-samd/common-hal/i2cslave/I2CSlave.h
new file mode 100644
index 000000000..bf4f877bd
--- /dev/null
+++ b/ports/atmel-samd/common-hal/i2cslave/I2CSlave.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Noralf Trønnes
+ *
+ * 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.
+ */
+
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_SLAVE_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_SLAVE_H
+
+#include "common-hal/microcontroller/Pin.h"
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+
+ uint8_t *addresses;
+ unsigned int num_addresses;
+
+ Sercom *sercom;
+ uint8_t scl_pin;
+ uint8_t sda_pin;
+ bool writing;
+} i2cslave_i2c_slave_obj_t;
+
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_SLAVE_H
diff --git a/ports/atmel-samd/common-hal/i2cslave/__init__.c b/ports/atmel-samd/common-hal/i2cslave/__init__.c
new file mode 100644
index 000000000..f289bbc0e
--- /dev/null
+++ b/ports/atmel-samd/common-hal/i2cslave/__init__.c
@@ -0,0 +1 @@
+// No i2cslave module functions.
diff --git a/ports/atmel-samd/external_flash/devices.h b/ports/atmel-samd/external_flash/devices.h
index 330d3e3b6..87df83676 100644
--- a/ports/atmel-samd/external_flash/devices.h
+++ b/ports/atmel-samd/external_flash/devices.h
@@ -217,6 +217,22 @@ typedef struct {
.supports_qspi_writes = true, \
}
+// Settings for the Winbond W25Q64JV-IQ 8MiB SPI flash. Note that JV-IM has a different .memory_type (0x70)
+// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf
+#define W25Q64JV_IQ {\
+ .total_size = (1 << 23), /* 8 MiB */ \
+ .start_up_time_us = 5000, \
+ .manufacturer_id = 0xef, \
+ .memory_type = 0x40, \
+ .capacity = 0x17, \
+ .max_clock_speed_mhz = 133, \
+ .has_sector_protection = false, \
+ .supports_fast_read = true, \
+ .supports_qspi = true, \
+ .has_quad_enable = true, \
+ .supports_qspi_writes = true, \
+}
+
// Settings for the Winbond W25Q80DL 1MiB SPI flash.
// Datasheet: https://www.winbond.com/resource-files/w25q80dv%20dl_revh_10022015.pdf
#define W25Q80DL {\
diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h
index 8b921c2a9..576325461 100644
--- a/ports/atmel-samd/mpconfigport.h
+++ b/ports/atmel-samd/mpconfigport.h
@@ -174,6 +174,7 @@ extern const struct _mp_obj_module_t digitalio_module;
extern const struct _mp_obj_module_t pulseio_module;
extern const struct _mp_obj_module_t busio_module;
extern const struct _mp_obj_module_t board_module;
+extern const struct _mp_obj_module_t i2cslave_module;
extern const struct _mp_obj_module_t math_module;
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t random_module;
@@ -225,11 +226,18 @@ extern const struct _mp_obj_module_t usb_hid_module;
#define AUDIOIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module },
#endif
+ #ifdef CIRCUITPY_I2CSLAVE
+ #define I2CSLAVE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_i2cslave), (mp_obj_t)&i2cslave_module },
+ #else
+ #define I2CSLAVE_MODULE
+ #endif
+
#ifndef EXTRA_BUILTIN_MODULES
#define EXTRA_BUILTIN_MODULES \
AUDIOIO_MODULE \
AUDIOBUSIO_MODULE \
{ MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \
+ I2CSLAVE_MODULE \
{ MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }
#endif
diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals
-Subproject 1140ff6d7ed413aa1e2f34c5d847dcc41c924bb
+Subproject 156279784cb3d22f7f8a8d93b4bb55e2d912a5f
diff --git a/ports/esp8266/common-hal/analogio/AnalogIn.c b/ports/esp8266/common-hal/analogio/AnalogIn.c
index e01eceabd..63580c07c 100644
--- a/ports/esp8266/common-hal/analogio/AnalogIn.c
+++ b/ports/esp8266/common-hal/analogio/AnalogIn.c
@@ -33,13 +33,14 @@
#include "py/mphal.h"
#include "common-hal/microcontroller/__init__.h"
#include "shared-bindings/analogio/AnalogIn.h"
+#include "supervisor/shared/translate.h"
#include "user_interface.h"
void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self,
const mcu_pin_obj_t *pin) {
if (pin != &pin_TOUT) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Pin %q does not have ADC capabilities", pin->name));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("Pin %q does not have ADC capabilities"), pin->name));
}
claim_pin(pin);
}
diff --git a/ports/esp8266/common-hal/analogio/AnalogOut.c b/ports/esp8266/common-hal/analogio/AnalogOut.c
index 15e9ee277..b01d8edb8 100644
--- a/ports/esp8266/common-hal/analogio/AnalogOut.c
+++ b/ports/esp8266/common-hal/analogio/AnalogOut.c
@@ -24,18 +24,19 @@
* THE SOFTWARE.
*/
+#include "shared-bindings/analogio/AnalogOut.h"
+
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "py/runtime.h"
-
-#include "shared-bindings/analogio/AnalogOut.h"
+#include "supervisor/shared/translate.h"
void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
const mcu_pin_obj_t *pin) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
- "No hardware support for analog out."));
+ translate("No hardware support for analog out.")));
}
bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) {
diff --git a/ports/esp8266/common-hal/busio/SPI.c b/ports/esp8266/common-hal/busio/SPI.c
index e1eeecc2a..d00997820 100644
--- a/ports/esp8266/common-hal/busio/SPI.c
+++ b/ports/esp8266/common-hal/busio/SPI.c
@@ -27,6 +27,7 @@
#include "shared-bindings/microcontroller/__init__.h"
#include "common-hal/busio/SPI.h"
#include "py/nlr.h"
+#include "supervisor/shared/translate.h"
#include "eagle_soc.h"
#include "ets_alt_task.h"
@@ -68,7 +69,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
(mosi == MP_OBJ_TO_PTR(mp_const_none) && miso == &pin_MTDI) ||
(mosi == &pin_MTCK && miso == &pin_MTDI))) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Pins not valid for SPI"));
+ translate("Pins not valid for SPI")));
}
busio_spi_init_gpio(SPI_CLK_USE_DIV, clock, mosi, miso);
diff --git a/ports/esp8266/common-hal/busio/UART.c b/ports/esp8266/common-hal/busio/UART.c
index 5540e3573..7a4ca6e0d 100644
--- a/ports/esp8266/common-hal/busio/UART.c
+++ b/ports/esp8266/common-hal/busio/UART.c
@@ -27,6 +27,7 @@
#include "common-hal/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/busio/UART.h"
+#include "supervisor/shared/translate.h"
#include "ets_sys.h"
#include "uart.h"
@@ -41,7 +42,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout,
uint8_t receiver_buffer_size) {
if (rx != mp_const_none || tx != &pin_GPIO2) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Only tx supported on UART1 (GPIO2)."));
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("Only tx supported on UART1 (GPIO2).")));
}
// set baudrate
@@ -63,7 +64,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
UartDev.data_bits = UART_EIGHT_BITS;
break;
default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid data bits"));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("invalid data bits")));
break;
}
@@ -87,7 +88,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
UartDev.stop_bits = UART_TWO_STOP_BIT;
break;
default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid stop bits"));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("invalid stop bits")));
break;
}
diff --git a/ports/esp8266/common-hal/digitalio/DigitalInOut.c b/ports/esp8266/common-hal/digitalio/DigitalInOut.c
index 96945737b..80584bb5f 100644
--- a/ports/esp8266/common-hal/digitalio/DigitalInOut.c
+++ b/ports/esp8266/common-hal/digitalio/DigitalInOut.c
@@ -33,6 +33,7 @@
#include "py/mphal.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "supervisor/shared/translate.h"
#include "common-hal/microcontroller/Pin.h"
extern volatile bool gpio16_in_use;
@@ -45,9 +46,9 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct(
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); //mux configuration for out enable
WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & ~1); //out disable
claim_pin(pin);
- } else {
+ } else {
PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function);
- }
+ }
return DIGITALINOUT_OK;
}
@@ -196,7 +197,7 @@ void common_hal_digitalio_digitalinout_set_pull(
digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) {
if (pull == PULL_DOWN) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
- "ESP8266 does not support pull down."));
+ translate("ESP8266 does not support pull down.")));
return;
}
if (self->pin->gpio_number == 16) {
@@ -206,7 +207,7 @@ void common_hal_digitalio_digitalinout_set_pull(
// raise the exception so the user knows PULL_UP is not available
if (pull != PULL_NONE){
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
- "GPIO16 does not support pull up."));
+ translate("GPIO16 does not support pull up.")));
}
return;
}
diff --git a/ports/esp8266/common-hal/microcontroller/__init__.c b/ports/esp8266/common-hal/microcontroller/__init__.c
index 6d446ceac..de9288a77 100644
--- a/ports/esp8266/common-hal/microcontroller/__init__.c
+++ b/ports/esp8266/common-hal/microcontroller/__init__.c
@@ -32,6 +32,7 @@
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/Processor.h"
+#include "supervisor/shared/translate.h"
#include "eagle_soc.h"
#include "ets_alt_task.h"
@@ -60,9 +61,9 @@ void common_hal_mcu_enable_interrupts() {
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
if (runmode == RUNMODE_BOOTLOADER) {
- mp_raise_ValueError("Cannot reset into bootloader because no bootloader is present.");
+ mp_raise_ValueError(translate("Cannot reset into bootloader because no bootloader is present."));
} else if (runmode == RUNMODE_SAFE_MODE) {
- mp_raise_ValueError("ESP8226 does not support safe mode.");
+ mp_raise_ValueError(translate("ESP8226 does not support safe mode."));
}
}
diff --git a/ports/esp8266/common-hal/pulseio/PWMOut.c b/ports/esp8266/common-hal/pulseio/PWMOut.c
index 9cc869794..f3a7bbc5a 100644
--- a/ports/esp8266/common-hal/pulseio/PWMOut.c
+++ b/ports/esp8266/common-hal/pulseio/PWMOut.c
@@ -31,6 +31,7 @@
#include "py/runtime.h"
#include "shared-bindings/pulseio/PWMOut.h"
+#include "supervisor/shared/translate.h"
#include "eagle_soc.h"
#include "c_types.h"
@@ -50,10 +51,10 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_p
bool variable_frequency) {
if (frequency > PWM_FREQ_MAX) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Maximum PWM frequency is %dhz.", PWM_FREQ_MAX));
+ translate("Maximum PWM frequency is %dhz."), PWM_FREQ_MAX));
} else if (frequency < 1) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
- "Minimum PWM frequency is 1hz."));
+ translate("Minimum PWM frequency is 1hz.")));
}
// start the PWM subsystem if it's not already running
@@ -64,7 +65,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_p
first_channel_variable = variable_frequency;
} else if (first_channel_variable || pwm_get_freq(0) != frequency) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Multiple PWM frequencies not supported. PWM already set to %dhz.", pwm_get_freq(0)));
+ translate("Multiple PWM frequencies not supported. PWM already set to %dhz."), pwm_get_freq(0)));
}
self->channel = pwm_add(pin->gpio_number,
@@ -73,7 +74,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_p
self->pin = pin;
if (self->channel == -1) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "PWM not supported on pin %d", pin->gpio_number));
+ translate("PWM not supported on pin %d"), pin->gpio_number));
}
}
@@ -109,10 +110,10 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) {
if (frequency > PWM_FREQ_MAX) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Maximum PWM frequency is %dhz.", PWM_FREQ_MAX));
+ translate("Maximum PWM frequency is %dhz."), PWM_FREQ_MAX));
} else if (frequency < 1) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
- "Minimum PWM frequency is 1hz."));
+ translate("Minimum PWM frequency is 1hz.")));
}
pwm_set_freq(frequency, 0);
}
diff --git a/ports/esp8266/common-hal/pulseio/PulseIn.c b/ports/esp8266/common-hal/pulseio/PulseIn.c
index 9720eaad5..40ba39e5f 100644
--- a/ports/esp8266/common-hal/pulseio/PulseIn.c
+++ b/ports/esp8266/common-hal/pulseio/PulseIn.c
@@ -35,6 +35,7 @@
#include "py/runtime.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/pulseio/PulseIn.h"
+#include "supervisor/shared/translate.h"
#include "common-hal/microcontroller/__init__.h"
static void pulsein_set_interrupt(pulseio_pulsein_obj_t *self, bool rising, bool falling) {
@@ -74,7 +75,7 @@ void pulseio_pulsein_interrupt_handler(void *data) {
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
if (pin->gpio_number == NO_GPIO || pin->gpio_function == SPECIAL_CASE) {
- mp_raise_msg_varg(&mp_type_ValueError, "No PulseIn support for %q", pin->name );
+ mp_raise_msg_varg(&mp_type_ValueError, translate("No PulseIn support for %q"), pin->name );
}
PIN_FUNC_SELECT(pin->peripheral, pin->gpio_function);
PIN_PULLUP_DIS(pin->peripheral);
@@ -82,7 +83,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false);
if (self->buffer == NULL) {
- mp_raise_msg_varg(&mp_type_MemoryError, "Failed to allocate RX buffer of %d bytes", maxlen * sizeof(uint16_t));
+ mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t));
}
self->maxlen = maxlen;
@@ -147,7 +148,7 @@ void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
if (self->len == 0) {
- mp_raise_IndexError("pop from an empty PulseIn");
+ mp_raise_IndexError(translate("pop from an empty PulseIn"));
}
common_hal_mcu_disable_interrupts();
uint16_t value = self->buffer[self->start];
@@ -178,7 +179,7 @@ uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self,
}
if (index < 0 || index >= self->len) {
common_hal_mcu_enable_interrupts();
- mp_raise_IndexError("index out of range");
+ mp_raise_IndexError(translate("index out of range"));
}
uint16_t value = self->buffer[(self->start + index) % self->maxlen];
common_hal_mcu_enable_interrupts();
diff --git a/ports/esp8266/common-hal/storage/__init__.c b/ports/esp8266/common-hal/storage/__init__.c
index b800ad2bd..71a2aca39 100644
--- a/ports/esp8266/common-hal/storage/__init__.c
+++ b/ports/esp8266/common-hal/storage/__init__.c
@@ -28,11 +28,12 @@
#include "py/runtime.h"
#include "shared-bindings/storage/__init__.h"
+#include "supervisor/shared/translate.h"
void common_hal_storage_remount(const char* mount_path, bool readonly) {
- mp_raise_NotImplementedError("");
+ mp_raise_NotImplementedError(translate("Unable to remount filesystem"));
}
void common_hal_storage_erase_filesystem() {
- mp_raise_NotImplementedError("Use esptool to erase flash and re-upload Python instead");
+ mp_raise_NotImplementedError(translate("Use esptool to erase flash and re-upload Python instead"));
}
diff --git a/ports/esp8266/esp8266.ld b/ports/esp8266/esp8266.ld
index deeb82b45..3d244f6ad 100644
--- a/ports/esp8266/esp8266.ld
+++ b/ports/esp8266/esp8266.ld
@@ -5,7 +5,7 @@ MEMORY
dport0_0_seg : org = 0x3ff00000, len = 0x10
dram0_0_seg : org = 0x3ffe8000, len = 0x14000
iram1_0_seg : org = 0x40100000, len = 0x8000
- irom0_0_seg : org = 0x40209000, len = 0x8f000
+ irom0_0_seg : org = 0x40209000, len = 0x91000
}
/* define common sections and symbols */
diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c
index fe669265e..33d7f2d84 100644
--- a/ports/esp8266/esp_mphal.c
+++ b/ports/esp8266/esp_mphal.c
@@ -34,6 +34,7 @@
#include "py/runtime.h"
#include "extmod/misc.h"
#include "lib/utils/pyexec.h"
+#include "supervisor/shared/translate.h"
STATIC byte input_buf_array[256];
ringbuf_t stdin_ringbuf = {input_buf_array, sizeof(input_buf_array)};
@@ -150,7 +151,7 @@ void ets_event_poll(void) {
void __assert_func(const char *file, int line, const char *func, const char *expr) {
printf("assert:%s:%d:%s: %s\n", file, line, func, expr);
nlr_raise(mp_obj_new_exception_msg(&mp_type_AssertionError,
- "C-level assert"));
+ translate("C-level assert")));
}
void mp_hal_signal_input(void) {
diff --git a/ports/esp8266/machine_adc.c b/ports/esp8266/machine_adc.c
index b422f0f9e..2d31ed8ea 100644
--- a/ports/esp8266/machine_adc.c
+++ b/ports/esp8266/machine_adc.c
@@ -28,6 +28,7 @@
#include <string.h>
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
#include "user_interface.h"
const mp_obj_type_t pyb_adc_type;
@@ -53,7 +54,7 @@ STATIC mp_obj_t pyb_adc_make_new(const mp_obj_type_t *type_in, size_t n_args, si
return &pyb_adc_vdd3;
default:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "not a valid ADC Channel: %d", chn));
+ translate("not a valid ADC Channel: %d"), chn));
}
}
diff --git a/ports/esp8266/machine_hspi.c b/ports/esp8266/machine_hspi.c
index 07770c8c8..ac464da45 100644
--- a/ports/esp8266/machine_hspi.c
+++ b/ports/esp8266/machine_hspi.c
@@ -37,6 +37,7 @@
#include "py/mphal.h"
#include "extmod/machine_spi.h"
#include "modmachine.h"
+#include "supervisor/shared/translate.h"
#include "hspi.h"
#if MICROPY_PY_MACHINE_SPI
@@ -127,13 +128,13 @@ STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ob
spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV);
spi_clock(HSPI, 0, 0);
} else if (self->baudrate > 40000000L) {
- mp_raise_ValueError("impossible baudrate");
+ mp_raise_ValueError(translate("impossible baudrate"));
} else {
uint32_t divider = 40000000L / self->baudrate;
uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1);
uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even
if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) {
- mp_raise_ValueError("impossible baudrate");
+ mp_raise_ValueError(translate("impossible baudrate"));
}
self->baudrate = 80000000L / (prediv * cntdiv);
spi_init_gpio(HSPI, SPI_CLK_USE_DIV);
diff --git a/ports/esp8266/machine_pin.c b/ports/esp8266/machine_pin.c
index 14505c8f0..0467ffb4b 100644
--- a/ports/esp8266/machine_pin.c
+++ b/ports/esp8266/machine_pin.c
@@ -39,6 +39,8 @@
#include "extmod/virtpin.h"
#include "modmachine.h"
+#include "supervisor/shared/translate.h"
+
#define GET_TRIGGER(phys_port) \
GPIO_PIN_INT_TYPE_GET(GPIO_REG_READ(GPIO_PIN_ADDR(phys_port)))
#define SET_TRIGGER(phys_port, trig) \
@@ -124,7 +126,7 @@ void pin_intr_handler(uint32_t status) {
pyb_pin_obj_t *mp_obj_get_pin_obj(mp_obj_t pin_in) {
if (mp_obj_get_type(pin_in) != &pyb_pin_type) {
- mp_raise_ValueError("expecting a pin");
+ mp_raise_ValueError(translate("expecting a pin"));
}
pyb_pin_obj_t *self = pin_in;
return self;
@@ -279,7 +281,7 @@ STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, size_t n_args, cons
// only pull-down seems to be supported by the hardware, and
// we only expose pull-up behaviour in software
if (pull != GPIO_PULL_NONE) {
- mp_raise_ValueError("Pin(16) doesn't support pull");
+ mp_raise_ValueError(translate("Pin(16) doesn't support pull"));
}
} else {
PIN_FUNC_SELECT(self->periph, self->func);
@@ -318,7 +320,7 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
pin = (pyb_pin_obj_t*)&pyb_pin_obj[wanted_pin];
}
if (pin == NULL || pin->base.type == NULL) {
- mp_raise_ValueError("invalid pin");
+ mp_raise_ValueError(translate("invalid pin"));
}
if (n_args > 1 || n_kw > 0) {
@@ -384,7 +386,7 @@ STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
if (self->phys_port >= 16) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "pin does not have IRQ capabilities"));
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("pin does not have IRQ capabilities")));
}
if (n_args > 1 || kw_args->used != 0) {
diff --git a/ports/esp8266/machine_pwm.c b/ports/esp8266/machine_pwm.c
index 961b8e547..a117a41d5 100644
--- a/ports/esp8266/machine_pwm.c
+++ b/ports/esp8266/machine_pwm.c
@@ -31,6 +31,7 @@
#include "py/runtime.h"
#include "modmachine.h"
+#include "supervisor/shared/translate.h"
typedef struct _pyb_pwm_obj_t {
mp_obj_base_t base;
@@ -66,7 +67,7 @@ STATIC void pyb_pwm_init_helper(pyb_pwm_obj_t *self, size_t n_args, const mp_obj
int channel = pwm_add(self->pin->phys_port, self->pin->periph, self->pin->func);
if (channel == -1) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "PWM not supported on pin %d", self->pin->phys_port));
+ translate("PWM not supported on pin %d"), self->pin->phys_port));
}
self->channel = channel;
diff --git a/ports/esp8266/machine_rtc.c b/ports/esp8266/machine_rtc.c
index bbfc172cd..9197efb7a 100644
--- a/ports/esp8266/machine_rtc.c
+++ b/ports/esp8266/machine_rtc.c
@@ -29,6 +29,7 @@
#include "py/runtime.h"
#include "lib/timeutils/timeutils.h"
+#include "supervisor/shared/translate.h"
#include "user_interface.h"
#include "modmachine.h"
@@ -181,7 +182,7 @@ STATIC mp_obj_t pyb_rtc_memory(size_t n_args, const mp_obj_t *args) {
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
if (bufinfo.len > MEM_USER_MAXLEN) {
- mp_raise_ValueError("buffer too long");
+ mp_raise_ValueError(translate("buffer too long"));
}
len = bufinfo.len;
@@ -205,7 +206,7 @@ STATIC mp_obj_t pyb_rtc_alarm(mp_obj_t self_in, mp_obj_t alarm_id, mp_obj_t time
// check we want alarm0
if (mp_obj_get_int(alarm_id) != 0) {
- mp_raise_ValueError("invalid alarm");
+ mp_raise_ValueError(translate("invalid alarm"));
}
// set expiry time (in microseconds)
@@ -219,7 +220,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_rtc_alarm_obj, pyb_rtc_alarm);
STATIC mp_obj_t pyb_rtc_alarm_left(size_t n_args, const mp_obj_t *args) {
// check we want alarm0
if (n_args > 1 && mp_obj_get_int(args[1]) != 0) {
- mp_raise_ValueError("invalid alarm");
+ mp_raise_ValueError(translate("invalid alarm"));
}
uint64_t now = pyb_rtc_get_us_since_2000();
@@ -242,7 +243,7 @@ STATIC mp_obj_t pyb_rtc_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
// check we want alarm0
if (args[ARG_trigger].u_int != 0) {
- mp_raise_ValueError("invalid alarm");
+ mp_raise_ValueError(translate("invalid alarm"));
}
// set the wake value
diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c
index e8be5e538..c6a4e1ba1 100644
--- a/ports/esp8266/machine_uart.c
+++ b/ports/esp8266/machine_uart.c
@@ -34,6 +34,7 @@
#include "py/runtime.h"
#include "py/stream.h"
#include "py/mperrno.h"
+#include "supervisor/shared/translate.h"
#include "modmachine.h"
// UartDev is defined and initialized in rom code.
@@ -104,7 +105,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o
self->bits = 8;
break;
default:
- mp_raise_ValueError("invalid data bits");
+ mp_raise_ValueError(translate("invalid data bits"));
break;
}
@@ -140,7 +141,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o
self->stop = 2;
break;
default:
- mp_raise_ValueError("invalid stop bits");
+ mp_raise_ValueError(translate("invalid stop bits"));
break;
}
@@ -165,7 +166,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
// get uart id
mp_int_t uart_id = mp_obj_get_int(args[0]);
if (uart_id != 0 && uart_id != 1) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART(%d) does not exist", uart_id));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("UART(%d) does not exist"), uart_id));
}
// create instance
@@ -215,7 +216,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (self->uart_id == 1) {
- mp_raise_msg(&mp_type_OSError, "UART(1) can't read");
+ mp_raise_msg(&mp_type_OSError, translate("UART(1) can't read"));
}
// make sure we want at least 1 char
diff --git a/ports/esp8266/makeimg.py b/ports/esp8266/makeimg.py
index 091854fa4..1071f83e1 100644
--- a/ports/esp8266/makeimg.py
+++ b/ports/esp8266/makeimg.py
@@ -21,6 +21,7 @@ with open(sys.argv[3], 'wb') as fout:
with open(sys.argv[2], 'rb') as f:
data_rom = f.read()
+ print(SEGS_MAX_SIZE, len(data_flash))
pad = b'\xff' * (SEGS_MAX_SIZE - len(data_flash))
assert len(pad) >= 4
fout.write(pad[:-4])
diff --git a/ports/esp8266/modesp.c b/ports/esp8266/modesp.c
index 76aa2cc21..b1b30cd8b 100644
--- a/ports/esp8266/modesp.c
+++ b/ports/esp8266/modesp.c
@@ -30,6 +30,7 @@
#include "py/runtime.h"
#include "py/mperrno.h"
#include "py/mphal.h"
+#include "supervisor/shared/translate.h"
#include "uart.h"
#include "user_interface.h"
#include "mem.h"
@@ -37,7 +38,7 @@
#define MODESP_INCLUDE_CONSTANTS (1)
-void error_check(bool status, const char *msg) {
+void error_check(bool status, const compressed_string_t *msg) {
if (!status) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, msg));
}
@@ -115,7 +116,7 @@ STATIC mp_obj_t esp_flash_write(mp_obj_t offset_in, const mp_obj_t buf_in) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
if (bufinfo.len & 0x3) {
- mp_raise_ValueError("len must be multiple of 4");
+ mp_raise_ValueError(translate("len must be multiple of 4"));
}
SpiFlashOpResult res = spi_flash_write(offset, bufinfo.buf, bufinfo.len);
if (res == SPI_FLASH_RESULT_OK) {
@@ -270,7 +271,7 @@ void *esp_native_code_commit(void *buf, size_t len) {
len = (len + 3) & ~3;
if (esp_native_code_cur + len > esp_native_code_end) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError,
- "memory allocation failed, allocating %u bytes for native code", (uint)len));
+ translate("memory allocation failed, allocating %u bytes for native code"), (uint)len));
}
void *dest;
@@ -313,7 +314,7 @@ STATIC mp_obj_t esp_set_native_code_location(mp_obj_t start_in, mp_obj_t len_in)
esp_native_code_erased = esp_native_code_start;
// memory-mapped flash is limited in extents to 1MByte
if (esp_native_code_end > FLASH_END - FLASH_START) {
- mp_raise_ValueError("flash location must be below 1MByte");
+ mp_raise_ValueError(translate("flash location must be below 1MByte"));
}
}
return mp_const_none;
diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c
index 7e5f6714b..dc7bad1c6 100644
--- a/ports/esp8266/modmachine.c
+++ b/ports/esp8266/modmachine.c
@@ -35,6 +35,7 @@
#include "extmod/machine_pulse.h"
#include "extmod/machine_i2c.h"
#include "modmachine.h"
+#include "supervisor/shared/translate.h"
#include "xtirq.h"
#include "os_type.h"
@@ -59,7 +60,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
// set
mp_int_t freq = mp_obj_get_int(args[0]) / 1000000;
if (freq != 80 && freq != 160) {
- mp_raise_ValueError("frequency can only be either 80Mhz or 160MHz");
+ mp_raise_ValueError(translate("frequency can only be either 80Mhz or 160MHz"));
}
system_update_cpu_freq(freq);
return mp_const_none;
diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c
index c7f3397c4..1a41aa4d6 100644
--- a/ports/esp8266/modnetwork.c
+++ b/ports/esp8266/modnetwork.c
@@ -32,6 +32,7 @@
#include "py/runtime.h"
#include "py/mphal.h"
#include "lib/netutils/netutils.h"
+#include "supervisor/shared/translate.h"
#include "queue.h"
#include "user_interface.h"
#include "espconn.h"
@@ -46,7 +47,7 @@ typedef struct _wlan_if_obj_t {
int if_id;
} wlan_if_obj_t;
-void error_check(bool status, const char *msg);
+void error_check(bool status, const compressed_string_t *msg);
const mp_obj_type_t wlan_if_type;
STATIC const wlan_if_obj_t wlan_objs[] = {
@@ -57,7 +58,7 @@ STATIC const wlan_if_obj_t wlan_objs[] = {
STATIC void require_if(mp_obj_t wlan_if, int if_no) {
wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if);
if (self->if_id != if_no) {
- error_check(false, if_no == STATION_IF ? "STA required" : "AP required");
+ error_check(false, if_no == STATION_IF ? translate("STA required") : translate("AP required"));
}
}
@@ -83,7 +84,7 @@ STATIC mp_obj_t esp_active(size_t n_args, const mp_obj_t *args) {
} else {
mode &= ~mask;
}
- error_check(wifi_set_opmode(mode), "Cannot update i/f status");
+ error_check(wifi_set_opmode(mode), translate("Cannot update i/f status"));
return mp_const_none;
}
@@ -138,9 +139,9 @@ STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
}
if (set_config) {
- error_check(wifi_station_set_config(&config), "Cannot set STA config");
+ error_check(wifi_station_set_config(&config), translate("Cannot set STA config"));
}
- error_check(wifi_station_connect(), "Cannot connect to AP");
+ error_check(wifi_station_connect(), translate("Cannot connect to AP"));
return mp_const_none;
}
@@ -148,7 +149,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_connect_obj, 1, esp_connect);
STATIC mp_obj_t esp_disconnect(mp_obj_t self_in) {
require_if(self_in, STATION_IF);
- error_check(wifi_station_disconnect(), "Cannot disconnect from AP");
+ error_check(wifi_station_disconnect(), translate("Cannot disconnect from AP"));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_disconnect_obj, esp_disconnect);
@@ -169,7 +170,7 @@ STATIC mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) {
return MP_OBJ_NEW_SMALL_INT(wifi_station_get_rssi());
}
}
- mp_raise_ValueError("unknown status param");
+ mp_raise_ValueError(translate("unknown status param"));
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_status_obj, 1, 2, esp_status);
@@ -218,7 +219,7 @@ STATIC mp_obj_t esp_scan(mp_obj_t self_in) {
require_if(self_in, STATION_IF);
if ((wifi_get_opmode() & STATION_MODE) == 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
- "STA must be active"));
+ translate("STA must be active")));
}
mp_obj_t list = mp_obj_new_list(0, NULL);
esp_scan_list = &list;
@@ -235,7 +236,7 @@ STATIC mp_obj_t esp_scan(mp_obj_t self_in) {
ets_loop_iter();
}
if (list == MP_OBJ_NULL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "scan failed"));
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("scan failed")));
}
return list;
}
@@ -302,7 +303,7 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) {
}
if (!wifi_set_ip_info(self->if_id, &info)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
- "wifi_set_ip_info() failed"));
+ translate("wifi_set_ip_info() failed")));
}
dns_setserver(0, &dns_addr);
if (restart_dhcp_server) {
@@ -315,7 +316,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj, 1, 2, esp_ifconfig)
STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
if (n_args != 1 && kwargs->used != 0) {
- mp_raise_TypeError("either pos or kw args are allowed");
+ mp_raise_TypeError(translate("either pos or kw args are allowed"));
}
wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
@@ -325,9 +326,9 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
} cfg;
if (self->if_id == STATION_IF) {
- error_check(wifi_station_get_config(&cfg.sta), "can't get STA config");
+ error_check(wifi_station_get_config(&cfg.sta), translate("can't get STA config"));
} else {
- error_check(wifi_softap_get_config(&cfg.ap), "can't get AP config");
+ error_check(wifi_softap_get_config(&cfg.ap), translate("can't get AP config"));
}
int req_if = -1;
@@ -342,7 +343,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ);
if (bufinfo.len != 6) {
- mp_raise_ValueError("invalid buffer length");
+ mp_raise_ValueError(translate("invalid buffer length"));
}
wifi_set_macaddr(self->if_id, bufinfo.buf);
break;
@@ -401,9 +402,9 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
}
if (self->if_id == STATION_IF) {
- error_check(wifi_station_set_config(&cfg.sta), "can't set STA config");
+ error_check(wifi_station_set_config(&cfg.sta), translate("can't set STA config"));
} else {
- error_check(wifi_softap_set_config(&cfg.ap), "can't set AP config");
+ error_check(wifi_softap_set_config(&cfg.ap), translate("can't set AP config"));
}
return mp_const_none;
@@ -412,7 +413,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
// Get config
if (n_args != 2) {
- mp_raise_TypeError("can query only one param");
+ mp_raise_TypeError(translate("can query only one param"));
}
mp_obj_t val;
@@ -465,7 +466,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
return val;
unknown:
- mp_raise_ValueError("unknown config param");
+ mp_raise_ValueError(translate("unknown config param"));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_config_obj, 1, esp_config);
diff --git a/ports/nrf/common-hal/analogio/AnalogIn.c b/ports/nrf/common-hal/analogio/AnalogIn.c
index a2f452b35..795191084 100644
--- a/ports/nrf/common-hal/analogio/AnalogIn.c
+++ b/ports/nrf/common-hal/analogio/AnalogIn.c
@@ -27,6 +27,7 @@
#include "common-hal/analogio/AnalogIn.h"
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
#include "nrfx_saadc.h"
#include "nrf_gpio.h"
@@ -35,7 +36,7 @@
void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin) {
if (pin->adc_channel == 0)
- mp_raise_ValueError("Pin does not have ADC capabilities");
+ mp_raise_ValueError(translate("Pin does not have ADC capabilities"));
nrf_gpio_cfg_default(NRF_GPIO_PIN_MAP(pin->port, pin->pin));
diff --git a/ports/nrf/common-hal/analogio/AnalogOut.c b/ports/nrf/common-hal/analogio/AnalogOut.c
index d1fd4982b..654639b59 100644
--- a/ports/nrf/common-hal/analogio/AnalogOut.c
+++ b/ports/nrf/common-hal/analogio/AnalogOut.c
@@ -24,17 +24,17 @@
* THE SOFTWARE.
*/
+#include "shared-bindings/analogio/AnalogOut.h"
+
#include <stdint.h>
#include <string.h>
#include "py/mperrno.h"
#include "py/runtime.h"
-
-#include "shared-bindings/analogio/AnalogOut.h"
-
+#include "supervisor/shared/translate.h"
void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin) {
- mp_raise_RuntimeError("AnalogOut functionality not supported");
+ mp_raise_RuntimeError(translate("AnalogOut functionality not supported"));
}
bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) {
diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c
index f42189162..7a29da153 100644
--- a/ports/nrf/common-hal/busio/I2C.c
+++ b/ports/nrf/common-hal/busio/I2C.c
@@ -29,6 +29,7 @@
#include "shared-bindings/busio/I2C.h"
#include "py/mperrno.h"
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
#include "nrfx_twim.h"
#include "nrf_gpio.h"
@@ -54,7 +55,7 @@ static uint8_t twi_error_to_mp(const nrfx_err_t err) {
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
if (scl->pin == sda->pin)
- mp_raise_ValueError("Invalid pins");
+ mp_raise_ValueError(translate("Invalid pins"));
const nrfx_twim_t instance = NRFX_TWIM_INSTANCE(INST_NO);
self->twim = instance;
diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c
index dbc6a8533..765c987b5 100644
--- a/ports/nrf/common-hal/busio/UART.c
+++ b/ports/nrf/common-hal/busio/UART.c
@@ -32,6 +32,7 @@
#include "py/mperrno.h"
#include "py/runtime.h"
#include "py/stream.h"
+#include "supervisor/shared/translate.h"
#include "tick.h"
@@ -41,15 +42,15 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout,
uint8_t receiver_buffer_size) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
}
bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
}
void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
if (common_hal_busio_uart_deinited(self)) {
return;
}
@@ -58,32 +59,32 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
// Read characters.
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
return 0;
}
// Write characters.
size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
return 0;
}
uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
return self->baudrate;
}
void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
self->baudrate = baudrate;
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
return 0;
}
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
- mp_raise_NotImplementedError("busio.UART not yet implemented");
+ mp_raise_NotImplementedError(translate("busio.UART not yet implemented"));
return false;
}
diff --git a/ports/nrf/common-hal/digitalio/DigitalInOut.c b/ports/nrf/common-hal/digitalio/DigitalInOut.c
index b84877703..4db9e5efa 100644
--- a/ports/nrf/common-hal/digitalio/DigitalInOut.c
+++ b/ports/nrf/common-hal/digitalio/DigitalInOut.c
@@ -26,6 +26,7 @@
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
#include "nrf_gpio.h"
@@ -154,7 +155,7 @@ digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin);
if (nrf_gpio_pin_dir_get(pin) == NRF_GPIO_PIN_DIR_OUTPUT) {
- mp_raise_AttributeError("Cannot get pull while in output mode");
+ mp_raise_AttributeError(translate("Cannot get pull while in output mode"));
return PULL_NONE;
}
diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c
index 0cceb6a66..2ce3e8bf5 100644
--- a/ports/nrf/common-hal/microcontroller/Processor.c
+++ b/ports/nrf/common-hal/microcontroller/Processor.c
@@ -26,6 +26,7 @@
#include "common-hal/microcontroller/Processor.h"
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
#ifdef BLUETOOTH_SD
#include "nrf_sdm.h"
@@ -45,7 +46,7 @@ float common_hal_mcu_processor_get_temperature(void) {
uint32_t err_code = sd_temp_get(&temp);
if (err_code != NRF_SUCCESS) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not get temperature. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not get temperature. status: 0x%02x"), (uint16_t)err_code));
return 0;
}
diff --git a/ports/nrf/common-hal/pulseio/PWMOut.c b/ports/nrf/common-hal/pulseio/PWMOut.c
index d23662948..0f1461092 100644
--- a/ports/nrf/common-hal/pulseio/PWMOut.c
+++ b/ports/nrf/common-hal/pulseio/PWMOut.c
@@ -32,6 +32,7 @@
#include "common-hal/pulseio/PWMOut.h"
#include "nrf_gpio.h"
#include "shared-bindings/pulseio/PWMOut.h"
+#include "supervisor/shared/translate.h"
#define PWM_MAX_MODULE 3
#define PWM_MAX_CHANNEL 4
@@ -145,7 +146,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
// check if mapped to PWM channel already
for(int i=0; i<PWM_MAX_MODULE; i++)
{
- int ch = pin2channel(pwm_arr[i], pin->pin);
+ int ch = pin2channel(pwm_arr[i], NRF_GPIO_PIN_MAP(pin->port, pin->pin));
if ( ch >= 0 )
{
self->pwm = pwm_arr[i];
@@ -167,7 +168,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
// disable before mapping pin channel
self->pwm->ENABLE = 0;
- self->pwm->PSEL.OUT[self->channel] = pin->pin;
+ self->pwm->PSEL.OUT[self->channel] = NRF_GPIO_PIN_MAP(pin->port, pin->pin);
self->pwm->COUNTERTOP = (PWM_MAX_FREQ/frequency);
self->freq = frequency;
@@ -223,7 +224,7 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) {
if (frequency == 0 || frequency > 16000000) {
- mp_raise_ValueError("Invalid PWM frequency");
+ mp_raise_ValueError(translate("Invalid PWM frequency"));
}
self->freq = frequency;
@@ -238,4 +239,3 @@ uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) {
return self->variable_freq;
}
-
diff --git a/ports/nrf/common-hal/usb_hid/Device.c b/ports/nrf/common-hal/usb_hid/Device.c
index c2fff7001..6acb2717f 100644
--- a/ports/nrf/common-hal/usb_hid/Device.c
+++ b/ports/nrf/common-hal/usb_hid/Device.c
@@ -29,6 +29,7 @@
#include "common-hal/usb_hid/Device.h"
#include "py/runtime.h"
#include "shared-bindings/usb_hid/Device.h"
+#include "supervisor/shared/translate.h"
#include "tusb.h"
uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) {
@@ -41,7 +42,7 @@ uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) {
void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) {
if (len != self->report_length) {
- mp_raise_ValueError_varg("Buffer incorrect size. Should be %d bytes.", self->report_length);
+ mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->report_length);
}
// Wait until interface is ready, timeout = 2 seconds
@@ -49,13 +50,13 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t*
while ( (ticks_ms < end_ticks) && !tud_hid_generic_ready() ) { }
if ( !tud_hid_generic_ready() ) {
- mp_raise_msg(&mp_type_OSError, "USB Busy");
+ mp_raise_msg(&mp_type_OSError, translate("USB Busy"));
}
memcpy(self->report_buffer, report, len);
if ( !tud_hid_generic_report(self->report_id, self->report_buffer, len) ) {
- mp_raise_msg(&mp_type_OSError, "USB Error");
+ mp_raise_msg(&mp_type_OSError, translate("USB Error"));
}
}
@@ -85,4 +86,3 @@ void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_t
}
}
}
-
diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c
index 28d728d71..7e95c2eab 100644
--- a/ports/nrf/drivers/bluetooth/ble_drv.c
+++ b/ports/nrf/drivers/bluetooth/ble_drv.c
@@ -35,6 +35,7 @@
#endif
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
#include "ble_drv.h"
#include "mpconfigport.h"
#include "nrf_sdm.h"
@@ -195,7 +196,7 @@ uint32_t ble_drv_stack_enable(void) {
(const uint8_t *)device_name,
strlen(device_name))) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Cannot apply GAP parameters."));
+ translate("Cannot apply GAP parameters.")));
}
// set connection parameters
@@ -209,7 +210,7 @@ uint32_t ble_drv_stack_enable(void) {
if (sd_ble_gap_ppcp_set(&gap_conn_params) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Cannot set PPCP parameters."));
+ translate("Cannot set PPCP parameters.")));
}
return err_code;
@@ -241,7 +242,7 @@ void ble_drv_address_get(ble_drv_addr_t * p_addr) {
if (err_code != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not query for the device address."));
+ translate("Can not query for the device address.")));
}
BLE_DRIVER_LOG("ble address, type: " HEX2_FMT ", " \
@@ -260,7 +261,7 @@ bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) {
if (sd_ble_uuid_vs_add((ble_uuid128_t const *)p_uuid, idx) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not add Vendor Specific 128-bit UUID."));
+ translate("Can not add Vendor Specific 128-bit UUID.")));
}
return true;
@@ -280,7 +281,7 @@ bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) {
&uuid,
&p_service_obj->handle) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not add Service."));
+ translate("Can not add Service.")));
}
} else if (p_service_obj->p_uuid->type == BLE_UUID_TYPE_BLE) {
BLE_DRIVER_LOG("adding service\n");
@@ -294,7 +295,7 @@ bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) {
&uuid,
&p_service_obj->handle) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not add Service."));
+ translate("Can not add Service.")));
}
}
return true;
@@ -369,7 +370,7 @@ bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) {
&attr_char_value,
&handles) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not add Characteristic."));
+ translate("Can not add Characteristic.")));
}
// apply handles to object instance
@@ -396,7 +397,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
p_adv_params->p_device_name,
p_adv_params->device_name_len) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not apply device name in the stack."));
+ translate("Can not apply device name in the stack.")));
}
BLE_DRIVER_LOG("Device name applied\n");
@@ -460,13 +461,13 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
// calculate total size of uuids
if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not encode UUID, to check length."));
+ translate("Can not encode UUID, to check length.")));
}
// do encoding into the adv buffer
if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can encode UUID into the advertisment packet."));
+ translate("Can encode UUID into the advertisment packet.")));
}
BLE_DRIVER_LOG("encoded uuid for service %u: ", 0);
@@ -510,13 +511,13 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
// calculate total size of uuids
if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not encode UUID, to check length."));
+ translate("Can not encode UUID, to check length.")));
}
// do encoding into the adv buffer
if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can encode UUID into the advertisment packet."));
+ translate("Can encode UUID into the advertisment packet.")));
}
BLE_DRIVER_LOG("encoded uuid for service %u: ", 0);
@@ -541,7 +542,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) {
if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not fit data into the advertisment packet."));
+ translate("Can not fit data into the advertisment packet.")));
}
memcpy(adv_data, p_adv_params->p_data, p_adv_params->data_len);
@@ -554,7 +555,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not apply advertisment data. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not apply advertisment data. status: 0x%02x"), (uint16_t)err_code));
}
BLE_DRIVER_LOG("Set Adv data size: " UINT_FMT "\n", byte_pos);
#endif
@@ -600,7 +601,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
if ((err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params)) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not apply advertisment data. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not apply advertisment data. status: 0x%02x"), (uint16_t)err_code));
}
err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_DEFAULT);
#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4)
@@ -610,7 +611,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
#endif
if (err_code != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not start advertisment. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not start advertisment. status: 0x%02x"), (uint16_t)err_code));
}
m_adv_in_progress = true;
@@ -627,7 +628,7 @@ void ble_drv_advertise_stop(void) {
if ((err_code = sd_ble_gap_adv_stop()) != 0) {
#endif
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not stop advertisment. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not stop advertisment. status: 0x%02x"), (uint16_t)err_code));
}
}
m_adv_in_progress = false;
@@ -646,7 +647,7 @@ void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, ui
&gatts_value);
if (err_code != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not read attribute value. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code));
}
}
@@ -663,7 +664,7 @@ void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, u
if (err_code != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not write attribute value. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code));
}
}
@@ -687,7 +688,7 @@ void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len,
uint32_t err_code;
if ((err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params)) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not notify attribute value. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not notify attribute value. status: 0x%02x"), (uint16_t)err_code));
}
}
@@ -722,7 +723,7 @@ void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, bl
0);
if (err_code != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not read attribute value. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code));
}
while (gattc_char_data_handle != NULL) {
@@ -752,7 +753,7 @@ void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, u
if (err_code != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not write attribute value. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code));
}
while (m_write_done != true) {
@@ -780,7 +781,7 @@ void ble_drv_scan_start(void) {
if ((err_code = sd_ble_gap_scan_start(&scan_params)) != 0) {
#endif
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not start scanning. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not start scanning. status: 0x%02x"), (uint16_t)err_code));
}
}
@@ -825,7 +826,7 @@ void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type) {
if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_DEFAULT)) != 0) {
#endif
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- "Can not connect. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ translate("Can not connect. status: 0x%02x"), (uint16_t)err_code));
}
}
diff --git a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c
index 8e1d0eb1e..0935615a5 100644
--- a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c
+++ b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c
@@ -26,6 +26,7 @@
#include "py/obj.h"
#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
#if MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL
@@ -64,7 +65,7 @@ STATIC mp_obj_t ubluepy_characteristic_make_new(const mp_obj_type_t *type, size_
// (void)sd_characterstic_add(s);
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "Invalid UUID parameter"));
+ translate("Invalid UUID parameter")));
}
if (args[1].u_int > 0) {
diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c
index 68d905743..59b81234f 100644
--- a/ports/nrf/modules/ubluepy/ubluepy_service.c
+++ b/ports/nrf/modules/ubluepy/ubluepy_service.c
@@ -27,6 +27,7 @@
#include "py/obj.h"
#include "py/runtime.h"
#include "py/objlist.h"
+#include "supervisor/shared/translate.h"
#if MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL
@@ -69,14 +70,14 @@ STATIC mp_obj_t ubluepy_service_make_new(const mp_obj_type_t *type, size_t n_arg
s->type = type;
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "Invalid Service type"));
+ translate("Invalid Service type")));
}
(void)ble_drv_service_add(s);
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "Invalid UUID parameter"));
+ translate("Invalid UUID parameter")));
}
// clear reference to peripheral
@@ -128,7 +129,7 @@ STATIC mp_obj_t service_get_characteristic(mp_obj_t self_in, mp_obj_t uuid) {
// validate that there is an UUID object passed in as parameter
if (!(MP_OBJ_IS_TYPE(uuid, &ubluepy_uuid_type))) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "Invalid UUID parameter"));
+ translate("Invalid UUID parameter")));
}
mp_obj_t * chars = NULL;
diff --git a/ports/nrf/modules/ubluepy/ubluepy_uuid.c b/ports/nrf/modules/ubluepy/ubluepy_uuid.c
index 380d2e404..b45494e41 100644
--- a/ports/nrf/modules/ubluepy/ubluepy_uuid.c
+++ b/ports/nrf/modules/ubluepy/ubluepy_uuid.c
@@ -28,6 +28,7 @@
#include "py/runtime.h"
#include "py/objstr.h"
#include "py/misc.h"
+#include "supervisor/shared/translate.h"
#if MICROPY_PY_UBLUEPY
@@ -123,7 +124,7 @@ STATIC mp_obj_t ubluepy_uuid_make_new(const mp_obj_type_t *type, size_t n_args,
ble_drv_uuid_add_vs(buffer, &s->uuid_vs_idx);
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "Invalid UUID string length"));
+ translate("Invalid UUID string length")));
}
} else if (MP_OBJ_IS_TYPE(uuid_obj, &ubluepy_uuid_type)) {
// deep copy instance
@@ -133,7 +134,7 @@ STATIC mp_obj_t ubluepy_uuid_make_new(const mp_obj_type_t *type, size_t n_args,
s->value[1] = p_old->value[1];
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "Invalid UUID parameter"));
+ translate("Invalid UUID parameter")));
}
return MP_OBJ_FROM_PTR(s);
diff --git a/ports/unix/Makefile b/ports/unix/Makefile
index 1c112e0b2..1d36198ec 100644
--- a/ports/unix/Makefile
+++ b/ports/unix/Makefile
@@ -242,7 +242,7 @@ freedos:
# build an interpreter for coverage testing and do the testing
coverage:
- $(MAKE) V=2 \
+ $(MAKE) \
COPT="-O0" CFLAGS_EXTRA='$(CFLAGS_EXTRA) -DMP_CONFIGFILE="<mpconfigport_coverage.h>" \
-fprofile-arcs -ftest-coverage \
-Wdouble-promotion -Wformat -Wmissing-declarations -Wmissing-prototypes -Wsign-compare \
diff --git a/ports/unix/file.c b/ports/unix/file.c
index 165bbd00b..98ac1b3cc 100644
--- a/ports/unix/file.c
+++ b/ports/unix/file.c
@@ -35,6 +35,7 @@
#include "py/stream.h"
#include "py/builtin.h"
#include "py/mphal.h"
+#include "supervisor/shared/translate.h"
#include "fdfile.h"
#if MICROPY_PY_IO && !MICROPY_VFS
@@ -46,7 +47,7 @@
#ifdef MICROPY_CPYTHON_COMPAT
STATIC void check_fd_is_open(const mp_obj_fdfile_t *o) {
if (o->fd < 0) {
- mp_raise_ValueError("I/O operation on closed file");
+ mp_raise_ValueError(translate("I/O operation on closed file"));
}
}
#else
diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c
index a12c249e2..fcbcebc39 100644
--- a/ports/unix/modffi.c
+++ b/ports/unix/modffi.c
@@ -36,6 +36,8 @@
#include "py/binary.h"
#include "py/mperrno.h"
+#include "supervisor/shared/translate.h"
+
/*
* modffi uses character codes to encode a value type, based on "struct"
* module type codes, with some extensions and overridings.
@@ -133,7 +135,7 @@ STATIC ffi_type *get_ffi_type(mp_obj_t o_in)
}
// TODO: Support actual libffi type objects
- mp_raise_TypeError("Unknown type");
+ mp_raise_TypeError(translate("Unknown type"));
}
STATIC mp_obj_t return_ffi_value(ffi_arg val, char type)
@@ -202,7 +204,7 @@ STATIC mp_obj_t make_func(mp_obj_t rettype_in, void *func, mp_obj_t argtypes_in)
int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params);
if (res != FFI_OK) {
- mp_raise_ValueError("Error in ffi_prep_cif");
+ mp_raise_ValueError(translate("Error in ffi_prep_cif"));
}
return MP_OBJ_FROM_PTR(o);
@@ -260,12 +262,12 @@ STATIC mp_obj_t mod_ffi_callback(mp_obj_t rettype_in, mp_obj_t func_in, mp_obj_t
int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params);
if (res != FFI_OK) {
- mp_raise_ValueError("Error in ffi_prep_cif");
+ mp_raise_ValueError(translate("Error in ffi_prep_cif"));
}
res = ffi_prep_closure_loc(o->clo, &o->cif, call_py_func, MP_OBJ_TO_PTR(func_in), o->func);
if (res != FFI_OK) {
- mp_raise_ValueError("ffi_prep_closure_loc");
+ mp_raise_ValueError(translate("ffi_prep_closure_loc"));
}
return MP_OBJ_FROM_PTR(o);
@@ -408,7 +410,7 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
}
error:
- mp_raise_TypeError("Don't know how to pass object to native function");
+ mp_raise_TypeError(translate("Don't know how to pass object to native function"));
}
STATIC const mp_obj_type_t ffifunc_type = {
diff --git a/ports/unix/modmachine.c b/ports/unix/modmachine.c
index 48dddec0a..b2bca1206 100644
--- a/ports/unix/modmachine.c
+++ b/ports/unix/modmachine.c
@@ -35,6 +35,8 @@
#include "extmod/machine_signal.h"
#include "extmod/machine_pulse.h"
+#include "supervisor/shared/translate.h"
+
#if MICROPY_PLAT_DEV_MEM
#include <errno.h>
#include <fcntl.h>
@@ -48,7 +50,7 @@
uintptr_t mod_machine_mem_get_addr(mp_obj_t addr_o, uint align) {
uintptr_t addr = mp_obj_int_get_truncated(addr_o);
if ((addr & (align - 1)) != 0) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("address %08x is not aligned to %d bytes"), addr, align));
}
#if MICROPY_PLAT_DEV_MEM
{
diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c
index ba50e6165..9b9869f5b 100644
--- a/ports/unix/modusocket.c
+++ b/ports/unix/modusocket.c
@@ -45,6 +45,8 @@
#include "py/builtin.h"
#include "py/mphal.h"
+#include "supervisor/shared/translate.h"
+
/*
The idea of this module is to implement reasonable minimum of
socket-related functions to write typical clients and servers.
@@ -469,7 +471,7 @@ STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) {
if (res != 0) {
// CPython: socket.gaierror
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[addrinfo error %d]", res));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("[addrinfo error %d]"), res));
}
assert(addr_list);
diff --git a/py/compile.c b/py/compile.c
index c4f447c56..1218aa07e 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -156,7 +156,7 @@ STATIC void compile_error_set_line(compiler_t *comp, mp_parse_node_t pn) {
}
}
-STATIC void compile_syntax_error(compiler_t *comp, mp_parse_node_t pn, const char *msg) {
+STATIC void compile_syntax_error(compiler_t *comp, mp_parse_node_t pn, const compressed_string_t *msg) {
// only register the error if there has been no other error
if (comp->compile_error == MP_OBJ_NULL) {
comp->compile_error = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg);
@@ -949,7 +949,7 @@ STATIC void compile_del_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
STATIC void compile_break_cont_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
uint16_t label;
- const char *error_msg;
+ const compressed_string_t *error_msg;
if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_break_stmt) {
label = comp->break_label;
error_msg = translate("'break' outside loop");
diff --git a/py/emitinlinextensa.c b/py/emitinlinextensa.c
index 3d3217f5b..9cd65824b 100644
--- a/py/emitinlinextensa.c
+++ b/py/emitinlinextensa.c
@@ -43,7 +43,7 @@ struct _emit_inline_asm_t {
qstr *label_lookup;
};
-STATIC void emit_inline_xtensa_error_msg(emit_inline_asm_t *emit, const char *msg) {
+STATIC void emit_inline_xtensa_error_msg(emit_inline_asm_t *emit, const compressed_string_t *msg) {
*emit->error_slot = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg);
}
@@ -83,17 +83,17 @@ STATIC void emit_inline_xtensa_end_pass(emit_inline_asm_t *emit, mp_uint_t type_
STATIC mp_uint_t emit_inline_xtensa_count_params(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params) {
if (n_params > 4) {
- emit_inline_xtensa_error_msg(emit, "can only have up to 4 parameters to Xtensa assembly");
+ emit_inline_xtensa_error_msg(emit, translate("can only have up to 4 parameters to Xtensa assembly"));
return 0;
}
for (mp_uint_t i = 0; i < n_params; i++) {
if (!MP_PARSE_NODE_IS_ID(pn_params[i])) {
- emit_inline_xtensa_error_msg(emit, "parameters must be registers in sequence a2 to a5");
+ emit_inline_xtensa_error_msg(emit, translate("parameters must be registers in sequence a2 to a5"));
return 0;
}
const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i]));
if (!(strlen(p) == 2 && p[0] == 'a' && p[1] == '2' + i)) {
- emit_inline_xtensa_error_msg(emit, "parameters must be registers in sequence a2 to a5");
+ emit_inline_xtensa_error_msg(emit, translate("parameters must be registers in sequence a2 to a5"));
return 0;
}
}
@@ -159,19 +159,19 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
}
emit_inline_xtensa_error_exc(emit,
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
- "'%s' expects a register", op));
+ translate("'%s' expects a register"), op));
return 0;
}
STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, int min, int max) {
mp_obj_t o;
if (!mp_parse_node_get_int_maybe(pn, &o)) {
- emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op));
+ emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects an integer"), op));
return 0;
}
uint32_t i = mp_obj_get_int_truncated(o);
if (min != max && ((int)i < min || (int)i > max)) {
- emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' integer %d is not within range %d..%d", op, i, min, max));
+ emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' integer %d is not within range %d..%d"), op, i, min, max));
return 0;
}
return i;
@@ -179,7 +179,7 @@ STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node
STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
if (!MP_PARSE_NODE_IS_ID(pn)) {
- emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op));
+ emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects a label"), op));
return 0;
}
qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn);
@@ -190,7 +190,7 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_
}
// only need to have the labels on the last pass
if (emit->pass == MP_PASS_EMIT) {
- emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "label '%q' not defined", label_qstr));
+ emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("label '%q' not defined"), label_qstr));
}
return 0;
}
@@ -324,12 +324,12 @@ STATIC void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
return;
unknown_op:
- emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "unsupported Xtensa instruction '%s' with %d arguments", op_str, n_args));
+ emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("unsupported Xtensa instruction '%s' with %d arguments"), op_str, n_args));
return;
/*
branch_not_in_range:
- emit_inline_xtensa_error_msg(emit, "branch not in range");
+ emit_inline_xtensa_error_msg(emit, translate("branch not in range"));
return;
*/
}
diff --git a/py/emitnative.c b/py/emitnative.c
index 47309040e..67b0025c6 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -180,7 +180,7 @@ STATIC void emit_native_set_native_type(emit_t *emit, mp_uint_t op, mp_uint_t ar
case MP_QSTR_ptr8: type = VTYPE_PTR8; break;
case MP_QSTR_ptr16: type = VTYPE_PTR16; break;
case MP_QSTR_ptr32: type = VTYPE_PTR32; break;
- default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "unknown type '%q'", arg2); return;
+ default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, translate("unknown type '%q'"), arg2); return;
}
if (op == MP_EMIT_NATIVE_TYPE_RETURN) {
emit->return_vtype = type;
@@ -257,7 +257,7 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
// right now we have a restriction of maximum of 4 arguments
if (scope->num_pos_args >= 5) {
- EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "Viper functions don't currently support more than 4 arguments");
+ EMIT_NATIVE_VIPER_TYPE_ERROR(emit, translate("Viper functions don't currently support more than 4 arguments"));
return;
}
@@ -918,7 +918,7 @@ STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
DEBUG_printf("load_fast(%s, " UINT_FMT ")\n", qstr_str(qst), local_num);
vtype_kind_t vtype = emit->local_vtype[local_num];
if (vtype == VTYPE_UNBOUND) {
- EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "local '%q' used before type known", qst);
+ EMIT_NATIVE_VIPER_TYPE_ERROR(emit, translate("local '%q' used before type known"), qst);
}
emit_native_pre(emit);
if (local_num == 0) {
@@ -1115,7 +1115,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) {
}
default:
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't load from '%q'", vtype_to_qstr(vtype_base));
+ translate("can't load from '%q'"), vtype_to_qstr(vtype_base));
}
} else {
// index is not an immediate
@@ -1125,7 +1125,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) {
emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1);
if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) {
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't load with '%q' index", vtype_to_qstr(vtype_index));
+ translate("can't load with '%q' index"), vtype_to_qstr(vtype_index));
}
switch (vtype_base) {
case VTYPE_PTR8: {
@@ -1153,7 +1153,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) {
}
default:
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't load from '%q'", vtype_to_qstr(vtype_base));
+ translate("can't load from '%q'"), vtype_to_qstr(vtype_base));
}
}
emit_post_push_reg(emit, VTYPE_INT, REG_RET);
@@ -1185,7 +1185,7 @@ STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num)
} else if (emit->local_vtype[local_num] != vtype) {
// type of local is not the same as object stored in it
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "local '%q' has type '%q' but source is '%q'",
+ translate("local '%q' has type '%q' but source is '%q'"),
qst, vtype_to_qstr(emit->local_vtype[local_num]), vtype_to_qstr(vtype));
}
}
@@ -1286,7 +1286,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
#endif
if (vtype_value != VTYPE_BOOL && vtype_value != VTYPE_INT && vtype_value != VTYPE_UINT) {
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't store '%q'", vtype_to_qstr(vtype_value));
+ translate("can't store '%q'"), vtype_to_qstr(vtype_value));
}
switch (vtype_base) {
case VTYPE_PTR8: {
@@ -1355,7 +1355,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
}
default:
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't store to '%q'", vtype_to_qstr(vtype_base));
+ translate("can't store to '%q'"), vtype_to_qstr(vtype_base));
}
} else {
// index is not an immediate
@@ -1366,7 +1366,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1);
if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) {
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't store with '%q' index", vtype_to_qstr(vtype_index));
+ translate("can't store with '%q' index"), vtype_to_qstr(vtype_index));
}
#if N_X86
// special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX)
@@ -1376,7 +1376,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
#endif
if (vtype_value != VTYPE_BOOL && vtype_value != VTYPE_INT && vtype_value != VTYPE_UINT) {
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't store '%q'", vtype_to_qstr(vtype_value));
+ translate("can't store '%q'"), vtype_to_qstr(vtype_value));
}
switch (vtype_base) {
case VTYPE_PTR8: {
@@ -1416,7 +1416,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
}
default:
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't store to '%q'", vtype_to_qstr(vtype_base));
+ translate("can't store to '%q'"), vtype_to_qstr(vtype_base));
}
}
@@ -1537,7 +1537,7 @@ STATIC void emit_native_jump_helper(emit_t *emit, bool pop) {
}
if (!(vtype == VTYPE_BOOL || vtype == VTYPE_INT || vtype == VTYPE_UINT)) {
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't implicitly convert '%q' to 'bool'", vtype_to_qstr(vtype));
+ translate("can't implicitly convert '%q' to 'bool'"), vtype_to_qstr(vtype));
}
}
// For non-pop need to save the vtype so that emit_native_adjust_stack_size
@@ -1771,7 +1771,7 @@ STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) {
} else {
adjust_stack(emit, 1);
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "unary op %q not implemented", mp_unary_op_method_name[op]);
+ translate("unary op %q not implemented"), mp_unary_op_method_name[op]);
}
}
@@ -1927,7 +1927,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
// TODO other ops not yet implemented
adjust_stack(emit, 1);
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "binary op %q not implemented", mp_binary_op_method_name[op]);
+ translate("binary op %q not implemented"), mp_binary_op_method_name[op]);
}
} else if (vtype_lhs == VTYPE_PYOBJ && vtype_rhs == VTYPE_PYOBJ) {
emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_3, &vtype_lhs, REG_ARG_2);
@@ -1948,7 +1948,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
} else {
adjust_stack(emit, -1);
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "can't do binary op between '%q' and '%q'",
+ translate("can't do binary op between '%q' and '%q'"),
vtype_to_qstr(vtype_lhs), vtype_to_qstr(vtype_rhs));
}
}
@@ -2170,7 +2170,7 @@ STATIC void emit_native_return_value(emit_t *emit) {
emit_pre_pop_reg(emit, &vtype, REG_RET);
if (vtype != emit->return_vtype) {
EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
- "return expected '%q' but got '%q'",
+ translate("return expected '%q' but got '%q'"),
vtype_to_qstr(emit->return_vtype), vtype_to_qstr(vtype));
}
}
@@ -2188,7 +2188,7 @@ STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) {
vtype_kind_t vtype_exc;
emit_pre_pop_reg(emit, &vtype_exc, REG_ARG_1); // arg1 = object to raise
if (vtype_exc != VTYPE_PYOBJ) {
- EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "must raise an object");
+ EMIT_NATIVE_VIPER_TYPE_ERROR(emit, translate("must raise an object"));
}
// TODO probably make this 1 call to the runtime (which could even call convert, native_raise(obj, type))
emit_call(emit, MP_F_NATIVE_RAISE);
diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index adf065c72..b0a043ee3 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -11,6 +11,14 @@ import sys
import collections
import gettext
+import os.path
+
+py = os.path.dirname(sys.argv[0])
+top = os.path.dirname(py)
+
+sys.path.append(os.path.join(top, "tools/huffman"))
+
+import huffman
# Python 2/3 compatibility:
# - iterating through bytes is different
@@ -83,9 +91,144 @@ def translate(translation_file, i18ns):
unescaped = original
for s in C_ESCAPES:
unescaped = unescaped.replace(C_ESCAPES[s], s)
- translations.append((original, table.gettext(unescaped)))
+ translation = table.gettext(unescaped)
+ # Add in carriage returns to work in terminals
+ translation = translation.replace("\n", "\r\n")
+ translations.append((original, translation))
return translations
+def compute_huffman_coding(translations, qstrs, compression_filename):
+ all_strings = [x[1] for x in translations]
+
+ # go through each qstr and print it out
+ for _, _, qstr in qstrs.values():
+ all_strings.append(qstr)
+ all_strings_concat = "".join(all_strings).encode("utf-8")
+ counts = collections.Counter(all_strings_concat)
+ # add other values
+ for i in range(256):
+ if i not in counts:
+ counts[i] = 0
+ cb = huffman.codebook(counts.items())
+ values = bytearray()
+ length_count = {}
+ renumbered = 0
+ last_l = None
+ canonical = {}
+ for ch, code in sorted(cb.items(), key=lambda x: (len(x[1]), x[0])):
+ values.append(ch)
+ l = len(code)
+ if l not in length_count:
+ length_count[l] = 0
+ length_count[l] += 1
+ if last_l:
+ renumbered <<= (l - last_l)
+ canonical[ch] = '{0:0{width}b}'.format(renumbered, width=l)
+ if chr(ch) in C_ESCAPES:
+ s = C_ESCAPES[chr(ch)]
+ else:
+ s = chr(ch)
+ print("//", ch, s, counts[ch], canonical[ch], renumbered)
+ renumbered += 1
+ last_l = l
+ lengths = bytearray()
+ for i in range(1, max(length_count) + 1):
+ lengths.append(length_count.get(i, 0))
+ print("//", values, lengths)
+ with open(compression_filename, "w") as f:
+ f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths))))
+ f.write("const uint8_t values[256] = {{ {} }};\n".format(", ".join(map(str, values))))
+ return values, lengths
+
+def decompress(encoding_table, length, encoded):
+ values, lengths = encoding_table
+ #print(l, encoded)
+ dec = bytearray(length)
+ this_byte = 0
+ this_bit = 7
+ b = encoded[this_byte]
+ for i in range(length):
+ bits = 0
+ bit_length = 0
+ max_code = lengths[0]
+ searched_length = lengths[0]
+ while True:
+ bits <<= 1
+ if 0x80 & b:
+ bits |= 1
+
+ b <<= 1
+ bit_length += 1
+ if this_bit == 0:
+ this_bit = 7
+ this_byte += 1
+ if this_byte < len(encoded):
+ b = encoded[this_byte]
+ else:
+ this_bit -= 1
+ if max_code > 0 and bits < max_code:
+ #print('{0:0{width}b}'.format(bits, width=bit_length))
+ break
+ max_code = (max_code << 1) + lengths[bit_length]
+ searched_length += lengths[bit_length]
+
+ v = values[searched_length + bits - max_code]
+ dec[i] = v
+ return dec
+
+def compress(encoding_table, decompressed):
+ if not isinstance(decompressed, bytes):
+ raise TypeError()
+ values, lengths = encoding_table
+ enc = bytearray(len(decompressed))
+ #print(decompressed)
+ #print(lengths)
+ current_bit = 7
+ current_byte = 0
+ for c in decompressed:
+ #print()
+ #print("char", c, values.index(c))
+ start = 0
+ end = lengths[0]
+ bits = 1
+ compressed = None
+ code = 0
+ while compressed is None:
+ s = start
+ e = end
+ #print("{0:0{width}b}".format(code, width=bits))
+ # Binary search!
+ while e > s:
+ midpoint = (s + e) // 2
+ #print(s, e, midpoint)
+ if values[midpoint] == c:
+ compressed = code + (midpoint - start)
+ #print("found {0:0{width}b}".format(compressed, width=bits))
+ break
+ elif c < values[midpoint]:
+ e = midpoint
+ else:
+ s = midpoint + 1
+ code += end - start
+ code <<= 1
+ start = end
+ end += lengths[bits]
+ bits += 1
+ #print("next bit", bits)
+
+ for i in range(bits - 1, 0, -1):
+ if compressed & (1 << (i - 1)):
+ enc[current_byte] |= 1 << current_bit
+ if current_bit == 0:
+ current_bit = 7
+ #print("packed {0:0{width}b}".format(enc[current_byte], width=8))
+ current_byte += 1
+ else:
+ current_bit -= 1
+ if current_bit != 7:
+ current_byte += 1
+ return enc[:current_byte]
+
def qstr_escape(qst):
def esc_char(m):
c = ord(m.group(0))
@@ -178,7 +321,7 @@ def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr):
qhash_str = ('\\x%02x' * cfg_bytes_hash) % tuple(((qhash >> (8 * i)) & 0xff) for i in range(cfg_bytes_hash))
return '(const byte*)"%s%s" "%s"' % (qhash_str, qlen_str, qdata)
-def print_qstr_data(qcfgs, qstrs, i18ns):
+def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns):
# get config variables
cfg_bytes_len = int(qcfgs['BYTES_IN_LEN'])
cfg_bytes_hash = int(qcfgs['BYTES_IN_HASH'])
@@ -191,6 +334,7 @@ def print_qstr_data(qcfgs, qstrs, i18ns):
print('QDEF(MP_QSTR_NULL, (const byte*)"%s%s" "")' % ('\\x00' * cfg_bytes_hash, '\\x00' * cfg_bytes_len))
total_qstr_size = 0
+ total_qstr_compressed_size = 0
# go through each qstr and print it out
for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]):
qbytes = make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr)
@@ -198,17 +342,23 @@ def print_qstr_data(qcfgs, qstrs, i18ns):
total_qstr_size += len(qstr)
total_text_size = 0
+ total_text_compressed_size = 0
for original, translation in i18ns:
- # Add in carriage returns to work in terminals
- translation = translation.replace("\n", "\r\n")
- for s in C_ESCAPES:
- translation = translation.replace(s, C_ESCAPES[s])
- print("TRANSLATION(\"{}\", \"{}\")".format(original, translation))
- total_text_size += len(translation)
+ translation_encoded = translation.encode("utf-8")
+ compressed = compress(encoding_table, translation_encoded)
+ total_text_compressed_size += len(compressed)
+ decompressed = decompress(encoding_table, len(translation_encoded), compressed).decode("utf-8")
+ for c in C_ESCAPES:
+ decompressed.replace(c, C_ESCAPES[c])
+ #print("// \"{}\"".format(translation))
+ print("TRANSLATION(\"{}\", {}, {{ {} }}) // {}".format(original, len(translation_encoded)+1, ", ".join(["0x{:02x}".format(x) for x in compressed]), decompressed))
+ total_text_size += len(translation.encode("utf-8"))
print()
print("// {} bytes worth of qstr".format(total_qstr_size))
print("// {} bytes worth of translations".format(total_text_size))
+ print("// {} bytes worth of translations compressed".format(total_text_compressed_size))
+ print("// {} bytes saved".format(total_text_size - total_text_compressed_size))
def print_qstr_enums(qstrs):
# print out the starter of the generated C header file
@@ -230,12 +380,15 @@ if __name__ == "__main__":
help='an integer for the accumulator')
parser.add_argument('--translation', default=None, type=str,
help='translations for i18n() items')
+ parser.add_argument('--compression_filename', default=None, type=str,
+ help='header for compression info')
args = parser.parse_args()
qcfgs, qstrs, i18ns = parse_input_headers(args.infiles)
if args.translation:
translations = translate(args.translation, i18ns)
- print_qstr_data(qcfgs, qstrs, translations)
+ encoding_table = compute_huffman_coding(translations, qstrs, args.compression_filename)
+ print_qstr_data(encoding_table, qcfgs, qstrs, translations)
else:
print_qstr_enums(qstrs)
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index 4b24e8811..fc7ec24c7 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -316,7 +316,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_min_obj, 1, mp_builtin_min);
STATIC mp_obj_t mp_builtin_next(mp_obj_t o) {
mp_obj_t ret = mp_iternext_allow_raise(o);
if (ret == MP_OBJ_STOP_ITERATION) {
- mp_raise_msg(&mp_type_StopIteration, "");
+ mp_raise_msg(&mp_type_StopIteration, NULL);
} else {
return ret;
}
diff --git a/py/moduerrno.c b/py/moduerrno.c
index 1b925dfc9..255c1a73e 100644
--- a/py/moduerrno.c
+++ b/py/moduerrno.c
@@ -102,20 +102,6 @@ const mp_obj_module_t mp_module_uerrno = {
};
const char* mp_errno_to_str(mp_obj_t errno_val) {
- // For commonly encountered errors, return human readable strings
- if (MP_OBJ_IS_SMALL_INT(errno_val)) {
- switch (MP_OBJ_SMALL_INT_VALUE(errno_val)) {
- case EPERM: return translate("Permission denied");
- case ENOENT: return translate("No such file/directory");
- case EIO: return translate("Input/output error");
- case EACCES: return translate("Permission denied");
- case EEXIST: return translate("File exists");
- case ENODEV: return translate("Unsupported operation");
- case EINVAL: return translate("Invalid argument");
- case EROFS: return translate("Read-only filesystem");
- }
- }
-
// Otherwise, return the Exxxx string for that error code
#if MICROPY_PY_UERRNO_ERRORCODE
// We have the errorcode dict so can do a lookup using the hash map
@@ -148,3 +134,21 @@ const char* mp_errno_to_str(mp_obj_t errno_val) {
}
#endif //MICROPY_PY_UERRNO
+
+
+// For commonly encountered errors, return human readable strings
+const compressed_string_t* mp_common_errno_to_str(mp_obj_t errno_val) {
+ if (MP_OBJ_IS_SMALL_INT(errno_val)) {
+ switch (MP_OBJ_SMALL_INT_VALUE(errno_val)) {
+ case EPERM: return translate("Permission denied");
+ case ENOENT: return translate("No such file/directory");
+ case EIO: return translate("Input/output error");
+ case EACCES: return translate("Permission denied");
+ case EEXIST: return translate("File exists");
+ case ENODEV: return translate("Unsupported operation");
+ case EINVAL: return translate("Invalid argument");
+ case EROFS: return translate("Read-only filesystem");
+ }
+ }
+ return NULL;
+}
diff --git a/py/mperrno.h b/py/mperrno.h
index c530ab183..876b090b5 100644
--- a/py/mperrno.h
+++ b/py/mperrno.h
@@ -141,5 +141,7 @@
#endif
const char* mp_errno_to_str(mp_obj_t errno_val);
+// For commonly encountered errors, return compressed human readable strings
+const compressed_string_t* mp_common_errno_to_str(mp_obj_t errno_val);
#endif // MICROPY_INCLUDED_PY_MPERRNO_H
diff --git a/py/obj.c b/py/obj.c
index 72bf9bda1..35a7519bb 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -86,19 +86,35 @@ void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) {
mp_obj_exception_get_traceback(exc, &n, &values);
if (n > 0) {
assert(n % 3 == 0);
- mp_print_str(print, translate("Traceback (most recent call last):\n"));
+ // Decompress the format strings
+ const compressed_string_t* traceback = translate("Traceback (most recent call last):\n");
+ char decompressed[traceback->length];
+ decompress(traceback, decompressed);
+#if MICROPY_ENABLE_SOURCE_LINE
+ const compressed_string_t* frame = translate(" File \"%q\", line %d");
+#else
+ const compressed_string_t* frame = translate(" File \"%q\"");
+#endif
+ char decompressed_frame[frame->length];
+ decompress(frame, decompressed_frame);
+ const compressed_string_t* block_fmt = translate(", in %q\n");
+ char decompressed_block[block_fmt->length];
+ decompress(block_fmt, decompressed_block);
+
+ // Print the traceback
+ mp_print_str(print, decompressed);
for (int i = n - 3; i >= 0; i -= 3) {
#if MICROPY_ENABLE_SOURCE_LINE
- mp_printf(print, translate(" File \"%q\", line %d"), values[i], (int)values[i + 1]);
+ mp_printf(print, decompressed_frame, values[i], (int)values[i + 1]);
#else
- mp_printf(print, translate(" File \"%q\""), values[i]);
+ mp_printf(print, decompressed_frame, values[i]);
#endif
// the block name can be NULL if it's unknown
qstr block = values[i + 2];
if (block == MP_QSTR_NULL) {
mp_print_str(print, "\n");
} else {
- mp_printf(print, translate(", in %q\n"), block);
+ mp_printf(print, decompressed_block, block);
}
}
}
diff --git a/py/obj.h b/py/obj.h
index 6d314e461..59cce0836 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -34,6 +34,8 @@
#include "py/mpprint.h"
#include "py/runtime0.h"
+#include "supervisor/shared/translate.h"
+
// This is the definition of the opaque MicroPython object type.
// All concrete objects have an encoding within this type and the
// particular encoding is specified by MICROPY_OBJ_REPR.
@@ -293,6 +295,13 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t;
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) \
const mp_obj_fun_builtin_var_t obj_name = \
{{&mp_type_fun_builtin_var}, true, n_args_min, MP_OBJ_FUN_ARGS_MAX, .fun.kw = fun_name}
+#define MP_DEFINE_CONST_PROP_GET(obj_name, fun_name) \
+ const mp_obj_fun_builtin_fixed_t fun_name##_obj = {{&mp_type_fun_builtin_1}, .fun._1 = fun_name}; \
+ const mp_obj_property_t obj_name = { \
+ .base.type = &mp_type_property, \
+ .proxy = {(mp_obj_t)&fun_name##_obj, \
+ (mp_obj_t)&mp_const_none_obj, \
+ (mp_obj_t)&mp_const_none_obj}, }
// These macros are used to define constant map/dict objects
// You can put "static" in front of the definition to make it local
@@ -639,9 +648,9 @@ mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type);
mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg);
mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args);
-mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg);
-mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
-mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const char *fmt, va_list ap); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
+mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg);
+mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
+mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list ap); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table);
mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table);
mp_obj_t mp_obj_new_fun_viper(size_t n_args, void *fun_data, mp_uint_t type_sig);
diff --git a/py/objexcept.c b/py/objexcept.c
index 68897d44d..8bd6245a4 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -114,7 +114,15 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin
} else if (o->args->len == 1) {
// try to provide a nice OSError error message
if (o->base.type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(o->args->items[0])) {
- const char* msg = mp_errno_to_str(o->args->items[0]);
+ const compressed_string_t* common = mp_common_errno_to_str(o->args->items[0]);
+ const char* msg;
+ char decompressed[50];
+ if (common != NULL && common->length <= 50) {
+ decompress(common, decompressed);
+ msg = decompressed;
+ } else {
+ msg = mp_errno_to_str(o->args->items[0]);
+ }
if (msg[0] != '\0') {
mp_printf(print, "[Errno " INT_FMT "] %s", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), msg);
return;
@@ -311,7 +319,7 @@ mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args,
return exc_type->make_new(exc_type, n_args, 0, args);
}
-mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg) {
+mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) {
return mp_obj_new_exception_msg_varg(exc_type, msg);
}
@@ -349,7 +357,7 @@ STATIC void exc_add_strn(void *data, const char *str, size_t len) {
}
-mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...) {
+mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) {
va_list ap;
va_start(ap, fmt);
mp_obj_t exception = mp_obj_new_exception_msg_vlist(exc_type, fmt, ap);
@@ -357,7 +365,7 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char
return exception;
}
-mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const char *fmt, va_list ap) {
+mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list ap) {
assert(fmt != NULL);
// Check that the given type is an exception type
@@ -365,7 +373,7 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const cha
// Try to allocate memory for the message
mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t);
- size_t o_str_alloc = strlen(fmt) + 1;
+ size_t o_str_alloc = fmt->length + 1;
byte *o_str_buf = m_new_maybe(byte, o_str_alloc);
bool used_emg_buf = false;
@@ -391,15 +399,16 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const cha
}
if (o_str_buf == NULL) {
- // No memory for the string buffer: assume that the fmt string is in ROM
- // and use that data as the data of the string
- o_str->len = o_str_alloc - 1; // will be equal to strlen(fmt)
- o_str->data = (const byte*)fmt;
+ // No memory for the string buffer: the string is compressed so don't add it.
+ o_str->len = 0;
+ o_str->data = NULL;
} else {
// We have some memory to format the string
struct _exc_printer_t exc_pr = {!used_emg_buf, o_str_alloc, 0, o_str_buf};
mp_print_t print = {&exc_pr, exc_add_strn};
- mp_vprintf(&print, fmt, ap);
+ char fmt_decompressed[fmt->length];
+ decompress(fmt, fmt_decompressed);
+ mp_vprintf(&print, fmt_decompressed, ap);
exc_pr.buf[exc_pr.len] = '\0';
o_str->len = exc_pr.len;
o_str->data = exc_pr.buf;
diff --git a/py/parsenum.c b/py/parsenum.c
index f6d419b91..6ef309b47 100644
--- a/py/parsenum.c
+++ b/py/parsenum.c
@@ -148,11 +148,11 @@ overflow:
value_error:
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_ValueError,
- "invalid syntax for integer");
+ translate("invalid syntax for integer"));
raise_exc(exc, lex);
} else if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL) {
mp_obj_t exc = mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- "invalid syntax for integer with base %d", base);
+ translate("invalid syntax for integer with base %d"), base);
raise_exc(exc, lex);
} else {
vstr_t vstr;
@@ -328,7 +328,7 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
}
#else
if (imag || force_complex) {
- raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "complex values not supported"), lex);
+ raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, translate("complex values not supported")), lex);
}
#endif
else {
@@ -336,9 +336,9 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
}
value_error:
- raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid syntax for number"), lex);
+ raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, translate("invalid syntax for number")), lex);
#else
- raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "decimal numbers not supported"), lex);
+ raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, translate("decimal numbers not supported")), lex);
#endif
}
diff --git a/py/py.mk b/py/py.mk
index dcaa0e805..9874dde4d 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -315,7 +315,7 @@ $(HEADER_BUILD)/qstrdefs.enum.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrd
# the lines in "" and then unwrap after the preprocessor is finished.
$(HEADER_BUILD)/qstrdefs.generated.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h
$(STEPECHO) "GEN $@"
- $(PYTHON3) $(PY_SRC)/makeqstrdata.py --translation $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@
+ $(PYTHON3) $(PY_SRC)/makeqstrdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@
$(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h
diff --git a/py/qstr.c b/py/qstr.c
index 90581664c..eea57c1e0 100755
--- a/py/qstr.c
+++ b/py/qstr.c
@@ -104,7 +104,7 @@ const qstr_pool_t mp_qstr_const_pool = {
{
#ifndef NO_QSTR
#define QDEF(id, str) str,
-#define TRANSLATION(id, str)
+#define TRANSLATION(id, length, compressed...)
#include "genhdr/qstrdefs.generated.h"
#undef TRANSLATION
#undef QDEF
diff --git a/py/runtime.c b/py/runtime.c
index 20e3e578e..3d7a97f58 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -1539,7 +1539,7 @@ NORETURN void m_malloc_fail(size_t num_bytes) {
translate("memory allocation failed, allocating %u bytes"), (uint)num_bytes);
}
-NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg) {
+NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) {
if (msg == NULL) {
nlr_raise(mp_obj_new_exception(exc_type));
} else {
@@ -1547,7 +1547,7 @@ NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg) {
}
}
-NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...) {
+NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) {
va_list argptr;
va_start(argptr,fmt);
mp_obj_t exception = mp_obj_new_exception_msg_vlist(exc_type, fmt, argptr);
@@ -1555,27 +1555,27 @@ NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const char *fmt,
nlr_raise(exception);
}
-NORETURN void mp_raise_AttributeError(const char *msg) {
+NORETURN void mp_raise_AttributeError(const compressed_string_t *msg) {
mp_raise_msg(&mp_type_AttributeError, msg);
}
-NORETURN void mp_raise_RuntimeError(const char *msg) {
+NORETURN void mp_raise_RuntimeError(const compressed_string_t *msg) {
mp_raise_msg(&mp_type_RuntimeError, msg);
}
-NORETURN void mp_raise_ImportError(const char *msg) {
+NORETURN void mp_raise_ImportError(const compressed_string_t *msg) {
mp_raise_msg(&mp_type_ImportError, msg);
}
-NORETURN void mp_raise_IndexError(const char *msg) {
+NORETURN void mp_raise_IndexError(const compressed_string_t *msg) {
mp_raise_msg(&mp_type_IndexError, msg);
}
-NORETURN void mp_raise_ValueError(const char *msg) {
+NORETURN void mp_raise_ValueError(const compressed_string_t *msg) {
mp_raise_msg(&mp_type_ValueError, msg);
}
-NORETURN void mp_raise_ValueError_varg(const char *fmt, ...) {
+NORETURN void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...) {
va_list argptr;
va_start(argptr,fmt);
mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_ValueError, fmt, argptr);
@@ -1583,11 +1583,11 @@ NORETURN void mp_raise_ValueError_varg(const char *fmt, ...) {
nlr_raise(exception);
}
-NORETURN void mp_raise_TypeError(const char *msg) {
+NORETURN void mp_raise_TypeError(const compressed_string_t *msg) {
mp_raise_msg(&mp_type_TypeError, msg);
}
-NORETURN void mp_raise_TypeError_varg(const char *fmt, ...) {
+NORETURN void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...) {
va_list argptr;
va_start(argptr,fmt);
mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_TypeError, fmt, argptr);
@@ -1600,7 +1600,7 @@ NORETURN void mp_raise_OSError(int errno_) {
}
-NORETURN void mp_raise_NotImplementedError(const char *msg) {
+NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) {
mp_raise_msg(&mp_type_NotImplementedError, msg);
}
diff --git a/py/runtime.h b/py/runtime.h
index 95f89ee9e..9c7ffc02f 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -147,18 +147,18 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level);
mp_obj_t mp_import_from(mp_obj_t module, qstr name);
void mp_import_all(mp_obj_t module);
-NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg);
-NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...);
-NORETURN void mp_raise_ValueError(const char *msg);
-NORETURN void mp_raise_ValueError_varg(const char *fmt, ...);
-NORETURN void mp_raise_TypeError(const char *msg);
-NORETURN void mp_raise_TypeError_varg(const char *fmt, ...);
-NORETURN void mp_raise_AttributeError(const char *msg);
-NORETURN void mp_raise_RuntimeError(const char *msg);
-NORETURN void mp_raise_ImportError(const char *msg);
-NORETURN void mp_raise_IndexError(const char *msg);
+NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg);
+NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...);
+NORETURN void mp_raise_ValueError(const compressed_string_t *msg);
+NORETURN void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...);
+NORETURN void mp_raise_TypeError(const compressed_string_t *msg);
+NORETURN void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...);
+NORETURN void mp_raise_AttributeError(const compressed_string_t *msg);
+NORETURN void mp_raise_RuntimeError(const compressed_string_t *msg);
+NORETURN void mp_raise_ImportError(const compressed_string_t *msg);
+NORETURN void mp_raise_IndexError(const compressed_string_t *msg);
NORETURN void mp_raise_OSError(int errno_);
-NORETURN void mp_raise_NotImplementedError(const char *msg);
+NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg);
NORETURN void mp_raise_recursion_depth(void);
#if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG
diff --git a/py/vm.c b/py/vm.c
index 498ecb491..72d0d0d60 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -252,7 +252,7 @@ dispatch_loop:
if (obj_shared == MP_OBJ_NULL) {
local_name_error: {
MARK_EXC_IP_SELECTIVE();
- mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NameError, "local variable referenced before assignment");
+ mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NameError, translate("local variable referenced before assignment"));
RAISE(obj);
}
}
@@ -1139,7 +1139,7 @@ unwind_return:
}
}
if (obj == MP_OBJ_NULL) {
- obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, "no active exception to reraise");
+ obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, translate("no active exception to reraise"));
RAISE(obj);
}
} else {
@@ -1281,7 +1281,7 @@ yield:
} else
#endif
{
- mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NotImplementedError, "byte code not implemented");
+ mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NotImplementedError, translate("byte code not implemented"));
nlr_pop();
fastn[0] = obj;
return MP_VM_RETURN_EXCEPTION;
diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c
index 831baea90..8bfa4c15b 100644
--- a/shared-bindings/audiobusio/PDMIn.c
+++ b/shared-bindings/audiobusio/PDMIn.c
@@ -196,7 +196,7 @@ STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destinat
mp_buffer_info_t bufinfo;
if (MP_OBJ_IS_TYPE(destination, &mp_type_fileio)) {
- mp_raise_NotImplementedError("");
+ mp_raise_NotImplementedError(translate("Cannot record to a file"));
} else if (mp_get_buffer(destination, &bufinfo, MP_BUFFER_WRITE)) {
if (bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL) < length) {
mp_raise_ValueError(translate("Destination capacity is smaller than destination_length."));
diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c
new file mode 100644
index 000000000..d2e001e4c
--- /dev/null
+++ b/shared-bindings/i2cslave/I2CSlave.c
@@ -0,0 +1,450 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Noralf Trønnes
+ *
+ * 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 "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/i2cslave/I2CSlave.h"
+#include "shared-bindings/time/__init__.h"
+#include "shared-bindings/util.h"
+
+#include "lib/utils/buffer_helper.h"
+#include "lib/utils/context_manager_helpers.h"
+#include "lib/utils/interrupt_char.h"
+
+#include "py/mperrno.h"
+#include "py/mphal.h"
+#include "py/obj.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+
+STATIC mp_obj_t mp_obj_new_i2cslave_i2c_slave_request(i2cslave_i2c_slave_obj_t *slave, uint8_t address, bool is_read, bool is_restart) {
+ i2cslave_i2c_slave_request_obj_t *self = m_new_obj(i2cslave_i2c_slave_request_obj_t);
+ self->base.type = &i2cslave_i2c_slave_request_type;
+ self->slave = slave;
+ self->address = address;
+ self->is_read = is_read;
+ self->is_restart = is_restart;
+ return (mp_obj_t)self;
+}
+
+//| .. currentmodule:: i2cslave
+//|
+//| :class:`I2CSlave` --- Two wire serial protocol slave
+//| ----------------------------------------------------
+//|
+//| .. class:: I2CSlave(scl, sda, addresses, smbus=False)
+//|
+//| I2C is a two-wire protocol for communicating between devices.
+//| This implements the slave side.
+//|
+//| :param ~microcontroller.Pin scl: The clock pin
+//| :param ~microcontroller.Pin sda: The data pin
+//| :param tuple addresses: The I2C addresses to respond to (how many is hw dependent).
+//| :param bool smbus: Use SMBUS timings if the hardware supports it
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);
+ i2cslave_i2c_slave_obj_t *self = m_new_obj(i2cslave_i2c_slave_obj_t);
+ self->base.type = &i2cslave_i2c_slave_type;
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+ enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_addresses, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_smbus, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ };
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ assert_pin(args[ARG_scl].u_obj, false);
+ assert_pin(args[ARG_sda].u_obj, false);
+ const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj);
+ assert_pin_free(scl);
+ const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj);
+ assert_pin_free(sda);
+
+ mp_obj_iter_buf_t iter_buf;
+ mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf);
+ mp_obj_t item;
+ uint8_t *addresses = NULL;
+ unsigned int i = 0;
+ while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
+ mp_int_t value;
+ if (!mp_obj_get_int_maybe(item, &value)) {
+ mp_raise_TypeError(translate("can't convert address to int"));
+ }
+ if (value < 0x00 || value > 0x7f) {
+ mp_raise_ValueError(translate("address out of bounds"));
+ }
+ addresses = m_renew(uint8_t, addresses, i, i + 1);
+ addresses[i++] = value;
+ }
+ if (i == 0) {
+ mp_raise_ValueError(translate("addresses is empty"));
+ }
+
+ common_hal_i2cslave_i2c_slave_construct(self, scl, sda, addresses, i, args[ARG_smbus].u_bool);
+ return (mp_obj_t)self;
+}
+
+//| .. method:: deinit()
+//|
+//| Releases control of the underlying hardware so other classes can use it.
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_obj_deinit(mp_obj_t self_in) {
+ mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_type));
+ i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_i2cslave_i2c_slave_deinit(self);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(i2cslave_i2c_slave_deinit_obj, i2cslave_i2c_slave_obj_deinit);
+
+//| .. method:: __enter__()
+//|
+//| No-op used in Context Managers.
+//|
+// Provided by context manager helper.
+
+//| .. method:: __exit__()
+//|
+//| Automatically deinitializes the hardware on context exit. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_type));
+ i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+ common_hal_i2cslave_i2c_slave_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave___exit___obj, 4, 4, i2cslave_i2c_slave_obj___exit__);
+
+//| .. method:: request(timeout=-1)
+//|
+//| Wait for an I2C request from a master.
+//|
+//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once
+//| :return: I2C Slave Request or None if timeout=-1 and there's no request
+//| :rtype: ~i2cslave.I2CSlaveRequest
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_type));
+ i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ raise_error_if_deinited(common_hal_i2cslave_i2c_slave_deinited(self));
+ enum { ARG_timeout };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} },
+ };
+ 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);
+
+ #if MICROPY_PY_BUILTINS_FLOAT
+ float f = mp_obj_get_float(args[ARG_timeout].u_obj) * 1000;
+ int timeout_ms = (int)f;
+ #else
+ int timeout_ms = mp_obj_get_int(args[ARG_timeout].u_obj) * 1000;
+ #endif
+
+ bool forever = false;
+ uint64_t timeout_end = 0;
+ if (timeout_ms == 0) {
+ forever = true;
+ } else if (timeout_ms > 0) {
+ timeout_end = common_hal_time_monotonic() + timeout_ms;
+ }
+
+ int last_error = 0;
+
+ do {
+ uint8_t address;
+ bool is_read;
+ bool is_restart;
+
+ MICROPY_VM_HOOK_LOOP
+ if (mp_hal_is_interrupted()) {
+ return mp_const_none;
+ }
+
+ int status = common_hal_i2cslave_i2c_slave_is_addressed(self, &address, &is_read, &is_restart);
+ if (status < 0) {
+ // On error try one more time before bailing out
+ if (last_error) {
+ mp_raise_OSError(last_error);
+ }
+ last_error = -status;
+ mp_hal_delay_ms(10);
+ continue;
+ }
+
+ last_error = 0;
+
+ if (status == 0) {
+ mp_hal_delay_us(10);
+ continue;
+ }
+
+ return mp_obj_new_i2cslave_i2c_slave_request(self, address, is_read, is_restart);
+ } while (forever || common_hal_time_monotonic() < timeout_end);
+
+ if (timeout_ms > 0) {
+ mp_raise_OSError(MP_ETIMEDOUT);
+ }
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(i2cslave_i2c_slave_request_obj, 1, i2cslave_i2c_slave_request);
+
+STATIC const mp_rom_map_elem_t i2cslave_i2c_slave_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2cslave_i2c_slave_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cslave_i2c_slave___exit___obj) },
+ { MP_ROM_QSTR(MP_QSTR_request), MP_ROM_PTR(&i2cslave_i2c_slave_request_obj) },
+
+};
+
+STATIC MP_DEFINE_CONST_DICT(i2cslave_i2c_slave_locals_dict, i2cslave_i2c_slave_locals_dict_table);
+
+const mp_obj_type_t i2cslave_i2c_slave_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_I2CSlave,
+ .make_new = i2cslave_i2c_slave_make_new,
+ .locals_dict = (mp_obj_dict_t*)&i2cslave_i2c_slave_locals_dict,
+};
+
+
+//| :class:`I2CSlaveRequest` --- I2C Slave Request
+//| ----------------------------------------------
+//|
+//| .. class:: I2CSlaveRequest(slave, address, is_read, is_restart)
+//|
+//| I2C transfer request from a master.
+//| This cannot be instantiated directly, but is returned by :py:meth:`I2CSlave.request`.
+//|
+//| :param ~i2cslave.I2CSlave slave: The I2C Slave receiving this request
+//| :param int address: I2C address
+//| :param bool is_read: I2C Master read request
+//| :param bool is_restart: Repeated Start Condition
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+ mp_arg_check_num(n_args, n_kw, 4, 4, false);
+ return mp_obj_new_i2cslave_i2c_slave_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3]));
+}
+
+//| .. method:: __enter__()
+//|
+//| No-op used in Context Managers.
+//|
+// Provided by context manager helper.
+
+//| .. method:: __exit__()
+//|
+//| Close the request.
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_request_type));
+ i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+ common_hal_i2cslave_i2c_slave_close(self->slave);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave_request___exit___obj, 4, 4, i2cslave_i2c_slave_request_obj___exit__);
+
+//| .. attribute:: address
+//|
+//| The I2C address of the request.
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request_get_address(mp_obj_t self_in) {
+ mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
+ i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return mp_obj_new_int(self->address);
+}
+MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_address_obj, i2cslave_i2c_slave_request_get_address);
+
+//| .. attribute:: is_read
+//|
+//| The I2C master is reading from the device.
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request_get_is_read(mp_obj_t self_in) {
+ mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
+ i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return mp_obj_new_bool(self->is_read);
+}
+MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_is_read_obj, i2cslave_i2c_slave_request_get_is_read);
+
+//| .. attribute:: is_restart
+//|
+//| Is Repeated Start Condition.
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request_get_is_restart(mp_obj_t self_in) {
+ mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
+ i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return mp_obj_new_bool(self->is_restart);
+}
+MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_is_restart_obj, i2cslave_i2c_slave_request_get_is_restart);
+
+//| .. method:: read(n=-1, ack=True)
+//|
+//| Read data.
+//| If ack=False, the caller is responsible for calling :py:meth:`I2CSlaveRequest.ack`.
+//|
+//| :param int n: Number of bytes to read (negative means all)
+//| :param bool ack: Whether or not to send an ACK after the n'th byte
+//| :return: Bytes read
+//| :rtype: bytearray
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_request_type));
+ i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ enum { ARG_n, ARG_ack };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_n, MP_ARG_INT, {.u_int = -1} },
+ { MP_QSTR_ack, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ };
+ 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);
+
+ if (self->is_read) {
+ mp_raise_OSError(MP_EACCES);
+ }
+
+ int n = args[ARG_n].u_int;
+ if (n == 0) {
+ return mp_obj_new_bytearray(0, NULL);
+ }
+ bool ack = args[ARG_ack].u_bool;
+
+ int i = 0;
+ uint8_t *buffer = NULL;
+ uint64_t timeout_end = common_hal_time_monotonic() + 10 * 1000;
+ while (common_hal_time_monotonic() < timeout_end) {
+ MICROPY_VM_HOOK_LOOP
+ if (mp_hal_is_interrupted()) {
+ break;
+ }
+
+ uint8_t data;
+ int num = common_hal_i2cslave_i2c_slave_read_byte(self->slave, &data);
+ if (num == 0) {
+ break;
+ }
+
+ buffer = m_renew(uint8_t, buffer, i, i + 1);
+ buffer[i++] = data;
+ if (i == n) {
+ if (ack) {
+ common_hal_i2cslave_i2c_slave_ack(self->slave, true);
+ }
+ break;
+ }
+ common_hal_i2cslave_i2c_slave_ack(self->slave, true);
+ }
+
+ return mp_obj_new_bytearray(i, buffer);
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(i2cslave_i2c_slave_request_read_obj, 1, i2cslave_i2c_slave_request_read);
+
+//| .. method:: write(buffer)
+//|
+//| Write the data contained in buffer.
+//|
+//| :param bytearray buffer: Write out the data in this buffer
+//| :return: Number of bytes written
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request_write(mp_obj_t self_in, mp_obj_t buf_in) {
+ mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
+ i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (!self->is_read) {
+ mp_raise_OSError(MP_EACCES);
+ }
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
+
+ for (size_t i = 0; i < bufinfo.len; i++) {
+ MICROPY_VM_HOOK_LOOP
+ if (mp_hal_is_interrupted()) {
+ break;
+ }
+
+ int num = common_hal_i2cslave_i2c_slave_write_byte(self->slave, ((uint8_t *)(bufinfo.buf))[i]);
+ if (num == 0) {
+ return mp_obj_new_int(i);
+ }
+ }
+
+ return mp_obj_new_int(bufinfo.len);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(i2cslave_i2c_slave_request_write_obj, i2cslave_i2c_slave_request_write);
+
+//| .. method:: ack(ack=True)
+//|
+//| Acknowledge or Not Acknowledge last byte received.
+//| Use together with :py:meth:`I2CSlaveRequest.read` ack=False.
+//|
+//| :param bool ack: Whether to send an ACK or NACK
+//|
+STATIC mp_obj_t i2cslave_i2c_slave_request_ack(uint n_args, const mp_obj_t *args) {
+ mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_request_type));
+ i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+ bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]);
+
+ if (self->is_read) {
+ mp_raise_OSError(MP_EACCES);
+ }
+
+ common_hal_i2cslave_i2c_slave_ack(self->slave, ack);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave_request_ack_obj, 1, 2, i2cslave_i2c_slave_request_ack);
+
+STATIC mp_obj_t i2cslave_i2c_slave_request_close(mp_obj_t self_in) {
+ mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
+ i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_i2cslave_i2c_slave_close(self->slave);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(i2cslave_i2c_slave_request_close_obj, i2cslave_i2c_slave_request_close);
+
+STATIC const mp_rom_map_elem_t i2cslave_i2c_slave_request_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cslave_i2c_slave_request___exit___obj) },
+ { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&i2cslave_i2c_slave_request_address_obj) },
+ { MP_ROM_QSTR(MP_QSTR_is_read), MP_ROM_PTR(&i2cslave_i2c_slave_request_is_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_is_restart), MP_ROM_PTR(&i2cslave_i2c_slave_request_is_restart_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&i2cslave_i2c_slave_request_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&i2cslave_i2c_slave_request_write_obj) },
+ { MP_ROM_QSTR(MP_QSTR_ack), MP_ROM_PTR(&i2cslave_i2c_slave_request_ack_obj) },
+ { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&i2cslave_i2c_slave_request_close_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(i2cslave_i2c_slave_request_locals_dict, i2cslave_i2c_slave_request_locals_dict_table);
+
+const mp_obj_type_t i2cslave_i2c_slave_request_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_I2CSlaveRequest,
+ .make_new = i2cslave_i2c_slave_request_make_new,
+ .locals_dict = (mp_obj_dict_t*)&i2cslave_i2c_slave_request_locals_dict,
+};
diff --git a/shared-bindings/i2cslave/I2CSlave.h b/shared-bindings/i2cslave/I2CSlave.h
new file mode 100644
index 000000000..abb761416
--- /dev/null
+++ b/shared-bindings/i2cslave/I2CSlave.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Noralf Trønnes
+ *
+ * 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.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H
+
+#include "py/obj.h"
+
+#include "common-hal/microcontroller/Pin.h"
+#include "common-hal/i2cslave/I2CSlave.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ i2cslave_i2c_slave_obj_t *slave;
+ uint16_t address;
+ bool is_read;
+ bool is_restart;
+} i2cslave_i2c_slave_request_obj_t;
+
+extern const mp_obj_type_t i2cslave_i2c_slave_request_type;
+
+extern const mp_obj_type_t i2cslave_i2c_slave_type;
+
+extern void common_hal_i2cslave_i2c_slave_construct(i2cslave_i2c_slave_obj_t *self,
+ const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda,
+ uint8_t *addresses, unsigned int num_addresses, bool smbus);
+extern void common_hal_i2cslave_i2c_slave_deinit(i2cslave_i2c_slave_obj_t *self);
+extern bool common_hal_i2cslave_i2c_slave_deinited(i2cslave_i2c_slave_obj_t *self);
+
+extern int common_hal_i2cslave_i2c_slave_is_addressed(i2cslave_i2c_slave_obj_t *self,
+ uint8_t *address, bool *is_read, bool *is_restart);
+extern int common_hal_i2cslave_i2c_slave_read_byte(i2cslave_i2c_slave_obj_t *self, uint8_t *data);
+extern int common_hal_i2cslave_i2c_slave_write_byte(i2cslave_i2c_slave_obj_t *self, uint8_t data);
+extern void common_hal_i2cslave_i2c_slave_ack(i2cslave_i2c_slave_obj_t *self, bool ack);
+extern void common_hal_i2cslave_i2c_slave_close(i2cslave_i2c_slave_obj_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H
diff --git a/shared-bindings/i2cslave/__init__.c b/shared-bindings/i2cslave/__init__.c
new file mode 100644
index 000000000..1c692e54e
--- /dev/null
+++ b/shared-bindings/i2cslave/__init__.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Noralf Trønnes
+ *
+ * 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 <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+//#include "shared-bindings/i2cslave/__init__.h"
+#include "shared-bindings/i2cslave/I2CSlave.h"
+
+#include "py/runtime.h"
+
+//| :mod:`i2cslave` --- Two wire serial protocol slave
+//| ==================================================
+//|
+//| .. module:: i2cslave
+//| :synopsis: Two wire serial protocol slave
+//| :platform: SAMD21, SAMD51
+//|
+//| The `i2cslave` module contains classes to support a I2C slave.
+//|
+//| Classes
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| I2CSlave
+//|
+//| Example emulating 2 devices::
+//|
+//| import board
+//| from i2cslave import I2CSlave
+//|
+//| regs = [0] * 16
+//| index = 0
+//|
+//| with I2CSlave(board.SCL, board.SDA, (0x40, 0x41)) as slave:
+//| while True:
+//| r = slave.request()
+//| if not r:
+//| # Maybe do some housekeeping
+//| continue
+//| with r: # Closes the transfer if necessary by sending a NACK or feeding the master dummy bytes
+//| if r.address == 0x40:
+//| if not r.is_read: # Master write which is Slave read
+//| b = r.read(1)
+//| if not b or b[0] > 15:
+//| break
+//| index = b[0]
+//| b = r.read(1)
+//| if b:
+//| regs[index] = b[0]
+//| elif r.is_restart: # Combined transfer: This is the Master read message
+//| n = r.write(bytes([regs[index]]))
+//| #else:
+//| # A read transfer is not supported in this example
+//| # If the Master tries, it will get 0xff byte(s) by the ctx manager (r.close())
+//| elif r.address == 0x41:
+//| if not r.is_read:
+//| b = r.read(1)
+//| if b and b[0] == 0xde:
+//| # do something
+//| pass
+//|
+//| This example sets up an I2C slave that can be accessed from Linux like this::
+//|
+//| $ i2cget -y 1 0x40 0x01
+//| 0x00
+//| $ i2cset -y 1 0x40 0x01 0xaa
+//| $ i2cget -y 1 0x40 0x01
+//| 0xaa
+//|
+//| .. warning::
+//| I2CSlave makes use of clock stretching in order to slow down the master.
+//| Make sure the I2C master supports this.
+//|
+//| Raspberry Pi in particular does not support this with its I2C hw block.
+//| This can be worked around by using the ``i2c-gpio`` bit banging driver.
+//| Since the RPi firmware uses the hw i2c, it's not possible to emulate a HAT eeprom.
+//|
+
+STATIC const mp_rom_map_elem_t i2cslave_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2cslave) },
+ { MP_ROM_QSTR(MP_QSTR_I2CSlave), MP_ROM_PTR(&i2cslave_i2c_slave_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(i2cslave_module_globals, i2cslave_module_globals_table);
+
+const mp_obj_module_t i2cslave_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&i2cslave_module_globals,
+};
diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst
index bcd6e1d1e..ec7f89f03 100644
--- a/shared-bindings/index.rst
+++ b/shared-bindings/index.rst
@@ -34,6 +34,7 @@ Module Supported Ports
`digitalio` **All Supported**
`gamepad` **SAMD Express, nRF**
`hashlib` **ESP8266**
+`i2cslave` **SAMD Express**
`math` **All Supported**
`microcontroller` **All Supported**
`multiterminal` **ESP8266**
diff --git a/shared-bindings/os/__init__.c b/shared-bindings/os/__init__.c
index 1b8831afa..55ebd6f59 100644
--- a/shared-bindings/os/__init__.c
+++ b/shared-bindings/os/__init__.c
@@ -197,7 +197,7 @@ STATIC mp_obj_t os_urandom(mp_obj_t size_in) {
mp_int_t size = mp_obj_get_int(size_in);
uint8_t tmp[size];
if (!common_hal_os_urandom(tmp, size)) {
- mp_raise_NotImplementedError("");
+ mp_raise_NotImplementedError(translate("No hardware random available"));
}
return mp_obj_new_bytes(tmp, size);
}
diff --git a/shared-module/audioio/WaveFile.c b/shared-module/audioio/WaveFile.c
index ce5877629..7efad05e0 100644
--- a/shared-module/audioio/WaveFile.c
+++ b/shared-module/audioio/WaveFile.c
@@ -84,7 +84,7 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self,
}
// Get the sample_rate
self->sample_rate = format.sample_rate;
- self->len = 512;
+ self->len = 256;
self->channel_count = format.num_channels;
self->bits_per_sample = format.bits_per_sample;
@@ -114,13 +114,13 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self,
self->buffer = m_malloc(self->len, false);
if (self->buffer == NULL) {
common_hal_audioio_wavefile_deinit(self);
- mp_raise_msg(&mp_type_MemoryError, "");
+ mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate first buffer"));
}
self->second_buffer = m_malloc(self->len, false);
if (self->second_buffer == NULL) {
common_hal_audioio_wavefile_deinit(self);
- mp_raise_msg(&mp_type_MemoryError, "");
+ mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate second buffer"));
}
}
diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c
index 34c5dfb6f..6c8be3be8 100755
--- a/supervisor/shared/memory.c
+++ b/supervisor/shared/memory.c
@@ -43,7 +43,7 @@ void memory_init(void) {
}
void free_memory(supervisor_allocation* allocation) {
- uint8_t index = 0;
+ int32_t index = 0;
bool found = false;
for (index = 0; index < CIRCUITPY_SUPERVISOR_ALLOC_COUNT; index++) {
found = allocation == &allocations[index];
diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c
index 570b4501e..1fa361c15 100644
--- a/supervisor/shared/translate.c
+++ b/supervisor/shared/translate.c
@@ -26,17 +26,58 @@
#include "supervisor/shared/translate.h"
+#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
-inline __attribute__((always_inline)) const char* translate(const char* c) {
+#ifndef NO_QSTR
+#include "genhdr/compression.generated.h"
+#endif
+
+char* decompress(const compressed_string_t* compressed, char* decompressed) {
+ uint8_t this_byte = 0;
+ uint8_t this_bit = 7;
+ uint8_t b = compressed->data[this_byte];
+ // Stop one early because the last byte is always NULL.
+ for (uint16_t i = 0; i < compressed->length - 1; i++) {
+ uint32_t bits = 0;
+ uint8_t bit_length = 0;
+ uint32_t max_code = lengths[0];
+ uint32_t searched_length = lengths[0];
+ while (true) {
+ bits <<= 1;
+ if ((0x80 & b) != 0) {
+ bits |= 1;
+ }
+ b <<= 1;
+ bit_length += 1;
+ if (this_bit == 0) {
+ this_bit = 7;
+ this_byte += 1;
+ b = compressed->data[this_byte]; // This may read past the end but its never used.
+ } else {
+ this_bit -= 1;
+ }
+ if (max_code > 0 && bits < max_code) {
+ break;
+ }
+ max_code = (max_code << 1) + lengths[bit_length];
+ searched_length += lengths[bit_length];
+ }
+ decompressed[i] = values[searched_length + bits - max_code];
+ }
+
+ decompressed[compressed->length-1] = '\0';
+ return decompressed;
+}
+
+inline __attribute__((always_inline)) const compressed_string_t* translate(const char* original) {
#ifndef NO_QSTR
#define QDEF(id, str)
- #define TRANSLATION(id, str) if (strcmp(c, id) == 0) { return str; } else
+ #define TRANSLATION(id, len, compressed...) if (strcmp(original, id) == 0) { static const compressed_string_t v = {.length = len, .data = compressed}; return &v; } else
#include "genhdr/qstrdefs.generated.h"
#undef TRANSLATION
#undef QDEF
#endif
- {
- return "";
- }
+ return NULL;
}
diff --git a/supervisor/shared/translate.h b/supervisor/shared/translate.h
index bd474e7eb..3a1ba4076 100644
--- a/supervisor/shared/translate.h
+++ b/supervisor/shared/translate.h
@@ -27,6 +27,15 @@
#ifndef MICROPY_INCLUDED_SUPERVISOR_TRANSLATE_H
#define MICROPY_INCLUDED_SUPERVISOR_TRANSLATE_H
-const char* translate(const char* c);
+#include <stdint.h>
+
+typedef struct {
+ uint16_t length;
+ const uint8_t data[];
+} compressed_string_t;
+
+const compressed_string_t* translate(const char* c);
+
+char* decompress(const compressed_string_t* compressed, char* decompressed);
#endif // MICROPY_INCLUDED_SUPERVISOR_TRANSLATE_H
diff --git a/tools/huffman b/tools/huffman
new file mode 160000
+Subproject 27b1bba76198a0b343f694a6d680b5293d1c56a