Merge branch 'master' of github.com:adafruit/circuitpython into translate-german
This commit is contained in:
commit
361f057927
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,7 +7,6 @@
|
||||
*.bin
|
||||
*.map
|
||||
*.hex
|
||||
!ports/nrf/**/bootloader/**/*.hex
|
||||
*.dis
|
||||
*.exe
|
||||
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
|
||||
|
@ -30,7 +30,8 @@ env:
|
||||
- TRAVIS_BOARD=pirkey_m0
|
||||
- TRAVIS_BOARD=gemma_m0
|
||||
- TRAVIS_BOARD=hallowing_m0_express
|
||||
- TRAVIS_BOARD=feather52832
|
||||
- TRAVIS_BOARD=feather_nrf52832
|
||||
- TRAVIS_BOARD=feather_nrf52840_express
|
||||
|
||||
addons:
|
||||
artifacts:
|
||||
@ -54,7 +55,7 @@ before_script:
|
||||
- ([[ -z "$TRAVIS_BOARD" || $TRAVIS_BOARD = "feather_huzzah" ]] || (wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~trusty1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb))
|
||||
|
||||
# For nrf builds
|
||||
- ([[ $TRAVIS_BOARD != "feather52832" && $TRAVIS_BOARD != "pca10056" ]] || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh)
|
||||
- ([[ $TRAVIS_BOARD != "feather_nrf52832" && $TRAVIS_BOARD != "feather_nrf52840_express" && $TRAVIS_BOARD != "pca10056" ]] || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh)
|
||||
# For huzzah builds
|
||||
- if [[ $TRAVIS_BOARD = "feather_huzzah" ]]; then wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar xavf xtensa-lx106-elf-standalone.tar.gz; PATH=$(readlink -f xtensa-lx106-elf/bin):$PATH; fi
|
||||
# For coverage testing (upgrade is used to get latest urllib3 version)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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 {
|
||||
|
@ -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]);
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 6d96b12e27ae60ca500365ee2137105145ada9dd
|
||||
Subproject commit 7b35cd0203bc409d7c1aefc075672103cb4a913e
|
@ -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
|
||||
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
786
locale/en_US.po
786
locale/en_US.po
File diff suppressed because it is too large
Load Diff
786
locale/es.po
786
locale/es.po
File diff suppressed because it is too large
Load Diff
2281
locale/fr.po
Normal file
2281
locale/fr.po
Normal file
File diff suppressed because it is too large
Load Diff
43
main.c
43
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);
|
||||
|
2
ports/atmel-samd/Makefile
Executable file → Normal file
2
ports/atmel-samd/Makefile
Executable file → Normal file
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -39,39 +39,41 @@
|
||||
// Number of times to try to send packet if failed.
|
||||
#define ATTEMPTS 2
|
||||
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) {
|
||||
if (*sercom_index == scl->sercom[j].index &&
|
||||
scl->sercom[j].pad == 1) {
|
||||
*scl_pinmux = PINMUX(scl->number, (j == 0) ? MUX_C : MUX_D);
|
||||
return potential_sercom;
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
Sercom* sercom = NULL;
|
||||
uint8_t sercom_index;
|
||||
uint32_t sda_pinmux = 0;
|
||||
uint32_t 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) {
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (sercom != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
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"));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
252
ports/atmel-samd/common-hal/i2cslave/I2CSlave.c
Normal file
252
ports/atmel-samd/common-hal/i2cslave/I2CSlave.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Glenn Ruben Bakke
|
||||
* 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
|
||||
@ -24,15 +24,22 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FEATHER52840
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_SLAVE_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_SLAVE_H
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "Feather52840"
|
||||
#define MICROPY_HW_MCU_NAME "nRF52840"
|
||||
#define MICROPY_PY_SYS_PLATFORM "Feather52840"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
#define MICROPY_HW_UART_RX NRF_GPIO_PIN_MAP(0, 8)
|
||||
#define MICROPY_HW_UART_TX NRF_GPIO_PIN_MAP(0, 6)
|
||||
#define MICROPY_HW_UART_HWFC (0)
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
|
||||
#define PORT_HEAP_SIZE (128 * 1024)
|
||||
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
|
||||
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
|
1
ports/atmel-samd/common-hal/i2cslave/__init__.c
Normal file
1
ports/atmel-samd/common-hal/i2cslave/__init__.c
Normal file
@ -0,0 +1 @@
|
||||
// No i2cslave module functions.
|
@ -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 {\
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 1140ff6d7ed413aa1e2f34c5d847dcc41c924bb9
|
||||
Subproject commit 156279784cb3d22f7f8a8d93b4bb55e2d912a5f8
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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"));
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -248,7 +248,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
||||
$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os
|
||||
$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os
|
||||
|
||||
.phony: all flash sd binary hex bootloader
|
||||
.phony: all flash sd binary hex
|
||||
|
||||
all: binary hex uf2
|
||||
|
||||
@ -266,6 +266,11 @@ hex: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
$(BUILD)/$(OUTPUT_FILENAME).hex: $(BUILD)/$(OUTPUT_FILENAME).elf
|
||||
$(OBJCOPY) -O ihex $< $@
|
||||
|
||||
## Create uf2 file
|
||||
uf2: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
$(ECHO) "Create $(OUTPUT_FILENAME).uf2"
|
||||
$(PYTHON2) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "$(BUILD)/$(OUTPUT_FILENAME).uf2" $^
|
||||
|
||||
#####################
|
||||
# Flash with debugger
|
||||
#####################
|
||||
@ -286,9 +291,6 @@ sd: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
nrfjprog --program $< --sectorerase -f $(MCU_VARIANT)
|
||||
nrfjprog --reset -f $(MCU_VARIANT)
|
||||
|
||||
bootloader:
|
||||
nrfjprog --program $(BOOT_FILE).hex -f nrf52 --chiperase --reset
|
||||
|
||||
else ifeq ($(FLASHER), pyocd)
|
||||
|
||||
flash: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
@ -303,21 +305,19 @@ sd: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
pyocd-flashtool -t $(MCU_SUB_VARIANT) $< --sector_erase
|
||||
pyocd-tool -t $(MCU_SUB_VARIANT) reset $(BOOT_SETTING_ADDR)
|
||||
|
||||
bootloader:
|
||||
pyocd-flashtool -t $(MCU_SUB_VARIANT) $(BOOT_FILE).hex --chip_erase
|
||||
pyocd-tool -t $(MCU_SUB_VARIANT) reset
|
||||
|
||||
endif
|
||||
|
||||
#####################
|
||||
# Flash with DFU
|
||||
#####################
|
||||
.phony: dfu-gen dfu-flash dfu-bootloader
|
||||
.phony: dfu-gen dfu-flash
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
NRFUTIL = ../../lib/nrfutil/binaries/win32/nrfutil.exe
|
||||
NRFUTIL = adafruit-nrfutil
|
||||
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52840)
|
||||
DFU_TOUCH = --touch 1200
|
||||
else
|
||||
NRFUTIL = nrfutil
|
||||
DFU_TOUCH =
|
||||
endif
|
||||
|
||||
check_defined = \
|
||||
@ -327,22 +327,16 @@ __check_defined = \
|
||||
$(if $(value $1),, \
|
||||
$(error Undefined make flag: $1$(if $2, ($2))))
|
||||
|
||||
dfu-gen: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
$(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip
|
||||
|
||||
## Flash with DFU serial
|
||||
dfu-flash: $(BUILD)/dfu-package.zip
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyUSB0)
|
||||
$(NRFUTIL) --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank
|
||||
$(NRFUTIL) --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank $(DFU_TOUCH)
|
||||
|
||||
dfu-bootloader:
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0)
|
||||
$(NRFUTIL) --verbose dfu serial --package $(BOOT_FILE).zip -p $(SERIAL) -b 115200
|
||||
## Create DFU package file
|
||||
dfu-gen: $(BUILD)/dfu-package.zip
|
||||
|
||||
uf2: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
$(ECHO) "Create $(OUTPUT_FILENAME).uf2"
|
||||
$(PYTHON2) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "$(BUILD)/$(OUTPUT_FILENAME).uf2" $^
|
||||
|
||||
$(BUILD)/dfu-package.zip: dfu-gen
|
||||
$(BUILD)/dfu-package.zip: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
$(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip
|
||||
|
||||
$(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ)
|
||||
$(ECHO) "LINK $@"
|
||||
|
@ -36,9 +36,9 @@ the following links:
|
||||
> **NOTE**: These board specific readmes may be more up to date than the
|
||||
generic board-neutral documentation further down.
|
||||
|
||||
* Adafruit [Feather nRF52](boards/feather52/README.md): 512KB Flash, 64KB SRAM
|
||||
* Adafruit [Feather nRF52840](boards/feather52840/README.md): 1MB Flash, 256KB SRAM
|
||||
* Nordic PCA10056 see [Feather nRF52840](boards/feather52840/README.md)
|
||||
* Adafruit [Feather nRF52](boards/feather_nrf52832/README.md): 512KB Flash, 64KB SRAM
|
||||
* Adafruit [Feather nRF52840](boards/feather_nrf52840_express/README.md): 1MB Flash, 256KB SRAM
|
||||
* Nordic PCA10056 see [Feather nRF52840](boards/pca10056/README.md)
|
||||
|
||||
For all other board targets, see the generic notes below.
|
||||
|
||||
@ -74,11 +74,12 @@ Note: further tuning of features to include in bluetooth or even setting up the
|
||||
|
||||
## Target Boards and Make Flags
|
||||
|
||||
Target Board (BOARD) | Bluetooth Stack (SD) | Bluetooth Support | Flash Util
|
||||
---------------------|-------------------------|------------------------|-------------------------------
|
||||
pca10040 | s132 | Peripheral and Scanner | [Segger](#segger-targets)
|
||||
feather52832 | s132 | Peripheral and Scanner | [UART DFU](#dfu-targets)
|
||||
pca10056 | s140 | Peripheral and Scanner | [Segger](#segger-targets)
|
||||
Target Board (BOARD) | Bluetooth Stack (SD) | Bluetooth Support | Flash Util
|
||||
-------------------------|-------------------------|------------------------|-------------------------------
|
||||
pca10040 | s132 | Peripheral and Scanner | [Segger](#segger-targets)
|
||||
pca10056 | s140 | Peripheral and Scanner | [Segger](#segger-targets)
|
||||
feather_nrf52832 | s132 | Peripheral and Scanner | [UART DFU](#dfu-targets)
|
||||
feather_nrf52840_express | s140 | Peripheral and Scanner | UF2 bootloader
|
||||
|
||||
## Segger Targets
|
||||
|
||||
@ -98,21 +99,18 @@ note: On Linux it might be required to link SEGGER's `libjlinkarm.so` inside nrf
|
||||
|
||||
## DFU Targets
|
||||
|
||||
sudo apt-get install build-essential libffi-dev pkg-config gcc-arm-none-eabi git python python-pip
|
||||
git clone https://github.com/adafruit/Adafruit_nRF52_Arduino.git
|
||||
cd Adafruit_nRF52_Arduino/tools/nrfutil-0.5.2/
|
||||
sudo pip install -r requirements.txt
|
||||
sudo python setup.py install
|
||||
run follow command to install [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) from PyPi
|
||||
|
||||
$ pip3 install --user adafruit-nrfutil
|
||||
|
||||
**make flash** and **make sd** will not work with DFU targets. Hence, **dfu-gen** and **dfu-flash** must be used instead.
|
||||
* dfu-gen: Generates a Firmware zip to be used by the DFU flash application.
|
||||
* dfu-flash: Triggers the DFU flash application to upload the firmware from the generated Firmware zip file.
|
||||
|
||||
Example on how to generate and flash feather52832 target:
|
||||
Example on how to generate and flash feather_nrf52832 target:
|
||||
|
||||
make BOARD=feather52832 SD=s132
|
||||
make BOARD=feather52832 SD=s132 dfu-gen
|
||||
make BOARD=feather52832 SD=s132 dfu-flash
|
||||
make BOARD=feather_nrf52832 SD=s132
|
||||
make BOARD=feather52832 SD=s132 dfu-gen dfu-flash
|
||||
|
||||
## Bluetooth LE REPL
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
GNU linker script for NRF52840 w/S140 6.0.0 SoftDevice
|
||||
GNU linker script for NRF52840 w/S140 6.x.x SoftDevice
|
||||
|
||||
MEMORY MAP
|
||||
------------------------------------------------------------------------
|
||||
@ -17,7 +17,7 @@
|
||||
0x00000000..0x00000FFF (4KB) Master Boot Record
|
||||
*/
|
||||
|
||||
/* Specify the memory areas (S140 6.0.0) */
|
||||
/* Specify the memory areas (S140 6.x.x) */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000
|
@ -1,2 +0,0 @@
|
||||
# Inform git that .zip files should be treated as binary
|
||||
*.zip binary
|
@ -1,9 +0,0 @@
|
||||
# Adafruit nRF52 Feather Single-Bank Bootloader
|
||||
|
||||
These files contain an implementation of a single-bank bootloader,
|
||||
which doubles the amount of flash memory available to applications
|
||||
at the expense of safe over the air updates.
|
||||
|
||||
Two versions are present, based on release **2.0.1** and **5.0.0**
|
||||
of the Nordic S132 SoftDevice. The SoftDevice is included as poart
|
||||
of the bootloader binary.
|
Binary file not shown.
Binary file not shown.
@ -1,11 +0,0 @@
|
||||
MCU_SERIES = m4
|
||||
MCU_VARIANT = nrf52
|
||||
MCU_SUB_VARIANT = nrf52
|
||||
SD ?= s132
|
||||
SOFTDEV_VERSION ?= 2.0.1
|
||||
|
||||
LD_FILE = boards/feather52832/custom_nrf52832_dfu_app_$(SOFTDEV_VERSION).ld
|
||||
BOOT_FILE = boards/feather52832/bootloader/feather52_bootloader_$(SOFTDEV_VERSION)_s132_single
|
||||
|
||||
BOOT_SETTING_ADDR = 0x7F000
|
||||
NRF_DEFINES += -DNRF52832_XXAA
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,16 +0,0 @@
|
||||
MCU_SERIES = m4
|
||||
MCU_VARIANT = nrf52
|
||||
MCU_SUB_VARIANT = nrf52840
|
||||
SD ?= s140
|
||||
SOFTDEV_VERSION ?= 6.0.0
|
||||
|
||||
BOOT_SETTING_ADDR = 0xFF000
|
||||
BOOT_FILE = boards/$(BOARD)/bootloader/$(SOFTDEV_VERSION)/$(BOARD)_bootloader_$(SOFTDEV_VERSION)_s140
|
||||
|
||||
ifeq ($(SD),)
|
||||
LD_FILE = boards/nrf52840_1M_256k.ld
|
||||
else
|
||||
LD_FILE = boards/bluefruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_$(SOFTDEV_VERSION).ld
|
||||
endif
|
||||
|
||||
NRF_DEFINES += -DNRF52840_XXAA
|
@ -21,24 +21,15 @@ $ cd ports/nrf
|
||||
$ ./drivers/bluetooth/download_ble_stack.sh
|
||||
```
|
||||
|
||||
## Installing `nrfutil`
|
||||
## Installing `adafruit-nrfutil`
|
||||
|
||||
The Adafruit Bluefruit nRF52 Feather ships with a serial and OTA BLE bootloader
|
||||
that can be used to flash firmware images over a simple serial connection,
|
||||
using the on-board USB serial converter.
|
||||
|
||||
If you haven't installed this command-line tool yet, go to the `/libs/nrfutil`
|
||||
folder (where nrfutil 0.5.2 is installed as a sub-module) and run the following
|
||||
commands:
|
||||
run following command to install [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) from PyPi
|
||||
|
||||
> If you get a 'sudo: pip: command not found' error running 'sudo pip install',
|
||||
you can install pip via 'sudo easy_install pip'
|
||||
|
||||
```
|
||||
$ cd ../../lib/nrfutil
|
||||
$ sudo pip install -r requirements.txt
|
||||
$ sudo python setup.py install
|
||||
```
|
||||
$ pip3 install --user adafruit-nrfutil
|
||||
|
||||
# Building and flashing firmware images
|
||||
|
||||
@ -47,12 +38,12 @@ $ sudo python setup.py install
|
||||
#### REPL over UART (default settings)
|
||||
|
||||
To build a CircuitPython binary with default settings for the
|
||||
`feather52832` target enter:
|
||||
`feather_nrf52832` target enter:
|
||||
|
||||
> **NOTE:** `BOARD=feather52832` is the default option and isn't stricly required.
|
||||
> **NOTE:** `BOARD=feather_nrf52832` is the default option and isn't stricly required.
|
||||
|
||||
```
|
||||
$ make BOARD=feather52832 V=1
|
||||
$ make BOARD=feather_nrf52832 V=1
|
||||
```
|
||||
|
||||
#### REPL over BLE UART (AKA 'NUS')
|
||||
@ -75,7 +66,7 @@ You can then connect over BLE UART using an application like Bluefruit LE
|
||||
Connect, available for Android, iOS and OS X, or any other application that
|
||||
supports the NUS service and allows you to send the corrent EOL sequence.
|
||||
|
||||
## Flashing binaries with `nrfutil`
|
||||
## Flashing binaries with `adafruit-nrfutil`
|
||||
|
||||
### 1. **Update bootloader** to single-bank version
|
||||
|
||||
@ -90,20 +81,25 @@ Due to the size of CircuitPython, we must migrate this bootloader to a
|
||||
bootloader from the dual-bank version that ships on Arduino-based Adafruit
|
||||
Feather52 boards to a single-bank CircuitPython compatible version:
|
||||
|
||||
Firstly clone the [Adafruit_nRF52_Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader.git) and enter its directory
|
||||
|
||||
$ git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader.git
|
||||
$ cd Adafruit_nRF52_Bootloader
|
||||
|
||||
#### S132 v2.0.1 single-bank (recommended):
|
||||
|
||||
By default s132 v2.0.1 is used when no `SOFTDEV_VERSION` field is passed in:
|
||||
To flash bootloader with s132 v2.0.1
|
||||
|
||||
```
|
||||
$ make BOARD=feather52832 SERIAL=/dev/tty.SLAB_USBtoUART boot-flash
|
||||
$ make BOARD=feather_nrf52832 VERSION=2.0.1 SERIAL=/dev/tty.SLAB_USBtoUART dfu-flash
|
||||
```
|
||||
|
||||
#### S132 v5.0.0 (BLE5, experimental):
|
||||
|
||||
To enable BLE5 support and the latest S132 release, flash the v5.0.0 bootloader via:
|
||||
To flash bootloader with s132 v5.0.0
|
||||
|
||||
```
|
||||
$ make BOARD=feather52832 SERIAL=/dev/tty.SLAB_USBtoUART SOFTDEV_VERSION=5.0.0 boot-flash
|
||||
$ make BOARD=feather52832 VERSION=5.0.0 SERIAL=/dev/tty.SLAB_USBtoUART dfu-flash
|
||||
```
|
||||
|
||||
### 2. Generate and flash a CircuitPython DFU .zip package over serial
|
||||
@ -117,7 +113,7 @@ image, as described earlier in this readme.
|
||||
> The name of the serial port target will vary, depending on your OS.
|
||||
|
||||
```
|
||||
$ make BOARD=feather52832 SERIAL=/dev/tty.SLAB_USBtoUART dfu-gen dfu-flash
|
||||
$ make BOARD=feather_nrf52832 SERIAL=/dev/tty.SLAB_USBtoUART dfu-gen dfu-flash
|
||||
```
|
||||
|
||||
By default, CircuitPython will build with **BLE** support enabled using
|
||||
@ -125,7 +121,7 @@ By default, CircuitPython will build with **BLE** support enabled using
|
||||
SD family or version you can enter the optional fields as shown below:
|
||||
|
||||
```
|
||||
$ make BOARD=feather52832 SERIAL=/dev/tty.SLAB_USBtoUART SD=s132 SOFTDEV_VERSION=5.0.0 dfu-gen dfu-flash
|
||||
$ make BOARD=feather_nrf52832 SERIAL=/dev/tty.SLAB_USBtoUART SD=s132 SOFTDEV_VERSION=5.0.0 dfu-gen dfu-flash
|
||||
```
|
||||
|
||||
## Working with CircuitPython
|
11
ports/nrf/boards/feather_nrf52832/mpconfigboard.mk
Normal file
11
ports/nrf/boards/feather_nrf52832/mpconfigboard.mk
Normal file
@ -0,0 +1,11 @@
|
||||
MCU_SERIES = m4
|
||||
MCU_VARIANT = nrf52
|
||||
MCU_SUB_VARIANT = nrf52
|
||||
SD ?= s132
|
||||
SOFTDEV_VERSION ?= 2.0.1
|
||||
|
||||
LD_FILE = boards/feather_nrf52832/custom_nrf52832_dfu_app_$(SOFTDEV_VERSION).ld
|
||||
BOOT_FILE = boards/feather_nrf52832/bootloader/feather52_bootloader_$(SOFTDEV_VERSION)_s132_single
|
||||
|
||||
BOOT_SETTING_ADDR = 0x7F000
|
||||
NRF_DEFINES += -DNRF52832_XXAA
|
@ -43,7 +43,7 @@ update the core CircuitPython firmware and internal file system contents
|
||||
using only a serial connection.
|
||||
|
||||
On empty devices, the serial bootloader will need to be flashed once using a
|
||||
HW debugger such as a Segger J-Link before the serial updater (`nrfutil`) can
|
||||
HW debugger such as a Segger J-Link before the serial updater (`adafruit-nrfutil`) can
|
||||
be used.
|
||||
|
||||
### Install `nrfjprog`
|
||||
@ -79,20 +79,27 @@ JLinkARM.dll version: 6.20f
|
||||
> This operation only needs to be done once, and only on boards that don't
|
||||
already have the serial bootloader installed.
|
||||
|
||||
Firstly clone the [Adafruit_nRF52_Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader.git) and enter its directory
|
||||
|
||||
```
|
||||
$ git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader.git
|
||||
$ cd Adafruit_nRF52_Bootloader
|
||||
```
|
||||
|
||||
Once `nrfjprog` is installed and available in `PATH` you can flash your
|
||||
board with the serial bootloader via the following command:
|
||||
|
||||
```
|
||||
make SD=s140 BOARD=feather52840 bootloader
|
||||
make BOARD=feather_nrf52840_express VERSION=latest flash
|
||||
```
|
||||
|
||||
This should give you the following (or very similar) output, and you will see
|
||||
a DFU blinky pattern on one of the board LEDs:
|
||||
|
||||
```
|
||||
$ make SD=s140 BOARD=feather52840 bootloader
|
||||
Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity.
|
||||
nrfjprog --program boards/feather52840/bootloader/feather52840_bootloader_6.0.0_s140_single.hex -f nrf52 --chiperase --reset
|
||||
$ make BOARD=pca10056 VERSION=latest flash
|
||||
Flashing: bin/pca10056/6.0.0r0/pca10056_bootloader_s140_6.0.0r0.hex
|
||||
nrfjprog --program bin/pca10056/6.0.0r0/pca10056_bootloader_s140_6.0.0r0.hex --chiperase -f nrf52 --reset
|
||||
Parsing hex file.
|
||||
Erasing user available code and UICR flash areas.
|
||||
Applying system reset.
|
||||
@ -105,6 +112,8 @@ Run.
|
||||
From this point onward, you can now use a simple serial port for firmware
|
||||
updates.
|
||||
|
||||
Note: You can specify other version that are available in the directory `Adafruit_nRF52_Bootloader/bin/feather_nrf52840_express/` . The `VERSION=latest` will use the latest bootloader available.
|
||||
|
||||
### IMPORTANT: Disable Mass Storage on PCA10056 J-Link
|
||||
|
||||
The J-Link firmware on the PCA10056 implement USB Mass Storage, but this
|
||||
@ -135,31 +144,14 @@ J-Link>exit
|
||||
|
||||
## Building and Flashing CircuitPython
|
||||
|
||||
### Installing `nrfutil`
|
||||
### Installing `adafruit-nrfutil`
|
||||
|
||||
If you haven't installed the required command-line tool yet, go to the
|
||||
`/libs/nrfutil` folder (where nrfutil 0.5.2b is installed as a sub-module)
|
||||
and run the following commands:
|
||||
|
||||
> If you get a 'sudo: pip: command not found' error running 'sudo pip install',
|
||||
you can install pip via 'sudo easy_install pip'
|
||||
run follow command to install [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) from PyPi
|
||||
|
||||
```
|
||||
$ cd ../../lib/nrfutil
|
||||
$ sudo pip install -r requirements.txt
|
||||
$ sudo python setup.py install
|
||||
$ pip3 install adafruit-nrfutil --user
|
||||
```
|
||||
|
||||
#### Changes to `nrfutil` in 0.5.2d
|
||||
|
||||
**IMPORTANT**: Make sure that you have version **0.5.2d**, since a small
|
||||
change was required to `dfu_transport_serial.py` to account for the
|
||||
increased minimum flash erase time on the nRF52840 compared to the earlier
|
||||
nRF52832!
|
||||
|
||||
You can also manually change the file with the following new values (lines
|
||||
67-68), and reinstall the utility via `sudo python setup.py install`:
|
||||
|
||||
### Flashing CircuitPython with USB CDC
|
||||
|
||||
With the serial bootloader present on your board, you first need to force your
|
||||
@ -169,8 +161,7 @@ BUTTON1 still pressed as you come out of reset).
|
||||
This will give you a **fast blinky DFU pattern** to indicate you are in DFU
|
||||
mode.
|
||||
|
||||
At this point, you can **build and flash** a CircuitPython binary via the following
|
||||
command:
|
||||
You can **build and flash** a CircuitPython binary via the following command:
|
||||
|
||||
```
|
||||
$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all dfu-gen dfu-flash
|
||||
@ -197,20 +188,14 @@ Device programmed.
|
||||
|
||||
### Flashing CircuitPython with MSC UF2
|
||||
|
||||
Make `uf2` target to generate the uf2
|
||||
uf2 file is generated last by `all` target
|
||||
|
||||
```
|
||||
$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all uf2
|
||||
$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all
|
||||
Create firmware.uf2
|
||||
../../tools/uf2/utils/uf2conv.py -c -o "build-feather52840-s140/firmware.uf2" "build-feather52840-s140/firmware.hex"
|
||||
../../tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "build-feather52840-s140/firmware.uf2" "build-feather52840-s140/firmware.hex"
|
||||
Converting to uf2, output size: 392192, start address: 0x26000
|
||||
Wrote 392192 bytes to build-feather52840-s140/firmware.uf2.
|
||||
```
|
||||
|
||||
Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done.
|
||||
|
||||
**Note**: you need to update `tools/uf2` for uf2conv.py to support hex file input, current circuitpython's master use older verion of uf2conv.py which only support biin file input. To update, change directory to top folder of circuitpython and run. The size of uf2 should be ~400KB, if using the old uf2conv.py the output file would be 1 MB which is not correct.
|
||||
|
||||
```
|
||||
git submodule update --init
|
||||
```
|
||||
Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done.
|
75
ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
Normal file
75
ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Glenn Ruben Bakke
|
||||
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define FEATHER52840
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "Adafruit Feather nRF52840 Express"
|
||||
#define MICROPY_HW_MCU_NAME "nRF52840"
|
||||
#define MICROPY_PY_SYS_PLATFORM "Feather52840"
|
||||
|
||||
// #define MICROPY_HW_NEOPIXEL NRF_GPIO_PIN_MAP(0, 13)
|
||||
|
||||
// #define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 9)
|
||||
// #define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 11)
|
||||
// #define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 12)
|
||||
// #define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 14)
|
||||
// #define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 8)
|
||||
// #define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 8)
|
||||
|
||||
// #define MICROPY_HW_UART_RX NRF_GPIO_PIN_MAP(0, 8)
|
||||
// #define MICROPY_HW_UART_TX NRF_GPIO_PIN_MAP(0, 6)
|
||||
// #define MICROPY_HW_UART_HWFC (0)
|
||||
|
||||
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
|
||||
|
||||
// If you change this, then make sure to update the linker scripts as well to
|
||||
// make sure you don't overwrite code
|
||||
#define PORT_HEAP_SIZE (128 * 1024)
|
||||
// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192
|
||||
|
||||
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
|
||||
|
||||
// TODO #include "external_flash/devices.h"
|
||||
|
||||
#define EXTERNAL_FLASH_DEVICE_COUNT 1
|
||||
#define EXTERNAL_FLASH_DEVICES GD25Q16C
|
||||
|
||||
#define EXTERNAL_FLASH_QSPI_DUAL
|
||||
|
||||
// TODO include "external_flash/external_flash.h"
|
||||
|
||||
#define BOARD_HAS_CRYSTAL 1
|
||||
|
||||
#define DEFAULT_I2C_BUS_SCL NRF_GPIO_PIN_MAP(1, 11)
|
||||
#define DEFAULT_I2C_BUS_SDA NRF_GPIO_PIN_MAP(1, 12)
|
||||
|
||||
#define DEFAULT_SPI_BUS_SCK NRF_GPIO_PIN_MAP(0, 20)
|
||||
#define DEFAULT_SPI_BUS_MOSI NRF_GPIO_PIN_MAP(0, 23)
|
||||
#define DEFAULT_SPI_BUS_MISO NRF_GPIO_PIN_MAP(0, 22)
|
||||
|
||||
#define DEFAULT_UART_BUS_RX NRF_GPIO_PIN_MAP(1, 0)
|
||||
#define DEFAULT_UART_BUS_TX NRF_GPIO_PIN_MAP(0, 24)
|
15
ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk
Normal file
15
ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk
Normal file
@ -0,0 +1,15 @@
|
||||
MCU_SERIES = m4
|
||||
MCU_VARIANT = nrf52
|
||||
MCU_SUB_VARIANT = nrf52840
|
||||
SD ?= s140
|
||||
SOFTDEV_VERSION ?= 6.1.0
|
||||
|
||||
BOOT_SETTING_ADDR = 0xFF000
|
||||
|
||||
ifeq ($(SD),)
|
||||
LD_FILE = boards/nrf52840_1M_256k.ld
|
||||
else
|
||||
LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
|
||||
endif
|
||||
|
||||
NRF_DEFINES += -DNRF52840_XXAA
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -2,16 +2,14 @@ MCU_SERIES = m4
|
||||
MCU_VARIANT = nrf52
|
||||
MCU_SUB_VARIANT = nrf52840
|
||||
SD ?= s140
|
||||
SOFTDEV_VERSION ?= 6.0.0
|
||||
SOFTDEV_VERSION ?= 6.1.0
|
||||
|
||||
BOOT_SETTING_ADDR = 0xFF000
|
||||
BOOT_FILE = boards/$(BOARD)/bootloader/$(SOFTDEV_VERSION)/$(BOARD)_bootloader_$(SOFTDEV_VERSION)_s140
|
||||
|
||||
ifeq ($(SD),)
|
||||
LD_FILE = boards/nrf52840_1M_256k.ld
|
||||
else
|
||||
LD_FILE = boards/bluefruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_$(SOFTDEV_VERSION).ld
|
||||
LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
|
||||
endif
|
||||
|
||||
|
||||
NRF_DEFINES += -DNRF52840_XXAA
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user