From b2dcc5bb6c50f9b6eb3c294c98df8a5880167fd8 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 29 Sep 2017 10:38:11 -0400 Subject: [PATCH 1/7] reset pins on PDMIn deinit(). Fixes #275. --- atmel-samd/common-hal/audiobusio/PDMIn.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atmel-samd/common-hal/audiobusio/PDMIn.c b/atmel-samd/common-hal/audiobusio/PDMIn.c index 555601c9dd..11411ee3d4 100644 --- a/atmel-samd/common-hal/audiobusio/PDMIn.c +++ b/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -148,6 +148,8 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self, void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self) { i2s_disable(&self->i2s_instance); i2s_reset(&self->i2s_instance); + reset_pin(self->clock_pin->pin); + reset_pin(self->data_pin->pin); } uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t* self) { From 7f744128826b8328aaa6434fdcb8f0a272c87d72 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 1 Oct 2017 14:43:42 -0400 Subject: [PATCH 2/7] Make touch more sensitive. Add .raw_value and .threshold attributes. --- atmel-samd/Makefile | 2 +- atmel-samd/common-hal/touchio/TouchIn.c | 21 +++++++- shared-bindings/touchio/TouchIn.c | 66 +++++++++++++++++++++++++ shared-bindings/touchio/TouchIn.h | 3 ++ 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index 1e5fe110d0..501851ab10 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -137,7 +137,7 @@ CFLAGS += -Os -ggdb -DNDEBUG -DENABLE_MICRO_TRACE_BUFFER -DMICROPY_DEBUG_MODULES else # -finline-limit can shrink the image size. -finline-limit=80 or so is similar to not having it on. # There is no simple default value, though. -CFLAGS += -Os -DNDEBUG -flto -finline-limit=49 +CFLAGS += -Os -DNDEBUG -flto -finline-limit=39 endif ifneq ($(FROZEN_DIR),) diff --git a/atmel-samd/common-hal/touchio/TouchIn.c b/atmel-samd/common-hal/touchio/TouchIn.c index 3575de3ed0..ddfd1055a8 100644 --- a/atmel-samd/common-hal/touchio/TouchIn.c +++ b/atmel-samd/common-hal/touchio/TouchIn.c @@ -71,7 +71,14 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, adafruit_ptc_init(PTC, &self->config); - self->threshold = 2 * get_raw_reading(self); + // Initial values for pins will vary, depending on what peripherals the pins + // share on-chip. + // + // Set a "touched" threshold not too far above the initial value. + // For simple finger touch, the values may vary as much as a factor of two, + // but for touches using fruit or other objects, the difference is much less. + + self->threshold = get_raw_reading(self) + 100; } void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self) { @@ -87,3 +94,15 @@ bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) { uint16_t reading = get_raw_reading(self); return reading > self->threshold; } + +uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self) { + return get_raw_reading(self); +} + +uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self) { + return self->threshold; +} + +void common_hal_touchio_touchin_set_threshold(touchio_touchin_obj_t *self, uint16_t new_threshold) { + self->threshold = new_threshold; +} diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 8947814231..213fbc669b 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#include #include #include "lib/utils/context_manager_helpers.h" @@ -106,6 +107,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, t //| .. attribute:: value //| //| Whether the touch pad is being touched or not. +//| True if `raw_value` > `threshold`. //| //| :return: True when touched, False otherwise. //| :rtype: bool @@ -123,12 +125,76 @@ const mp_obj_property_t touchio_touchin_value_obj = { (mp_obj_t)&mp_const_none_obj}, }; + +//| .. attribute:: raw_value +//| +//| The raw touch measurement. Not settable. +//| +//| :return: an integer >= 0 +//| :rtype: int +//| +STATIC mp_obj_t touchio_touchin_obj_get_raw_value(mp_obj_t self_in) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_raw_value(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_raw_value_obj, touchio_touchin_obj_get_raw_value); + +const mp_obj_property_t touchio_touchin_raw_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&touchio_touchin_get_raw_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, + }; + + +//| .. attribute:: threshold +//| +//| `value` will return True if `raw_value` is greater than than this threshold. +//| When the **TouchIn** object is created, an initial `raw_value` is read from the pin, +//| and then `threshold` is set to be 100 + that value. +//| +//| You can set the threshold to a different value to make the pin more or less sensitive. +//| +//| :return: an integer >= 0 +//| :rtype: int +//| +STATIC mp_obj_t touchio_touchin_obj_get_threshold(mp_obj_t self_in) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_threshold(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_threshold_obj, touchio_touchin_obj_get_threshold); + +STATIC mp_obj_t touchio_touchin_obj_set_threshold(mp_obj_t self_in, mp_obj_t threshold_obj) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint32_t new_threshold = mp_obj_get_int(threshold_obj); + if (new_threshold < 0 || new_threshold > UINT16_MAX) { + // I would use MP_STRINGIFY(UINT16_MAX), but that prints "0xffff" instead of 65536. + mp_raise_ValueError("threshold must be in the range 0-65536"); + } + common_hal_touchio_touchin_set_threshold(self, new_threshold); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_2(touchio_touchin_set_threshold_obj, touchio_touchin_obj_set_threshold); + +const mp_obj_property_t touchio_touchin_threshold_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&touchio_touchin_get_threshold_obj, + (mp_obj_t)&touchio_touchin_set_threshold_obj, + (mp_obj_t)&mp_const_none_obj}, + }; + + STATIC const mp_rom_map_elem_t touchio_touchin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&touchio_touchin___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&touchio_touchin_deinit_obj) }, { MP_OBJ_NEW_QSTR(MP_QSTR_value), MP_ROM_PTR(&touchio_touchin_value_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_raw_value), MP_ROM_PTR(&touchio_touchin_raw_value_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_threshold), MP_ROM_PTR(&touchio_touchin_threshold_obj)}, }; STATIC MP_DEFINE_CONST_DICT(touchio_touchin_locals_dict, touchio_touchin_locals_dict_table); diff --git a/shared-bindings/touchio/TouchIn.h b/shared-bindings/touchio/TouchIn.h index 6ee668f383..0570afb20d 100644 --- a/shared-bindings/touchio/TouchIn.h +++ b/shared-bindings/touchio/TouchIn.h @@ -35,5 +35,8 @@ extern const mp_obj_type_t touchio_touchin_type; void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, const mcu_pin_obj_t *pin); void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self); bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self); +uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self); +uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self); +void common_hal_touchio_touchin_set_threshold(touchio_touchin_obj_t *self, uint16_t new_threshold); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO_TOUCHIN_H From c2bb9e2eb50e0dee6d7405fd738f1b4b0f94d10b Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Tue, 3 Oct 2017 20:24:48 +0200 Subject: [PATCH 3/7] Add board file for the hacked Trinket M0 Haxpress (#303) Add a hacked Tinket M0 Haxpress board definition Based on https://daveastels.com/2017/09/01/trinket-m0-express-hack/ --- atmel-samd/boards/flash_W25Q32BV.h | 51 ++++ atmel-samd/boards/trinket_m0_haxpress/board.c | 37 +++ .../boards/trinket_m0_haxpress/conf_access.h | 115 +++++++++ .../boards/trinket_m0_haxpress/conf_board.h | 14 ++ .../boards/trinket_m0_haxpress/conf_clocks.h | 1 + .../boards/trinket_m0_haxpress/conf_usb.h | 221 ++++++++++++++++++ .../trinket_m0_haxpress/mpconfigboard.h | 39 ++++ .../trinket_m0_haxpress/mpconfigboard.mk | 8 + atmel-samd/boards/trinket_m0_haxpress/pins.c | 31 +++ 9 files changed, 517 insertions(+) create mode 100644 atmel-samd/boards/flash_W25Q32BV.h create mode 100644 atmel-samd/boards/trinket_m0_haxpress/board.c create mode 100644 atmel-samd/boards/trinket_m0_haxpress/conf_access.h create mode 100644 atmel-samd/boards/trinket_m0_haxpress/conf_board.h create mode 100644 atmel-samd/boards/trinket_m0_haxpress/conf_clocks.h create mode 100644 atmel-samd/boards/trinket_m0_haxpress/conf_usb.h create mode 100644 atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h create mode 100644 atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk create mode 100644 atmel-samd/boards/trinket_m0_haxpress/pins.c diff --git a/atmel-samd/boards/flash_W25Q32BV.h b/atmel-samd/boards/flash_W25Q32BV.h new file mode 100644 index 0000000000..ae730fc6a2 --- /dev/null +++ b/atmel-samd/boards/flash_W25Q32BV.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BOARD_FLASH_W25Q32BV_H +#define MICROPY_INCLUDED_ATMEL_SAMD_BOARD_FLASH_W25Q32BV_H + +// The total flash size in bytes. +#define SPI_FLASH_TOTAL_SIZE (1 << 21) // 2 MiB + +// The size of the smallest erase unit thats erased with command 0x20. +#define SPI_FLASH_ERASE_SIZE (1 << 12) // 4 KiB + +// The size of a page that is programmed with page program command 0x02. +#define SPI_FLASH_PAGE_SIZE (256) // 256 bytes + +// These are the first three response bytes to the JEDEC ID command 0x9f that is +// used to confirm we're talking to the flash we expect. +#ifndef SPI_FLASH_JEDEC_MANUFACTURER +#define SPI_FLASH_JEDEC_MANUFACTURER 0xef +#define SPI_FLASH_SECTOR_PROTECTION false +#else +#define SPI_FLASH_JEDEC_MANUFACTURER_2 0xef +#define SPI_FLASH_SECTOR_PROTECTION_2 false +#endif +#define SPI_FLASH_JEDEC_MEMORY_TYPE 0x40 +#define SPI_FLASH_JEDEC_CAPACITY 0x16 + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARD_FLASH_W25Q32BV_H diff --git a/atmel-samd/boards/trinket_m0_haxpress/board.c b/atmel-samd/boards/trinket_m0_haxpress/board.c new file mode 100644 index 0000000000..d7e856d611 --- /dev/null +++ b/atmel-samd/boards/trinket_m0_haxpress/board.c @@ -0,0 +1,37 @@ +/* + * 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" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/atmel-samd/boards/trinket_m0_haxpress/conf_access.h b/atmel-samd/boards/trinket_m0_haxpress/conf_access.h new file mode 100644 index 0000000000..2326bfcdf2 --- /dev/null +++ b/atmel-samd/boards/trinket_m0_haxpress/conf_access.h @@ -0,0 +1,115 @@ +/** + * \file + * + * \brief Memory access control configuration file. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _CONF_ACCESS_H_ +#define _CONF_ACCESS_H_ + +#include "compiler.h" +#include "board.h" + + +/*! \name Activation of Logical Unit Numbers + */ +//! @{ +#define LUN_0 ENABLE //!< On-Chip Virtual Memory. +#define LUN_1 DISABLE //!< AT45DBX Data Flash. +#define LUN_2 DISABLE //!< SD/MMC Card over SPI. +#define LUN_3 DISABLE //!< SD/MMC Card over MCI Slot 0. +#define LUN_4 DISABLE +#define LUN_5 DISABLE +#define LUN_6 DISABLE +#define LUN_7 DISABLE +#define LUN_USB DISABLE //!< Host Mass-Storage Memory. +//! @} + +/*! \name LUN 0 Definitions + */ +//! @{ +#define LUN_0_INCLUDE "access_vfs.h" +#define Lun_0_test_unit_ready vfs_test_unit_ready +#define Lun_0_read_capacity vfs_read_capacity +#define Lun_0_unload NULL +#define Lun_0_wr_protect vfs_wr_protect +#define Lun_0_removal vfs_removal +#define Lun_0_usb_read_10 vfs_usb_read_10 +#define Lun_0_usb_write_10 vfs_usb_write_10 +#define LUN_0_NAME "\"CircuitPython VFS[0]\"" +//! @} + +#define MEM_USB LUN_USB + +/*! \name Actions Associated with Memory Accesses + * + * Write here the action to associate with each memory access. + * + * \warning Be careful not to waste time in order not to disturb the functions. + */ +//! @{ +#define memory_start_read_action(nb_sectors) +#define memory_stop_read_action() +#define memory_start_write_action(nb_sectors) +#define memory_stop_write_action() +//! @} + +/*! \name Activation of Interface Features + */ +//! @{ +#define ACCESS_USB true //!< MEM <-> USB interface. +#define ACCESS_MEM_TO_RAM false //!< MEM <-> RAM interface. +#define ACCESS_STREAM false //!< Streaming MEM <-> MEM interface. +#define ACCESS_STREAM_RECORD false //!< Streaming MEM <-> MEM interface in record mode. +#define ACCESS_MEM_TO_MEM false //!< MEM <-> MEM interface. +#define ACCESS_CODEC false //!< Codec interface. +//! @} + +/*! \name Specific Options for Access Control + */ +//! @{ +#define GLOBAL_WR_PROTECT false //!< Management of a global write protection. +//! @} + + +#endif // _CONF_ACCESS_H_ diff --git a/atmel-samd/boards/trinket_m0_haxpress/conf_board.h b/atmel-samd/boards/trinket_m0_haxpress/conf_board.h new file mode 100644 index 0000000000..7b88c97fc2 --- /dev/null +++ b/atmel-samd/boards/trinket_m0_haxpress/conf_board.h @@ -0,0 +1,14 @@ +/** + * \file + * + * \brief User board configuration template + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef CONF_BOARD_H +#define CONF_BOARD_H + +#endif // CONF_BOARD_H diff --git a/atmel-samd/boards/trinket_m0_haxpress/conf_clocks.h b/atmel-samd/boards/trinket_m0_haxpress/conf_clocks.h new file mode 100644 index 0000000000..9e4f7876be --- /dev/null +++ b/atmel-samd/boards/trinket_m0_haxpress/conf_clocks.h @@ -0,0 +1 @@ +#include "conf_clocks_crystalless.h" diff --git a/atmel-samd/boards/trinket_m0_haxpress/conf_usb.h b/atmel-samd/boards/trinket_m0_haxpress/conf_usb.h new file mode 100644 index 0000000000..80ad4627e6 --- /dev/null +++ b/atmel-samd/boards/trinket_m0_haxpress/conf_usb.h @@ -0,0 +1,221 @@ + +#include +#include + +#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h" + +#ifndef CONF_USB_H_INCLUDED +#define CONF_USB_H_INCLUDED + +#define USB_DEVICE_MAJOR_VERSION 1 +#define USB_DEVICE_MINOR_VERSION 0 +#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA) +#define USB_DEVICE_ATTR \ + (USB_CONFIG_ATTR_BUS_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) + +//! USB Device string definitions (Optional) +#ifndef USB_DEVICE_MANUFACTURE_NAME +# define USB_DEVICE_MANUFACTURE_NAME "Radomir Dopieralski" +#endif + +#ifndef USB_DEVICE_PRODUCT_NAME +# define USB_DEVICE_PRODUCT_NAME "Trinket M0 Haxpress" +#endif +// #define USB_DEVICE_SERIAL_NAME "12...EF" +#define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number +#define USB_DEVICE_GET_SERIAL_NAME_LENGTH 32 +extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + +//! Control endpoint size +#define USB_DEVICE_EP_CTRL_SIZE 64 + +//! Interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 + +// (3 | USB_EP_DIR_IN) // CDC Notify endpoint +// (4 | USB_EP_DIR_IN) // CDC TX +// (5 | USB_EP_DIR_OUT) // CDC RX +// (1 | USB_EP_DIR_IN) // MSC IN +// (2 | USB_EP_DIR_OUT) // MSC OUT +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 + +#define UDI_CDC_PORT_NB 1 +#define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) +extern bool mp_cdc_enable(uint8_t port); +#define UDI_CDC_DISABLE_EXT(port) mp_cdc_disable(port) +extern void mp_cdc_disable(uint8_t port); +#define UDI_CDC_LOW_RATE + +#define UDI_CDC_DEFAULT_RATE 115200 +#define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 +#define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE +#define UDI_CDC_DEFAULT_DATABITS 8 + +#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() +void usb_rx_notify(void); + +#define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg) +void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding); +#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) +void usb_dtr_notify(uint8_t port, bool set); +#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) +void usb_rts_notify(uint8_t port, bool set); + +/** + * USB CDC low level configuration + * In standalone these configurations are defined by the CDC module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition + +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_0 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (5 | USB_EP_DIR_OUT) // RX + +//! Interface numbers +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 + +/** + * Configuration of MSC interface + * @{ + */ +//! Vendor name and Product version of MSC interface +#define UDI_MSC_GLOBAL_VENDOR_ID \ + 'A', 'T', 'M', 'E', 'L', ' ', ' ', ' ' +#define UDI_MSC_GLOBAL_PRODUCT_VERSION \ + '1', '.', '0', '0' + +//! Interface callback definition +#define UDI_MSC_ENABLE_EXT() mp_msc_enable() +extern bool mp_msc_enable(void); +#define UDI_MSC_DISABLE_EXT() mp_msc_disable() +extern void mp_msc_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_MSC_STRING_ID 5 + +/** + * USB MSC low level configuration + * In standalone these configurations are defined by the MSC module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_MSC_EP_IN (1 | USB_EP_DIR_IN) +#define UDI_MSC_EP_OUT (2 | USB_EP_DIR_OUT) + +//! Interface number +#define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 + +/** + * Description of Composite Device + * @{ + */ +//! USB Interfaces descriptor structure +#define UDI_COMPOSITE_DESC_T \ + usb_iad_desc_t udi_cdc_iad; \ + udi_cdc_comm_desc_t udi_cdc_comm; \ + udi_cdc_data_desc_t udi_cdc_data; \ + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd + +//! USB Interfaces descriptor value for Full Speed +#define UDI_COMPOSITE_DESC_FS \ + .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC + +//! USB Interfaces descriptor value for High Speed +#define UDI_COMPOSITE_DESC_HS \ + .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC + +//! USB Interface APIs +#define UDI_COMPOSITE_API \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, \ + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd +//@} + +/** + * USB Device Driver Configuration + * @{ + */ +//@} + +//! The includes of classes and other headers must be done at the end of this file to avoid compile error +#include "udi_cdc.h" +#include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" + +#endif diff --git a/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h b/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h new file mode 100644 index 0000000000..e8ae381a71 --- /dev/null +++ b/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h @@ -0,0 +1,39 @@ +#define USB_REPL + +#define MICROPY_HW_BOARD_NAME "Trinket M0 Haxpress" +#define MICROPY_HW_MCU_NAME "samd21e18" + +// Rev B - Black +#define MICROPY_HW_APA102_MOSI (&pin_PA00) +#define MICROPY_HW_APA102_SCK (&pin_PA01) + +// Salae reads 12mhz which is the limit even though we set it to the +// safer 8mhz. +#define SPI_FLASH_BAUDRATE (8000000) + +#define SPI_FLASH_MUX_SETTING SPI_SIGNAL_MUX_SETTING_D +#define SPI_FLASH_PAD0_PINMUX PINMUX_PA16D_SERCOM3_PAD0 // MOSI +#define SPI_FLASH_PAD1_PINMUX PINMUX_PA17D_SERCOM3_PAD1 // SCK +#define SPI_FLASH_PAD2_PINMUX PINMUX_UNUSED // Use default pinmux for the chip + // select since we manage it + // ourselves. +#define SPI_FLASH_PAD3_PINMUX PINMUX_PA19D_SERCOM3_PAD3 // MISO +#define SPI_FLASH_SERCOM SERCOM3 + +#define SPI_FLASH_CS PIN_PA11 + +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA11 | PORT_PA16 |\ + PORT_PA17 | PORT_PA18 | PORT_PA19 | PORT_PA24 |\ + PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CALIBRATE_CRYSTALLESS 1 + +#include "spi_flash.h" + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#include "flash_W25Q32BV.h" + diff --git a/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk new file mode 100644 index 0000000000..cfa924b606 --- /dev/null +++ b/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk @@ -0,0 +1,8 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld +USB_VID = 0x239A +USB_PID = 0x801F + +FLASH_IMPL = spi_flash.c + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 diff --git a/atmel-samd/boards/trinket_m0_haxpress/pins.c b/atmel-samd/boards/trinket_m0_haxpress/pins.c new file mode 100644 index 0000000000..ac58986009 --- /dev/null +++ b/atmel-samd/boards/trinket_m0_haxpress/pins.c @@ -0,0 +1,31 @@ +#include "samd21_pins.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA09) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) }, + + { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); From c478c10923b9085b2abe135470e968029aaf2fdb Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 2 Oct 2017 20:49:40 -0400 Subject: [PATCH 4/7] Do not allow a *io object to be used after deinit(). Fixes #278, #277, #276, #275. --- atmel-samd/Makefile | 11 ++-- .../boards/feather_m0_basic/mpconfigboard.mk | 1 + atmel-samd/common-hal/analogio/AnalogIn.c | 8 +++ atmel-samd/common-hal/analogio/AnalogOut.c | 8 +++ atmel-samd/common-hal/analogio/AnalogOut.h | 1 + atmel-samd/common-hal/audiobusio/PDMIn.c | 9 ++++ atmel-samd/common-hal/audioio/AudioOut.c | 9 ++++ atmel-samd/common-hal/busio/I2C.c | 9 ++++ atmel-samd/common-hal/busio/SPI.c | 8 +++ atmel-samd/common-hal/busio/UART.c | 9 ++++ .../common-hal/digitalio/DigitalInOut.c | 8 +++ atmel-samd/common-hal/pulseio/PWMOut.c | 10 +++- atmel-samd/common-hal/pulseio/PulseIn.c | 8 +++ atmel-samd/common-hal/pulseio/PulseOut.c | 9 ++++ atmel-samd/common-hal/touchio/TouchIn.c | 11 +++- atmel-samd/common-hal/touchio/TouchIn.h | 1 - esp8266/Makefile | 6 ++- esp8266/common-hal/analogio/AnalogIn.c | 8 +++ esp8266/common-hal/analogio/AnalogIn.h | 2 +- esp8266/common-hal/analogio/AnalogOut.c | 4 ++ esp8266/common-hal/busio/SPI.c | 10 ++++ esp8266/common-hal/busio/SPI.h | 1 + esp8266/common-hal/busio/UART.c | 8 +++ esp8266/common-hal/busio/UART.h | 3 +- esp8266/common-hal/digitalio/DigitalInOut.c | 8 +++ esp8266/common-hal/pulseio/PWMOut.c | 12 ++++- esp8266/common-hal/pulseio/PulseIn.c | 5 +- esp8266/common-hal/pulseio/PulseOut.c | 4 ++ shared-bindings/analogio/AnalogIn.c | 11 ++-- shared-bindings/analogio/AnalogIn.h | 1 + shared-bindings/analogio/AnalogOut.c | 3 ++ shared-bindings/analogio/AnalogOut.h | 1 + shared-bindings/audiobusio/PDMIn.c | 4 +- shared-bindings/audiobusio/PDMIn.h | 1 + shared-bindings/audioio/AudioOut.c | 6 +++ shared-bindings/audioio/AudioOut.h | 1 + shared-bindings/bitbangio/I2C.c | 13 ++++- shared-bindings/bitbangio/I2C.h | 1 + shared-bindings/bitbangio/OneWire.c | 4 ++ shared-bindings/bitbangio/OneWire.h | 1 + shared-bindings/bitbangio/SPI.c | 17 +++++-- shared-bindings/bitbangio/SPI.h | 1 + shared-bindings/busio/I2C.c | 12 ++++- shared-bindings/busio/I2C.h | 1 + shared-bindings/busio/OneWire.c | 4 ++ shared-bindings/busio/OneWire.h | 1 + shared-bindings/busio/SPI.c | 12 ++++- shared-bindings/busio/SPI.h | 1 + shared-bindings/busio/UART.c | 12 +++-- shared-bindings/busio/UART.h | 1 + shared-bindings/digitalio/DigitalInOut.c | 11 ++++ shared-bindings/digitalio/DigitalInOut.h | 1 + shared-bindings/pulseio/PWMOut.c | 14 +++-- shared-bindings/pulseio/PWMOut.h | 1 + shared-bindings/pulseio/PulseIn.c | 12 +++++ shared-bindings/pulseio/PulseIn.h | 1 + shared-bindings/pulseio/PulseOut.c | 3 ++ shared-bindings/pulseio/PulseOut.h | 1 + shared-bindings/touchio/TouchIn.c | 51 ++++++++++--------- shared-bindings/touchio/TouchIn.h | 1 + shared-bindings/util.c | 42 +++++++++++++++ shared-bindings/util.h | 33 ++++++++++++ shared-module/bitbangio/I2C.c | 8 +++ shared-module/bitbangio/OneWire.c | 7 +++ shared-module/bitbangio/SPI.c | 7 +++ shared-module/busio/I2C.c | 4 ++ shared-module/busio/OneWire.c | 7 +++ 67 files changed, 445 insertions(+), 59 deletions(-) create mode 100644 shared-bindings/util.c create mode 100644 shared-bindings/util.h diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index 501851ab10..daf21568a8 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -135,9 +135,13 @@ ifeq ($(DEBUG), 1) # -DMICROPY_DEBUG_MODULES may also be added to an -flto build, if you wish. CFLAGS += -Os -ggdb -DNDEBUG -DENABLE_MICRO_TRACE_BUFFER -DMICROPY_DEBUG_MODULES else -# -finline-limit can shrink the image size. -finline-limit=80 or so is similar to not having it on. +# GCC_INLINE_LIMIT specifies -finline-limit, which can shrink the image size. +# -finline-limit=80 or so is similar to not having it on. # There is no simple default value, though. -CFLAGS += -Os -DNDEBUG -flto -finline-limit=39 +ifeq ($(FLASH_IMPL),internal_flash.c) +GCC_INLINE_LIMIT = -finline-limit=19 +endif +CFLAGS += -Os -DNDEBUG -flto $(GCC_INLINE_LIMIT) endif ifneq ($(FROZEN_DIR),) @@ -272,7 +276,8 @@ SRC_BINDINGS_ENUMS = \ digitalio/Direction.c \ digitalio/DriveMode.c \ digitalio/Pull.c \ - help.c + help.c \ + util.c SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ diff --git a/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk b/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk index 755157cb7e..c6c64f4a2c 100644 --- a/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk +++ b/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk @@ -5,3 +5,4 @@ USB_PID = 0x8015 FLASH_IMPL = internal_flash.c CHIP_VARIANT = SAMD21G18A + diff --git a/atmel-samd/common-hal/analogio/AnalogIn.c b/atmel-samd/common-hal/analogio/AnalogIn.c index 2103663c1f..c520b407d0 100644 --- a/atmel-samd/common-hal/analogio/AnalogIn.c +++ b/atmel-samd/common-hal/analogio/AnalogIn.c @@ -77,7 +77,14 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, active_channel_count++; } +bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { + return self->pin == mp_const_none; +} + void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { + if (common_hal_analogio_analogin_deinited(self)) { + return; + } active_channel_count--; if (active_channel_count == 0) { adc_reset(adc_instance); @@ -89,6 +96,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { config_adc = NULL; } reset_pin(self->pin->pin); + self->pin = mp_const_none; } void analogin_reset() { diff --git a/atmel-samd/common-hal/analogio/AnalogOut.c b/atmel-samd/common-hal/analogio/AnalogOut.c index 9f4d06375f..d547873918 100644 --- a/atmel-samd/common-hal/analogio/AnalogOut.c +++ b/atmel-samd/common-hal/analogio/AnalogOut.c @@ -59,10 +59,18 @@ void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, dac_enable(&self->dac_instance); } +bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { + return self->deinited; +} + void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { + if (common_hal_analogio_analogout_deinited(self)) { + return; + } dac_disable(&self->dac_instance); dac_chan_disable(&self->dac_instance, DAC_CHANNEL_0); reset_pin(PIN_PA02); + self->deinited = true; } void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, diff --git a/atmel-samd/common-hal/analogio/AnalogOut.h b/atmel-samd/common-hal/analogio/AnalogOut.h index 1c2705a83b..b60658da69 100644 --- a/atmel-samd/common-hal/analogio/AnalogOut.h +++ b/atmel-samd/common-hal/analogio/AnalogOut.h @@ -36,6 +36,7 @@ typedef struct { mp_obj_base_t base; struct dac_module dac_instance; + bool deinited; } analogio_analogout_obj_t; #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H diff --git a/atmel-samd/common-hal/audiobusio/PDMIn.c b/atmel-samd/common-hal/audiobusio/PDMIn.c index 11411ee3d4..db671f213f 100644 --- a/atmel-samd/common-hal/audiobusio/PDMIn.c +++ b/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -145,11 +145,20 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self, self->bit_depth = bit_depth; } +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t* self) { + return self->clock_pin == mp_const_none; +} + void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self) { + if (common_hal_audiobusio_pdmin_deinited(self)) { + return; + } i2s_disable(&self->i2s_instance); i2s_reset(&self->i2s_instance); reset_pin(self->clock_pin->pin); reset_pin(self->data_pin->pin); + self->clock_pin = mp_const_none; + self->data_pin = mp_const_none; } uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t* self) { diff --git a/atmel-samd/common-hal/audioio/AudioOut.c b/atmel-samd/common-hal/audioio/AudioOut.c index 1755414592..9f69808900 100644 --- a/atmel-samd/common-hal/audioio/AudioOut.c +++ b/atmel-samd/common-hal/audioio/AudioOut.c @@ -381,7 +381,14 @@ void common_hal_audioio_audioout_construct_from_file(audioio_audioout_obj_t* sel } } +bool common_hal_audioio_audioout_deinited(audioio_audioout_obj_t* self) { + return self->pin == mp_const_none; +} + void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self) { + if (common_hal_audioio_audioout_deinited(self)) { + return; + } refcount--; if (refcount == 0) { if (MP_STATE_VM(audioout_sample_timer) != NULL) { @@ -407,6 +414,8 @@ void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self) { } reset_pin(self->pin->pin); } + + self->pin = mp_const_none; } static void set_timer_frequency(uint32_t frequency) { diff --git a/atmel-samd/common-hal/busio/I2C.c b/atmel-samd/common-hal/busio/I2C.c index b495417354..b929b0cb03 100644 --- a/atmel-samd/common-hal/busio/I2C.c +++ b/atmel-samd/common-hal/busio/I2C.c @@ -95,10 +95,19 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, i2c_master_enable(&self->i2c_master_instance); } +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return self->sda_pin == NO_PIN; +} + void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } i2c_master_reset(&self->i2c_master_instance); reset_pin(self->sda_pin); reset_pin(self->scl_pin); + self->sda_pin = NO_PIN; + self->scl_pin = NO_PIN; } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { diff --git a/atmel-samd/common-hal/busio/SPI.c b/atmel-samd/common-hal/busio/SPI.c index c7e7d6fd78..c1b13cec88 100644 --- a/atmel-samd/common-hal/busio/SPI.c +++ b/atmel-samd/common-hal/busio/SPI.c @@ -159,11 +159,19 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, spi_enable(&self->spi_master_instance); } +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->clock_pin == NO_PIN; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + return; + } spi_disable(&self->spi_master_instance); reset_pin(self->clock_pin); reset_pin(self->MOSI_pin); reset_pin(self->MISO_pin); + self->clock_pin = NO_PIN; } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/atmel-samd/common-hal/busio/UART.c b/atmel-samd/common-hal/busio/UART.c index 5dda268adc..79f7cf4a9e 100644 --- a/atmel-samd/common-hal/busio/UART.c +++ b/atmel-samd/common-hal/busio/UART.c @@ -243,7 +243,14 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->uart_instance.hw->USART.INTENSET.bit.RXC = true; } +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return self->rx_pin == NO_PIN && self->tx_pin == NO_PIN; +} + void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + if (common_hal_busio_uart_deinited(self)) { + return; + } self->uart_instance.hw->USART.INTENCLR.bit.RXC = true; uint8_t instance_index = _sercom_get_sercom_inst_index(self->uart_instance.hw); @@ -256,6 +263,8 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { usart_disable(&self->uart_instance); reset_pin(self->rx_pin); reset_pin(self->tx_pin); + self->rx_pin = NO_PIN; + self->tx_pin = NO_PIN; } // Read characters. diff --git a/atmel-samd/common-hal/digitalio/DigitalInOut.c b/atmel-samd/common-hal/digitalio/DigitalInOut.c index 3f178fac02..abb4547cc1 100644 --- a/atmel-samd/common-hal/digitalio/DigitalInOut.c +++ b/atmel-samd/common-hal/digitalio/DigitalInOut.c @@ -51,8 +51,16 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct( return DIGITALINOUT_OK; } +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) { + return self->pin == mp_const_none; +} + void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } reset_pin(self->pin->pin); + self->pin = mp_const_none; } void common_hal_digitalio_digitalinout_switch_to_input( diff --git a/atmel-samd/common-hal/pulseio/PWMOut.c b/atmel-samd/common-hal/pulseio/PWMOut.c index e1abb3687f..bf2b0cb331 100644 --- a/atmel-samd/common-hal/pulseio/PWMOut.c +++ b/atmel-samd/common-hal/pulseio/PWMOut.c @@ -238,7 +238,14 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, common_hal_pulseio_pwmout_set_duty_cycle(self, duty); } -extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { +bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { + return self->pin == mp_const_none; +} + +void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { + if (common_hal_pulseio_pwmout_deinited(self)) { + return; + } const pin_timer_t* t = self->timer; uint8_t index = (((uint32_t) t->tcc) - ((uint32_t) TCC0)) / 0x400; timer_refcount[index]--; @@ -260,6 +267,7 @@ extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { } } reset_pin(self->pin->pin); + self->pin = mp_const_none; } extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { diff --git a/atmel-samd/common-hal/pulseio/PulseIn.c b/atmel-samd/common-hal/pulseio/PulseIn.c index ecbab29bd0..99f747caf8 100644 --- a/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/atmel-samd/common-hal/pulseio/PulseIn.c @@ -152,10 +152,18 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, extint_chan_enable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); } +bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { + return self->pin == NO_PIN; +} + void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + return; + } extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); active_pulseins[self->channel] = NULL; reset_pin(self->pin); + self->pin = NO_PIN; } void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { diff --git a/atmel-samd/common-hal/pulseio/PulseOut.c b/atmel-samd/common-hal/pulseio/PulseOut.c index 4628d3ccb9..b2d594232e 100644 --- a/atmel-samd/common-hal/pulseio/PulseOut.c +++ b/atmel-samd/common-hal/pulseio/PulseOut.c @@ -34,6 +34,7 @@ #include "mpconfigport.h" #include "py/gc.h" #include "py/runtime.h" +#include "samd21_pins.h" #include "shared-bindings/pulseio/PulseOut.h" #undef ENABLE @@ -128,7 +129,14 @@ void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, turn_off(self->pincfg); } +bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) { + return self->pin == NO_PIN; +} + void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { + if (common_hal_pulseio_pulseout_deinited(self)) { + return; + } PortGroup *const port_base = port_get_group_from_gpio_pin(self->pin); port_base->DIRCLR.reg = 1 << (self->pin % 32); @@ -140,6 +148,7 @@ void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { gc_free(MP_STATE_VM(pulseout_tc_instance)); MP_STATE_VM(pulseout_tc_instance) = NULL; } + self->pin = NO_PIN; } void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { diff --git a/atmel-samd/common-hal/touchio/TouchIn.c b/atmel-samd/common-hal/touchio/TouchIn.c index ddfd1055a8..6bb96ff00e 100644 --- a/atmel-samd/common-hal/touchio/TouchIn.c +++ b/atmel-samd/common-hal/touchio/TouchIn.c @@ -33,6 +33,7 @@ #include "py/mphal.h" #include "shared-bindings/touchio/TouchIn.h" +#include "samd21_pins.h" #include "tick.h" #include "adafruit_ptc.h" @@ -81,9 +82,17 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, self->threshold = get_raw_reading(self) + 100; } +bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t* self) { + return self->config.pin == NO_PIN; +} + void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self) { // TODO(tannewt): Reset the PTC. - reset_pin(self->pin->pin); + if (common_hal_touchio_touchin_deinited(self)) { + return; + } + reset_pin(self->config.pin); + self->config.pin = NO_PIN; } void touchin_reset() { diff --git a/atmel-samd/common-hal/touchio/TouchIn.h b/atmel-samd/common-hal/touchio/TouchIn.h index d4cd1539b5..ffe8a6c017 100644 --- a/atmel-samd/common-hal/touchio/TouchIn.h +++ b/atmel-samd/common-hal/touchio/TouchIn.h @@ -36,7 +36,6 @@ typedef struct { mp_obj_base_t base; - const mcu_pin_obj_t * pin; struct adafruit_ptc_config config; uint16_t threshold; } touchio_touchin_obj_t; diff --git a/esp8266/Makefile b/esp8266/Makefile index 3daff9c62e..bfaefb4651 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -121,12 +121,14 @@ SRC_COMMON_HAL = \ time/__init__.c \ board/__init__.c + # These don't have corresponding files in each port but are still located in # shared-bindings to make it clear what the contents of the modules are. SRC_BINDINGS_ENUMS = \ digitalio/Direction.c \ digitalio/DriveMode.c \ - digitalio/Pull.c + digitalio/Pull.c \ + util.c SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ @@ -141,7 +143,7 @@ SRC_SHARED_MODULE = \ multiterminal/__init__.c \ os/__init__.c \ random/__init__.c \ - storage/__init__.c \ + storage/__init__.c SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ $(addprefix shared-module/, $(SRC_SHARED_MODULE)) diff --git a/esp8266/common-hal/analogio/AnalogIn.c b/esp8266/common-hal/analogio/AnalogIn.c index 0f43a08791..d3a81272ee 100644 --- a/esp8266/common-hal/analogio/AnalogIn.c +++ b/esp8266/common-hal/analogio/AnalogIn.c @@ -46,8 +46,16 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, adc_in_use = true; } +bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t* self) { + return self->deinited; +} + void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t* self) { + if (common_hal_analogio_analogin_deinited(self)) { + return; + } adc_in_use = false; + self->deinited = true; } uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { diff --git a/esp8266/common-hal/analogio/AnalogIn.h b/esp8266/common-hal/analogio/AnalogIn.h index 0f529957a6..b20b8cc61e 100644 --- a/esp8266/common-hal/analogio/AnalogIn.h +++ b/esp8266/common-hal/analogio/AnalogIn.h @@ -33,7 +33,7 @@ typedef struct { mp_obj_base_t base; - const mcu_pin_obj_t * pin; + bool deinited; } analogio_analogin_obj_t; #endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H diff --git a/esp8266/common-hal/analogio/AnalogOut.c b/esp8266/common-hal/analogio/AnalogOut.c index 30dc448300..15e9ee2778 100644 --- a/esp8266/common-hal/analogio/AnalogOut.c +++ b/esp8266/common-hal/analogio/AnalogOut.c @@ -38,6 +38,10 @@ void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, "No hardware support for analog out.")); } +bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { + return true; +} + void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { } diff --git a/esp8266/common-hal/busio/SPI.c b/esp8266/common-hal/busio/SPI.c index 910e1e40de..b372d07643 100644 --- a/esp8266/common-hal/busio/SPI.c +++ b/esp8266/common-hal/busio/SPI.c @@ -74,7 +74,15 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE); } +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->deinited; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + return; + } + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 0); PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); @@ -86,6 +94,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { // Turn off outputs 12 - 14. gpio_output_set(0x0, 0x0, 0x0, 0x7 << 12); + + self->deinited = true; } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/esp8266/common-hal/busio/SPI.h b/esp8266/common-hal/busio/SPI.h index ea2f3d9eff..24822ca3c8 100644 --- a/esp8266/common-hal/busio/SPI.h +++ b/esp8266/common-hal/busio/SPI.h @@ -34,6 +34,7 @@ typedef struct { mp_obj_base_t base; bool locked; + bool deinited; } busio_spi_obj_t; #endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H diff --git a/esp8266/common-hal/busio/UART.c b/esp8266/common-hal/busio/UART.c index b2a1d69b8a..8d6e0b7bcf 100644 --- a/esp8266/common-hal/busio/UART.c +++ b/esp8266/common-hal/busio/UART.c @@ -92,8 +92,16 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uart_setup(UART1); } +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return self->deinited; +} + void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + if (common_hal_busio_uart_deinited(self)) { + return; + } PIN_FUNC_SELECT(FUNC_U1TXD_BK, 0); + self->deinited = true; } size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { diff --git a/esp8266/common-hal/busio/UART.h b/esp8266/common-hal/busio/UART.h index 75e68c78e5..d5dd138add 100644 --- a/esp8266/common-hal/busio/UART.h +++ b/esp8266/common-hal/busio/UART.h @@ -32,7 +32,8 @@ #include "py/obj.h" typedef struct { - mp_obj_base_t base; + mp_obj_base_t base; + bool deinited; } busio_uart_obj_t; #endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H diff --git a/esp8266/common-hal/digitalio/DigitalInOut.c b/esp8266/common-hal/digitalio/DigitalInOut.c index ba6589d889..70ed207d59 100644 --- a/esp8266/common-hal/digitalio/DigitalInOut.c +++ b/esp8266/common-hal/digitalio/DigitalInOut.c @@ -41,13 +41,21 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct( return DIGITALINOUT_OK; } +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) { + return self->pin == mp_const_none; +} + void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } if (self->pin->gpio_number < 16) { uint32_t pin_mask = 1 << self->pin->gpio_number; gpio_output_set(0x0, 0x0, 0x0, pin_mask); PIN_FUNC_SELECT(self->pin->peripheral, 0); PIN_PULLUP_DIS(self->pin->peripheral); } + self->pin = mp_const_none; } void common_hal_digitalio_digitalinout_switch_to_input( diff --git a/esp8266/common-hal/pulseio/PWMOut.c b/esp8266/common-hal/pulseio/PWMOut.c index 40a46e3927..9cc869794b 100644 --- a/esp8266/common-hal/pulseio/PWMOut.c +++ b/esp8266/common-hal/pulseio/PWMOut.c @@ -77,7 +77,14 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_p } } -extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { +bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { + return self->pin == mp_const_none; +} + +void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { + if (common_hal_pulseio_pwmout_deinited(self)) { + return; + } pwm_delete(self->channel); pwm_start(); if (self->pin->gpio_number < 16) { @@ -86,9 +93,10 @@ extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { PIN_FUNC_SELECT(self->pin->peripheral, 0); PIN_PULLUP_DIS(self->pin->peripheral); } + self->pin = mp_const_none; } -extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { +void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { // We get 16 bits of duty in but the underlying code is only ten bit. pwm_set_duty(duty >> 6, self->channel); pwm_start(); diff --git a/esp8266/common-hal/pulseio/PulseIn.c b/esp8266/common-hal/pulseio/PulseIn.c index 784116befe..783442b35c 100644 --- a/esp8266/common-hal/pulseio/PulseIn.c +++ b/esp8266/common-hal/pulseio/PulseIn.c @@ -37,8 +37,11 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, mp_raise_NotImplementedError(""); } -void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { +bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { + return true; +} +void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { } void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { diff --git a/esp8266/common-hal/pulseio/PulseOut.c b/esp8266/common-hal/pulseio/PulseOut.c index 1301abbf38..db2f7cbd92 100644 --- a/esp8266/common-hal/pulseio/PulseOut.c +++ b/esp8266/common-hal/pulseio/PulseOut.c @@ -35,6 +35,10 @@ void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "No hardware support for PulseOut.")); } +bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) { + return true; +} + void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { } diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index dc625e8559..14b788295e 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -34,6 +34,7 @@ #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/analogio/AnalogIn.h" +#include "shared-bindings/util.h" //| .. currentmodule:: analogio //| @@ -114,8 +115,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4, //| :rtype: int //| STATIC mp_obj_t analogio_analogin_obj_get_value(mp_obj_t self_in) { - analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_analogio_analogin_get_value(self)); + analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_analogio_analogin_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_analogio_analogin_get_value(self)); } MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_value_obj, analogio_analogin_obj_get_value); @@ -134,8 +136,9 @@ const mp_obj_property_t analogio_analogin_value_obj = { //| :rtype: float //| STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { - analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_float(common_hal_analogio_analogin_get_reference_voltage(self)); + analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_analogio_analogin_deinited(self)); + return mp_obj_new_float(common_hal_analogio_analogin_get_reference_voltage(self)); } MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_reference_voltage_obj, analogio_analogin_obj_get_reference_voltage); diff --git a/shared-bindings/analogio/AnalogIn.h b/shared-bindings/analogio/AnalogIn.h index 9c13526acb..4aa7fca233 100644 --- a/shared-bindings/analogio/AnalogIn.h +++ b/shared-bindings/analogio/AnalogIn.h @@ -34,6 +34,7 @@ extern const mp_obj_type_t analogio_analogin_type; void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, const mcu_pin_obj_t *pin); void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t* self); +bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t* self); uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t* self); float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t* self); diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index 6b65878b4d..0c7a59db81 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -30,8 +30,10 @@ #include "lib/utils/context_manager_helpers.h" #include "py/objproperty.h" #include "py/runtime.h" + #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/analogio/AnalogOut.h" +#include "shared-bindings/util.h" //| .. currentmodule:: analogio //| @@ -112,6 +114,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4 //| STATIC mp_obj_t analogio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { analogio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_analogio_analogout_deinited(self)); uint32_t v = mp_obj_get_int(value); if (v >= (1 << 16)) { mp_raise_ValueError("AnalogOut is only 16 bits. Value must be less than 65536."); diff --git a/shared-bindings/analogio/AnalogOut.h b/shared-bindings/analogio/AnalogOut.h index 4276ec4aea..6fe5d9b193 100644 --- a/shared-bindings/analogio/AnalogOut.h +++ b/shared-bindings/analogio/AnalogOut.h @@ -34,6 +34,7 @@ extern const mp_obj_type_t analogio_analogout_type; void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin); void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self); +bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self); void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGOUT_H diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index eea1e76ac7..e13e09d64e 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -32,6 +32,7 @@ #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/audiobusio/PDMIn.h" +#include "shared-bindings/util.h" //| .. currentmodule:: audiobusio //| @@ -161,7 +162,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4, //| STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj); - + raise_error_if_deinited(common_hal_audiobusio_pdmin_deinited(self)); if (!MP_OBJ_IS_SMALL_INT(destination_length)) { mp_raise_TypeError("destination_length must be int"); } @@ -198,6 +199,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(audiobusio_pdmin_record_obj, audiobusio_pdmin_obj_reco //| STATIC mp_obj_t audiobusio_pdmin_obj_get_frequency(mp_obj_t self_in) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audiobusio_pdmin_deinited(self)); return MP_OBJ_NEW_SMALL_INT(common_hal_audiobusio_pdmin_get_frequency(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_get_frequency_obj, audiobusio_pdmin_obj_get_frequency); diff --git a/shared-bindings/audiobusio/PDMIn.h b/shared-bindings/audiobusio/PDMIn.h index a12b0a1f10..a0702c9788 100644 --- a/shared-bindings/audiobusio/PDMIn.h +++ b/shared-bindings/audiobusio/PDMIn.h @@ -37,6 +37,7 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self, const mcu_pin_obj_t* clock_pin, const mcu_pin_obj_t* data_pin, uint32_t frequency, uint8_t bit_depth, bool mono, uint8_t oversample); void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self); +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t* self); uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* self, uint16_t* buffer, uint32_t length); uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t* self); diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 56c307a4ff..4e76565e9b 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -32,6 +32,7 @@ #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/audioio/AudioOut.h" +#include "shared-bindings/util.h" //| .. currentmodule:: audioio //| @@ -162,6 +163,7 @@ STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_arg { MP_QSTR_loop, MP_ARG_BOOL, {.u_bool = false} }, }; audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -177,6 +179,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_pl //| STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); common_hal_audioio_audioout_stop(self); return mp_const_none; } @@ -188,6 +191,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop); //| STATIC mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); return mp_obj_new_bool(common_hal_audioio_audioout_get_playing(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_playing_obj, audioio_audioout_obj_get_playing); @@ -207,12 +211,14 @@ const mp_obj_property_t audioio_audioout_playing_obj = { //| STATIC mp_obj_t audioio_audioout_obj_get_frequency(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_audioout_get_frequency(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_frequency_obj, audioio_audioout_obj_get_frequency); STATIC mp_obj_t audioio_audioout_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); common_hal_audioio_audioout_set_frequency(self, mp_obj_get_int(frequency)); return mp_const_none; } diff --git a/shared-bindings/audioio/AudioOut.h b/shared-bindings/audioio/AudioOut.h index 2293486adb..befd4d35e6 100644 --- a/shared-bindings/audioio/AudioOut.h +++ b/shared-bindings/audioio/AudioOut.h @@ -39,6 +39,7 @@ void common_hal_audioio_audioout_construct_from_file(audioio_audioout_obj_t* sel const mcu_pin_obj_t* pin, pyb_file_obj_t* file); void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self); +bool common_hal_audioio_audioout_deinited(audioio_audioout_obj_t* self); void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self, bool loop); void common_hal_audioio_audioout_stop(audioio_audioout_obj_t* self); bool common_hal_audioio_audioout_get_playing(audioio_audioout_obj_t* self); diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 147a8d4f19..80718090ab 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -29,6 +29,7 @@ #include "shared-bindings/bitbangio/I2C.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" #include "lib/utils/buffer_helper.h" #include "lib/utils/context_manager_helpers.h" @@ -52,6 +53,7 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); + raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); self->base.type = &bitbangio_i2c_type; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); @@ -114,6 +116,7 @@ static void check_lock(bitbangio_i2c_obj_t *self) { //| STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); check_lock(self); mp_obj_t list = mp_obj_new_list(0, NULL); // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved @@ -132,7 +135,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_scan_obj, bitbangio_i2c_scan); //| Attempts to grab the I2C lock. Returns True on success. //| STATIC mp_obj_t bitbangio_i2c_obj_try_lock(mp_obj_t self_in) { - return mp_obj_new_bool(shared_module_bitbangio_i2c_try_lock(MP_OBJ_TO_PTR(self_in))); + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); + return mp_obj_new_bool(shared_module_bitbangio_i2c_try_lock(self)); } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_try_lock_obj, bitbangio_i2c_obj_try_lock); @@ -141,7 +146,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_try_lock_obj, bitbangio_i2c_obj_try_lock //| Releases the I2C lock. //| STATIC mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) { - shared_module_bitbangio_i2c_unlock(MP_OBJ_TO_PTR(self_in)); + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); + shared_module_bitbangio_i2c_unlock(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); @@ -169,6 +176,7 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); check_lock(self); @@ -215,6 +223,7 @@ STATIC mp_obj_t bitbangio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, m { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, }; bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); check_lock(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); diff --git a/shared-bindings/bitbangio/I2C.h b/shared-bindings/bitbangio/I2C.h index d8acbecd20..9d393ee124 100644 --- a/shared-bindings/bitbangio/I2C.h +++ b/shared-bindings/bitbangio/I2C.h @@ -42,6 +42,7 @@ extern void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, uint32_t frequency); extern void shared_module_bitbangio_i2c_deinit(bitbangio_i2c_obj_t *self); +extern bool shared_module_bitbangio_i2c_deinited(bitbangio_i2c_obj_t *self); extern bool shared_module_bitbangio_i2c_try_lock(bitbangio_i2c_obj_t *self); extern bool shared_module_bitbangio_i2c_has_lock(bitbangio_i2c_obj_t *self); diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c index bbdf7c8f53..608c98100b 100644 --- a/shared-bindings/bitbangio/OneWire.c +++ b/shared-bindings/bitbangio/OneWire.c @@ -32,6 +32,7 @@ #include "py/runtime0.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/bitbangio/OneWire.h" +#include "shared-bindings/util.h" //| .. currentmodule:: bitbangio //| @@ -117,6 +118,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_onewire___exit___obj, 4, 4, //| STATIC mp_obj_t bitbangio_onewire_obj_reset(mp_obj_t self_in) { bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self)); return mp_obj_new_bool(shared_module_bitbangio_onewire_reset(self)); } @@ -131,6 +133,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_reset_obj, bitbangio_onewire_obj_res //| STATIC mp_obj_t bitbangio_onewire_obj_read_bit(mp_obj_t self_in) { bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self)); return mp_obj_new_bool(shared_module_bitbangio_onewire_read_bit(self)); } @@ -142,6 +145,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_read_bit_obj, bitbangio_onewire_obj_ //| STATIC mp_obj_t bitbangio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self)); shared_module_bitbangio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); return mp_const_none; diff --git a/shared-bindings/bitbangio/OneWire.h b/shared-bindings/bitbangio/OneWire.h index 894c6e3687..ef50db737b 100644 --- a/shared-bindings/bitbangio/OneWire.h +++ b/shared-bindings/bitbangio/OneWire.h @@ -35,6 +35,7 @@ extern const mp_obj_type_t bitbangio_onewire_type; extern void shared_module_bitbangio_onewire_construct(bitbangio_onewire_obj_t* self, const mcu_pin_obj_t* pin); extern void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t* self); +extern bool shared_module_bitbangio_onewire_deinited(bitbangio_onewire_obj_t* self); extern bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self); extern bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t* self); extern void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t* self, bool bit); diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 8589025d91..6c7bac3e51 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -31,6 +31,7 @@ #include "shared-bindings/bitbangio/SPI.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" #include "lib/utils/context_manager_helpers.h" #include "py/mperrno.h" @@ -138,6 +139,7 @@ STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args, { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, }; bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); check_lock(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -168,7 +170,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configu //| :rtype: bool //| STATIC mp_obj_t bitbangio_spi_obj_try_lock(mp_obj_t self_in) { - return mp_obj_new_bool(shared_module_bitbangio_spi_try_lock(MP_OBJ_TO_PTR(self_in))); + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); + return mp_obj_new_bool(shared_module_bitbangio_spi_try_lock(self)); } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_try_lock_obj, bitbangio_spi_obj_try_lock); @@ -177,7 +181,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_try_lock_obj, bitbangio_spi_obj_try_lock //| Releases the SPI lock. //| STATIC mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) { - shared_module_bitbangio_spi_unlock(MP_OBJ_TO_PTR(self_in)); + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); + shared_module_bitbangio_spi_unlock(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); @@ -188,9 +194,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); //| // TODO(tannewt): Add support for start and end kwargs. STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) { + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); mp_buffer_info_t src; mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ); - bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); check_lock(self); bool ok = shared_module_bitbangio_spi_write(self, src.buf, src.len); if (!ok) { @@ -207,10 +214,12 @@ MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write); //| // TODO(tannewt): Add support for start and end kwargs. STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) { + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]); + raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); check_lock(args[0]); - bool ok = shared_module_bitbangio_spi_read(args[0], bufinfo.buf, bufinfo.len); + bool ok = shared_module_bitbangio_spi_read(self, bufinfo.buf, bufinfo.len); if (!ok) { mp_raise_OSError(MP_EIO); } diff --git a/shared-bindings/bitbangio/SPI.h b/shared-bindings/bitbangio/SPI.h index 93089a8aab..0ce3297980 100644 --- a/shared-bindings/bitbangio/SPI.h +++ b/shared-bindings/bitbangio/SPI.h @@ -41,6 +41,7 @@ extern void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, const mcu_pin_obj_t * miso); extern void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self); +extern bool shared_module_bitbangio_spi_deinited(bitbangio_spi_obj_t *self); extern void shared_module_bitbangio_spi_configure(bitbangio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 0431add784..cdc960f803 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -29,6 +29,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/busio/I2C.h" +#include "shared-bindings/util.h" #include "lib/utils/buffer_helper.h" #include "lib/utils/context_manager_helpers.h" @@ -126,6 +127,7 @@ static void check_lock(busio_i2c_obj_t *self) { //| STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); check_lock(self); mp_obj_t list = mp_obj_new_list(0, NULL); // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved @@ -147,7 +149,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan); //| :rtype: bool //| STATIC mp_obj_t busio_i2c_obj_try_lock(mp_obj_t self_in) { - return mp_obj_new_bool(common_hal_busio_i2c_try_lock(MP_OBJ_TO_PTR(self_in))); + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); + return mp_obj_new_bool(common_hal_busio_i2c_try_lock(self)); } MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock); @@ -156,7 +160,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock); //| Releases the I2C lock. //| STATIC mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) { - common_hal_busio_i2c_unlock(MP_OBJ_TO_PTR(self_in)); + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); + common_hal_busio_i2c_unlock(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); @@ -184,6 +190,7 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); check_lock(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -229,6 +236,7 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, }; busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); check_lock(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h index 00a55726b6..7185d6075c 100644 --- a/shared-bindings/busio/I2C.h +++ b/shared-bindings/busio/I2C.h @@ -49,6 +49,7 @@ extern void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, uint32_t frequency); extern void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self); +extern bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self); extern bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self); extern bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self); diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c index f270d9d924..95fce68f32 100644 --- a/shared-bindings/busio/OneWire.c +++ b/shared-bindings/busio/OneWire.c @@ -32,6 +32,7 @@ #include "py/runtime0.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/busio/OneWire.h" +#include "shared-bindings/util.h" //| .. currentmodule:: busio //| @@ -120,6 +121,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_onewire___exit___obj, 4, 4, bus //| STATIC mp_obj_t busio_onewire_obj_reset(mp_obj_t self_in) { busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_onewire_deinited(self)); return mp_obj_new_bool(common_hal_busio_onewire_reset(self)); } @@ -134,6 +136,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_reset_obj, busio_onewire_obj_reset); //| STATIC mp_obj_t busio_onewire_obj_read_bit(mp_obj_t self_in) { busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_onewire_deinited(self)); return mp_obj_new_bool(common_hal_busio_onewire_read_bit(self)); } @@ -145,6 +148,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_read_bit_obj, busio_onewire_obj_read_bit //| STATIC mp_obj_t busio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_onewire_deinited(self)); common_hal_busio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); return mp_const_none; diff --git a/shared-bindings/busio/OneWire.h b/shared-bindings/busio/OneWire.h index 893ee99199..9ee5f639b1 100644 --- a/shared-bindings/busio/OneWire.h +++ b/shared-bindings/busio/OneWire.h @@ -35,6 +35,7 @@ extern const mp_obj_type_t busio_onewire_type; extern void common_hal_busio_onewire_construct(busio_onewire_obj_t* self, const mcu_pin_obj_t* pin); extern void common_hal_busio_onewire_deinit(busio_onewire_obj_t* self); +extern bool common_hal_busio_onewire_deinited(busio_onewire_obj_t* self); extern bool common_hal_busio_onewire_reset(busio_onewire_obj_t* self); extern bool common_hal_busio_onewire_read_bit(busio_onewire_obj_t* self); extern void common_hal_busio_onewire_write_bit(busio_onewire_obj_t* self, bool bit); diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index 6e2ea5a6aa..12f888f23d 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -31,6 +31,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/busio/SPI.h" +#include "shared-bindings/util.h" #include "lib/utils/buffer_helper.h" #include "lib/utils/context_manager_helpers.h" @@ -151,6 +152,7 @@ STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_ { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, }; busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_busio_spi_deinited(self)); check_lock(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -184,7 +186,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure); //| :rtype: bool //| STATIC mp_obj_t busio_spi_obj_try_lock(mp_obj_t self_in) { - return mp_obj_new_bool(common_hal_busio_spi_try_lock(MP_OBJ_TO_PTR(self_in))); + busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_spi_deinited(self)); + return mp_obj_new_bool(common_hal_busio_spi_try_lock(self)); } MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock); @@ -193,7 +197,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock); //| Releases the SPI lock. //| STATIC mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) { - common_hal_busio_spi_unlock(MP_OBJ_TO_PTR(self_in)); + busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_spi_deinited(self)); + common_hal_busio_spi_unlock(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock); @@ -214,6 +220,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_ { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_busio_spi_deinited(self)); check_lock(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -251,6 +258,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m { MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_busio_spi_deinited(self)); check_lock(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h index 966444f25d..ac31d5060d 100644 --- a/shared-bindings/busio/SPI.h +++ b/shared-bindings/busio/SPI.h @@ -41,6 +41,7 @@ extern void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * miso); extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self); +extern bool common_hal_busio_spi_deinited(busio_spi_obj_t *self); extern bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index ee23ff0553..3a3cb42463 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -27,6 +27,8 @@ #include #include "shared-bindings/busio/UART.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" #include "lib/utils/context_manager_helpers.h" @@ -34,7 +36,6 @@ #include "py/runtime.h" #include "py/stream.h" -#include "shared-bindings/microcontroller/Pin.h" //| .. currentmodule:: busio //| @@ -179,7 +180,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ // These three methods are used by the shared stream methods. STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { - busio_uart_obj_t *self = self_in; + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_uart_deinited(self)); byte *buf = buf_in; // make sure we want at least 1 char @@ -191,14 +193,16 @@ STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, } STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { - busio_uart_obj_t *self = self_in; + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_uart_deinited(self)); const byte *buf = buf_in; return common_hal_busio_uart_write(self, buf, size, errcode); } STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { - busio_uart_obj_t *self = self_in; + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_uart_deinited(self)); mp_uint_t ret; if (request == MP_IOCTL_POLL) { mp_uint_t flags = arg; diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h index 4432d59969..28196931a9 100644 --- a/shared-bindings/busio/UART.h +++ b/shared-bindings/busio/UART.h @@ -45,6 +45,7 @@ extern void common_hal_busio_uart_construct(busio_uart_obj_t *self, uint8_t receiver_buffer_size); extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self); +extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self); // Read characters. len is in characters NOT bytes! extern size_t common_hal_busio_uart_read(busio_uart_obj_t *self, diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index 7fd823a602..ea2ba0b893 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -40,6 +40,7 @@ #include "shared-bindings/digitalio/Direction.h" #include "shared-bindings/digitalio/DriveMode.h" #include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/util.h" //| .. currentmodule:: digitalio //| @@ -119,6 +120,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_ { MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = &digitalio_drive_mode_push_pull_obj} }, }; digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -155,6 +157,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_o { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, }; digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -187,6 +190,7 @@ extern const digitalio_digitalio_direction_obj_t digitalio_digitalio_direction_o STATIC mp_obj_t digitalio_digitalinout_obj_get_direction(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); enum digitalio_direction_t direction = common_hal_digitalio_digitalinout_get_direction(self); if (direction == DIRECTION_INPUT) { return (mp_obj_t)&digitalio_direction_input_obj; @@ -197,6 +201,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_direction_obj, digitalio_di STATIC mp_obj_t digitalio_digitalinout_obj_set_direction(mp_obj_t self_in, mp_obj_t value) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); if (value == &digitalio_direction_input_obj) { common_hal_digitalio_digitalinout_switch_to_input(self, PULL_NONE); } else if (value == &digitalio_direction_output_obj) { @@ -221,6 +226,7 @@ const mp_obj_property_t digitalio_digitalio_direction_obj = { //| STATIC mp_obj_t digitalio_digitalinout_obj_get_value(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); bool value = common_hal_digitalio_digitalinout_get_value(self); return mp_obj_new_bool(value); } @@ -228,6 +234,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_value_obj, digitalio_digita STATIC mp_obj_t digitalio_digitalinout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { mp_raise_AttributeError("Cannot set value when direction is input."); return mp_const_none; @@ -250,6 +257,7 @@ const mp_obj_property_t digitalio_digitalinout_value_obj = { //| STATIC mp_obj_t digitalio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { mp_raise_AttributeError("Drive mode not used when direction is input."); return mp_const_none; @@ -264,6 +272,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_drive_mode_obj, digitalio_d STATIC mp_obj_t digitalio_digitalinout_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { mp_raise_AttributeError("Drive mode not used when direction is input."); return mp_const_none; @@ -293,6 +302,7 @@ const mp_obj_property_t digitalio_digitalio_drive_mode_obj = { //| STATIC mp_obj_t digitalio_digitalinout_obj_get_pull(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) { mp_raise_AttributeError("Pull not used when direction is output."); return mp_const_none; @@ -309,6 +319,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_pull_obj, digitalio_digital STATIC mp_obj_t digitalio_digitalinout_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) { mp_raise_AttributeError("Pull not used when direction is output."); return mp_const_none; diff --git a/shared-bindings/digitalio/DigitalInOut.h b/shared-bindings/digitalio/DigitalInOut.h index da0856edca..74970881b8 100644 --- a/shared-bindings/digitalio/DigitalInOut.h +++ b/shared-bindings/digitalio/DigitalInOut.h @@ -42,6 +42,7 @@ typedef enum { digitalinout_result_t common_hal_digitalio_digitalinout_construct(digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin); void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self); +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self); void common_hal_digitalio_digitalinout_switch_to_input(digitalio_digitalinout_obj_t* self, enum digitalio_pull_t pull); void common_hal_digitalio_digitalinout_switch_to_output(digitalio_digitalinout_obj_t* self, bool value, enum digitalio_drive_mode_t drive_mode); enum digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(digitalio_digitalinout_obj_t* self); diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c index 80036ae724..8f6c766808 100644 --- a/shared-bindings/pulseio/PWMOut.c +++ b/shared-bindings/pulseio/PWMOut.c @@ -29,8 +29,10 @@ #include "lib/utils/context_manager_helpers.h" #include "py/objproperty.h" #include "py/runtime.h" + #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/pulseio/PWMOut.h" +#include "shared-bindings/util.h" //| .. currentmodule:: pulseio //| @@ -147,13 +149,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pwmout___exit___obj, 4, 4, pu //| (0). 0xffff will always be high, 0 will always be low and 0x7fff will //| be half high and then half low. STATIC mp_obj_t pulseio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) { - pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_duty_cycle(self)); + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_duty_cycle(self)); } MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_duty_cycle_obj, pulseio_pwmout_obj_get_duty_cycle); STATIC mp_obj_t pulseio_pwmout_obj_set_duty_cycle(mp_obj_t self_in, mp_obj_t duty_cycle) { pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); mp_int_t duty = mp_obj_get_int(duty_cycle); if (duty < 0 || duty > 0xffff) { mp_raise_ValueError("PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"); @@ -176,13 +180,15 @@ const mp_obj_property_t pulseio_pwmout_duty_cycle_obj = { //| second). Only writeable when constructed with ``variable_frequency=True``. //| STATIC mp_obj_t pulseio_pwmout_obj_get_frequency(mp_obj_t self_in) { - pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_frequency(self)); + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_frequency(self)); } MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_frequency_obj, pulseio_pwmout_obj_get_frequency); STATIC mp_obj_t pulseio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency) { pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); if (!common_hal_pulseio_pwmout_get_variable_frequency(self)) { mp_raise_AttributeError( "PWM frequency not writeable when variable_frequency is False on " diff --git a/shared-bindings/pulseio/PWMOut.h b/shared-bindings/pulseio/PWMOut.h index 98858654d1..0b630816b9 100644 --- a/shared-bindings/pulseio/PWMOut.h +++ b/shared-bindings/pulseio/PWMOut.h @@ -36,6 +36,7 @@ extern void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, bool variable_frequency); extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self); +extern bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self); extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty); extern uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self); extern void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency); diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 0abc066804..da9e6ac2c5 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -32,6 +32,7 @@ #include "py/runtime0.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/pulseio/PulseIn.h" +#include "shared-bindings/util.h" //| .. currentmodule:: pulseio //| @@ -139,6 +140,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulsein___exit___obj, 4, 4, p //| STATIC mp_obj_t pulseio_pulsein_obj_pause(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); common_hal_pulseio_pulsein_pause(self); return mp_const_none; @@ -162,6 +164,8 @@ STATIC mp_obj_t pulseio_pulsein_obj_resume(size_t n_args, const mp_obj_t *pos_ar { MP_QSTR_trigger_duration, MP_ARG_INT, {.u_int = 0} }, }; pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -176,6 +180,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pulseio_pulsein_resume_obj, 1, pulseio_pulsein_obj_re //| STATIC mp_obj_t pulseio_pulsein_obj_clear(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); common_hal_pulseio_pulsein_clear(self); return mp_const_none; @@ -188,6 +193,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_clear_obj, pulseio_pulsein_obj_clear); //| STATIC mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_popleft(self)); } MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_popleft); @@ -199,6 +206,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_pople //| STATIC mp_obj_t pulseio_pulsein_obj_get_maxlen(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_maxlen(self)); } MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_get_maxlen_obj, pulseio_pulsein_obj_get_maxlen); @@ -221,6 +230,7 @@ const mp_obj_property_t pulseio_pulsein_maxlen_obj = { //| STATIC mp_obj_t pulsein_unary_op(mp_uint_t op, mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); uint16_t len = common_hal_pulseio_pulsein_get_len(self); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); @@ -244,6 +254,8 @@ STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t va mp_raise_AttributeError("Cannot delete values"); } else { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { mp_raise_NotImplementedError("Slices not supported"); } else { diff --git a/shared-bindings/pulseio/PulseIn.h b/shared-bindings/pulseio/PulseIn.h index 1b96c93c9d..88b6f356ed 100644 --- a/shared-bindings/pulseio/PulseIn.h +++ b/shared-bindings/pulseio/PulseIn.h @@ -35,6 +35,7 @@ extern const mp_obj_type_t pulseio_pulsein_type; extern void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state); extern void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self); +extern bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self); extern void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self); extern void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration); extern void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self); diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 0b1391f748..a44e28d5d9 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -29,9 +29,11 @@ #include "lib/utils/context_manager_helpers.h" #include "py/objproperty.h" #include "py/runtime.h" + #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/pulseio/PulseOut.h" #include "shared-bindings/pulseio/PWMOut.h" +#include "shared-bindings/util.h" //| .. currentmodule:: pulseio //| @@ -123,6 +125,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulseout___exit___obj, 4, 4, //| STATIC mp_obj_t pulseio_pulseout_obj_send(mp_obj_t self_in, mp_obj_t pulses) { pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pulseout_deinited(self)); mp_buffer_info_t bufinfo; mp_get_buffer_raise(pulses, &bufinfo, MP_BUFFER_READ); diff --git a/shared-bindings/pulseio/PulseOut.h b/shared-bindings/pulseio/PulseOut.h index d6279ed6f6..2cf78d3f29 100644 --- a/shared-bindings/pulseio/PulseOut.h +++ b/shared-bindings/pulseio/PulseOut.h @@ -36,6 +36,7 @@ extern const mp_obj_type_t pulseio_pulseout_type; extern void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, const pulseio_pwmout_obj_t* carrier); extern void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self); +extern bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self); extern void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t len); diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 213fbc669b..1d91233128 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -35,6 +35,7 @@ #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/touchio/TouchIn.h" +#include "shared-bindings/util.h" //| .. currentmodule:: touchio //| @@ -113,8 +114,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, t //| :rtype: bool //| STATIC mp_obj_t touchio_touchin_obj_get_value(mp_obj_t self_in) { - touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(common_hal_touchio_touchin_get_value(self)); + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_touchio_touchin_deinited(self)); + return mp_obj_new_bool(common_hal_touchio_touchin_get_value(self)); } MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_value_obj, touchio_touchin_obj_get_value); @@ -134,17 +136,18 @@ const mp_obj_property_t touchio_touchin_value_obj = { //| :rtype: int //| STATIC mp_obj_t touchio_touchin_obj_get_raw_value(mp_obj_t self_in) { - touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_raw_value(self)); + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_touchio_touchin_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_raw_value(self)); } MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_raw_value_obj, touchio_touchin_obj_get_raw_value); const mp_obj_property_t touchio_touchin_raw_value_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&touchio_touchin_get_raw_value_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&touchio_touchin_get_raw_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, }; @@ -160,31 +163,33 @@ const mp_obj_property_t touchio_touchin_raw_value_obj = { //| :rtype: int //| STATIC mp_obj_t touchio_touchin_obj_get_threshold(mp_obj_t self_in) { - touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_threshold(self)); + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_touchio_touchin_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_threshold(self)); } MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_threshold_obj, touchio_touchin_obj_get_threshold); STATIC mp_obj_t touchio_touchin_obj_set_threshold(mp_obj_t self_in, mp_obj_t threshold_obj) { - touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint32_t new_threshold = mp_obj_get_int(threshold_obj); - if (new_threshold < 0 || new_threshold > UINT16_MAX) { - // I would use MP_STRINGIFY(UINT16_MAX), but that prints "0xffff" instead of 65536. - mp_raise_ValueError("threshold must be in the range 0-65536"); - } - common_hal_touchio_touchin_set_threshold(self, new_threshold); - return mp_const_none; + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_touchio_touchin_deinited(self)); + uint32_t new_threshold = mp_obj_get_int(threshold_obj); + if (new_threshold < 0 || new_threshold > UINT16_MAX) { + // I would use MP_STRINGIFY(UINT16_MAX), but that prints "0xffff" instead of 65536. + mp_raise_ValueError("threshold must be in the range 0-65536"); + } + common_hal_touchio_touchin_set_threshold(self, new_threshold); + return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(touchio_touchin_set_threshold_obj, touchio_touchin_obj_set_threshold); const mp_obj_property_t touchio_touchin_threshold_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&touchio_touchin_get_threshold_obj, - (mp_obj_t)&touchio_touchin_set_threshold_obj, - (mp_obj_t)&mp_const_none_obj}, - }; + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&touchio_touchin_get_threshold_obj, + (mp_obj_t)&touchio_touchin_set_threshold_obj, + (mp_obj_t)&mp_const_none_obj}, +}; STATIC const mp_rom_map_elem_t touchio_touchin_locals_dict_table[] = { diff --git a/shared-bindings/touchio/TouchIn.h b/shared-bindings/touchio/TouchIn.h index 0570afb20d..2e5c516079 100644 --- a/shared-bindings/touchio/TouchIn.h +++ b/shared-bindings/touchio/TouchIn.h @@ -34,6 +34,7 @@ extern const mp_obj_type_t touchio_touchin_type; void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, const mcu_pin_obj_t *pin); void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self); +bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t* self); bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self); uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self); uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self); diff --git a/shared-bindings/util.c b/shared-bindings/util.c new file mode 100644 index 0000000000..3dadc4c189 --- /dev/null +++ b/shared-bindings/util.c @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_UTIL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_UTIL_H + +#include "py/runtime.h" + +#include "shared-bindings/util.h" + +// Check if pin is None. If so, deinit() has already been called on the object, so complain. +void raise_error_if_deinited(bool deinited) { + if (deinited) { + mp_raise_ValueError("Object has been deinitialized and can no longer be used. Create a new object."); + } +} + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_UTIL_H diff --git a/shared-bindings/util.h b/shared-bindings/util.h new file mode 100644 index 0000000000..b26ed7e937 --- /dev/null +++ b/shared-bindings/util.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H + +void raise_error_if_deinited(bool deinited); + + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H diff --git a/shared-module/bitbangio/I2C.c b/shared-module/bitbangio/I2C.c index 0f017fc18d..7eeda0e00e 100644 --- a/shared-module/bitbangio/I2C.c +++ b/shared-module/bitbangio/I2C.c @@ -162,7 +162,15 @@ void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, stop(self); } +bool shared_module_bitbangio_i2c_deinited(bitbangio_i2c_obj_t *self) { + // If one is deinited, both will be. + return common_hal_digitalio_digitalinout_deinited(&self->scl); +} + void shared_module_bitbangio_i2c_deinit(bitbangio_i2c_obj_t *self) { + if (shared_module_bitbangio_i2c_deinited(self)) { + return; + } common_hal_digitalio_digitalinout_deinit(&self->scl); common_hal_digitalio_digitalinout_deinit(&self->sda); } diff --git a/shared-module/bitbangio/OneWire.c b/shared-module/bitbangio/OneWire.c index 46c0c406cc..e77bdb3b29 100644 --- a/shared-module/bitbangio/OneWire.c +++ b/shared-module/bitbangio/OneWire.c @@ -38,7 +38,14 @@ void shared_module_bitbangio_onewire_construct(bitbangio_onewire_obj_t* self, common_hal_digitalio_digitalinout_construct(&self->pin, pin); } +bool shared_module_bitbangio_onewire_deinited(bitbangio_onewire_obj_t* self) { + return common_hal_digitalio_digitalinout_deinited(&self->pin); +} + void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t* self) { + if (shared_module_bitbangio_onewire_deinited(self)) { + return; + } common_hal_digitalio_digitalinout_deinit(&self->pin); } diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c index a3c70dde9a..0576a6e56c 100644 --- a/shared-module/bitbangio/SPI.c +++ b/shared-module/bitbangio/SPI.c @@ -70,7 +70,14 @@ void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, self->phase = 0; } +bool shared_module_bitbangio_spi_deinited(bitbangio_spi_obj_t *self) { + return common_hal_digitalio_digitalinout_deinited(&self->clock); +} + void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self) { + if (shared_module_bitbangio_spi_deinited(self)) { + return; + } common_hal_digitalio_digitalinout_deinit(&self->clock); if (self->has_mosi) { common_hal_digitalio_digitalinout_deinit(&self->mosi); diff --git a/shared-module/busio/I2C.c b/shared-module/busio/I2C.c index f8f154e7ff..68d6ea22ab 100644 --- a/shared-module/busio/I2C.c +++ b/shared-module/busio/I2C.c @@ -34,6 +34,10 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, shared_module_bitbangio_i2c_construct(&self->bitbang, scl, sda, freq); } +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return shared_module_bitbangio_i2c_deinited(&self->bitbang); +} + void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { shared_module_bitbangio_i2c_deinit(&self->bitbang); } diff --git a/shared-module/busio/OneWire.c b/shared-module/busio/OneWire.c index 73d3d29d75..6bb7dedcd1 100644 --- a/shared-module/busio/OneWire.c +++ b/shared-module/busio/OneWire.c @@ -34,7 +34,14 @@ void common_hal_busio_onewire_construct(busio_onewire_obj_t* self, shared_module_bitbangio_onewire_construct(&self->bitbang, pin); } +bool common_hal_busio_onewire_deinited(busio_onewire_obj_t* self) { + return shared_module_bitbangio_onewire_deinited(&self->bitbang); +} + void common_hal_busio_onewire_deinit(busio_onewire_obj_t* self) { + if (common_hal_busio_onewire_deinited(self)) { + return; + } shared_module_bitbangio_onewire_deinit(&self->bitbang); } From f4981677b0b73d286f3af098a4111f8ba6d286bc Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Tue, 3 Oct 2017 22:35:57 +0200 Subject: [PATCH 5/7] Add a `gamepad` module for handling buttons in the background. (#295) The `GamePad` singleton monitors buttons in the background to make sure a button press is never missed and debouncing happens consistently. --- atmel-samd/Makefile | 2 + atmel-samd/mpconfigport.h | 4 + atmel-samd/tick.c | 6 ++ shared-bindings/gamepad/GamePad.c | 146 +++++++++++++++++++++++++++++ shared-bindings/gamepad/GamePad.h | 33 +++++++ shared-bindings/gamepad/__init__.c | 54 +++++++++++ shared-bindings/index.rst | 5 +- shared-module/gamepad/GamePad.c | 46 +++++++++ shared-module/gamepad/GamePad.h | 45 +++++++++ shared-module/gamepad/__init__.c | 51 ++++++++++ shared-module/gamepad/__init__.h | 32 +++++++ 11 files changed, 422 insertions(+), 2 deletions(-) create mode 100644 shared-bindings/gamepad/GamePad.c create mode 100644 shared-bindings/gamepad/GamePad.h create mode 100644 shared-bindings/gamepad/__init__.c create mode 100644 shared-module/gamepad/GamePad.c create mode 100644 shared-module/gamepad/GamePad.h create mode 100644 shared-module/gamepad/__init__.c create mode 100644 shared-module/gamepad/__init__.h diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index daf21568a8..3bbe91ea9a 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -289,6 +289,8 @@ SRC_SHARED_MODULE = \ bitbangio/OneWire.c \ bitbangio/SPI.c \ busio/OneWire.c \ + gamepad/__init__.c \ + gamepad/GamePad.c \ os/__init__.c \ random/__init__.c \ storage/__init__.c \ diff --git a/atmel-samd/mpconfigport.h b/atmel-samd/mpconfigport.h index e99d190be5..fc061d1cb8 100644 --- a/atmel-samd/mpconfigport.h +++ b/atmel-samd/mpconfigport.h @@ -152,6 +152,7 @@ extern const struct _mp_obj_module_t neopixel_write_module; extern const struct _mp_obj_module_t uheap_module; extern const struct _mp_obj_module_t ustack_module; extern const struct _mp_obj_module_t samd_module; +extern const struct _mp_obj_module_t gamepad_module; extern const struct _mp_obj_module_t touchio_module; extern const struct _mp_obj_module_t usb_hid_module; @@ -171,10 +172,13 @@ extern const struct _mp_obj_module_t usb_hid_module; #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_CPYTHON_COMPAT (1) + // Scan gamepad every 32ms + #define CIRCUITPY_GAMEPAD_TICKS 0x1f #define EXTRA_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_audiobusio), (mp_obj_t)&audiobusio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_nvm), (mp_obj_t)&cpy_nvm_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module } diff --git a/atmel-samd/tick.c b/atmel-samd/tick.c index cbe72abc6e..e97da07303 100644 --- a/atmel-samd/tick.c +++ b/atmel-samd/tick.c @@ -1,4 +1,5 @@ #include "autoreload.h" +#include "shared-module/gamepad/__init__.h" #include "tick.h" @@ -17,6 +18,11 @@ static void ms_tick(struct tc_module *const module_inst) { #ifdef CIRCUITPY_AUTORELOAD_DELAY_MS autoreload_tick(); #endif + #ifdef CIRCUITPY_GAMEPAD_TICKS + if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) { + gamepad_tick(); + } + #endif } void tick_init() { diff --git a/shared-bindings/gamepad/GamePad.c b/shared-bindings/gamepad/GamePad.c new file mode 100644 index 0000000000..bdc3359fb6 --- /dev/null +++ b/shared-bindings/gamepad/GamePad.c @@ -0,0 +1,146 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski 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 "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "shared-module/gamepad/GamePad.h" +#include "GamePad.h" + + +gamepad_obj_t* gamepad_singleton = NULL; + +//| .. currentmodule:: gamepad +//| +//| :class:`GamePad` -- Scan buttons for presses +//| ============================================ +//| +//| Usage:: +//| +//| import board +//| import digitalio +//| import gamepad +//| import time +//| +//| B_UP = 1 << 0 +//| B_DOWN = 1 << 1 +//| +//| +//| pad = gamepad.GamePad( +//| digitalio.DigitalInOut(board.D0), +//| digitalio.DigitalInOut(board.D1), +//| ) +//| +//| y = 0 +//| while True: +//| buttons = pad.get_pressed() +//| if buttons & B_UP: +//| y -= 1 +//| print(y) +//| elif buttons & B_DOWN: +//| y += 1 +//| print(y) +//| time.sleep(0.1) +//| while pad.get_pressed(): +//| # Wait for all buttons to be released. +//| time.sleep(0.1) +//| + +//| .. class:: GamePad([b1[, b2[, b3[, b4[, b5[, b6[, b7[, b8]]]]]]]]) +//| +//| Initializes button scanning routines. +//| +//| The ``b1``-``b8`` parameters are ``DigitalInOut`` objects, which +//| immediately get switched to input with a pull-up, and then scanned +//| regularly for button presses. The order is the same as the order of +//| bits returned by the ``get_pressed`` function. You can re-initialize +//| it with different keys, then the new object will replace the previous +//| one. +//| +//| The basic feature required here is the ability to poll the keys at +//| regular intervals (so that de-bouncing is consistent) and fast enough +//| (so that we don't miss short button presses) while at the same time +//| letting the user code run normally, call blocking functions and wait +//| on delays. +//| +//| They button presses are accumulated, until the ``get_pressed`` method +//| is called, at which point the button state is cleared, and the new +//| button presses start to be recorded. +//| +STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args, + size_t n_kw, const mp_obj_t *args) { + if (!gamepad_singleton) { + gamepad_singleton = m_new_obj(gamepad_obj_t); + gamepad_singleton->base.type = &gamepad_type; + } + gamepad_init(n_args, args); + return MP_OBJ_FROM_PTR(gamepad_singleton); +} + + +//| .. method:: get_pressed() +//| +//| Get the status of buttons pressed since the last call and clear it. +//| +//| Returns an 8-bit number, with bits that correspond to buttons, +//| which have been pressed (or held down) since the last call to this +//| function set to 1, and the remaining bits set to 0. Then it clears +//| the button state, so that new button presses (or buttons that are +//| held down) can be recorded for the next call. +//| +STATIC mp_obj_t gamepad_get_pressed(mp_obj_t self_in) { + gamepad_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_t gamepad = MP_OBJ_NEW_SMALL_INT(self->pressed); + self->pressed = 0; + return gamepad; +} +MP_DEFINE_CONST_FUN_OBJ_1(gamepad_get_pressed_obj, gamepad_get_pressed); + + +//| .. method:: deinit() +//| +//| Disable button scanning. +//| +STATIC mp_obj_t gamepad_deinit(mp_obj_t self_in) { + gamepad_singleton = NULL; + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(gamepad_deinit_obj, gamepad_deinit); + + +STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args, + size_t n_kw, const mp_obj_t *args); +STATIC const mp_rom_map_elem_t gamepad_locals_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&gamepad_get_pressed_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gamepad_deinit_obj)}, +}; +STATIC MP_DEFINE_CONST_DICT(gamepad_locals_dict, gamepad_locals_dict_table); +const mp_obj_type_t gamepad_type = { + { &mp_type_type }, + .name = MP_QSTR_GamePad, + .make_new = gamepad_make_new, + .locals_dict = (mp_obj_dict_t*)&gamepad_locals_dict, +}; + diff --git a/shared-bindings/gamepad/GamePad.h b/shared-bindings/gamepad/GamePad.h new file mode 100644 index 0000000000..172c95ace8 --- /dev/null +++ b/shared-bindings/gamepad/GamePad.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski 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. + */ + + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H + +extern const mp_obj_type_t gamepad_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H diff --git a/shared-bindings/gamepad/__init__.c b/shared-bindings/gamepad/__init__.c new file mode 100644 index 0000000000..0c99d0d52b --- /dev/null +++ b/shared-bindings/gamepad/__init__.c @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski 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 "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "GamePad.h" + + +//| :mod:`gamepad` --- Button handling +//| ================================== +//| +//| .. module:: gamepad +//| :synopsis: Button handling +//| :platform: SAMD21 +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| GamePad +//| +STATIC const mp_rom_map_elem_t gamepad_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gamepad) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GamePad), MP_ROM_PTR(&gamepad_type)}, +}; +STATIC MP_DEFINE_CONST_DICT(gamepad_module_globals, + gamepad_module_globals_table); + +const mp_obj_module_t gamepad_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&gamepad_module_globals, +}; diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst index 49b6ce5bc3..556626268b 100644 --- a/shared-bindings/index.rst +++ b/shared-bindings/index.rst @@ -21,9 +21,10 @@ Module / Port SAMD21 SAMD21 Express ESP8266 `board` **Yes** **Yes** **Yes** `busio` **Yes** **Yes** **Yes** `digitalio` **Yes** **Yes** **Yes** -`microcontroller` **Yes** **Yes** **Yes** +`gamepad` No **Yes** No +`microcontroller` **Yes** **Yes** **Yes** `multiterminal` No No **Yes** -`neopixel_write` **Yes** **Yes** **Yes** +`neopixel_write` **Yes** **Yes** **Yes** `nvm` No **Yes** No `os` **Yes** **Yes** **Yes** `pulseio` No **Yes** No diff --git a/shared-module/gamepad/GamePad.c b/shared-module/gamepad/GamePad.c new file mode 100644 index 0000000000..3a2b8a3fe9 --- /dev/null +++ b/shared-module/gamepad/GamePad.c @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski 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 + +#include "__init__.h" +#include "GamePad.h" + +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + + +void gamepad_init(size_t n_pins, const mp_obj_t* pins) { + for (size_t i=0; i<8; ++i) { + gamepad_singleton->pins[i] = NULL; + } + for (size_t i=0; ipins[i] = pin; + common_hal_digitalio_digitalinout_switch_to_input(pin, PULL_UP); + } + gamepad_singleton->last = 0; +} diff --git a/shared-module/gamepad/GamePad.h b/shared-module/gamepad/GamePad.h new file mode 100644 index 0000000000..e5f709134d --- /dev/null +++ b/shared-module/gamepad/GamePad.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski 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. + */ + +#ifndef MICROPY_INCLUDED_GAMEPAD_GAMEPAD_H +#define MICROPY_INCLUDED_GAMEPAD_GAMEPAD_H + +#include + +#include "shared-bindings/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + digitalio_digitalinout_obj_t* pins[8]; + volatile uint8_t last; + volatile uint8_t pressed; +} gamepad_obj_t; + +extern gamepad_obj_t* gamepad_singleton; + +void gamepad_init(size_t n_pins, const mp_obj_t* pins); + +#endif // MICROPY_INCLUDED_GAMEPAD_GAMEPAD_H diff --git a/shared-module/gamepad/__init__.c b/shared-module/gamepad/__init__.c new file mode 100644 index 0000000000..1aebf611d3 --- /dev/null +++ b/shared-module/gamepad/__init__.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski 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 + +#include "__init__.h" +#include "GamePad.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" + + +void gamepad_tick(void) { + if (!gamepad_singleton) { + return; + } + uint8_t gamepad_current = 0; + for (int i=0; i<8; ++i) { + digitalio_digitalinout_obj_t* pin = gamepad_singleton->pins[i]; + if (!pin) { + break; + } + if (!common_hal_digitalio_digitalinout_get_value(pin)) { + gamepad_current |= 1<pressed |= gamepad_singleton->last & gamepad_current; + gamepad_singleton->last = gamepad_current; +} diff --git a/shared-module/gamepad/__init__.h b/shared-module/gamepad/__init__.h new file mode 100644 index 0000000000..eacd723669 --- /dev/null +++ b/shared-module/gamepad/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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. + */ + +#ifndef MICROPY_INCLUDED_GAMEPAD_H +#define MICROPY_INCLUDED_GAMEPAD_H + +void gamepad_tick(void); + +#endif // MICROPY_INCLUDED_GAMEPAD_H From ef65ee78c544f0996eeb77ae762d2c4c7ed17057 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 3 Oct 2017 18:10:13 -0400 Subject: [PATCH 6/7] Freeze libraries needed by adafruit_circuitplayground library into firmware. This saves a lot of RAM. Fixes #287. Also fixed compilation of frozen_mpy.c to use supplied make rule rather than builtin rule (supplied rule suppresses printing out the gcc command line). --- .gitmodules | 9 +++++++++ .../boards/circuitplayground_express/mpconfigboard.mk | 3 +++ frozen/Adafruit_CircuitPython_BusDevice | 1 + frozen/Adafruit_CircuitPython_LIS3DH | 1 + frozen/Adafruit_CircuitPython_Thermistor | 1 + py/mkrules.mk | 6 ++++++ 6 files changed, 21 insertions(+) create mode 160000 frozen/Adafruit_CircuitPython_BusDevice create mode 160000 frozen/Adafruit_CircuitPython_LIS3DH create mode 160000 frozen/Adafruit_CircuitPython_Thermistor diff --git a/.gitmodules b/.gitmodules index 54c4d5a9cc..faad88a857 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,3 +20,12 @@ [submodule "atmel-samd/frozen/Adafruit_CircuitPython_NeoPixel"] path = frozen/Adafruit_CircuitPython_NeoPixel url = https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel +[submodule "frozen/Adafruit_CircuitPython_Thermistor"] + path = frozen/Adafruit_CircuitPython_Thermistor + url = https://github.com/adafruit/Adafruit_CircuitPython_Thermistor.git +[submodule "frozen/Adafruit_CircuitPython_LIS3DH"] + path = frozen/Adafruit_CircuitPython_LIS3DH + url = https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH.git +[submodule "frozen/Adafruit_CircuitPython_BusDevice"] + path = frozen/Adafruit_CircuitPython_BusDevice + url = https://github.com/adafruit/Adafruit_CircuitPython_BusDevice.git diff --git a/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk index d773f2f600..e8195c90da 100644 --- a/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk +++ b/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk @@ -7,4 +7,7 @@ FLASH_IMPL = spi_flash.c CHIP_VARIANT = SAMD21G18A # Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice new file mode 160000 index 0000000000..39f28ed4e0 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -0,0 +1 @@ +Subproject commit 39f28ed4e0e5a06fc33fd01c1efc8c52c4140f03 diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH new file mode 160000 index 0000000000..fa00b61d1b --- /dev/null +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -0,0 +1 @@ +Subproject commit fa00b61d1bde90c3cf9cce74388cb9717058b2be diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor new file mode 160000 index 0000000000..2d57c0ba9a --- /dev/null +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -0,0 +1 @@ +Subproject commit 2d57c0ba9a09d6d30f0ae2b98aba9567c25e6fb6 diff --git a/py/mkrules.mk b/py/mkrules.mk index 9ed5483b28..656ffd03cb 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -46,6 +46,12 @@ vpath %.c . $(TOP) $(BUILD)/%.o: %.c $(call compile_c) +# frozen.c and frozen_mpy.c are created in $(BUILD), so use our rule +# for those as well. +vpath %.c . $(BUILD) +$(BUILD)/%.o: %.c + $(call compile_c) + # List all native flags since the current build system doesn't have # the MicroPython configuration available. However, these flags are # needed to extract all qstrings From 922006dd59323e6019e8fbfe1938e0c30121999c Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 12 Oct 2017 14:35:39 -0400 Subject: [PATCH 7/7] Don't create a new filesystem if we restart in safe mode. (#319) --- atmel-samd/main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/atmel-samd/main.c b/atmel-samd/main.c index 3a2d5a63c2..36d5dde273 100644 --- a/atmel-samd/main.c +++ b/atmel-samd/main.c @@ -107,7 +107,7 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) { // 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 init_flash_fs(void) { +void init_flash_fs(bool create_allowed) { // init the vfs object fs_user_mount_t *vfs_fat = &fs_user_mount_flash; vfs_fat->flags = 0; @@ -116,7 +116,7 @@ void init_flash_fs(void) { // try to mount the flash FRESULT res = f_mount(&vfs_fat->fatfs); - if (res == FR_NO_FILESYSTEM) { + if (res == FR_NO_FILESYSTEM && create_allowed) { // no filesystem so create a fresh one uint8_t working_buf[_MAX_SS]; @@ -653,7 +653,10 @@ int main(void) { mp_stack_fill_with_sentinel(); #endif - init_flash_fs(); + // Create a new filesystem only if we're not in a safe mode. + // A power brownout here could make it appear as if there's + // no SPI flash filesystem, and we might erase the existing one. + init_flash_fs(safe_mode == NO_SAFE_MODE); // Reset everything and prep MicroPython to run boot.py. reset_samd21();