Merge branch 'master' into 3.0_hid
This commit is contained in:
commit
435e894fa0
|
@ -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
|
||||
|
|
13
.travis.yml
13
.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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
--------------
|
||||
|
|
|
@ -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/>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -72,7 +72,6 @@ BASE_CFLAGS = \
|
|||
-Wnested-externs \
|
||||
-Wunreachable-code \
|
||||
-Wcast-align \
|
||||
-Wno-error=lto-type-mismatch \
|
||||
-D__$(CHIP_VARIANT)__ \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) },
|
||||
|
|
|
@ -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) {
|
||||
}
|
|
@ -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"
|
|
@ -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
|
|
@ -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);
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */ \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit c3deba11eb4be397ec719cfbfba1abcaecda2c08
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -1,2 +0,0 @@
|
|||
# Adafruit_FreeTouch
|
||||
A QTouch-compatible library
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
7
py/bc.c
7
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) {
|
||||
|
|
16
py/binary.c
16
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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");
|
||||
|
|
47
py/objtype.c
47
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) },
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
if (vfs_obj == NULL) {
|
||||
mp_raise_OSError(MP_EINVAL);
|
||||
}
|
||||
|
||||
common_hal_storage_umount_object(vfs_obj);
|
||||
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));
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_storage_getmount(const char *mount_path) {
|
||||
return storage_object_from_path(mount_path);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
def gen():
|
||||
yield from gen()
|
||||
|
||||
try:
|
||||
print(list(gen()))
|
||||
except RuntimeError:
|
||||
print("RuntimeError")
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -9,6 +9,12 @@ except:
|
|||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
try:
|
||||
struct.pack('O', None)
|
||||
except ValueError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
class A():
|
||||
pass
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -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))
|
||||
|
|
|
@ -7,7 +7,7 @@ hello!world!
|
|||
12
|
||||
h
|
||||
e
|
||||
True
|
||||
o
|
||||
d
|
||||
True
|
||||
[('foo_dir', 16384, 0)]
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
True
|
||||
True
|
||||
label: LABEL TEST
|
||||
statvfs: (512, 512, 16, 16, 16, 0, 0, 0, 0, 255)
|
||||
getcwd: /
|
||||
True
|
||||
|
|
|
@ -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)
|
||||
|
||||
print("{} tests performed ({} individual testcases)".format(test_count, testcase_count))
|
||||
print("{} tests passed".format(passed_count))
|
||||
if num_threads > 1:
|
||||
pool = ThreadPool(num_threads)
|
||||
pool.map(run_one_test, tests)
|
||||
else:
|
||||
for test in tests:
|
||||
run_one_test(test)
|
||||
|
||||
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)))
|
||||
print("{} tests performed ({} individual testcases)".format(test_count.value, testcase_count.value))
|
||||
print("{} tests passed".format(passed_count.value))
|
||||
|
||||
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()
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue