Merge branch 'master' into 3.0_hid

This commit is contained in:
Dan Halbert 2018-04-02 19:19:43 -04:00
commit 435e894fa0
85 changed files with 771 additions and 1204 deletions

6
.gitmodules vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -72,7 +72,6 @@ BASE_CFLAGS = \
-Wnested-externs \
-Wunreachable-code \
-Wcast-align \
-Wno-error=lto-type-mismatch \
-D__$(CHIP_VARIANT)__ \
-ffunction-sections \
-fdata-sections \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,2 +0,0 @@
# Adafruit_FreeTouch
A QTouch-compatible library

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

28
tests/basics/array_mul.py Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,7 @@
def gen():
yield from gen()
try:
print(list(gen()))
except RuntimeError:
print("RuntimeError")

View File

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

View File

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

View File

@ -9,6 +9,12 @@ except:
print("SKIP")
raise SystemExit
try:
struct.pack('O', None)
except ValueError:
print("SKIP")
raise SystemExit
class A():
pass

20
tests/basics/types3.py Normal file
View File

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

View File

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

View File

@ -7,7 +7,7 @@ hello!world!
12
h
e
True
o
d
True
[('foo_dir', 16384, 0)]

View File

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

View File

@ -1,5 +1,6 @@
True
True
label: LABEL TEST
statvfs: (512, 512, 16, 16, 16, 0, 0, 0, 0, 255)
getcwd: /
True

View File

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

View File

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