summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2018-04-02 19:19:43 -0400
committerDan Halbert <halbert@halwitz.org>2018-04-02 19:19:43 -0400
commit435e894fa0ec5e9ce82b7bdef308413c6731e06a (patch)
treeaf8d62363157a6ba969684538e012871a88224c6
parentd005b123267ab4ac2f0471c730b762cc3e94232c (diff)
parent98c7d70fe406d66d80c3c9cc888602f96cf444c4 (diff)
Merge branch 'master' into 3.0_hid
-rw-r--r--.gitmodules6
-rw-r--r--.travis.yml13
-rw-r--r--CONTRIBUTING.md3
-rw-r--r--README.rst3
-rw-r--r--docs/drivers.rst5
-rw-r--r--extmod/vfs_fat.c37
-rw-r--r--extmod/vfs_fat_file.c6
-rw-r--r--ports/atmel-samd/Makefile1
-rw-r--r--ports/atmel-samd/README.rst40
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/pins.c8
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/board.c38
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h34
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk10
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/pins.c30
-rw-r--r--ports/atmel-samd/boards/gemma_m0/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h6
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/pins.c23
-rw-r--r--ports/atmel-samd/common-hal/busio/I2C.c53
-rw-r--r--ports/atmel-samd/common-hal/busio/SPI.c11
-rw-r--r--ports/atmel-samd/common-hal/busio/UART.c31
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Pin.h5
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Processor.c2
-rw-r--r--ports/atmel-samd/external_flash/common_commands.h4
-rw-r--r--ports/atmel-samd/external_flash/devices.h2
-rw-r--r--ports/atmel-samd/external_flash/external_flash.c33
-rw-r--r--ports/atmel-samd/external_flash/qspi_flash.c18
-rw-r--r--ports/atmel-samd/external_flash/spi_flash.c4
-rw-r--r--ports/atmel-samd/external_flash/spi_flash_api.h3
m---------ports/atmel-samd/freetouch0
-rw-r--r--ports/atmel-samd/freetouch/Adafruit_FreeTouch.cpp280
-rw-r--r--ports/atmel-samd/freetouch/Adafruit_FreeTouch.h37
-rw-r--r--ports/atmel-samd/freetouch/README.md2
-rw-r--r--ports/atmel-samd/freetouch/adafruit_ptc.c148
-rw-r--r--ports/atmel-samd/freetouch/adafruit_ptc.h109
-rw-r--r--ports/atmel-samd/freetouch/examples/freetouch/freetouch.ino56
-rw-r--r--ports/atmel-samd/freetouch/samd21_ptc_component.h350
-rw-r--r--ports/atmel-samd/mpconfigport.h2
-rw-r--r--ports/atmel-samd/peripherals.h2
-rw-r--r--ports/atmel-samd/samd21_peripherals.c3
-rw-r--r--ports/atmel-samd/samd21_pins.c8
-rw-r--r--ports/atmel-samd/samd51_peripherals.c3
-rw-r--r--ports/atmel-samd/samd51_pins.c8
-rw-r--r--ports/atmel-samd/supervisor/filesystem.c14
-rw-r--r--ports/atmel-samd/usb.c48
-rw-r--r--ports/atmel-samd/usb_mass_storage.c18
-rw-r--r--ports/esp8266/mpconfigport.h2
-rw-r--r--ports/nrf/common-hal/microcontroller/Processor.c2
-rw-r--r--ports/nrf/mpconfigport.h2
-rw-r--r--ports/unix/Makefile10
-rw-r--r--ports/unix/mpconfigport_coverage.h1
-rw-r--r--ports/windows/.appveyor.yml32
-rw-r--r--py/bc.c7
-rw-r--r--py/binary.c16
-rw-r--r--py/gc_long_lived.c6
-rw-r--r--py/mpconfig.h6
-rw-r--r--py/objarray.c35
-rw-r--r--py/objgenerator.c2
-rw-r--r--py/objint_mpz.c4
-rw-r--r--py/objstr.c5
-rw-r--r--py/objtype.c47
-rw-r--r--shared-bindings/gamepad/GamePad.c7
-rw-r--r--shared-bindings/help.c2
-rw-r--r--shared-bindings/storage/__init__.c53
-rw-r--r--shared-bindings/storage/__init__.h1
-rw-r--r--shared-module/gamepad/GamePad.c8
-rw-r--r--shared-module/gamepad/__init__.c6
-rw-r--r--shared-module/storage/__init__.c18
-rw-r--r--shared-module/struct/__init__.c2
-rw-r--r--tests/basics/array_micropython.py6
-rw-r--r--tests/basics/array_mul.py28
-rw-r--r--tests/basics/builtin_pow3.py5
-rw-r--r--tests/basics/class_super.py7
-rw-r--r--tests/basics/core_class_superproperty.py (renamed from tests/cpydiff/core_class_superproperty.py)5
-rw-r--r--tests/basics/fun_calldblstar.py7
-rw-r--r--tests/basics/gen_stack_overflow.py7
-rw-r--r--tests/basics/string_find.py1
-rw-r--r--tests/basics/string_rfind.py1
-rw-r--r--tests/basics/struct_micropython.py6
-rw-r--r--tests/basics/types3.py20
-rw-r--r--tests/extmod/vfs_fat_fileio1.py6
-rw-r--r--tests/extmod/vfs_fat_fileio1.py.exp2
-rw-r--r--tests/extmod/vfs_fat_ramdisk.py2
-rw-r--r--tests/extmod/vfs_fat_ramdisk.py.exp1
-rwxr-xr-xtests/run-tests69
-rwxr-xr-xtools/build_adafruit_bins.sh2
85 files changed, 768 insertions, 1202 deletions
diff --git a/.gitmodules b/.gitmodules
index a7f31837a..ec0b01e33 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -33,9 +33,6 @@
path = lib/stm32lib
url = https://github.com/micropython/stm32lib
branch = work-F4-1.13.1+F7-1.5.0+L4-1.3.0
-[submodule "freetouch2"]
- path = ports/atmel-samd/freetouch
- url = https://github.com/adafruit/Adafruit_FreeTouch.git
[submodule "atmel-samd/asf4"]
path = ports/atmel-samd/asf4
url = https://github.com/adafruit/asf4.git
@@ -46,3 +43,6 @@
[submodule "lib/nrfutil"]
path = lib/nrfutil
url = https://github.com/adafruit/nRF52_nrfutil
+[submodule "ports/atmel-samd/freetouch"]
+ path = ports/atmel-samd/freetouch
+ url = https://github.com/adafruit/Adafruit_FreeTouch.git
diff --git a/.travis.yml b/.travis.yml
index a69840333..94f7059b0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,6 +11,7 @@ env:
- TRAVIS_BOARD=feather_m0_rfm69
- TRAVIS_BOARD=feather_m0_rfm9x
- TRAVIS_BOARD=feather_m0_express
+ - TRAVIS_BOARD=feather_m4_express
- TRAVIS_BOARD=itsybitsy_m0_express
- TRAVIS_BOARD=metro_m0_express
- TRAVIS_BOARD=metro_m4_express
@@ -77,24 +78,24 @@ script:
- echo -en 'travis_fold:end:qemu\\r'
# run tests without coverage info
- #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests)
- #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests --emit native)
+ #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1)
+ #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1 --emit native)
# run tests with coverage info
- echo 'Test all' && echo -en 'travis_fold:start:test_all\\r'
- - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests))
+ - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1))
- echo -en 'travis_fold:end:test_all\\r'
- echo 'Test threads' && echo -en 'travis_fold:start:test_threads\\r'
- - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -d thread))
+ - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread))
- echo -en 'travis_fold:end:test_threads\\r'
- echo 'Testing with native' && echo -en 'travis_fold:start:test_native\\r'
- - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --emit native))
+ - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native))
- echo -en 'travis_fold:end:test_native\\r'
- (echo 'Testing with mpy' && echo -en 'travis_fold:start:test_mpy\\r')
- - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --via-mpy -d basics float))
+ - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float))
- echo -en 'travis_fold:end:test_mpy\\r'
- (echo 'Building docs' && echo -en 'travis_fold:start:build_docs\\r')
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5401892dd..2eb0214da 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,8 +8,7 @@ so will result in corrective actions such as time out or ban from the project.
## Developer contact
[@tannewt](https://github.com/tannewt) is the main developer of CircuitPython
and is sponsored by [Adafruit Industries LLC](https://adafruit.com). He is
-reachable on [Discord](https://adafru.it/discord) as tannewt and
-[Gitter](gitter.im/adafruit/circuitpython) as tannewt during US West Coast
+reachable on [Discord](https://adafru.it/discord) as tannewt during US West Coast
working hours. He also checks GitHub issues and the [Adafruit support forum](https://forums.adafruit.com/viewforum.php?f=60).
## Licensing
diff --git a/README.rst b/README.rst
index 7e234331e..31c0cce59 100644
--- a/README.rst
+++ b/README.rst
@@ -83,8 +83,7 @@ Conduct <https://github.com/adafruit/circuitpython/blob/master/CODE_OF_CONDUCT.m
Contributors who follow the `Code of
Conduct <https://github.com/adafruit/circuitpython/blob/master/CODE_OF_CONDUCT.md>`__
are welcome to submit pull requests and they will be promptly reviewed
-by project admins. Please join the `Gitter
-chat <https://gitter.im/adafruit/circuitpython>`__ or
+by project admins. Please join the
`Discord <https://discord.gg/nBQh6qu>`__ too.
--------------
diff --git a/docs/drivers.rst b/docs/drivers.rst
index 523316b09..951967e09 100644
--- a/docs/drivers.rst
+++ b/docs/drivers.rst
@@ -76,6 +76,7 @@ Multi-color led drivers.
NeoPixel <https://circuitpython.readthedocs.io/projects/neopixel/en/latest/>
DotStar <https://circuitpython.readthedocs.io/projects/dotstar/en/latest/>
+ WS2801 <https://circuitpython.readthedocs.io/projects/ws2801/en/latest/>
Displays
-------------
@@ -111,7 +112,7 @@ Motion relating sensing including ``acceleration``, ``magnetic``, ``gyro``, and
.. toctree::
BNO055 Accelerometer, Magnetometer, Gyroscope and Absolution Orientation <https://circuitpython.readthedocs.io/projects/bno055/en/latest/>
- FXAS21002C Gyroscope <https://circuitpython.readthedocs.io/projects/fxas21002C/en/latest/>
+ FXAS21002C Gyroscope <https://circuitpython.readthedocs.io/projects/fxas21002c/en/latest/>
FXOS8700 Accelerometer <https://circuitpython.readthedocs.io/projects/fxos8700/en/latest/>
GPS Global Position <https://circuitpython.readthedocs.io/projects/gps/en/latest/>
LIS3DH Accelerometer <https://circuitpython.readthedocs.io/projects/lis3dh/en/latest/>
@@ -154,6 +155,7 @@ These sensors detect light related attributes such as ``color``, ``light`` (unit
.. toctree::
APDS9960 Proximity, Light, RGB, and Gesture <https://circuitpython.readthedocs.io/projects/apds9960/en/latest/>
+ AS726x Color Spectrum Sensor <https://circuitpython.readthedocs.io/projects/as726x/en/latest/>
TCS34725 Color Sensor <https://circuitpython.readthedocs.io/projects/tcs34725/en/latest/>
TSL2561 Light Sensor <https://circuitpython.readthedocs.io/projects/tsl2561/en/latest/>
TSL2591 High Dynamic Range Light Sensor <https://circuitpython.readthedocs.io/projects/tsl2591/en/latest/>
@@ -191,6 +193,7 @@ These provide functionality similar to `analogio`, `digitalio`, `pulseio`, and `
ADS1x15 Analog-to-Digital Converter <https://circuitpython.readthedocs.io/projects/ads1x15/en/latest/>
DS2413 OneWire GPIO Expander <https://circuitpython.readthedocs.io/projects/ds2413/en/latest/>
FocalTech Capacitive Touch <https://circuitpython.readthedocs.io/projects/focaltouch/en/latest/>
+ MCP230xx GPIO Expander <https://circuitpython.readthedocs.io/projects/mcp230xx/en/latest/>
MCP4725 Digital-to-Analog Converter <https://circuitpython.readthedocs.io/projects/mcp4725/en/latest/>
PCA9685 16 x 12-bit PWM Driver <https://circuitpython.readthedocs.io/projects/pca9685/en/latest/>
TLC5947 24 x 12-bit PWM Driver <https://circuitpython.readthedocs.io/projects/tlc5947/en/latest/>
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index 22346bdf1..81ca1e23d 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -33,6 +33,7 @@
#endif
#include <string.h>
+#include "py/objproperty.h"
#include "py/runtime.h"
#include "py/mperrno.h"
#include "lib/oofatfs/ff.h"
@@ -317,6 +318,39 @@ STATIC mp_obj_t vfs_fat_umount(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, vfs_fat_umount);
+#if MICROPY_FATFS_USE_LABEL
+STATIC mp_obj_t vfs_fat_getlabel(mp_obj_t self_in) {
+ fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
+ char working_buf[12];
+ FRESULT res = f_getlabel(&self->fatfs, working_buf, NULL);
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
+ return mp_obj_new_str(working_buf, strlen(working_buf), false);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getlabel_obj, vfs_fat_getlabel);
+
+static mp_obj_t vfs_fat_setlabel(mp_obj_t self_in, mp_obj_t label_in) {
+ fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
+ const char *label_str = mp_obj_str_get_str(label_in);
+ FRESULT res = f_setlabel(&self->fatfs, label_str);
+ if (res != FR_OK) {
+ if(res == FR_WRITE_PROTECTED) {
+ mp_raise_msg(&mp_type_OSError, "Read-only filesystem");
+ }
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_setlabel_obj, vfs_fat_setlabel);
+STATIC const mp_obj_property_t fat_vfs_label_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&fat_vfs_getlabel_obj,
+ (mp_obj_t)&fat_vfs_setlabel_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+#endif
+
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&fat_vfs_open_obj) },
@@ -331,6 +365,9 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&fat_vfs_statvfs_obj) },
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_fat_mount_obj) },
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) },
+#if MICROPY_FATFS_USE_LABEL
+ { MP_ROM_QSTR(MP_QSTR_label), MP_ROM_PTR(&fat_vfs_label_obj) },
+#endif
};
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index f580184a7..be9c8c792 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -125,11 +125,7 @@ STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg,
break;
case 1: // SEEK_CUR
- if (s->offset != 0) {
- *errcode = MP_EOPNOTSUPP;
- return MP_STREAM_ERROR;
- }
- // no-operation
+ f_lseek(&self->fp, f_tell(&self->fp) + s->offset);
break;
case 2: // SEEK_END
diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile
index 49823c0de..39625ad95 100644
--- a/ports/atmel-samd/Makefile
+++ b/ports/atmel-samd/Makefile
@@ -72,7 +72,6 @@ BASE_CFLAGS = \
-Wnested-externs \
-Wunreachable-code \
-Wcast-align \
- -Wno-error=lto-type-mismatch \
-D__$(CHIP_VARIANT)__ \
-ffunction-sections \
-fdata-sections \
diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst
index 8785ccada..d475e3816 100644
--- a/ports/atmel-samd/README.rst
+++ b/ports/atmel-samd/README.rst
@@ -115,16 +115,54 @@ PB03 **Yes** **Yes** **Yes** **Yes**
Setup
-----
-Install required compiler packages:
+
+An ARM compiler is required for the build, along with the associated binary
+utilities. On Ubuntu, these can be installed as follows:
.. code-block:: shell
sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
sudo apt-get install gcc-arm-embedded
+On Arch Linux the compiler is available for via the package
+``arm-none-eabi-gcc``.
+
+For other systems, the `GNU Arm Embedded Toolchain <https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads>`_
+may be available in binary form.
+
+The latest available package from team-gcc-arm-embedded is used to produce the
+binaries shipped by AdaFruit. Other compiler versions, particularly older
+ones, may not work properly. In particular, the ``gcc-arm-none-eabi`` package
+in Debian Stretch is too old.
+
+The compiler can be changed using the ``CROSS_COMPILE`` variable when invoking
+``make``.
+
Building
--------
+Before building the firmware for a given board, there are two additional steps.
+These commands should be executed from the root directory of the repository
+(``circuitpython/``).
+
+1. There are various submodules that reside in different repositories. In order
+ to have these submodules locally, you must pull them into your clone, using:
+
+.. code-block:: shell
+
+ git submodule update --init --recursive
+
+2. The MicroPython cross-compiler must be built; it will be used to pre-compile
+ some of the built-in scripts to bytecode. The cross-compiler is built and
+ run on the host machine, using:
+
+.. code-block:: shell
+
+ make -C mpy-cross
+
+
+Build commands are run from the ``circuitpython/ports/atmel-samd`` directory.
+
To build for the Arduino Zero:
.. code-block:: shell
diff --git a/ports/atmel-samd/boards/circuitplayground_express/pins.c b/ports/atmel-samd/boards/circuitplayground_express/pins.c
index 4be74f377..aecd7f416 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/pins.c
+++ b/ports/atmel-samd/boards/circuitplayground_express/pins.c
@@ -2,17 +2,25 @@
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA02) },
{ MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA05) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA06) },
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA07) },
{ MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB03) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) },
{ MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB02) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) },
{ MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB09) },
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB09) },
{ MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB08) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB08) },
{ MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PA11) },
{ MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA11) },
diff --git a/ports/atmel-samd/boards/feather_m4_express/board.c b/ports/atmel-samd/boards/feather_m4_express/board.c
new file mode 100644
index 000000000..8096b9b8e
--- /dev/null
+++ b/ports/atmel-samd/boards/feather_m4_express/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft 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.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h
new file mode 100644
index 000000000..bd56a7bdf
--- /dev/null
+++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h
@@ -0,0 +1,34 @@
+#define MICROPY_HW_BOARD_NAME "Feather M4 Express"
+#define MICROPY_HW_MCU_NAME "samd51j19"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+// This is for Rev C which is green
+
+#define MICROPY_HW_NEOPIXEL (&pin_PB23)
+
+// These are pins not to reset.
+// QSPI Data pins and TX LED
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09)
+// RX LED, QSPI CS, QSPI SCK and NeoPixel pin
+#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11 | PORT_PB23 )
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define AUTORESET_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 CIRCUITPY_INTERNAL_NVM_SIZE 256
+#define CIRCUITPY_INTERNAL_NVM_SIZE 0
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#include "external_flash/devices.h"
+
+#define EXTERNAL_FLASH_DEVICE_COUNT 2
+#define EXTERNAL_FLASH_DEVICES W25Q16FW, GD25Q16C
+
+#define EXTERNAL_FLASH_QSPI_DUAL
+
+#include "external_flash/external_flash.h"
diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
new file mode 100644
index 000000000..61620ffa2
--- /dev/null
+++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
@@ -0,0 +1,10 @@
+LD_FILE = boards/samd51x19-bootloader-external-flash.ld
+USB_VID = 0x239A
+USB_PID = 0x8026
+USB_PRODUCT = "Feather M4 Express"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+QSPI_FLASH_FILESYSTEM = 1
+
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/feather_m4_express/pins.c b/ports/atmel-samd/boards/feather_m4_express/pins.c
new file mode 100644
index 000000000..c161e736e
--- /dev/null
+++ b/ports/atmel-samd/boards/feather_m4_express/pins.c
@@ -0,0 +1,30 @@
+#include "samd21_pins.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_PA03) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h
index 4baafcb11..6457d481f 100644
--- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h
+++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h
@@ -1,8 +1,8 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Gemma M0"
#define MICROPY_HW_MCU_NAME "samd21e18"
-// #define MICROPY_HW_APA102_MOSI (&pin_PA00)
-// #define MICROPY_HW_APA102_SCK (&pin_PA01)
+#define MICROPY_HW_APA102_MOSI (&pin_PA00)
+#define MICROPY_HW_APA102_SCK (&pin_PA01)
// #define CIRCUITPY_BITBANG_APA102
diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
index b541af80c..e2b7f9982 100644
--- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
@@ -3,18 +3,18 @@
#define CIRCUITPY_MCU_FAMILY samd51
-// This is for Rev D which is light blue
+// This is for Rev F which is green
#define MICROPY_HW_LED_TX PIN_PA27
#define MICROPY_HW_LED_RX PIN_PB06
-#define MICROPY_HW_NEOPIXEL (&pin_PB17)
+#define MICROPY_HW_NEOPIXEL (&pin_PB22)
// These are pins not to reset.
// QSPI Data pins and TX LED
#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 | PORT_PA27)
// RX LED, QSPI CS, QSPI SCK and NeoPixel pin
-#define MICROPY_PORT_B ( PORT_PB06 | PORT_PB10 | PORT_PB11 | PORT_PB17)
+#define MICROPY_PORT_B ( PORT_PB06 | PORT_PB10 | PORT_PB11 | PORT_PB22)
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
diff --git a/ports/atmel-samd/boards/metro_m4_express/pins.c b/ports/atmel-samd/boards/metro_m4_express/pins.c
index 33b69b32b..32ecdf492 100644
--- a/ports/atmel-samd/boards/metro_m4_express/pins.c
+++ b/ports/atmel-samd/boards/metro_m4_express/pins.c
@@ -7,36 +7,37 @@ STATIC const mp_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PA05 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PA06 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PB09 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PA04 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PB08 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PA07 },
-
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PB09 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D0), (mp_obj_t)&pin_PA23 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PA23 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D1), (mp_obj_t)&pin_PA22 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PA22 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PA04 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PB17 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PB16 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PB13 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D5), (mp_obj_t)&pin_PB14 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D6), (mp_obj_t)&pin_PB15 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PA14 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PA16 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PA17 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PB12 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PA21 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PA20 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D10), (mp_obj_t)&pin_PA18 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D11), (mp_obj_t)&pin_PA19 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PA20 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA21 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PA17 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA16 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB02 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB03 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB17 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_AREF), (mp_obj_t)&pin_PA03 },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB22 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PA13 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA15 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA14 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), (mp_obj_t)&pin_PB06 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), (mp_obj_t)&pin_PA27 },
diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c
index 4182c8651..77676b535 100644
--- a/ports/atmel-samd/common-hal/busio/I2C.c
+++ b/ports/atmel-samd/common-hal/busio/I2C.c
@@ -34,6 +34,7 @@
#include "peripherals.h"
#include "pins.h"
+#include "shared-bindings/microcontroller/__init__.h"
// Number of times to try to send packet if failed.
@@ -46,19 +47,21 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
uint32_t sda_pinmux = 0;
uint32_t scl_pinmux = 0;
for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) {
- Sercom* potential_sercom = sda->sercom[i].sercom;
- if (potential_sercom == NULL ||
- potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 ||
+ 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->pin, (i == 0) ? MUX_C : MUX_D);
for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) {
- if (potential_sercom == scl->sercom[j].sercom &&
+ if (sercom_index == scl->sercom[j].index &&
scl->sercom[j].pad == 1) {
scl_pinmux = PINMUX(scl->pin, (j == 0) ? MUX_C : MUX_D);
sercom = potential_sercom;
- sercom_index = scl->sercom[j].index; // 2 for SERCOM2, etc.
break;
}
}
@@ -70,24 +73,46 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
mp_raise_ValueError("Invalid pins");
}
+ // Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
+ gpio_set_pin_function(sda->pin, GPIO_PIN_FUNCTION_OFF);
+ gpio_set_pin_function(scl->pin, GPIO_PIN_FUNCTION_OFF);
+ gpio_set_pin_direction(sda->pin, GPIO_DIRECTION_IN);
+ gpio_set_pin_direction(scl->pin, GPIO_DIRECTION_IN);
+
+ gpio_set_pin_pull_mode(sda->pin, GPIO_PULL_DOWN);
+ gpio_set_pin_pull_mode(scl->pin, GPIO_PULL_DOWN);
+
+ common_hal_mcu_delay_us(10);
+
+ gpio_set_pin_pull_mode(sda->pin, GPIO_PULL_OFF);
+ gpio_set_pin_pull_mode(scl->pin, GPIO_PULL_OFF);
+
+ // We must pull up within 3us to achieve 400khz.
+ common_hal_mcu_delay_us(3);
+
+ if (!gpio_get_pin_level(sda->pin) || !gpio_get_pin_level(scl->pin)) {
+ reset_pin(sda->pin);
+ reset_pin(scl->pin);
+ mp_raise_RuntimeError("SDA or SCL needs a pull up");
+ }
+ gpio_set_pin_function(sda->pin, sda_pinmux);
+ gpio_set_pin_function(scl->pin, scl_pinmux);
// Set up I2C clocks on sercom.
samd_peripherals_sercom_clock_init(sercom, sercom_index);
if (i2c_m_sync_init(&self->i2c_desc, sercom) != ERR_NONE) {
- mp_raise_OSError(MP_EIO);
+ reset_pin(sda->pin);
+ reset_pin(scl->pin);
+ mp_raise_OSError(MP_EIO);
}
-
- gpio_set_pin_pull_mode(sda->pin, GPIO_PULL_OFF);
- gpio_set_pin_function(sda->pin, sda_pinmux);
-
- gpio_set_pin_pull_mode(scl->pin, GPIO_PULL_OFF);
- gpio_set_pin_function(scl->pin, scl_pinmux);
// clkrate is always 0. baud_rate is in kHz.
-
+
// Frequency must be set before the I2C device is enabled.
if (i2c_m_sync_set_baudrate(&self->i2c_desc, 0, frequency / 1000) != ERR_NONE) {
+ reset_pin(sda->pin);
+ reset_pin(scl->pin);
mp_raise_ValueError("Unsupported baudrate");
}
@@ -113,7 +138,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
i2c_m_sync_disable(&self->i2c_desc);
i2c_m_sync_deinit(&self->i2c_desc);
-
+
reset_pin(self->sda_pin);
reset_pin(self->scl_pin);
self->sda_pin = NO_PIN;
diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c
index eca73be78..a2bf30f05 100644
--- a/ports/atmel-samd/common-hal/busio/SPI.c
+++ b/ports/atmel-samd/common-hal/busio/SPI.c
@@ -55,9 +55,12 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
uint8_t miso_pad = 0;
uint8_t dopo = 255;
for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) {
- Sercom* potential_sercom = clock->sercom[i].sercom;
sercom_index = clock->sercom[i].index; // 2 for SERCOM2, etc.
- if (potential_sercom == NULL ||
+ if (sercom_index >= SERCOM_INST_NUM) {
+ continue;
+ }
+ Sercom* potential_sercom = sercom_insts[sercom_index];
+ if (
#if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !defined(CIRCUITPY_BITBANG_APA102)
(potential_sercom->SPI.CTRLA.bit.ENABLE != 0 &&
potential_sercom != status_apa102.spi_desc.dev.prvt &&
@@ -74,7 +77,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
}
for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) {
if (!mosi_none) {
- if(potential_sercom == mosi->sercom[j].sercom) {
+ if (sercom_index == mosi->sercom[j].index) {
mosi_pinmux = PINMUX(mosi->pin, (j == 0) ? MUX_C : MUX_D);
mosi_pad = mosi->sercom[j].pad;
dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad);
@@ -91,7 +94,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
}
if (!miso_none) {
for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) {
- if (potential_sercom == miso->sercom[k].sercom) {
+ if (sercom_index == miso->sercom[k].index) {
miso_pinmux = PINMUX(miso->pin, (k == 0) ? MUX_C : MUX_D);
miso_pad = miso->sercom[k].pad;
sercom = potential_sercom;
diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c
index 292e01e60..537677520 100644
--- a/ports/atmel-samd/common-hal/busio/UART.c
+++ b/ports/atmel-samd/common-hal/busio/UART.c
@@ -56,7 +56,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) {
Sercom* sercom = NULL;
- uint8_t sercom_index;
+ uint8_t sercom_index = 255; // Unset index
uint32_t rx_pinmux = 0;
uint8_t rx_pad = 255; // Unset pad
uint32_t tx_pinmux = 0;
@@ -71,7 +71,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
if (!have_tx && !have_rx) {
mp_raise_ValueError("tx and rx cannot both be None");
}
-
+
self->baudrate = baudrate;
self->character_bits = bits;
self->timeout_ms = timeout;
@@ -82,10 +82,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) {
Sercom* potential_sercom = NULL;
if (have_tx) {
- potential_sercom = tx->sercom[i].sercom;
sercom_index = tx->sercom[i].index;
- if (potential_sercom == NULL ||
- potential_sercom->USART.CTRLA.bit.ENABLE != 0 ||
+ if (sercom_index >= SERCOM_INST_NUM) {
+ continue;
+ }
+ potential_sercom = sercom_insts[sercom_index];
+ if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 ||
!(tx->sercom[i].pad == 0 ||
tx->sercom[i].pad == 2)) {
continue;
@@ -98,12 +100,13 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
}
}
for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) {
- if (((!have_tx && rx->sercom[j].sercom->USART.CTRLA.bit.ENABLE == 0) ||
- potential_sercom == rx->sercom[j].sercom) &&
+ if (((!have_tx && rx->sercom[j].index < SERCOM_INST_NUM &&
+ sercom_insts[rx->sercom[j].index]->USART.CTRLA.bit.ENABLE == 0) ||
+ sercom_index == rx->sercom[j].index) &&
rx->sercom[j].pad != tx_pad) {
rx_pinmux = PINMUX(rx->pin, (j == 0) ? MUX_C : MUX_D);
rx_pad = rx->sercom[j].pad;
- sercom = rx->sercom[j].sercom;
+ sercom = sercom_insts[rx->sercom[j].index];
sercom_index = rx->sercom[j].index;
break;
}
@@ -147,7 +150,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// usart_async_init() sets a number of defaults based on a prototypical SERCOM
// which don't necessarily match what we need. After calling it, set the values
// specific to this instantiation of UART.
-
+
// Set pads computed for this SERCOM.
// TXPO:
// 0x0: TX pad 0; no RTS/CTS
@@ -182,7 +185,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// http://start.atmel.com/static/help/index.html?GUID-79201A5A-226F-4FBB-B0B8-AB0BE0554836
// Look at the ASFv4 code example for async USART.
usart_async_register_callback(usart_desc_p, USART_ASYNC_RXC_CB, usart_async_rxc_callback);
-
+
if (have_tx) {
gpio_set_pin_direction(tx->pin, GPIO_DIRECTION_OUT);
@@ -193,7 +196,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
} else {
self->tx_pin = NO_PIN;
}
-
+
if (have_rx) {
gpio_set_pin_direction(rx->pin, GPIO_DIRECTION_IN);
gpio_set_pin_pull_mode(rx->pin, GPIO_PULL_OFF);
@@ -238,7 +241,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// Nothing to read.
return 0;
}
-
+
struct io_descriptor *io;
usart_async_get_io_descriptor(usart_desc_p, &io);
@@ -266,7 +269,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
MICROPY_VM_HOOK_LOOP
#endif
}
-
+
return total_read;
}
@@ -305,7 +308,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
*errcode = MP_EAGAIN;
return MP_STREAM_ERROR;
}
-
+
struct usart_async_status async_status;
// Could return ERR_BUSY, but if that's true there's already a problem.
usart_async_get_status(usart_desc_p, &async_status);
diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.h b/ports/atmel-samd/common-hal/microcontroller/Pin.h
index ca639eb84..4e21a14cd 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Pin.h
+++ b/ports/atmel-samd/common-hal/microcontroller/Pin.h
@@ -34,9 +34,8 @@
#include "include/component/sercom.h"
typedef struct {
- Sercom *const sercom; // SERCOM0, SERCOM1, etc.
- uint8_t index; // 0, 1, etc. corresponding to SERCOM<n>.
- uint8_t pad; // which of the four SERCOM pads to use
+ uint8_t index:6; // 0, 1, etc. corresponding to SERCOM<n>.
+ uint8_t pad:2; // which of the four SERCOM pads to use
} pin_sercom_t;
typedef struct {
diff --git a/ports/atmel-samd/common-hal/microcontroller/Processor.c b/ports/atmel-samd/common-hal/microcontroller/Processor.c
index 1c57808f7..5c0d72c96 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Processor.c
+++ b/ports/atmel-samd/common-hal/microcontroller/Processor.c
@@ -243,7 +243,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
for (int i=0; i<4; i++) {
for (int k=0; k<4; k++) {
- raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xf;
+ raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xff;
}
}
}
diff --git a/ports/atmel-samd/external_flash/common_commands.h b/ports/atmel-samd/external_flash/common_commands.h
index fc05e70de..bb2060708 100644
--- a/ports/atmel-samd/external_flash/common_commands.h
+++ b/ports/atmel-samd/external_flash/common_commands.h
@@ -35,7 +35,11 @@
#define CMD_PAGE_PROGRAM 0x02
// #define CMD_PAGE_PROGRAM CMD_READ_JEDEC_ID
#define CMD_READ_STATUS 0x05
+#define CMD_READ_STATUS2 0x35
#define CMD_WRITE_STATUS_BYTE1 0x01
+#define CMD_DUAL_READ 0x3b
#define CMD_QUAD_READ 0x6b
+#define CMD_ENABLE_RESET 0x66
+#define CMD_RESET 0x99
#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H
diff --git a/ports/atmel-samd/external_flash/devices.h b/ports/atmel-samd/external_flash/devices.h
index ce2c6c3dc..d8baf5aca 100644
--- a/ports/atmel-samd/external_flash/devices.h
+++ b/ports/atmel-samd/external_flash/devices.h
@@ -169,7 +169,7 @@ typedef struct {
.supports_qspi_writes = true, \
}
-// Settings for the Winbond W25Q32BV 2MiB SPI flash.
+// Settings for the Winbond W25Q32BV 4MiB SPI flash.
// Datasheet: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf
#define W25Q32BV {\
.total_size = (1 << 22), /* 4 MiB */ \
diff --git a/ports/atmel-samd/external_flash/external_flash.c b/ports/atmel-samd/external_flash/external_flash.c
index 304bf6462..ccc47e5b1 100644
--- a/ports/atmel-samd/external_flash/external_flash.c
+++ b/ports/atmel-samd/external_flash/external_flash.c
@@ -185,12 +185,11 @@ void external_flash_init(void) {
if (flash_device != NULL) {
return;
}
- uint8_t num_possible_devices = sizeof(*possible_devices) / sizeof(external_flash_device);
// Delay to give the SPI Flash time to get going.
// TODO(tannewt): Only do this when we know power was applied vs a reset.
uint16_t max_start_up_delay_us = 0;
- for (uint8_t i = 0; i < num_possible_devices; i++) {
+ for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) {
if (possible_devices[i].start_up_time_us > max_start_up_delay_us) {
max_start_up_delay_us = possible_devices[i].start_up_time_us;
}
@@ -199,10 +198,14 @@ void external_flash_init(void) {
spi_flash_init();
- for (uint8_t i = 0; i < num_possible_devices; i++) {
- const external_flash_device* possible_device = &possible_devices[i];
- uint8_t jedec_id_response[3] = {0x00, 0x00, 0x00};
+ // The response will be 0xff if the flash needs more time to start up.
+ uint8_t jedec_id_response[3] = {0xff, 0xff, 0xff};
+ while (jedec_id_response[0] == 0xff) {
spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3);
+ }
+
+ for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) {
+ const external_flash_device* possible_device = &possible_devices[i];
if (jedec_id_response[0] == possible_device->manufacturer_id &&
jedec_id_response[1] == possible_device->memory_type &&
jedec_id_response[2] == possible_device->capacity) {
@@ -215,6 +218,26 @@ void external_flash_init(void) {
return;
}
+ // We don't know what state the flash is in so wait for any remaining writes and then reset.
+ uint8_t read_status_response[1] = {0x00};
+ // The write in progress bit should be low.
+ do {
+ spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1);
+ } while ((read_status_response[0] & 0x1) != 0);
+ // The suspended write/erase bit should be low.
+ do {
+ spi_flash_read_command(CMD_READ_STATUS2, read_status_response, 1);
+ } while ((read_status_response[0] & 0x80) != 0);
+
+
+ spi_flash_command(CMD_ENABLE_RESET);
+ spi_flash_command(CMD_RESET);
+
+ // Wait 30us for the reset
+ common_hal_mcu_delay_us(30);
+
+ spi_flash_init_device(flash_device);
+
// Activity LED for flash writes.
#ifdef MICROPY_HW_LED_MSC
gpio_set_pin_function(SPI_FLASH_CS_PIN, GPIO_PIN_FUNCTION_OFF);
diff --git a/ports/atmel-samd/external_flash/qspi_flash.c b/ports/atmel-samd/external_flash/qspi_flash.c
index 46e3cb92a..f4d5ec904 100644
--- a/ports/atmel-samd/external_flash/qspi_flash.c
+++ b/ports/atmel-samd/external_flash/qspi_flash.c
@@ -29,6 +29,8 @@
#include <stdint.h>
#include <string.h>
+#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL
+
#include "external_flash/common_commands.h"
#include "shared_dma.h"
@@ -139,8 +141,13 @@ bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
}
bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
+ #ifdef EXTERNAL_FLASH_QSPI_DUAL
+ QSPI->INSTRCTRL.bit.INSTR = CMD_DUAL_READ;
+ uint32_t mode = QSPI_INSTRFRAME_WIDTH_DUAL_OUTPUT;
+ #else
QSPI->INSTRCTRL.bit.INSTR = CMD_QUAD_READ;
uint32_t mode = QSPI_INSTRFRAME_WIDTH_QUAD_OUTPUT;
+ #endif
QSPI->INSTRFRAME.reg = mode |
QSPI_INSTRFRAME_ADDRLEN_24BITS |
@@ -174,7 +181,7 @@ void spi_flash_init(void) {
// Slow, good for debugging with Saleae
// QSPI->BAUD.bit.BAUD = 32;
- // Super fast
+ // Super fast, may be unreliable when Saleae is connected to high speed lines.
QSPI->BAUD.bit.BAUD = 2;
QSPI->CTRLB.reg = QSPI_CTRLB_MODE_MEMORY |
QSPI_CTRLB_DATALEN_8BITS |
@@ -189,14 +196,17 @@ void spi_flash_init(void) {
gpio_set_pin_pull_mode(pins[i], GPIO_PULL_OFF);
gpio_set_pin_function(pins[i], GPIO_PIN_FUNCTION_H);
}
+}
+void spi_flash_init_device(const external_flash_device* device) {
// Verify that QSPI mode is enabled.
uint8_t status;
- spi_flash_read_command(0x35, &status, 1);
+ spi_flash_read_command(CMD_READ_STATUS2, &status, 1);
+ // Bit 1 is Quad Enable
if ((status & 0x2) == 0) {
- uint8_t full_status[3] = { 0, status | 0x2, 0x70};
+ uint8_t full_status[2] = { 0x0, 0x2};
spi_flash_command(CMD_ENABLE_WRITE);
- spi_flash_write_command(0x01, full_status, 3);
+ spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status, 2);
}
}
diff --git a/ports/atmel-samd/external_flash/spi_flash.c b/ports/atmel-samd/external_flash/spi_flash.c
index fcaedcaac..8a8cbaef8 100644
--- a/ports/atmel-samd/external_flash/spi_flash.c
+++ b/ports/atmel-samd/external_flash/spi_flash.c
@@ -152,3 +152,7 @@ void spi_flash_init(void) {
spi_m_sync_enable(&spi_flash_desc);
}
+
+void spi_flash_init_device(const external_flash_device* device) {
+
+}
diff --git a/ports/atmel-samd/external_flash/spi_flash_api.h b/ports/atmel-samd/external_flash/spi_flash_api.h
index b858ff0ea..a6df0c459 100644
--- a/ports/atmel-samd/external_flash/spi_flash_api.h
+++ b/ports/atmel-samd/external_flash/spi_flash_api.h
@@ -29,6 +29,8 @@
#include <stdbool.h>
#include <stdint.h>
+#include "external_flash/devices.h"
+
// This API is implemented for both normal SPI peripherals and QSPI peripherals.
bool spi_flash_command(uint8_t command);
@@ -38,5 +40,6 @@ bool spi_flash_sector_command(uint8_t command, uint32_t address);
bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length);
bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length);
void spi_flash_init(void);
+void spi_flash_init_device(const external_flash_device* device);
#endif // MICROPY_INCLUDED_ATMEL_SAMD_SPI_FLASH_H
diff --git a/ports/atmel-samd/freetouch b/ports/atmel-samd/freetouch
new file mode 160000
+Subproject c3deba11eb4be397ec719cfbfba1abcaecda2c0
diff --git a/ports/atmel-samd/freetouch/Adafruit_FreeTouch.cpp b/ports/atmel-samd/freetouch/Adafruit_FreeTouch.cpp
deleted file mode 100644
index 45cac3867..000000000
--- a/ports/atmel-samd/freetouch/Adafruit_FreeTouch.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * FreeTouch, a QTouch-compatible library - tested on ATSAMD21 only!
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Limor 'ladyada' Fried 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.
- */
-
-#include "Adafruit_FreeTouch.h"
-
-#include "adafruit_ptc.h"
-
-Adafruit_FreeTouch::Adafruit_FreeTouch(int p, oversample_t f, series_resistor_t r, freq_mode_t fh) {
- adafruit_ptc_get_config_default(&config);
- pin = p;
- uint8_t port_offset = 0;
- if (g_APinDescription[pin].ulPort == PORTB) {
- port_offset += 32;
- }
- config.pin = port_offset + g_APinDescription[pin].ulPin;
- config.yline = getYLine(); // determine the Y0-15 #
- config.oversample = f;
- config.seriesres = r;
- config.freqhop = fh;
-}
-
-bool Adafruit_FreeTouch::begin(void) {
- if (config.yline == -1) { // not all pins have Y line
- return false;
- }
-
- /* Setup and enable generic clock source for PTC module.
- struct system_gclk_chan_config gclk_chan_conf;
- system_gclk_chan_get_config_defaults(&gclk_chan_conf);
- */
-
- uint8_t channel = PTC_GCLK_ID;
- uint8_t source_generator = 1;
-
- // original line: system_gclk_chan_set_config(PTC_GCLK_ID, &gclk_chan_conf);
- uint32_t new_clkctrl_config = (channel << GCLK_CLKCTRL_ID_Pos); // from gclk.c
-
- // original line: gclk_chan_conf.source_generator = GCLK_GENERATOR_1;
- /* Select the desired generic clock generator */
- new_clkctrl_config |= source_generator << GCLK_CLKCTRL_GEN_Pos; // from gclk.c
-
- /* Disable generic clock channel */
- // original line: system_gclk_chan_disable(channel);
- noInterrupts();
-
- /* Select the requested generator channel */
- *((uint8_t*)&GCLK->CLKCTRL.reg) = channel;
-
- /* Sanity check WRTLOCK */
- //Assert(!GCLK->CLKCTRL.bit.WRTLOCK);
-
- /* Switch to known-working source so that the channel can be disabled */
- uint32_t prev_gen_id = GCLK->CLKCTRL.bit.GEN;
- GCLK->CLKCTRL.bit.GEN = 0;
-
- /* Disable the generic clock */
- GCLK->CLKCTRL.reg &= ~GCLK_CLKCTRL_CLKEN;
- while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN) {
- /* Wait for clock to become disabled */
- }
-
- /* Restore previous configured clock generator */
- GCLK->CLKCTRL.bit.GEN = prev_gen_id;
-
- //system_interrupt_leave_critical_section();
- interrupts();
-
- /* Write the new configuration */
- GCLK->CLKCTRL.reg = new_clkctrl_config;
-
- // original line: system_gclk_chan_enable(PTC_GCLK_ID);
- *((uint8_t*)&GCLK->CLKCTRL.reg) = channel;
- GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_CLKEN; /* Enable the generic clock */
-
-
- // original line: system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_PTC);
- PM->APBCMASK.reg |= PM_APBCMASK_PTC;
-
- adafruit_ptc_init(PTC, &config);
-
- return true;
-}
-
-uint16_t Adafruit_FreeTouch::measure(void) {
- uint16_t m;
-
- m = measureRaw();
- if (m == -1) return -1;
-
- // normalize the signal
- switch (config.oversample) {
- case OVERSAMPLE_1: return m;
- case OVERSAMPLE_2: return m/2;
- case OVERSAMPLE_4: return m/4;
- case OVERSAMPLE_8: return m/8;
- case OVERSAMPLE_16: return m/16;
- case OVERSAMPLE_32: return m/32;
- case OVERSAMPLE_64: return m/64;
- }
-
- return -1; // shouldn't reach here but fail if we do!
-}
-
-uint16_t Adafruit_FreeTouch::measureRaw(void) {
- adafruit_ptc_start_conversion(PTC, &config);
-
- while (!adafruit_ptc_is_conversion_finished(PTC)) {
- yield();
- }
-
- return adafruit_ptc_get_conversion_result(PTC);
-}
-
-/*********************************** low level config **/
-
-int Adafruit_FreeTouch::getYLine(void) {
- int p = g_APinDescription[pin].ulPin;
- if (g_APinDescription[pin].ulPort == PORTA) {
- if ((p >= 2) && (p <= 7)) {
- return (p - 2);
- }
- }
- if (g_APinDescription[pin].ulPort == PORTB) {
- if ((p >= 0) && (p <= 9)) {
- return (p + 6);
- }
- }
-
- // not valid
- return -1;
-}
-
-void Adafruit_FreeTouch::setCompCap(uint16_t cc) {
- config.compcap = cc & 0x3FFF;
-}
-
-void Adafruit_FreeTouch::setIntCap(uint8_t ic) {
- config.intcap = ic & 0x3F;
-}
-
-void Adafruit_FreeTouch::setOversampling(oversample_t lvl) {
- config.oversample = lvl; // back it up for later
-}
-
-void Adafruit_FreeTouch::setSeriesResistor(series_resistor_t res) {
- config.seriesres = res;
-}
-
-void Adafruit_FreeTouch::setFreqHopping(freq_mode_t fh, freq_hop_t hs) {
- config.freqhop = fh;
- config.hops = hs;
-}
-
-/**************************** DEBUGGING ASSIST *************************/
-void Adafruit_FreeTouch::snapshotRegsAndPrint(uint32_t base, uint8_t numregs) {
- volatile uint32_t addr = base;
- uint8_t datas[255];
-
- digitalWrite(LED_BUILTIN, HIGH);
- for (uint8_t i=0; i<numregs; i++) {
- datas[i] = *(uint8_t *)(addr+i);
- }
- digitalWrite(LED_BUILTIN, LOW);
- printPTCregs(base, datas, numregs);
-
- for (uint8_t i=0; i<numregs; i++) {
- // Serial.print("$"); Serial.print(addr+i, HEX); Serial.print("\t0x");
- // printHex(datas[i]); Serial.println();
- }
-
-}
-
-// Print a hex with leading zero
-void Adafruit_FreeTouch::printHex(uint8_t h, boolean newline) {
- if (h < 0x10) Serial.print("0");
- Serial.print(h, HEX);
- if (newline) Serial.println();
-}
-
-void Adafruit_FreeTouch::printPTCregs(uint32_t base, uint8_t *regs, uint8_t num) {
- Serial.println("--------------------------------------------------------");
- for (uint8_t i=0; i<num; i++) {
- switch (i + base) {
- case 0x41004430: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PMUX0:\t\t0x"); printHex(regs[i], true); break;
- case 0x41004431: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PMUX1:\t\t0x"); printHex(regs[i], true); break;
- case 0x41004432: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PMUX2:\t\t0x"); printHex(regs[i], true); break;
- case 0x41004433: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PMUX3:\t\t0x"); printHex(regs[i], true); break;
-
- case 0x41004440: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PCFG0:\t\t0x"); printHex(regs[i], true); break;
- case 0x41004441: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PCFG1:\t\t0x"); printHex(regs[i], true); break;
- case 0x41004442: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PCFG2:\t\t0x"); printHex(regs[i], true); break;
- case 0x41004443: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PCFG3:\t\t0x"); printHex(regs[i], true); break;
- case 0x41004444: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" PCFG4:\t\t0x"); printHex(regs[i], true); break;
-
-
- case 0x42004C00: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Control A:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C01: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Sync: \t\t0x"); printHex(regs[i], true); break;
- case 0x42004C04: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Prescaler:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C05: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Init: \t\t0x"); printHex(regs[i], true); break;
- case 0x42004C08: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Disable Irq:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C09: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Enable Irq:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C0A: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Flags: \t\t0x"); printHex(regs[i], true); break;
- case 0x42004C0C: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Freq Cntl:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C0D: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Conv Cntl:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C10: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Y Select1:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C11: Serial.print("0x"); Serial.print(i+0x42004C00, HEX);
- Serial.print(" Y Select2:\t\t0x"); printHex(regs[i], true); break;
-/*
- case 0x42004C12: Serial.print("0x"); Serial.print(i+0x42004C00, HEX);
- Serial.print(" X Select1:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C13: Serial.print("0x"); Serial.print(i+0x42004C00, HEX);
- Serial.print(" X Select2:\t\t0x"); printHex(regs[i], true); break;
-*/
- case 0x42004C14: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Y Enable1:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C15: Serial.print("0x"); Serial.print(i+0x42004C00, HEX);
- Serial.print(" Y Enable2:\t\t0x"); printHex(regs[i], true); break;
-/*
- case 0x42004C16: Serial.print("0x"); Serial.print(i+0x42004C00, HEX);
- Serial.print(" X Enable1:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C17: Serial.print("0x"); Serial.print(i+0x42004C00, HEX);
- Serial.print(" X Enable2:\t\t0x"); printHex(regs[i], true); break;
-*/
- case 0x42004C18: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Compcap L:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C19: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Compcap H:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C1A: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Intcap: \t\t0x"); printHex(regs[i], true); break;
- case 0x42004C1B: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Sense res:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C1C: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Result L:\t\t0x"); printHex(regs[i], true); break;
- case 0x42004C1D: Serial.print("0x"); Serial.print(i+base, HEX);
- Serial.print(" Result H:\t\t0x"); printHex(regs[i], true); break;
-
- }
- }
-}
diff --git a/ports/atmel-samd/freetouch/Adafruit_FreeTouch.h b/ports/atmel-samd/freetouch/Adafruit_FreeTouch.h
deleted file mode 100644
index 85dd08988..000000000
--- a/ports/atmel-samd/freetouch/Adafruit_FreeTouch.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef ADAFRUIT_FREETOUCH_H
-#define ADAFRUIT_FREETOUCH_H
-
-#include <Arduino.h>
-#include "adafruit_ptc.h"
-
-class Adafruit_FreeTouch {
- public:
- Adafruit_FreeTouch(int p = 0, oversample_t f = OVERSAMPLE_4, series_resistor_t r = RESISTOR_0, freq_mode_t fh = FREQ_MODE_NONE);
- bool begin(void);
-
- uint16_t measure(void);
- uint16_t measureRaw(void);
-
- private:
- void ptcInitSettings(void);
- void ptcConfigIOpin(void);
- uint16_t startPtcAcquire(void);
-
- int getYLine(void);
- void selectYLine(void);
- void setOversampling(oversample_t lvl);
- void setSeriesResistor(series_resistor_t res);
- void setFreqHopping(freq_mode_t fh, freq_hop_t hops = FREQ_HOP_1);
- void setCompCap(uint16_t cc);
- void setIntCap(uint8_t ic);
-
- void snapshotRegsAndPrint(uint32_t base, uint8_t numregs);
- void printHex(uint8_t h, boolean newline);
- void printPTCregs(uint32_t base, uint8_t *regs, uint8_t num);
-
- private:
- int pin; // arduino pin #
- struct adafruit_ptc_config config;
-};
-
-#endif
diff --git a/ports/atmel-samd/freetouch/README.md b/ports/atmel-samd/freetouch/README.md
deleted file mode 100644
index 3b179a45c..000000000
--- a/ports/atmel-samd/freetouch/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Adafruit_FreeTouch
-A QTouch-compatible library
diff --git a/ports/atmel-samd/freetouch/adafruit_ptc.c b/ports/atmel-samd/freetouch/adafruit_ptc.c
deleted file mode 100644
index f4369cf4a..000000000
--- a/ports/atmel-samd/freetouch/adafruit_ptc.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * FreeTouch, a QTouch-compatible library - tested on ATSAMD21 only!
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Limor 'ladyada' Fried 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.
- */
-
-#include "adafruit_ptc.h"
-#include "pinmux.h"
-
-static void sync_config(Ptc const* module_inst) {
- while (module_inst->CONTROLB.bit.SYNCFLAG) ;
-}
-
-void adafruit_ptc_get_config_default(struct adafruit_ptc_config *config) {
- config->pin = 0xff;
- config->yline = -1;
- config->oversample = OVERSAMPLE_4;
- config->seriesres = RESISTOR_0;
- config->freqhop = FREQ_MODE_NONE;
- config->compcap = 0x2000;
- config->intcap = 0x3F;
-}
-
-void adafruit_ptc_init(Ptc* module_inst, struct adafruit_ptc_config const* config) {
- struct system_pinmux_config pinmux_config;
- system_pinmux_get_config_defaults(&pinmux_config);
- pinmux_config.mux_position = 0x1;
- pinmux_config.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
- system_pinmux_pin_set_config(config->pin, &pinmux_config);
-
- sync_config(module_inst);
- module_inst->CONTROLA.bit.ENABLE = 0;
- sync_config(module_inst);
-
- module_inst->UNK4C04.reg &= 0xF7; //MEMORY[0x42004C04] &= 0xF7u;
- module_inst->UNK4C04.reg &= 0xFB; //MEMORY[0x42004C04] &= 0xFBu;
- module_inst->UNK4C04.reg &= 0xFC; //MEMORY[0x42004C04] &= 0xFCu;
- sync_config(module_inst);
- module_inst->FREQCONTROL.reg &= 0x9F; //MEMORY[0x42004C0C] &= 0x9Fu;
- sync_config(module_inst);
- module_inst->FREQCONTROL.reg &= 0xEF; //MEMORY[0x42004C0C] &= 0xEFu;
- sync_config(module_inst);
- module_inst->FREQCONTROL.bit.SAMPLEDELAY = 0; //MEMORY[0x42004C0C] &= 0xF0u;
- module_inst->CONTROLC.bit.INIT = 1; //MEMORY[0x42004C05] |= 1u;
- module_inst->CONTROLA.bit.RUNINSTANDBY = 1; //MEMORY[0x42004C00] |= 4u;
- sync_config(module_inst);
- module_inst->INTDISABLE.bit.WCO = 1;
- sync_config(module_inst);
- module_inst->INTDISABLE.bit.EOC = 1;
- sync_config(module_inst);
-
- // enable the sensor, only done once per line
- if (config->yline < 8) {
- sync_config(module_inst);
- module_inst->YENABLEL.reg |= 1 << config->yline;
- sync_config(module_inst);
- } else if (config->yline < 16) {
- module_inst->YENABLEH.reg |= 1 << (config->yline - 8);
- }
-
- sync_config(module_inst);
- module_inst->CONTROLA.bit.ENABLE = 1;
- sync_config(module_inst);
-}
-
-void adafruit_ptc_start_conversion(Ptc* module_inst, struct adafruit_ptc_config const* config) {
- module_inst->CONTROLA.bit.RUNINSTANDBY = 1;
- sync_config(module_inst);
- module_inst->CONTROLA.bit.ENABLE = 1;
- sync_config(module_inst);
- module_inst->INTDISABLE.bit.WCO = 1;
- sync_config(module_inst);
- module_inst->INTFLAGS.bit.WCO = 1;
- sync_config(module_inst);
- module_inst->INTFLAGS.bit.EOC = 1;
- sync_config(module_inst);
-
- // set up pin!
- sync_config(module_inst);
- if (config->yline < 8) {
- module_inst->YSELECTL.reg = 1 << config->yline;
- } else {
- module_inst->YSELECTL.reg = 0;
- }
-
- if (config->yline > 7) {
- module_inst->YSELECTH.reg = 1 << (config->yline - 8);
- } else {
- module_inst->YSELECTH.reg = 0;
- }
-
- sync_config(module_inst);
- // set up sense resistor
- module_inst->SERRES.bit.RESISTOR = config->seriesres;
- sync_config(module_inst);
- // set up prescalar
- module_inst->CONVCONTROL.bit.ADCACCUM = config->oversample;
- sync_config(module_inst);
- // set up freq hopping
- if (config->freqhop == FREQ_MODE_NONE) {
- module_inst->FREQCONTROL.bit.FREQSPREADEN = 0;
- module_inst->FREQCONTROL.bit.SAMPLEDELAY = 0;
- } else {
- module_inst->FREQCONTROL.bit.FREQSPREADEN = 1;
- module_inst->FREQCONTROL.bit.SAMPLEDELAY = config->hops;
- }
- // set up compensation cap + int (?) cap
- sync_config(module_inst);
- module_inst->COMPCAPL.bit.VALUE = config->compcap & 0xFF;
- module_inst->COMPCAPH.bit.VALUE = (config->compcap>>8) & 0x3F;
- sync_config(module_inst);
- module_inst->INTCAP.bit.VALUE = config->intcap & 0x3F;
- sync_config(module_inst);
-
- module_inst->BURSTMODE.reg = 0xA4;
- sync_config(module_inst);
-
- module_inst->CONVCONTROL.bit.CONVERT = 1;
- sync_config(module_inst);
-}
-
-bool adafruit_ptc_is_conversion_finished(Ptc* module_inst) {
- return module_inst->CONVCONTROL.bit.CONVERT == 0;
-}
-
-uint16_t adafruit_ptc_get_conversion_result(Ptc* module_inst) {
- sync_config(module_inst);
- return module_inst->RESULT.reg;
-}
diff --git a/ports/atmel-samd/freetouch/adafruit_ptc.h b/ports/atmel-samd/freetouch/adafruit_ptc.h
deleted file mode 100644
index 93bb16ef4..000000000
--- a/ports/atmel-samd/freetouch/adafruit_ptc.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * FreeTouch, a QTouch-compatible library - tested on ATSAMD21 only!
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Limor 'ladyada' Fried 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.
- */
-
-// This is similar to the drivers found in sam0/drivers but for the PTC.
-#ifndef ADAFRUIT_FREETOUCH_ADAFRUIT_PTC_H
-#define ADAFRUIT_FREETOUCH_ADAFRUIT_PTC_H
-
-#include <stdint.h>
-
-#include "samd21_ptc_component.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Touch library oversampling (filter) setting */
-typedef enum tag_oversample_level_t {
- OVERSAMPLE_1,
- OVERSAMPLE_2,
- OVERSAMPLE_4,
- OVERSAMPLE_8,
- OVERSAMPLE_16,
- OVERSAMPLE_32,
- OVERSAMPLE_64
-}
-oversample_t;
-
-/* Touch library series resistor setting */
-typedef enum tag_series_resistor_t {
- RESISTOR_0,
- RESISTOR_20K,
- RESISTOR_50K,
- RESISTOR_100K,
-}
-series_resistor_t;
-
-typedef enum tag_freq_mode_t {
- FREQ_MODE_NONE,
- FREQ_MODE_HOP,
- FREQ_MODE_SPREAD,
- FREQ_MODE_SPREAD_MEDIAN
-}
-freq_mode_t;
-
-typedef enum tag_freq_hop_t {
- FREQ_HOP_1,
- FREQ_HOP_2,
- FREQ_HOP_3,
- FREQ_HOP_4,
- FREQ_HOP_5,
- FREQ_HOP_6,
- FREQ_HOP_7,
- FREQ_HOP_8,
- FREQ_HOP_9,
- FREQ_HOP_10,
- FREQ_HOP_11,
- FREQ_HOP_12,
- FREQ_HOP_13,
- FREQ_HOP_14,
- FREQ_HOP_15,
- FREQ_HOP_16
-}
-freq_hop_t;
-
-struct adafruit_ptc_config {
- uint8_t pin; // ASF pin #
- int8_t yline; // the Y select line (see datasheet)
- oversample_t oversample;
- series_resistor_t seriesres;
- freq_mode_t freqhop;
- freq_hop_t hops;
- uint16_t compcap;
- uint8_t intcap;
-};
-
-void adafruit_ptc_get_config_default(struct adafruit_ptc_config *config);
-void adafruit_ptc_init(Ptc* module_inst, struct adafruit_ptc_config const* config);
-void adafruit_ptc_start_conversion(Ptc* module_inst, struct adafruit_ptc_config const* config);
-
-bool adafruit_ptc_is_conversion_finished(Ptc* module_inst);
-uint16_t adafruit_ptc_get_conversion_result(Ptc* module_inst);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // ADAFRUIT_FREETOUCH_ADAFRUIT_PTC_H
diff --git a/ports/atmel-samd/freetouch/examples/freetouch/freetouch.ino b/ports/atmel-samd/freetouch/examples/freetouch/freetouch.ino
deleted file mode 100644
index d89642c2e..000000000
--- a/ports/atmel-samd/freetouch/examples/freetouch/freetouch.ino
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "Adafruit_FreeTouch.h"
-
-Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(A0, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
-Adafruit_FreeTouch qt_2 = Adafruit_FreeTouch(A1, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
-Adafruit_FreeTouch qt_3 = Adafruit_FreeTouch(A2, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
-Adafruit_FreeTouch qt_4 = Adafruit_FreeTouch(A3, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
-
-void setup() {
- Serial.begin(115200);
-
- while (!Serial);
- Serial.println("FreeTouch test");
- // initialize digital pin LED_BUILTIN as an output.
- pinMode(LED_BUILTIN, OUTPUT);
-
- if (! qt_1.begin())
- Serial.println("Failed to begin qt on pin A0");
- if (! qt_2.begin())
- Serial.println("Failed to begin qt on pin A1");
- if (! qt_3.begin())
- Serial.println("Failed to begin qt on pin A2");
- if (! qt_4.begin())
- Serial.println("Failed to begin qt on pin A3");
-
-}
-
-
-
-void loop() {
- int counter, result = 0;
-
- // DIY
- Serial.println("\n*************************************");
-
- counter = millis();
- result = qt_1.measure();
- Serial.print("QT 1: "); Serial.print(result);
- Serial.print(" ("); Serial.print(millis() - counter); Serial.println(" ms)");
-
- counter = millis();
- result = qt_2.measure();
- Serial.print("QT 2: "); Serial.print(result);
- Serial.print(" ("); Serial.print(millis() - counter); Serial.println(" ms)");
-
- counter = millis();
- result = qt_3.measure();
- Serial.print("QT 3: "); Serial.print(result);
- Serial.print(" ("); Serial.print(millis() - counter); Serial.println(" ms)");
-
- counter = millis();
- result = qt_4.measure();
- Serial.print("QT 4: "); Serial.print(result);
- Serial.print(" ("); Serial.print(millis() - counter); Serial.println(" ms)");
-
- delay(200);
-} \ No newline at end of file
diff --git a/ports/atmel-samd/freetouch/samd21_ptc_component.h b/ports/atmel-samd/freetouch/samd21_ptc_component.h
deleted file mode 100644
index 0af3236d3..000000000
--- a/ports/atmel-samd/freetouch/samd21_ptc_component.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * FreeTouch, a QTouch-compatible library - tested on ATSAMD21 only!
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Limor 'ladyada' Fried 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.
- */
-
-// This is similar to the component definitions found in
-// sam0/utils/cmsis/samd21/include/component but for the PTC.
-#ifndef ADAFRUIT_FREETOUCH_PTC_COMPONENT_H
-#define ADAFRUIT_FREETOUCH_PTC_COMPONENT_H
-
-#include "compiler.h"
-
-#undef ENABLE
-
-/*************** CONTROL A register ***************/
-#define PTC_REG_CONTROLA 0x42004C00
-#define PTC_BIT_ENABLE 0x02
-#define PTC_BIT_RUNINSTBY 0x04
-
-
-typedef union {
- struct {
- uint8_t SWRESET:1;
- uint8_t ENABLE:1;
- uint8_t RUNINSTANDBY:1;
- uint8_t __pad0__:5;
- } bit;
- uint8_t reg;
-} PTC_REG_CONTROLA_Type;
-
-/*************** CONTROL B register ***************/
-
-#define PTC_REG_CONTROLB 0x42004C01
-#define PTC_BIT_SYNCFLAG 0x80
-
-typedef union {
- struct {
- uint8_t __pad0__:7;
- uint8_t SYNCFLAG:1;
- } bit;
- uint8_t reg;
-} PTC_REG_CONTROLB_Type;
-
-/*************** UNK4C04 register ***************/
-
-#define PTC_REG_UNK4C04 0x42004C04
-
-typedef union {
- uint8_t reg;
-} PTC_REG_UNK4C04_Type;
-
-
-/*************** CONTROL C register ***************/
-
-#define PTC_REG_CONTROLC 0x42004C05
-#define PTC_BIT_INIT 0x01
-
-typedef union {
- struct {
- uint8_t INIT:1;
- uint8_t __pad0__:7;
- } bit;
- uint8_t reg;
-} PTC_REG_CONTROLC_Type;
-
-
-
-/*************** INT registers ***************/
-
-typedef union {
- struct {
- uint8_t EOC:1;
- uint8_t WCO:1;
- uint8_t __pad0__:6;
- } bit;
- uint8_t reg;
-} PTC_REG_INT_Type;
-
-
-#define PTC_REG_INTDISABLE 0x42004C08
-#define PTC_REG_INTENABLE 0x42004C09
-#define PTC_BIT_EOCINTEN 0x01
-#define PTC_BIT_WCOINTEN 0x02
-
-#define PTC_REG_INTFLAGS 0x42004C0A
-#define PTC_BIT_EOCINTFLAG 0x01
-#define PTC_BIT_WCOINTFLAG 0x02
-
-
-/*************** FREQ CONTROL reg ***************/
-
-typedef union {
- struct {
- uint8_t SAMPLEDELAY:4;
- uint8_t FREQSPREADEN:1;
- uint8_t __pad0__:3;
- } bit;
- uint8_t reg;
-} PTC_REG_FREQCONTROL_Type;
-
-#define PTC_REG_FREQCONTROL 0x42004C0C
-#define PTC_BIT_FREQSPREADEN 0x10
-#define PTC_REG_SAMPLEDELAY_MASK 0x0F
-
-/*************** CONVERT CONTROL reg ***************/
-
-typedef union {
- struct {
- uint8_t ADCACCUM:3;
- uint8_t __pad0__:4;
- uint8_t CONVERT:1;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_CONVCONTROL_Type;
-
-
-#define PTC_REG_CONVCONTROL 0x42004C0D
-#define PTC_BIT_CONVSTARTED 0x80
-#define PTC_REG_ADCACC_MASK 0x07
-
-
-/*************** Y SELECT L+H reg ***************/
-
-typedef union {
- struct {
- uint8_t Y0:1;
- uint8_t Y1:1;
- uint8_t Y2:1;
- uint8_t Y3:1;
- uint8_t Y4:1;
- uint8_t Y5:1;
- uint8_t Y6:1;
- uint8_t Y7:1;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_YSELECTL_Type;
-
-typedef union {
- struct {
- uint8_t Y8:1;
- uint8_t Y9:1;
- uint8_t Y10:1;
- uint8_t Y11:1;
- uint8_t Y12:1;
- uint8_t Y13:1;
- uint8_t Y14:1;
- uint8_t Y15:1;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_YSELECTH_Type;
-
-#define PTC_REG_YSELECT_L 0x42004C10
-#define PTC_REG_YSELECT_H 0x42004C11
-
-#define PTC_REG_YENABLE_L 0x42004C14
-#define PTC_REG_YENABLE_H 0x42004C15
-
-
-/*************** X SELECT L+H reg ***************/
-
-typedef union {
- struct {
- uint8_t X0:1;
- uint8_t X1:1;
- uint8_t X2:1;
- uint8_t X3:1;
- uint8_t X4:1;
- uint8_t X5:1;
- uint8_t X6:1;
- uint8_t X7:1;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_XSELECTL_Type;
-
-typedef union {
- struct {
- uint8_t X8:1;
- uint8_t X9:1;
- uint8_t X10:1;
- uint8_t X11:1;
- uint8_t X12:1;
- uint8_t X13:1;
- uint8_t X14:1;
- uint8_t X15:1;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_XSELECTH_Type;
-
-
-#define PTC_REG_XSELECT_L 0x42004C12
-#define PTC_REG_XSELECT_H 0x42004C13
-
-#define PTC_REG_XENABLE_L 0x42004C16
-#define PTC_REG_XENABLE_H 0x42004C17
-
-/*************** Compensation Cap reg ***************/
-
-typedef union {
- struct {
- uint8_t VALUE:8;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_COMPCAPL_Type;
-
-typedef union {
- struct {
- uint8_t VALUE:6;
- uint8_t __pad0__:2;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_COMPCAPH_Type;
-
-#define PTC_REG_COMPCAPL 0x42004C18
-#define PTC_REG_COMPCAPH 0x42004C19
-
-/*************** Int Cap reg ***************/
-
-typedef union {
- struct {
- uint8_t VALUE:6;
- uint8_t __pad0__:2;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_INTCAP_Type;
-
-
-#define PTC_REG_INTCAP 0x42004C1A
-
-/*************** Series resistor reg ***************/
-
-typedef union {
- struct {
- uint8_t RESISTOR:2;
- uint8_t __pad0__:6;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_SERRES_Type;
-
-#define PTC_REG_SERIESRES 0x42004C1B
-
-/*************** conversion result reg ***************/
-
-typedef union {
- struct {
- uint8_t LOWBYTE;
- uint8_t HIGHBYTE;
- } byte;
- uint16_t reg;
-} __attribute__ ((packed)) PTC_REG_CONVRESULT_Type;
-
-#define PTC_REG_CONVRESULT_L 0x42004C1C
-#define PTC_REG_CONVRESULT_H 0x42004C1D
-
-/*************** burst mode reg ***************/
-
-typedef union {
- struct {
- uint8_t __pad0__:2;
- uint8_t CTSLOWPOWER:1;
- uint8_t __pad1__:1;
- uint8_t BURSTMODE:4;
- } bit;
- uint8_t reg;
-} __attribute__ ((packed)) PTC_REG_BURSTMODE_Type;
-
-
-#define PTC_REG_BURSTMODE 0x42004C20
-#define PTC_REG_BURSTMODE_MASK 0xF0
-#define PTC_BIT_CTSLOWPOWER 0x04
-
-/*************** etc unused reg ***************/
-
-#define PTC_REG_XYENABLE 0x42004C16
-#define PTC_BIT_XYENABLE 0x02
-
-#define PTC_REG_WCO_MODE 0x42004C21
-#define PTC_REG_WCO_MODE_MASK 0x07
-
-#define PTC_SET_WCO_THRESHHOLD_A_L 0x42004C24
-#define PTC_SET_WCO_THRESHHOLD_A_H 0x42004C25
-#define PTC_SET_WCO_THRESHHOLD_B_L 0x42004C26
-#define PTC_SET_WCO_THRESHHOLD_B_H 0x42004C27
-
-typedef struct {
- __IO PTC_REG_CONTROLA_Type CONTROLA; // 0x42004C00
- __IO PTC_REG_CONTROLB_Type CONTROLB; // 0x42004C01
- uint8_t __pad4c02__; // 0x42004C02 unknown
- uint8_t __pad4c03__; // 0x42004C03 unknown
- __IO PTC_REG_UNK4C04_Type UNK4C04; // 0x42004C04 unknown
- __IO PTC_REG_CONTROLC_Type CONTROLC; // 0x42004C05
- uint8_t __pad4c06__; // 0x42004C06 unknown
- uint8_t __pad4c07__; // 0x42004C07 unknown
- __IO PTC_REG_INT_Type INTDISABLE; // 0x42004C08
- __IO PTC_REG_INT_Type INTENABLE; // 0x42004C09
- __IO PTC_REG_INT_Type INTFLAGS; // 0x42004C0A
- uint8_t __pad4c0b__; // 0x42004C0B unknown
- __IO PTC_REG_FREQCONTROL_Type FREQCONTROL; //0x42004C0C
- __IO PTC_REG_CONVCONTROL_Type CONVCONTROL; // 0x42004C0D
- uint8_t __pad4c0e__; // 0x42004C0E unknown
- uint8_t __pad4c0f__; // 0x42004C0F unknown
- __IO PTC_REG_YSELECTL_Type YSELECTL; // 0x42004C10
- __IO PTC_REG_YSELECTL_Type YSELECTH; // 0x42004C11
- __IO PTC_REG_XSELECTL_Type XSELECTL; // 0x42004C12
- __IO PTC_REG_XSELECTL_Type XSELECTH; // 0x42004C13
- __IO PTC_REG_YSELECTL_Type YENABLEL; // 0x42004C14
- __IO PTC_REG_YSELECTL_Type YENABLEH; // 0x42004C15
- __IO PTC_REG_XSELECTL_Type XENABLEL; // 0x42004C16
- __IO PTC_REG_XSELECTL_Type XENABLEH; // 0x42004C17
-
- __IO PTC_REG_COMPCAPL_Type COMPCAPL; // 0x42004C18
- __IO PTC_REG_COMPCAPH_Type COMPCAPH; // 0x42004C19
- __IO PTC_REG_INTCAP_Type INTCAP; // 0x42004C1A
- __IO PTC_REG_SERRES_Type SERRES; // 0x42004C1B
-
- __IO PTC_REG_CONVRESULT_Type RESULT; // 0x42004C1C + 0x42004C1D
- uint8_t __pad4c1e__; // 0x42004C1E unknown
- uint8_t __pad4c1f__; // 0x42004C1F unknown
- __IO PTC_REG_BURSTMODE_Type BURSTMODE; // 0x42004C20
-} Ptc;
-
-#define PTC (( Ptc *)0x42004C00U)
-
-#define PTC_REG_INTDISABLE 0x42004C08
-#define PTC_REG_INTENABLE 0x42004C09
-#define PTC_BIT_EOCINTEN 0x01
-#define PTC_BIT_WCOINTEN 0x02
-
-#define PTC_REG_INTFLAGS 0x42004C0A
-
-#endif // ADAFRUIT_FREETOUCH_PTC_COMPONENT_H
diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h
index 032bd164f..c66f0d0b3 100644
--- a/ports/atmel-samd/mpconfigport.h
+++ b/ports/atmel-samd/mpconfigport.h
@@ -46,6 +46,7 @@
#define MICROPY_PY_BUILTINS_SLICE (1)
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
+#define MICROPY_NONSTANDARD_TYPECODES (0)
#define MICROPY_PY_BUILTINS_PROPERTY (1)
#define MICROPY_PY_BUILTINS_MIN_MAX (1)
#define MICROPY_PY___FILE__ (1)
@@ -63,6 +64,7 @@
#define MICROPY_PY_SYS (1)
#define MICROPY_PY_SYS_MAXSIZE (1)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
+#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1)
#define MICROPY_STREAMS_NON_BLOCK (1)
// fatfs configuration used in ffconf.h
diff --git a/ports/atmel-samd/peripherals.h b/ports/atmel-samd/peripherals.h
index bb01bc1ac..18c7f44d5 100644
--- a/ports/atmel-samd/peripherals.h
+++ b/ports/atmel-samd/peripherals.h
@@ -35,6 +35,8 @@
uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate);
uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value);
+Sercom* sercom_insts[SERCOM_INST_NUM];
+
#ifdef SAMD21
#include "samd21_peripherals.h"
#endif
diff --git a/ports/atmel-samd/samd21_peripherals.c b/ports/atmel-samd/samd21_peripherals.c
index 484c787cb..a27e49e0e 100644
--- a/ports/atmel-samd/samd21_peripherals.c
+++ b/ports/atmel-samd/samd21_peripherals.c
@@ -56,7 +56,8 @@ static const uint8_t SERCOMx_GCLK_ID_SLOW[] = {
#endif
};
-
+Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS;
+
// Clock initialization as done in Atmel START.
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) {
_pm_enable_bus_clock(PM_BUS_APBC, sercom);
diff --git a/ports/atmel-samd/samd21_pins.c b/ports/atmel-samd/samd21_pins.c
index f1d006de8..eafc4b5fb 100644
--- a/ports/atmel-samd/samd21_pins.c
+++ b/ports/atmel-samd/samd21_pins.c
@@ -30,15 +30,13 @@
#define SERCOM(sercom_index, p_pad) \
{ \
- .sercom = SERCOM## sercom_index, \
.index = sercom_index, \
.pad = p_pad \
}
#define NO_SERCOM \
{ \
- .sercom = 0, \
- .index = 0, \
+ .index = 0x3f, \
.pad = 0 \
}
@@ -57,7 +55,7 @@
.wave_output = p_wave_output \
}
-#define NO_TIMER TCC(0, 0)
+#define NO_TIMER TCC(0xff, 0)
#define TOUCH(y_line) \
.has_touch = true, \
@@ -92,8 +90,6 @@ const mcu_pin_obj_t pin_## p_name = { \
.sercom = {p_primary_sercom, p_secondary_sercom}, \
}
-#define NO_ADC_INPUT (0)
-
// Pins in datasheet order.
// NOTE(tannewt): TC wave out 0 is commented out because the first channel is
// used to vary the 16 bit timer's frequency.
diff --git a/ports/atmel-samd/samd51_peripherals.c b/ports/atmel-samd/samd51_peripherals.c
index e06f7f9df..8f37bdfd1 100644
--- a/ports/atmel-samd/samd51_peripherals.c
+++ b/ports/atmel-samd/samd51_peripherals.c
@@ -60,7 +60,8 @@ static const uint8_t SERCOMx_GCLK_ID_SLOW[] = {
#endif
};
-
+Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS;
+
// Clock initialization as done in Atmel START.
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) {
hri_gclk_write_PCHCTRL_reg(GCLK,
diff --git a/ports/atmel-samd/samd51_pins.c b/ports/atmel-samd/samd51_pins.c
index 78bdf0553..6d597b6e1 100644
--- a/ports/atmel-samd/samd51_pins.c
+++ b/ports/atmel-samd/samd51_pins.c
@@ -30,15 +30,13 @@
#define SERCOM(sercom_index, p_pad) \
{ \
- .sercom = SERCOM## sercom_index, \
.index = sercom_index, \
.pad = p_pad \
}
#define NO_SERCOM \
{ \
- .sercom = 0, \
- .index = 0, \
+ .index = 0x3f, \
.pad = 0 \
}
@@ -91,8 +89,6 @@ const mcu_pin_obj_t pin_## p_name = { \
.sercom = {p_primary_sercom, p_secondary_sercom}, \
}
-#define NO_ADC_INPUT (0)
-
// Pins in datasheet order.
// NOTE(tannewt): TC wave out 0 is commented out because the first channel is
// used to vary the 16 bit timer's frequency.
@@ -1139,7 +1135,7 @@ PIN(PA31, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH,
#else
NO_SERCOM,
#endif
- SERCOM(1, 23),
+ SERCOM(1, 3),
#ifdef TC6
TC(6, 1),
#else
diff --git a/ports/atmel-samd/supervisor/filesystem.c b/ports/atmel-samd/supervisor/filesystem.c
index 45dc5667b..bff78a41c 100644
--- a/ports/atmel-samd/supervisor/filesystem.c
+++ b/ports/atmel-samd/supervisor/filesystem.c
@@ -42,6 +42,12 @@
fs_user_mount_t fs_user_mount_flash;
mp_vfs_mount_t mp_vfs_mount_flash;
+static void make_empty_file(FATFS *fatfs, const char *path) {
+ FIL fp;
+ f_open(fatfs, &fp, path, FA_WRITE | FA_CREATE_ALWAYS);
+ f_close(&fp);
+}
+
// we don't make this function static because it needs a lot of stack and we
// want it to be executed without using stack within main() function
void filesystem_init(bool create_allowed) {
@@ -65,6 +71,14 @@ void filesystem_init(bool create_allowed) {
// set label
f_setlabel(&vfs_fat->fatfs, "CIRCUITPY");
+
+ // inhibit file indexing on MacOS
+ f_mkdir(&vfs_fat->fatfs, "/.fseventsd");
+ make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index");
+ make_empty_file(&vfs_fat->fatfs, "/.Trashes");
+ make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log");
+
+ // and ensure everything is flushed
flash_flush();
} else if (res != FR_OK) {
return;
diff --git a/ports/atmel-samd/usb.c b/ports/atmel-samd/usb.c
index f8df04b74..7fff957c0 100644
--- a/ports/atmel-samd/usb.c
+++ b/ports/atmel-samd/usb.c
@@ -102,12 +102,13 @@ static void init_hardware(void) {
#endif
}
-COMPILER_ALIGNED(4) uint8_t cdc_packet_buffer[64];
+#define CDC_BULKOUT_SIZE CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ
+COMPILER_ALIGNED(4) uint8_t cdc_packet_buffer[CDC_BULKOUT_SIZE];
static volatile bool pending_read;
static int32_t start_read(void) {
pending_read = true;
- int32_t result = cdcdf_acm_read(cdc_packet_buffer, 64);
+ int32_t result = cdcdf_acm_read(cdc_packet_buffer, CDC_BULKOUT_SIZE);
if (result != ERR_NONE) {
pending_read = false;
}
@@ -151,14 +152,6 @@ static bool read_complete(const uint8_t ep, const enum usb_xfer_code rc, const u
}
atomic_leave_critical(&flags);
- // Trigger a follow up read if we have space.
- if (usb_rx_count < USB_RX_BUF_SIZE) {
- int32_t result = start_read();
- if (result != ERR_NONE) {
- return true;
- }
- }
-
/* No error. */
return false;
}
@@ -170,7 +163,9 @@ static bool write_complete(const uint8_t ep,
return false; // No errors.
}
// This is called after writes are finished.
+
usb_transmitting = false;
+
/* No error. */
return false;
}
@@ -228,25 +223,32 @@ void init_usb(void) {
}
static bool cdc_enabled(void) {
- if (mp_cdc_enabled) {
- return true;
- }
if (!cdcdf_acm_is_enabled()) {
+ mp_cdc_enabled = false;
return false;
}
- cdcdf_acm_register_callback(CDCDF_ACM_CB_READ, (FUNC_PTR)read_complete);
- cdcdf_acm_register_callback(CDCDF_ACM_CB_WRITE, (FUNC_PTR)write_complete);
- cdcdf_acm_register_callback(CDCDF_ACM_CB_STATE_C, (FUNC_PTR)usb_device_cb_state_c);
- cdcdf_acm_register_callback(CDCDF_ACM_CB_LINE_CODING_C, (FUNC_PTR)usb_device_cb_line_coding_c);
- mp_cdc_enabled = true;
+ if (!mp_cdc_enabled) {
+ cdcdf_acm_register_callback(CDCDF_ACM_CB_READ, (FUNC_PTR)read_complete);
+ cdcdf_acm_register_callback(CDCDF_ACM_CB_WRITE, (FUNC_PTR)write_complete);
+ cdcdf_acm_register_callback(CDCDF_ACM_CB_STATE_C, (FUNC_PTR)usb_device_cb_state_c);
+ cdcdf_acm_register_callback(CDCDF_ACM_CB_LINE_CODING_C, (FUNC_PTR)usb_device_cb_line_coding_c);
+ mp_cdc_enabled = true;
+ }
return true;
}
bool usb_bytes_available(void) {
+ // Check if the buffer has data, but not enough
+ // space to hold another read.
+ if (usb_rx_count > USB_RX_BUF_SIZE - CDC_BULKOUT_SIZE) {
+ return true;
+ }
+ // Buffer has enough room
if (cdc_enabled() && !pending_read) {
start_read();
}
+ // Buffer is empty and/or no new data is available
if (usb_rx_count == 0) {
return false;
}
@@ -264,16 +266,11 @@ int usb_read(void) {
data = usb_rx_buf[usb_rx_buf_head];
usb_rx_buf_head++;
usb_rx_count--;
- if ((USB_RX_BUF_SIZE) == usb_rx_buf_head) {
+ if (usb_rx_buf_head == USB_RX_BUF_SIZE) {
usb_rx_buf_head = 0;
}
CRITICAL_SECTION_LEAVE();
- // Trigger a new read because we just cleared some space.
- if (!pending_read && usb_rx_count == USB_RX_BUF_SIZE - 1) {
- start_read();
- }
-
return data;
}
@@ -320,9 +317,10 @@ bool usb_connected(void) {
// Poll for input if keyboard interrupts are enabled,
// so that we can check for the interrupt char. read_complete() does the checking.
+// also make sure we have enough room in the local buffer
void usb_cdc_background() {
//
- if (mp_interrupt_char != -1 && cdc_enabled() && !pending_read) {
+ if (mp_interrupt_char != -1 && cdc_enabled() && !pending_read && (usb_rx_count < USB_RX_BUF_SIZE - CDC_BULKOUT_SIZE)) {
start_read();
}
}
diff --git a/ports/atmel-samd/usb_mass_storage.c b/ports/atmel-samd/usb_mass_storage.c
index 818736a78..9b6715158 100644
--- a/ports/atmel-samd/usb_mass_storage.c
+++ b/ports/atmel-samd/usb_mass_storage.c
@@ -260,6 +260,9 @@ int32_t usb_msc_xfer_done(uint8_t lun) {
if (active_read) {
active_addr += 1;
active_nblocks--;
+ if (active_nblocks == 0) {
+ active_read = false;
+ }
}
if (active_write) {
@@ -277,11 +280,14 @@ int32_t usb_msc_xfer_done(uint8_t lun) {
// drive into our cache and trigger the USB DMA to output the
// sector. Once the sector is transmitted, xfer_done will be called.
void usb_msc_background(void) {
- if (active_read && !usb_busy) {
- if (active_nblocks == 0) {
- active_read = false;
- return;
- }
+ // Check USB busy first because we never want to queue another transfer if it is. Checking
+ // active_read or active_write first leaves the possibility that they are true, an xfer done
+ // interrupt occurs (setting them false), turning off usb_busy and causing us to queue a
+ // spurious transfer.
+ if (usb_busy) {
+ return;
+ }
+ if (active_read) {
fs_user_mount_t * vfs = get_vfs(active_lun);
disk_read(vfs, sector_buffer, active_addr, 1);
CRITICAL_SECTION_ENTER();
@@ -289,7 +295,7 @@ void usb_msc_background(void) {
usb_busy = result == ERR_NONE;
CRITICAL_SECTION_LEAVE();
}
- if (active_write && !usb_busy) {
+ if (active_write) {
if (sector_loaded) {
fs_user_mount_t * vfs = get_vfs(active_lun);
disk_write(vfs, sector_buffer, active_addr, 1);
diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h
index cdf06450c..616e9875c 100644
--- a/ports/esp8266/mpconfigport.h
+++ b/ports/esp8266/mpconfigport.h
@@ -49,6 +49,7 @@
#define MICROPY_PY_GC (1)
#define MICROPY_PY_ARRAY (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
+#define MICROPY_NONSTANDARD_TYPECODES (0)
#define MICROPY_PY_COLLECTIONS (1)
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
#define MICROPY_PY_MATH (0)
@@ -90,6 +91,7 @@
#define MICROPY_CPYTHON_COMPAT (0)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
+#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL)
#define MICROPY_WARNINGS (1)
#define MICROPY_PY_STR_BYTES_CMP_WARN (1)
diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c
index cf808cdf4..0cceb6a66 100644
--- a/ports/nrf/common-hal/microcontroller/Processor.c
+++ b/ports/nrf/common-hal/microcontroller/Processor.c
@@ -76,7 +76,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
for (int i=0; i<2; i++) {
for (int k=0; k<4; k++) {
- raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xf;
+ raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xff;
}
}
}
diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h
index 053a3bbab..45c82439b 100644
--- a/ports/nrf/mpconfigport.h
+++ b/ports/nrf/mpconfigport.h
@@ -47,6 +47,7 @@
//CP UPDATE: See mpconfigport.h for LONGINT implementation
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
+#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1)
#define MICROPY_OPT_COMPUTED_GOTO (0)
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
@@ -99,6 +100,7 @@
#define MICROPY_PY_ALL_SPECIAL_METHODS (0)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (0)
+#define MICROPY_NONSTANDARD_TYPECODES (0)
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (0)
#define MICROPY_PY_SYS_EXIT (1)
#define MICROPY_PY_SYS_MAXSIZE (1)
diff --git a/ports/unix/Makefile b/ports/unix/Makefile
index 5bdcf4e1a..dacf68019 100644
--- a/ports/unix/Makefile
+++ b/ports/unix/Makefile
@@ -189,7 +189,7 @@ include $(TOP)/py/mkrules.mk
test: $(PROG) $(TOP)/tests/run-tests
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
- cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests
+ cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests --auto-jobs
# install micropython in /usr/local/bin
TARGET = micropython
@@ -254,10 +254,10 @@ coverage:
coverage_test: coverage
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
- cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests
- cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -d thread
- cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --emit native
- cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --via-mpy -d basics float
+ cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --auto-jobs
+ cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --auto-jobs -d thread
+ cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --auto-jobs --emit native
+ cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 --via-mpy -d basics float
gcov -o build-coverage/py $(TOP)/py/*.c
gcov -o build-coverage/extmod $(TOP)/extmod/*.c
diff --git a/ports/unix/mpconfigport_coverage.h b/ports/unix/mpconfigport_coverage.h
index 367b4853a..86d95eb39 100644
--- a/ports/unix/mpconfigport_coverage.h
+++ b/ports/unix/mpconfigport_coverage.h
@@ -43,4 +43,5 @@
#define MICROPY_PY_IO_BUFFEREDWRITER (1)
#undef MICROPY_VFS_FAT
#define MICROPY_VFS_FAT (1)
+#define MICROPY_FATFS_USE_LABEL (1)
#define MICROPY_PY_FRAMEBUF (1)
diff --git a/ports/windows/.appveyor.yml b/ports/windows/.appveyor.yml
deleted file mode 100644
index a82cf5adc..000000000
--- a/ports/windows/.appveyor.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-environment:
- # Python version used
- MICROPY_CPYTHON3: c:/python34/python.exe
-
-init:
- # Set build version number to commit to be travis-like
-- ps: Update-AppveyorBuild -Version $env:appveyor_repo_commit.substring(0,8)
-
-configuration:
-- Debug
-- Release
-
-platform:
-- x86
-- x64
-
-build:
- project: ports/windows/micropython.vcxproj
- verbosity: normal
-
-test_script:
-- cmd: >-
- cd tests
-
- %MICROPY_CPYTHON3% run-tests
-
-skip_tags: true
-
-deploy: off
-
-nuget:
- disable_publish_on_pr: true
diff --git a/py/bc.c b/py/bc.c
index 381daa24d..442a29771 100644
--- a/py/bc.c
+++ b/py/bc.c
@@ -190,6 +190,13 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
for (size_t i = 0; i < n_kw; i++) {
// the keys in kwargs are expected to be qstr objects
mp_obj_t wanted_arg_name = kwargs[2 * i];
+ if(MP_UNLIKELY(!MP_OBJ_IS_QSTR(wanted_arg_name))) {
+ #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
+ mp_raise_TypeError("unexpected keyword argument");
+ #else
+ mp_raise_TypeError("keywords must be strings");
+ #endif
+ }
for (size_t j = 0; j < n_pos_args + n_kwonly_args; j++) {
if (wanted_arg_name == arg_names[j]) {
if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) {
diff --git a/py/binary.c b/py/binary.c
index 62cb384f1..bb334ed3d 100644
--- a/py/binary.c
+++ b/py/binary.c
@@ -57,8 +57,10 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) {
size = 4; break;
case 'q': case 'Q':
size = 8; break;
+#if MICROPY_NONSTANDARD_TYPECODES
case 'P': case 'O': case 'S':
size = sizeof(void*); break;
+#endif
case 'f':
size = sizeof(float); break;
case 'd':
@@ -89,9 +91,11 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) {
case 'q': case 'Q':
align = alignof(long long);
size = sizeof(long long); break;
+#if MICROPY_NONSTANDARD_TYPECODES
case 'P': case 'O': case 'S':
align = alignof(void*);
size = sizeof(void*); break;
+#endif
case 'f':
align = alignof(float);
size = sizeof(float); break;
@@ -148,12 +152,14 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) {
case 'd':
return mp_obj_new_float(((double*)p)[index]);
#endif
+#if MICROPY_NONSTANDARD_TYPECODES
// Extension to CPython: array of objects
case 'O':
return ((mp_obj_t*)p)[index];
// Extension to CPython: array of pointers
case 'P':
return mp_obj_new_int((mp_int_t)(uintptr_t)((void**)p)[index]);
+#endif
}
return MP_OBJ_NEW_SMALL_INT(val);
}
@@ -202,11 +208,13 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
long long val = mp_binary_get_int(size, is_signed(val_type), (struct_type == '>'), p);
- if (val_type == 'O') {
+ if (MICROPY_NONSTANDARD_TYPECODES && (val_type == 'O')) {
return (mp_obj_t)(mp_uint_t)val;
+#if MICROPY_NONSTANDARD_TYPECODES
} else if (val_type == 'S') {
const char *s_val = (const char*)(uintptr_t)(mp_uint_t)val;
return mp_obj_new_str(s_val, strlen(s_val), false);
+#endif
#if MICROPY_PY_BUILTINS_FLOAT
} else if (val_type == 'f') {
union { uint32_t i; float f; } fpu = {val};
@@ -267,9 +275,11 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
mp_uint_t val;
switch (val_type) {
+#if MICROPY_NONSTANDARD_TYPECODES
case 'O':
val = (mp_uint_t)val_in;
break;
+#endif
#if MICROPY_PY_BUILTINS_FLOAT
case 'f': {
union { uint32_t i; float f; } fp_sp;
@@ -324,10 +334,12 @@ void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t v
((double*)p)[index] = mp_obj_get_float(val_in);
break;
#endif
+#if MICROPY_NONSTANDARD_TYPECODES
// Extension to CPython: array of objects
case 'O':
((mp_obj_t*)p)[index] = val_in;
break;
+#endif
default:
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) {
@@ -384,9 +396,11 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, m
((double*)p)[index] = val;
break;
#endif
+#if MICROPY_NONSTANDARD_TYPECODES
// Extension to CPython: array of pointers
case 'P':
((void**)p)[index] = (void*)(uintptr_t)val;
break;
+#endif
}
}
diff --git a/py/gc_long_lived.c b/py/gc_long_lived.c
index c50bbcd83..d34fde5d9 100644
--- a/py/gc_long_lived.c
+++ b/py/gc_long_lived.c
@@ -78,9 +78,9 @@ mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max
if (max_depth == 0) {
return prop;
}
- prop->proxy[0] = make_fun_bc_long_lived((mp_obj_fun_bc_t*) prop->proxy[0], max_depth - 1);
- prop->proxy[1] = make_fun_bc_long_lived((mp_obj_fun_bc_t*) prop->proxy[1], max_depth - 1);
- prop->proxy[2] = make_fun_bc_long_lived((mp_obj_fun_bc_t*) prop->proxy[2], max_depth - 1);
+ prop->proxy[0] = make_obj_long_lived((mp_obj_fun_bc_t*) prop->proxy[0], max_depth - 1);
+ prop->proxy[1] = make_obj_long_lived((mp_obj_fun_bc_t*) prop->proxy[1], max_depth - 1);
+ prop->proxy[2] = make_obj_long_lived((mp_obj_fun_bc_t*) prop->proxy[2], max_depth - 1);
return gc_make_long_lived(prop);
}
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 252ab7f37..765ae1e8f 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -888,6 +888,12 @@ typedef double mp_float_t;
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (0)
#endif
+// Whether to support nonstandard typecodes "O", "P" and "S"
+// in array and struct modules.
+#ifndef MICROPY_NONSTANDARD_TYPECODES
+#define MICROPY_NONSTANDARD_TYPECODES (1)
+#endif
+
// Whether to support attrtuple type (MicroPython extension)
// It provides space-efficient tuples with attribute access
#ifndef MICROPY_PY_ATTRTUPLE
diff --git a/py/objarray.c b/py/objarray.c
index a1a979b56..c4c547e19 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -241,6 +241,39 @@ STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
mp_obj_array_t *lhs = MP_OBJ_TO_PTR(lhs_in);
switch (op) {
+ case MP_BINARY_OP_MULTIPLY:
+ case MP_BINARY_OP_INPLACE_MULTIPLY: {
+ if (!MP_OBJ_IS_INT(rhs_in)) {
+ return MP_OBJ_NULL; // op not supported
+ }
+ mp_uint_t repeat = mp_obj_get_int(rhs_in);
+ bool inplace = (op == MP_BINARY_OP_INPLACE_MULTIPLY);
+ mp_buffer_info_t lhs_bufinfo;
+ array_get_buffer(lhs_in, &lhs_bufinfo, MP_BUFFER_READ);
+ mp_obj_array_t *res;
+ byte *ptr;
+ size_t orig_lhs_bufinfo_len = lhs_bufinfo.len;
+ if(inplace) {
+ res = lhs;
+ size_t item_sz = mp_binary_get_size('@', lhs->typecode, NULL);
+ lhs->items = m_renew(byte, lhs->items, (lhs->len + lhs->free) * item_sz, lhs->len * repeat * item_sz);
+ lhs->len = lhs->len * repeat;
+ lhs->free = 0;
+ if (!repeat)
+ return MP_OBJ_FROM_PTR(res);
+ repeat--;
+ ptr = (byte*)res->items + orig_lhs_bufinfo_len;
+ } else {
+ res = array_new(lhs_bufinfo.typecode, lhs->len * repeat);
+ ptr = (byte*)res->items;
+ }
+ if(orig_lhs_bufinfo_len) {
+ for(;repeat--; ptr += orig_lhs_bufinfo_len) {
+ memcpy(ptr, lhs_bufinfo.buf, orig_lhs_bufinfo_len);
+ }
+ }
+ return MP_OBJ_FROM_PTR(res);
+ }
case MP_BINARY_OP_ADD: {
// allow to add anything that has the buffer protocol (extension to CPython)
mp_buffer_info_t lhs_bufinfo;
@@ -437,9 +470,11 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
} else {
mp_seq_replace_slice_no_grow(dest_items, o->len,
slice.start, slice.stop, src_items, src_len, item_sz);
+#if MICROPY_NONSTANDARD_TYPECODES
// Clear "freed" elements at the end of list
// TODO: This is actually only needed for typecode=='O'
mp_seq_clear(dest_items, o->len + len_adj, o->len, item_sz);
+#endif
// TODO: alloc policy after shrinking
}
o->len += len_adj;
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 139452442..ff566c076 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -32,6 +32,7 @@
#include "py/bc.h"
#include "py/objgenerator.h"
#include "py/objfun.h"
+#include "py/stackctrl.h"
/******************************************************************************/
/* generator wrapper */
@@ -92,6 +93,7 @@ STATIC void gen_instance_print(const mp_print_t *print, mp_obj_t self_in, mp_pri
}
mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) {
+ MP_STACK_CHECK();
mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_gen_instance));
mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in);
if (self->code_state.ip == 0) {
diff --git a/py/objint_mpz.c b/py/objint_mpz.c
index 7b5cb0b9d..808fae6e4 100644
--- a/py/objint_mpz.c
+++ b/py/objint_mpz.c
@@ -343,6 +343,10 @@ mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus) {
mpz_t *rhs = mp_mpz_for_int(exponent, &r_temp);
mpz_t *mod = mp_mpz_for_int(modulus, &m_temp);
+ if (mpz_is_zero(mod)) {
+ mp_raise_msg(&mp_type_ValueError, "pow() 3rd argument cannot be 0");
+ }
+
mpz_pow3_inpl(&(res_p->mpz), lhs, rhs, mod);
if (lhs == &l_temp) { mpz_deinit(lhs); }
diff --git a/py/objstr.c b/py/objstr.c
index 64306f54f..7ace1cf73 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -692,8 +692,13 @@ STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, b
end = str_index_to_ptr(self_type, haystack, haystack_len, args[3], true);
}
+ if (end < start) {
+ goto out_error;
+ }
+
const byte *p = find_subbytes(start, end - start, needle, needle_len, direction);
if (p == NULL) {
+ out_error:
// not found
if (is_index) {
mp_raise_ValueError("substring not found");
diff --git a/py/objtype.c b/py/objtype.c
index 1d6dc0b6c..5b70e8e48 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -567,6 +567,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
mp_obj_class_lookup(&lookup, self->base.type);
mp_obj_t member = dest[0];
if (member != MP_OBJ_NULL) {
+ // changes here may may require changes to super_attr, below
#if MICROPY_PY_BUILTINS_PROPERTY
if (MP_OBJ_IS_TYPE(member, &mp_type_property)) {
// object member is a property; delegate the load to the property
@@ -980,8 +981,14 @@ const mp_obj_type_t mp_type_type = {
};
mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) {
- assert(MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)); // MicroPython restriction, for now
- assert(MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)); // MicroPython restriction, for now
+ if(!MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)) {
+ // MicroPython restriction, for now
+ mp_raise_TypeError("type() argument 2 must be tuple");
+ }
+ if(!MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)) {
+ // MicroPython restriction, for now
+ mp_raise_TypeError("type() argument 3 must be dict");
+ }
// TODO might need to make a copy of locals_dict; at least that's how CPython does it
@@ -990,7 +997,9 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
mp_obj_t *items;
mp_obj_tuple_get(bases_tuple, &len, &items);
for (size_t i = 0; i < len; i++) {
- assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type));
+ if(!MP_OBJ_IS_TYPE(items[i], &mp_type_type)) {
+ mp_raise_TypeError("type is not an acceptable base type");
+ }
mp_obj_type_t *t = MP_OBJ_TO_PTR(items[i]);
// TODO: Verify with CPy, tested on function type
if (t->make_new == NULL) {
@@ -1076,6 +1085,9 @@ STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, size
// 0 arguments are turned into 2 in the compiler
// 1 argument is not yet implemented
mp_arg_check_num(n_args, n_kw, 2, 2, false);
+ if(!MP_OBJ_IS_TYPE(args[0], &mp_type_type)) {
+ mp_raise_TypeError("first argument to super() must be type");
+ }
mp_obj_super_t *o = m_new_obj(mp_obj_super_t);
*o = (mp_obj_super_t){{type_in}, args[0], args[1]};
return MP_OBJ_FROM_PTR(o);
@@ -1112,14 +1124,37 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type));
mp_obj_class_lookup(&lookup, (mp_obj_type_t*)MP_OBJ_TO_PTR(items[i]));
if (dest[0] != MP_OBJ_NULL) {
- return;
+ break;
}
}
} else {
mp_obj_class_lookup(&lookup, type->parent);
- if (dest[0] != MP_OBJ_NULL) {
- return;
+ }
+
+ if (dest[0] != MP_OBJ_NULL) {
+ mp_obj_t member = dest[0];
+ // changes to mp_obj_instance_load_attr may require changes
+ // here...
+ #if MICROPY_PY_BUILTINS_PROPERTY
+ if (MP_OBJ_IS_TYPE(member, &mp_type_property)) {
+ const mp_obj_t *proxy = mp_obj_property_get(member);
+ if (proxy[0] == mp_const_none) {
+ mp_raise_AttributeError("unreadable attribute");
+ } else {
+ dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self_in);
+ }
+ }
+ #endif
+ #if MICROPY_PY_DESCRIPTORS
+ mp_obj_t attr_get_method[4];
+ mp_load_method_maybe(member, MP_QSTR___get__, attr_get_method);
+ if (attr_get_method[0] != MP_OBJ_NULL) {
+ attr_get_method[2] = self_in;
+ attr_get_method[3] = MP_OBJ_FROM_PTR(mp_obj_get_type(self_in));
+ dest[0] = mp_call_method_n_kw(2, 0, attr_get_method);
}
+ #endif
+ return;
}
mp_obj_class_lookup(&lookup, &mp_type_object);
diff --git a/shared-bindings/gamepad/GamePad.c b/shared-bindings/gamepad/GamePad.c
index a03b9318d..d80d1fcf6 100644
--- a/shared-bindings/gamepad/GamePad.c
+++ b/shared-bindings/gamepad/GamePad.c
@@ -27,6 +27,7 @@
#include "py/runtime.h"
#include "py/mphal.h"
#include "shared-module/gamepad/GamePad.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
#include "GamePad.h"
@@ -96,6 +97,12 @@ STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args,
gamepad_singleton = m_new_obj(gamepad_obj_t);
gamepad_singleton->base.type = &gamepad_type;
}
+ for (size_t i = 0; i < n_args; ++i) {
+ if (!MP_OBJ_IS_TYPE(args[i], &digitalio_digitalinout_type)) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
+ "Expected a %q", digitalio_digitalinout_type.name));
+ }
+ }
gamepad_init(n_args, args);
return MP_OBJ_FROM_PTR(gamepad_singleton);
}
diff --git a/shared-bindings/help.c b/shared-bindings/help.c
index cdd9a4a93..d8ffc13dd 100644
--- a/shared-bindings/help.c
+++ b/shared-bindings/help.c
@@ -35,7 +35,7 @@
//| prints general port information.
//|
-const char *circuitpython_help_text =
+const char circuitpython_help_text[] =
"Welcome to Adafruit CircuitPython " MICROPY_GIT_TAG "!\r\n"
"\r\n"
"Please visit learn.adafruit.com/category/circuitpython for project guides.\r\n"
diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c
index 6f6a30da6..734cabcc1 100644
--- a/shared-bindings/storage/__init__.c
+++ b/shared-bindings/storage/__init__.c
@@ -122,12 +122,22 @@ mp_obj_t storage_remount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
}
MP_DEFINE_CONST_FUN_OBJ_KW(storage_remount_obj, 1, storage_remount);
+//| .. function:: getmount(mount_path)
+//|
+//| Retrieves the mount object associated with the mount path
+//|
+mp_obj_t storage_getmount(const mp_obj_t mnt_in) {
+ return common_hal_storage_getmount(mp_obj_str_get_str(mnt_in));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(storage_getmount_obj, storage_getmount);
+
STATIC const mp_rom_map_elem_t storage_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_storage) },
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&storage_mount_obj) },
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&storage_umount_obj) },
{ MP_ROM_QSTR(MP_QSTR_remount), MP_ROM_PTR(&storage_remount_obj) },
+ { MP_ROM_QSTR(MP_QSTR_getmount), MP_ROM_PTR(&storage_getmount_obj) },
//| .. class:: VfsFat(block_device)
//|
@@ -135,6 +145,49 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = {
//|
//| :param block_device: Block device the the filesystem lives on
//|
+ //| .. attribute:: label
+ //|
+ //| The filesystem label, up to 11 case-insensitive bytes. Note that
+ //| this property can only be set when the device is writable by the
+ //| microcontroller.
+ //|
+ //| .. method:: mkfs
+ //|
+ //| Format the block device, deleting any data that may have been there
+ //|
+ //| .. method:: open(path, mode)
+ //|
+ //| Like builtin ``open()``
+ //|
+ //| .. method:: ilistdir([path])
+ //|
+ //| Return an iterator whose values describe files and folders within
+ //| ``path``
+ //|
+ //| .. method:: mkdir(path)
+ //|
+ //| Like `os.mkdir`
+ //|
+ //| .. method:: rmdir(path)
+ //|
+ //| Like `os.rmdir`
+ //|
+ //| .. method:: stat(path)
+ //|
+ //| Like `os.stat`
+ //|
+ //| .. method:: statvfs(path)
+ //|
+ //| Like `os.statvfs`
+ //|
+ //| .. method:: mount(readonly, mkfs)
+ //|
+ //| Don't call this directly, call `storage.mount`.
+ //|
+ //| .. method:: umount
+ //|
+ //| Don't call this directly, call `storage.umount`.
+ //|
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
};
diff --git a/shared-bindings/storage/__init__.h b/shared-bindings/storage/__init__.h
index 574b5ff8d..76b9ae854 100644
--- a/shared-bindings/storage/__init__.h
+++ b/shared-bindings/storage/__init__.h
@@ -34,5 +34,6 @@ void common_hal_storage_mount(mp_obj_t vfs_obj, const char* path, bool readonly)
void common_hal_storage_umount_path(const char* path);
void common_hal_storage_umount_object(mp_obj_t vfs_obj);
void common_hal_storage_remount(const char* path, bool readonly);
+mp_obj_t common_hal_storage_getmount(const char* path);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_STORAGE___INIT___H
diff --git a/shared-module/gamepad/GamePad.c b/shared-module/gamepad/GamePad.c
index 3a2b8a3fe..cd1df9b57 100644
--- a/shared-module/gamepad/GamePad.c
+++ b/shared-module/gamepad/GamePad.c
@@ -31,6 +31,7 @@
#include "shared-bindings/digitalio/Pull.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/util.h"
void gamepad_init(size_t n_pins, const mp_obj_t* pins) {
@@ -39,8 +40,13 @@ void gamepad_init(size_t n_pins, const mp_obj_t* pins) {
}
for (size_t i=0; i<n_pins; ++i) {
digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(pins[i]);
+ raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(pin));
+ digitalio_direction_t direction = common_hal_digitalio_digitalinout_get_direction(pin);
+ digitalio_pull_t pull = common_hal_digitalio_digitalinout_get_pull(pin);
+ if (direction != DIRECTION_INPUT || pull == PULL_NONE) {
+ common_hal_digitalio_digitalinout_switch_to_input(pin, PULL_UP);
+ }
gamepad_singleton->pins[i] = pin;
- common_hal_digitalio_digitalinout_switch_to_input(pin, PULL_UP);
}
gamepad_singleton->last = 0;
}
diff --git a/shared-module/gamepad/__init__.c b/shared-module/gamepad/__init__.c
index b6c8be215..591a2fa0a 100644
--- a/shared-module/gamepad/__init__.c
+++ b/shared-module/gamepad/__init__.c
@@ -42,8 +42,10 @@ void gamepad_tick(void) {
if (!pin) {
break;
}
- if (!common_hal_digitalio_digitalinout_get_value(pin)) {
- gamepad_current |= 1<<i;
+ digitalio_pull_t pull = common_hal_digitalio_digitalinout_get_pull(pin);
+ bool value = common_hal_digitalio_digitalinout_get_value(pin);
+ if ((pull == PULL_UP && !value) || (pull == PULL_DOWN && value)) {
+ gamepad_current |= 1 << i;
}
}
gamepad_singleton->pressed |= gamepad_singleton->last & gamepad_current;
diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c
index 97a049bac..5b0bbe01e 100644
--- a/shared-module/storage/__init__.c
+++ b/shared-module/storage/__init__.c
@@ -109,19 +109,19 @@ void common_hal_storage_umount_object(mp_obj_t vfs_obj) {
mp_vfs_proxy_call(vfs, MP_QSTR_umount, 0, NULL);
}
-void common_hal_storage_umount_path(const char* mount_path) {
- // remove vfs from the mount table
- mp_obj_t *vfs_obj = NULL;
+STATIC mp_obj_t storage_object_from_path(const char* mount_path) {
for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) {
if (strcmp(mount_path, (*vfsp)->str) == 0) {
- vfs_obj = (*vfsp)->obj;
- break;
+ return (*vfsp)->obj;
}
}
+ mp_raise_OSError(MP_EINVAL);
+}
- if (vfs_obj == NULL) {
- mp_raise_OSError(MP_EINVAL);
- }
+void common_hal_storage_umount_path(const char* mount_path) {
+ common_hal_storage_umount_object(storage_object_from_path(mount_path));
+}
- common_hal_storage_umount_object(vfs_obj);
+mp_obj_t common_hal_storage_getmount(const char *mount_path) {
+ return storage_object_from_path(mount_path);
}
diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c
index e944f7738..eac41c9c3 100644
--- a/shared-module/struct/__init__.c
+++ b/shared-module/struct/__init__.c
@@ -33,9 +33,11 @@
#include "py/parsenum.h"
void struct_validate_format(char fmt) {
+#if MICROPY_NONSTANDARD_TYPECODES
if( fmt == 'S' || fmt == 'O') {
mp_raise_RuntimeError("'S' and 'O' are not supported format types");
}
+#endif
}
char get_fmt_type(const char **fmt) {
diff --git a/tests/basics/array_micropython.py b/tests/basics/array_micropython.py
index e26ad7ae9..b92c5a9b9 100644
--- a/tests/basics/array_micropython.py
+++ b/tests/basics/array_micropython.py
@@ -5,6 +5,12 @@ except ImportError:
print("SKIP")
raise SystemExit
+try:
+ array.array('O')
+except ValueError:
+ print("SKIP")
+ raise SystemExit
+
# arrays of objects
a = array.array('O')
a.append(1)
diff --git a/tests/basics/array_mul.py b/tests/basics/array_mul.py
new file mode 100644
index 000000000..bb5f3aa6b
--- /dev/null
+++ b/tests/basics/array_mul.py
@@ -0,0 +1,28 @@
+try:
+ import array
+except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+a1 = array.array('I', [1])
+a2 = array.array('I', [2]) * 2
+a3 = (a1 + a2)
+print(a3)
+
+a3 *= 5
+print(a3)
+
+a3 *= 0
+print(a3)
+
+a4 = a2 * 0
+print(a4)
+
+a4 *= 0
+print(a4)
+
+a4 = a4 * 2
+print(a4)
+
+a4 *= 2
+print(a4)
diff --git a/tests/basics/builtin_pow3.py b/tests/basics/builtin_pow3.py
index 69b57e548..293a5acc9 100644
--- a/tests/basics/builtin_pow3.py
+++ b/tests/basics/builtin_pow3.py
@@ -22,3 +22,8 @@ try:
print(pow(4, 5, "z"))
except TypeError:
print("TypeError expected")
+
+try:
+ print(pow(4, 5, 0))
+except ValueError:
+ print("ValueError expected")
diff --git a/tests/basics/class_super.py b/tests/basics/class_super.py
index 1338ef452..5a18017ac 100644
--- a/tests/basics/class_super.py
+++ b/tests/basics/class_super.py
@@ -34,3 +34,10 @@ class B(A):
print(super().bar) # accessing attribute after super()
return super().foo().count(2) # calling a subsequent method
print(B().foo())
+
+try:
+ super(1, 1).x
+except TypeError:
+ print(True)
+else:
+ print(False)
diff --git a/tests/cpydiff/core_class_superproperty.py b/tests/basics/core_class_superproperty.py
index 1ec210550..69db10046 100644
--- a/tests/cpydiff/core_class_superproperty.py
+++ b/tests/basics/core_class_superproperty.py
@@ -1,8 +1,5 @@
"""
-categories: Core,Classes
-description: Calling super() getter property in subclass will return a property object, not the value
-cause: Unknown
-workaround: Unknown
+test that calling super() getter property in subclass will return the value
"""
class A:
@property
diff --git a/tests/basics/fun_calldblstar.py b/tests/basics/fun_calldblstar.py
index aae9828cf..15038b2f5 100644
--- a/tests/basics/fun_calldblstar.py
+++ b/tests/basics/fun_calldblstar.py
@@ -15,3 +15,10 @@ class A:
a = A()
a.f(1, **{'b':2})
a.f(1, **{'b':val for val in range(1)})
+
+try:
+ f(1, **{len: 1})
+except TypeError:
+ print(True)
+else:
+ print(False)
diff --git a/tests/basics/gen_stack_overflow.py b/tests/basics/gen_stack_overflow.py
new file mode 100644
index 000000000..5cba0e054
--- /dev/null
+++ b/tests/basics/gen_stack_overflow.py
@@ -0,0 +1,7 @@
+def gen():
+ yield from gen()
+
+try:
+ print(list(gen()))
+except RuntimeError:
+ print("RuntimeError")
diff --git a/tests/basics/string_find.py b/tests/basics/string_find.py
index 4a206eb0e..f9fcad3e5 100644
--- a/tests/basics/string_find.py
+++ b/tests/basics/string_find.py
@@ -21,6 +21,7 @@ print("0000".find('-1', 3))
print("0000".find('1', 3))
print("0000".find('1', 4))
print("0000".find('1', 5))
+print("aaaaaaaaaaa".find("bbb", 9, 2))
try:
'abc'.find(1)
diff --git a/tests/basics/string_rfind.py b/tests/basics/string_rfind.py
index 4d0e84018..54269d6f5 100644
--- a/tests/basics/string_rfind.py
+++ b/tests/basics/string_rfind.py
@@ -21,3 +21,4 @@ print("0000".rfind('-1', 3))
print("0000".rfind('1', 3))
print("0000".rfind('1', 4))
print("0000".rfind('1', 5))
+print("aaaaaaaaaaa".rfind("bbb", 9, 2))
diff --git a/tests/basics/struct_micropython.py b/tests/basics/struct_micropython.py
index f203a4666..e72153071 100644
--- a/tests/basics/struct_micropython.py
+++ b/tests/basics/struct_micropython.py
@@ -9,6 +9,12 @@ except:
print("SKIP")
raise SystemExit
+try:
+ struct.pack('O', None)
+except ValueError:
+ print("SKIP")
+ raise SystemExit
+
class A():
pass
diff --git a/tests/basics/types3.py b/tests/basics/types3.py
new file mode 100644
index 000000000..71f790692
--- /dev/null
+++ b/tests/basics/types3.py
@@ -0,0 +1,20 @@
+try:
+ type('abc', None, None)
+except TypeError:
+ print(True)
+else:
+ print(False)
+
+try:
+ type('abc', (), None)
+except TypeError:
+ print(True)
+else:
+ print(False)
+
+try:
+ type('abc', (1,), {})
+except TypeError:
+ print(True)
+else:
+ print(False)
diff --git a/tests/extmod/vfs_fat_fileio1.py b/tests/extmod/vfs_fat_fileio1.py
index d19df120b..8b9ff92eb 100644
--- a/tests/extmod/vfs_fat_fileio1.py
+++ b/tests/extmod/vfs_fat_fileio1.py
@@ -91,10 +91,8 @@ with open("foo_file.txt") as f2:
f2.seek(0, 1) # SEEK_CUR
print(f2.read(1))
- try:
- f2.seek(1, 1) # SEEK_END
- except OSError as e:
- print(e.args[0] == uerrno.EOPNOTSUPP)
+ f2.seek(2, 1) # SEEK_CUR
+ print(f2.read(1))
f2.seek(-2, 2) # SEEK_END
print(f2.read(1))
diff --git a/tests/extmod/vfs_fat_fileio1.py.exp b/tests/extmod/vfs_fat_fileio1.py.exp
index d777585cf..a66f07605 100644
--- a/tests/extmod/vfs_fat_fileio1.py.exp
+++ b/tests/extmod/vfs_fat_fileio1.py.exp
@@ -7,7 +7,7 @@ hello!world!
12
h
e
-True
+o
d
True
[('foo_dir', 16384, 0)]
diff --git a/tests/extmod/vfs_fat_ramdisk.py b/tests/extmod/vfs_fat_ramdisk.py
index 801c69786..896641ab3 100644
--- a/tests/extmod/vfs_fat_ramdisk.py
+++ b/tests/extmod/vfs_fat_ramdisk.py
@@ -54,6 +54,8 @@ print(b"hello!" not in bdev.data)
vfs = uos.VfsFat(bdev)
uos.mount(vfs, "/ramdisk")
+vfs.label = 'label test'
+print("label:", vfs.label)
print("statvfs:", vfs.statvfs("/ramdisk"))
print("getcwd:", vfs.getcwd())
diff --git a/tests/extmod/vfs_fat_ramdisk.py.exp b/tests/extmod/vfs_fat_ramdisk.py.exp
index ccd0f7134..a3c3470a9 100644
--- a/tests/extmod/vfs_fat_ramdisk.py.exp
+++ b/tests/extmod/vfs_fat_ramdisk.py.exp
@@ -1,5 +1,6 @@
True
True
+label: LABEL TEST
statvfs: (512, 512, 16, 16, 16, 0, 0, 0, 0, 255)
getcwd: /
True
diff --git a/tests/run-tests b/tests/run-tests
index f1035c435..bcd2e5dcc 100755
--- a/tests/run-tests
+++ b/tests/run-tests
@@ -6,6 +6,9 @@ import sys
import platform
import argparse
import re
+import threading
+import multiprocessing
+from multiprocessing.pool import ThreadPool
from glob import glob
# Tests require at least CPython 3.3. If your default python3 executable
@@ -197,13 +200,27 @@ def run_micropython(pyb, args, test_file, is_special=False):
def run_feature_check(pyb, args, base_path, test_file):
return run_micropython(pyb, args, base_path + "/feature_check/" + test_file, is_special=True)
+class ThreadSafeCounter:
+ def __init__(self, start=0):
+ self._value = start
+ self._lock = threading.Lock()
-def run_tests(pyb, tests, args, base_path="."):
- test_count = 0
- testcase_count = 0
- passed_count = 0
- failed_tests = []
- skipped_tests = []
+ def add(self, to_add):
+ with self._lock: self._value += to_add
+
+ def append(self, arg):
+ self.add([arg])
+
+ @property
+ def value(self):
+ return self._value
+
+def run_tests(pyb, tests, args, base_path=".", num_threads=1):
+ test_count = ThreadSafeCounter()
+ testcase_count = ThreadSafeCounter()
+ passed_count = ThreadSafeCounter()
+ failed_tests = ThreadSafeCounter([])
+ skipped_tests = ThreadSafeCounter([])
skip_tests = set()
skip_native = False
@@ -328,7 +345,7 @@ def run_tests(pyb, tests, args, base_path="."):
# Remove them from the below when they work
if args.emit == 'native':
skip_tests.update({'basics/%s.py' % t for t in 'gen_yield_from gen_yield_from_close gen_yield_from_ducktype gen_yield_from_exc gen_yield_from_iter gen_yield_from_send gen_yield_from_stopped gen_yield_from_throw gen_yield_from_throw2 gen_yield_from_throw3 generator1 generator2 generator_args generator_close generator_closure generator_exc generator_return generator_send'.split()}) # require yield
- skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class globals_del string_join'.split()}) # require yield
+ skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class globals_del string_join gen_stack_overflow'.split()}) # require yield
skip_tests.update({'basics/async_%s.py' % t for t in 'def await await2 for for2 with with2'.split()}) # require yield
skip_tests.update({'basics/%s.py' % t for t in 'try_reraise try_reraise2'.split()}) # require raise_varargs
skip_tests.update({'basics/%s.py' % t for t in 'with_break with_continue with_return'.split()}) # require complete with support
@@ -354,7 +371,7 @@ def run_tests(pyb, tests, args, base_path="."):
skip_tests.add('micropython/heapalloc_iter.py') # requires generators
skip_tests.add('micropython/schedule.py') # native code doesn't check pending events
- for test_file in tests:
+ def run_one_test(test_file):
test_file = test_file.replace('\\', '/')
test_basename = os.path.basename(test_file)
test_name = os.path.splitext(test_basename)[0]
@@ -377,7 +394,7 @@ def run_tests(pyb, tests, args, base_path="."):
if skip_it:
print("skip ", test_file)
skipped_tests.append(test_name)
- continue
+ return
# get expected output
test_file_expected = test_file + '.exp'
@@ -405,7 +422,7 @@ def run_tests(pyb, tests, args, base_path="."):
output_expected = output_expected.replace(b'\r\n', b'\n')
if args.write_exp:
- continue
+ return
# run MicroPython
output_mupy = run_micropython(pyb, args, test_file)
@@ -413,16 +430,16 @@ def run_tests(pyb, tests, args, base_path="."):
if output_mupy == b'SKIP\n':
print("skip ", test_file)
skipped_tests.append(test_name)
- continue
+ return
- testcase_count += len(output_expected.splitlines())
+ testcase_count.add(len(output_expected.splitlines()))
filename_expected = test_basename + ".exp"
filename_mupy = test_basename + ".out"
if output_expected == output_mupy:
print("pass ", test_file)
- passed_count += 1
+ passed_count.add(1)
rm_f(filename_expected)
rm_f(filename_mupy)
else:
@@ -437,15 +454,22 @@ def run_tests(pyb, tests, args, base_path="."):
print("FAIL ", test_file)
failed_tests.append(test_name)
- test_count += 1
+ test_count.add(1)
+
+ if num_threads > 1:
+ pool = ThreadPool(num_threads)
+ pool.map(run_one_test, tests)
+ else:
+ for test in tests:
+ run_one_test(test)
- print("{} tests performed ({} individual testcases)".format(test_count, testcase_count))
- print("{} tests passed".format(passed_count))
+ print("{} tests performed ({} individual testcases)".format(test_count.value, testcase_count.value))
+ print("{} tests passed".format(passed_count.value))
- if len(skipped_tests) > 0:
- print("{} tests skipped: {}".format(len(skipped_tests), ' '.join(skipped_tests)))
- if len(failed_tests) > 0:
- print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests)))
+ if len(skipped_tests.value) > 0:
+ print("{} tests skipped: {}".format(len(skipped_tests.value), ' '.join(sorted(skipped_tests.value))))
+ if len(failed_tests.value) > 0:
+ print("{} tests failed: {}".format(len(failed_tests.value), ' '.join(sorted(failed_tests.value))))
return False
# all tests succeeded
@@ -464,11 +488,14 @@ def main():
cmd_parser.add_argument('--heapsize', help='heapsize to use (use default if not specified)')
cmd_parser.add_argument('--via-mpy', action='store_true', help='compile .py files to .mpy first')
cmd_parser.add_argument('--keep-path', action='store_true', help='do not clear MICROPYPATH when running tests')
+ cmd_parser.add_argument('-j', '--jobs', default=1, metavar='N', type=int, help='Number of tests to run simultaneously')
+ cmd_parser.add_argument('--auto-jobs', action='store_const', dest='jobs', const=multiprocessing.cpu_count(), help='Set the -j values to the CPU (thread) count')
cmd_parser.add_argument('files', nargs='*', help='input test files')
args = cmd_parser.parse_args()
EXTERNAL_TARGETS = ('pyboard', 'wipy', 'esp8266', 'minimal')
if args.target in EXTERNAL_TARGETS:
+ args.jobs = 1
import pyboard
pyb = pyboard.Pyboard(args.device, args.baudrate, args.user, args.password)
pyb.enter_raw_repl()
@@ -507,7 +534,7 @@ def main():
# run-tests script itself.
base_path = os.path.dirname(sys.argv[0]) or "."
try:
- res = run_tests(pyb, tests, args, base_path)
+ res = run_tests(pyb, tests, args, base_path, args.jobs)
finally:
if pyb:
pyb.close()
diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh
index 0bc3d4551..34fae9d85 100755
--- a/tools/build_adafruit_bins.sh
+++ b/tools/build_adafruit_bins.sh
@@ -2,7 +2,7 @@ rm -rf ports/atmel-samd/build*
rm -rf ports/esp8266/build*
rm -rf ports/nrf/build*
-ATMEL_BOARDS="arduino_zero circuitplayground_express feather_m0_basic feather_m0_adalogger itsybitsy_m0_express feather_m0_rfm69 feather_m0_rfm9x feather_m0_express metro_m0_express metro_m4_express pirkey_m0 trinket_m0 gemma_m0 feather52"
+ATMEL_BOARDS="arduino_zero circuitplayground_express feather_m0_basic feather_m0_adalogger itsybitsy_m0_express feather_m0_rfm69 feather_m0_rfm9x feather_m0_express feather_m4_express metro_m0_express metro_m4_express pirkey_m0 trinket_m0 gemma_m0 feather52"
ROSIE_SETUPS="rosie-ci"
PARALLEL="-j 5"