Merge branch 'master' of github.com:adafruit/circuitpython into translate-german

This commit is contained in:
Sebastian Plamauer 2018-08-26 12:47:21 +02:00
commit 361f057927
149 changed files with 6329 additions and 22750 deletions

1
.gitignore vendored
View File

@ -7,7 +7,6 @@
*.bin
*.map
*.hex
!ports/nrf/**/bootloader/**/*.hex
*.dis
*.exe

3
.gitmodules vendored
View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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"));
}
}

View File

@ -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];

View File

@ -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 {

View File

@ -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]);

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2281
locale/fr.po Normal file

File diff suppressed because it is too large Load Diff

43
main.c
View File

@ -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
View 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 \

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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"));
}

View File

@ -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

View File

@ -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.

View 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);
}
}

View File

@ -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

View File

@ -0,0 +1 @@
// No i2cslave module functions.

View File

@ -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 {\

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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."));
}
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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"));
}

View File

@ -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 */

View File

@ -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) {

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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])

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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 $@"

View File

@ -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

View File

@ -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

View File

@ -1,2 +0,0 @@
# Inform git that .zip files should be treated as binary
*.zip binary

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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.

View 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)

View 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

View File

@ -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