Merge branch 'master' into nrf52840_usbboot
This commit is contained in:
commit
6d2702ed98
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -67,3 +67,6 @@
|
|||||||
[submodule "frozen/Adafruit_CircuitPython_DotStar"]
|
[submodule "frozen/Adafruit_CircuitPython_DotStar"]
|
||||||
path = frozen/Adafruit_CircuitPython_DotStar
|
path = frozen/Adafruit_CircuitPython_DotStar
|
||||||
url = https://github.com/adafruit/Adafruit_CircuitPython_DotStar.git
|
url = https://github.com/adafruit/Adafruit_CircuitPython_DotStar.git
|
||||||
|
[submodule "ports/atmel-samd/peripherals"]
|
||||||
|
path = ports/atmel-samd/peripherals
|
||||||
|
url = https://github.com/adafruit/samd-peripherals.git
|
||||||
|
@ -22,7 +22,8 @@ env:
|
|||||||
- TRAVIS_BOARD=pirkey_m0
|
- TRAVIS_BOARD=pirkey_m0
|
||||||
- TRAVIS_BOARD=trinket_m0
|
- TRAVIS_BOARD=trinket_m0
|
||||||
- TRAVIS_BOARD=gemma_m0
|
- TRAVIS_BOARD=gemma_m0
|
||||||
- TRAVIS_BOARD=feather52
|
- TRAVIS_BOARD=feather52832
|
||||||
|
- TRAVIS_BOARD=pca10056
|
||||||
- TRAVIS_TEST=qemu
|
- TRAVIS_TEST=qemu
|
||||||
- TRAVIS_TEST=unix
|
- TRAVIS_TEST=unix
|
||||||
- TRAVIS_TEST=docs
|
- TRAVIS_TEST=docs
|
||||||
@ -57,7 +58,7 @@ before_script:
|
|||||||
# For teensy build
|
# For teensy build
|
||||||
- sudo apt-get install realpath
|
- sudo apt-get install realpath
|
||||||
# For nrf builds
|
# For nrf builds
|
||||||
- ([[ $TRAVIS_BOARD != "feather52" ]] || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh)
|
- ([[ $TRAVIS_BOARD != "feather52832" && $TRAVIS_BOARD != "pca10056" ]] || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh)
|
||||||
# For huzzah builds
|
# For huzzah builds
|
||||||
- if [[ $TRAVIS_BOARD = "feather_huzzah" ]]; then wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar xavf xtensa-lx106-elf-standalone.tar.gz; PATH=$(readlink -f xtensa-lx106-elf/bin):$PATH; fi
|
- if [[ $TRAVIS_BOARD = "feather_huzzah" ]]; then wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar xavf xtensa-lx106-elf-standalone.tar.gz; PATH=$(readlink -f xtensa-lx106-elf/bin):$PATH; fi
|
||||||
# For coverage testing (upgrade is used to get latest urllib3 version)
|
# For coverage testing (upgrade is used to get latest urllib3 version)
|
||||||
|
@ -55,6 +55,7 @@ INC += -I. \
|
|||||||
-Iasf4_conf/$(CHIP_FAMILY) \
|
-Iasf4_conf/$(CHIP_FAMILY) \
|
||||||
-Iboards/$(BOARD) \
|
-Iboards/$(BOARD) \
|
||||||
-Iboards/ \
|
-Iboards/ \
|
||||||
|
-Iperipherals/ \
|
||||||
-Ifreetouch \
|
-Ifreetouch \
|
||||||
-I$(BUILD)
|
-I$(BUILD)
|
||||||
|
|
||||||
@ -248,21 +249,21 @@ SRC_C = \
|
|||||||
flash_api.c \
|
flash_api.c \
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
reset.c \
|
reset.c \
|
||||||
peripherals/clocks.c \
|
peripherals/samd/clocks.c \
|
||||||
peripherals/dma.c \
|
peripherals/samd/dma.c \
|
||||||
peripherals/events.c \
|
peripherals/samd/events.c \
|
||||||
peripherals/external_interrupts.c \
|
peripherals/samd/external_interrupts.c \
|
||||||
peripherals/sercom.c \
|
peripherals/samd/sercom.c \
|
||||||
peripherals/timers.c \
|
peripherals/samd/timers.c \
|
||||||
peripherals/$(CHIP_FAMILY)/adc.c \
|
peripherals/samd/$(CHIP_FAMILY)/adc.c \
|
||||||
peripherals/$(CHIP_FAMILY)/cache.c \
|
peripherals/samd/$(CHIP_FAMILY)/cache.c \
|
||||||
peripherals/$(CHIP_FAMILY)/clocks.c \
|
peripherals/samd/$(CHIP_FAMILY)/clocks.c \
|
||||||
peripherals/$(CHIP_FAMILY)/dma.c \
|
peripherals/samd/$(CHIP_FAMILY)/dma.c \
|
||||||
peripherals/$(CHIP_FAMILY)/events.c \
|
peripherals/samd/$(CHIP_FAMILY)/events.c \
|
||||||
peripherals/$(CHIP_FAMILY)/external_interrupts.c \
|
peripherals/samd/$(CHIP_FAMILY)/external_interrupts.c \
|
||||||
peripherals/$(CHIP_FAMILY)/pins.c \
|
peripherals/samd/$(CHIP_FAMILY)/pins.c \
|
||||||
peripherals/$(CHIP_FAMILY)/sercom.c \
|
peripherals/samd/$(CHIP_FAMILY)/sercom.c \
|
||||||
peripherals/$(CHIP_FAMILY)/timers.c \
|
peripherals/samd/$(CHIP_FAMILY)/timers.c \
|
||||||
tick.c \
|
tick.c \
|
||||||
usb.c \
|
usb.c \
|
||||||
usb_mass_storage.c \
|
usb_mass_storage.c \
|
||||||
@ -402,7 +403,7 @@ ifneq ($(CHIP_VARIANT),SAMD51G18A)
|
|||||||
audiobusio/__init__.c \
|
audiobusio/__init__.c \
|
||||||
audiobusio/I2SOut.c \
|
audiobusio/I2SOut.c \
|
||||||
audiobusio/PDMIn.c
|
audiobusio/PDMIn.c
|
||||||
SRC_C += peripherals/i2s.c peripherals/$(CHIP_FAMILY)/i2s.c
|
SRC_C += peripherals/samd/i2s.c peripherals/samd/$(CHIP_FAMILY)/i2s.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "audio_dma.h"
|
#include "audio_dma.h"
|
||||||
#include "peripherals/clocks.h"
|
#include "samd/clocks.h"
|
||||||
#include "peripherals/events.h"
|
#include "samd/events.h"
|
||||||
#include "peripherals/dma.h"
|
#include "samd/dma.h"
|
||||||
|
|
||||||
#include "shared-bindings/audioio/RawSample.h"
|
#include "shared-bindings/audioio/RawSample.h"
|
||||||
#include "shared-bindings/audioio/WaveFile.h"
|
#include "shared-bindings/audioio/WaveFile.h"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bindings/samd/Clock.h"
|
#include "bindings/samd/Clock.h"
|
||||||
#include "peripherals/clocks.h"
|
#include "samd/clocks.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/objproperty.h"
|
#include "py/objproperty.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "shared-bindings/microcontroller/Pin.h"
|
#include "shared-bindings/microcontroller/Pin.h"
|
||||||
#include "mpconfigboard.h"
|
#include "mpconfigboard.h"
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
|
||||||
#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)
|
#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "py/binary.h"
|
#include "py/binary.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
|
||||||
#include "peripherals/adc.h"
|
#include "samd/adc.h"
|
||||||
#include "shared-bindings/analogio/AnalogIn.h"
|
#include "shared-bindings/analogio/AnalogIn.h"
|
||||||
|
|
||||||
#include "atmel_start_pins.h"
|
#include "atmel_start_pins.h"
|
||||||
|
@ -45,12 +45,12 @@
|
|||||||
#include "hpl/pm/hpl_pm_base.h"
|
#include "hpl/pm/hpl_pm_base.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
#include "samd/clocks.h"
|
||||||
#include "peripherals/dma.h"
|
#include "samd/dma.h"
|
||||||
#include "peripherals/events.h"
|
#include "samd/events.h"
|
||||||
#include "peripherals/i2s.h"
|
#include "samd/i2s.h"
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
#include "peripherals/timers.h"
|
#include "samd/timers.h"
|
||||||
|
|
||||||
#include "audio_dma.h"
|
#include "audio_dma.h"
|
||||||
|
|
||||||
|
@ -41,11 +41,11 @@
|
|||||||
#include "hal/include/hal_gpio.h"
|
#include "hal/include/hal_gpio.h"
|
||||||
#include "hal/utils/include/utils.h"
|
#include "hal/utils/include/utils.h"
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
#include "samd/clocks.h"
|
||||||
#include "peripherals/events.h"
|
#include "samd/events.h"
|
||||||
#include "peripherals/i2s.h"
|
#include "samd/i2s.h"
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
#include "peripherals/dma.h"
|
#include "samd/dma.h"
|
||||||
|
|
||||||
#include "audio_dma.h"
|
#include "audio_dma.h"
|
||||||
#include "tick.h"
|
#include "tick.h"
|
||||||
|
@ -46,10 +46,10 @@
|
|||||||
|
|
||||||
#include "audio_dma.h"
|
#include "audio_dma.h"
|
||||||
|
|
||||||
#include "peripherals/dma.h"
|
#include "samd/dma.h"
|
||||||
#include "peripherals/events.h"
|
#include "samd/events.h"
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
#include "peripherals/timers.h"
|
#include "samd/timers.h"
|
||||||
|
|
||||||
void audioout_reset(void) {
|
void audioout_reset(void) {
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#include "hal/include/hal_i2c_m_sync.h"
|
#include "hal/include/hal_i2c_m_sync.h"
|
||||||
#include "hal/include/hpl_i2c_m_sync.h"
|
#include "hal/include/hpl_i2c_m_sync.h"
|
||||||
|
|
||||||
#include "peripherals/sercom.h"
|
#include "samd/sercom.h"
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
#include "hal/include/hpl_spi_m_sync.h"
|
#include "hal/include/hpl_spi_m_sync.h"
|
||||||
#include "supervisor/shared/rgb_led_status.h"
|
#include "supervisor/shared/rgb_led_status.h"
|
||||||
|
|
||||||
#include "peripherals/dma.h"
|
#include "samd/dma.h"
|
||||||
#include "peripherals/sercom.h"
|
#include "samd/sercom.h"
|
||||||
|
|
||||||
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||||
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
|
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#include "hal/include/hal_usart_async.h"
|
#include "hal/include/hal_usart_async.h"
|
||||||
#include "hal/include/hpl_usart_async.h"
|
#include "hal/include/hpl_usart_async.h"
|
||||||
|
|
||||||
#include "peripherals/sercom.h"
|
#include "samd/sercom.h"
|
||||||
|
|
||||||
// Do-nothing callback needed so that usart_async code will enable rx interrupts.
|
// Do-nothing callback needed so that usart_async code will enable rx interrupts.
|
||||||
// See comment below re usart_async_register_callback()
|
// See comment below re usart_async_register_callback()
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "atmel_start_pins.h"
|
#include "atmel_start_pins.h"
|
||||||
#include "hal/include/hal_gpio.h"
|
#include "hal/include/hal_gpio.h"
|
||||||
|
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
#include "supervisor/shared/rgb_led_status.h"
|
#include "supervisor/shared/rgb_led_status.h"
|
||||||
|
|
||||||
#ifdef MICROPY_HW_NEOPIXEL
|
#ifdef MICROPY_HW_NEOPIXEL
|
||||||
|
@ -81,6 +81,6 @@ void reset_all_pins(void);
|
|||||||
void reset_pin(uint8_t pin);
|
void reset_pin(uint8_t pin);
|
||||||
void claim_pin(const mcu_pin_obj_t* pin);
|
void claim_pin(const mcu_pin_obj_t* pin);
|
||||||
|
|
||||||
#include "peripherals/pins.h"
|
#include "peripherals/samd/pins.h"
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H
|
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
#include "common-hal/microcontroller/Processor.h"
|
#include "common-hal/microcontroller/Processor.h"
|
||||||
|
|
||||||
#include "peripherals/adc.h"
|
#include "samd/adc.h"
|
||||||
|
|
||||||
#include "peripheral_clk_config.h"
|
#include "peripheral_clk_config.h"
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@
|
|||||||
|
|
||||||
#include "atmel_start_pins.h"
|
#include "atmel_start_pins.h"
|
||||||
#include "hal/utils/include/utils_repeat_macro.h"
|
#include "hal/utils/include/utils_repeat_macro.h"
|
||||||
#include "peripherals/timers.h"
|
#include "samd/timers.h"
|
||||||
|
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
|
|
||||||
#undef ENABLE
|
#undef ENABLE
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@
|
|||||||
#include "mpconfigport.h"
|
#include "mpconfigport.h"
|
||||||
#include "py/gc.h"
|
#include "py/gc.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "peripherals/external_interrupts.h"
|
#include "samd/external_interrupts.h"
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
#include "shared-bindings/pulseio/PulseIn.h"
|
#include "shared-bindings/pulseio/PulseIn.h"
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#include "hal/include/hal_gpio.h"
|
#include "hal/include/hal_gpio.h"
|
||||||
|
|
||||||
#include "mpconfigport.h"
|
#include "mpconfigport.h"
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
#include "peripherals/timers.h"
|
#include "samd/timers.h"
|
||||||
#include "py/gc.h"
|
#include "py/gc.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "shared-bindings/pulseio/PulseOut.h"
|
#include "shared-bindings/pulseio/PulseOut.h"
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include "atmel_start_pins.h"
|
#include "atmel_start_pins.h"
|
||||||
|
|
||||||
#include "peripherals/external_interrupts.h"
|
#include "samd/external_interrupts.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
|
||||||
void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self,
|
void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self,
|
||||||
|
@ -37,8 +37,8 @@
|
|||||||
#include "hpl/pm/hpl_pm_base.h"
|
#include "hpl/pm/hpl_pm_base.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
#include "samd/clocks.h"
|
||||||
#include "peripherals/pins.h"
|
#include "samd/pins.h"
|
||||||
|
|
||||||
#include "tick.h"
|
#include "tick.h"
|
||||||
#include "adafruit_ptc.h"
|
#include "adafruit_ptc.h"
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL
|
#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL
|
||||||
|
|
||||||
#include "external_flash/common_commands.h"
|
#include "external_flash/common_commands.h"
|
||||||
#include "peripherals/cache.h"
|
#include "samd/cache.h"
|
||||||
#include "peripherals/dma.h"
|
#include "samd/dma.h"
|
||||||
|
|
||||||
#include "atmel_start_pins.h"
|
#include "atmel_start_pins.h"
|
||||||
#include "hal_gpio.h"
|
#include "hal_gpio.h"
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "external_flash/common_commands.h"
|
#include "external_flash/common_commands.h"
|
||||||
#include "peripherals/sercom.h"
|
#include "samd/sercom.h"
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
|
|
||||||
#include "hal_gpio.h"
|
#include "hal_gpio.h"
|
||||||
|
@ -318,7 +318,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
|
|||||||
|
|
||||||
#define MP_STATE_PORT MP_STATE_VM
|
#define MP_STATE_PORT MP_STATE_VM
|
||||||
|
|
||||||
#include "peripherals/dma.h"
|
#include "peripherals/samd/dma.h"
|
||||||
|
|
||||||
#define MICROPY_PORT_ROOT_POINTERS \
|
#define MICROPY_PORT_ROOT_POINTERS \
|
||||||
const char *readline_hist[8]; \
|
const char *readline_hist[8]; \
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017 by 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_PERIPHERALS_ADC_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H
|
|
||||||
|
|
||||||
#include "include/sam.h"
|
|
||||||
#include "hal/include/hal_adc_sync.h"
|
|
||||||
|
|
||||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H
|
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017 by 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_SAMD51_PERIPHERALS_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H
|
|
||||||
|
|
||||||
void samd_peripherals_disable_and_clear_cache(void);
|
|
||||||
void samd_peripherals_enable_cache(void);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H
|
|
@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "clocks.h"
|
|
||||||
|
|
||||||
#include "hpl_gclk_config.h"
|
|
||||||
|
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
|
|
||||||
// TODO(tannewt): Should we have a way of sharing GCLKs based on their speed? Divisor doesn't
|
|
||||||
// gaurantee speed because it depends on the source.
|
|
||||||
uint8_t find_free_gclk(uint16_t divisor) {
|
|
||||||
if (divisor > 0xff) {
|
|
||||||
if (gclk_enabled(1)) {
|
|
||||||
return 0xff;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
uint8_t first_8_bit = 2;
|
|
||||||
#ifdef SAMD21
|
|
||||||
first_8_bit = 3;
|
|
||||||
if (divisor <= (1 << 5) && !gclk_enabled(2)) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
for (uint8_t i = first_8_bit; i < GCLK_GEN_NUM; i++) {
|
|
||||||
if (!gclk_enabled(i)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t last_static_clock = 0;
|
|
||||||
|
|
||||||
void init_dynamic_clocks(void) {
|
|
||||||
// Find the last statically initialized clock and save it. Everything after will be reset with
|
|
||||||
// the VM via reset_gclks.
|
|
||||||
for (uint8_t i = 0; i < GCLK_GEN_NUM; i++) {
|
|
||||||
if (gclk_enabled(i)) {
|
|
||||||
last_static_clock = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_gclks(void) {
|
|
||||||
for (uint8_t i = last_static_clock + 1; i < GCLK_GEN_NUM; i++) {
|
|
||||||
disable_gclk(i);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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_CLOCKS_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_CLOCKS_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "include/sam.h"
|
|
||||||
#include "mpconfigboard.h" // for BOARD_HAS_CRYSTAL
|
|
||||||
|
|
||||||
#ifdef SAMD51
|
|
||||||
#define CLOCK_48MHZ GCLK_GENCTRL_SRC_DFLL_Val
|
|
||||||
#endif
|
|
||||||
#ifdef SAMD21
|
|
||||||
#define CLOCK_48MHZ GCLK_GENCTRL_SRC_DFLL48M_Val
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CORE_GCLK 0
|
|
||||||
|
|
||||||
uint8_t find_free_gclk(uint16_t divisor);
|
|
||||||
|
|
||||||
bool gclk_enabled(uint8_t gclk);
|
|
||||||
void disable_gclk(uint8_t gclk);
|
|
||||||
void reset_gclks(void);
|
|
||||||
|
|
||||||
void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral);
|
|
||||||
void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral);
|
|
||||||
|
|
||||||
void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor);
|
|
||||||
void disable_clock_generator(uint8_t gclk);
|
|
||||||
|
|
||||||
static inline bool board_has_crystal(void) {
|
|
||||||
#ifdef BOARD_HAS_CRYSTAL
|
|
||||||
return BOARD_HAS_CRYSTAL == 1;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void clock_init(void);
|
|
||||||
void init_dynamic_clocks(void);
|
|
||||||
|
|
||||||
bool clock_get_enabled(uint8_t type, uint8_t index);
|
|
||||||
bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index);
|
|
||||||
uint32_t clock_get_frequency(uint8_t type, uint8_t index);
|
|
||||||
uint32_t clock_get_calibration(uint8_t type, uint8_t index);
|
|
||||||
int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val);
|
|
||||||
void save_usb_clock_calibration(void);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_CLOCKS_H
|
|
@ -1,244 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "peripherals/dma.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "py/gc.h"
|
|
||||||
#include "py/mpstate.h"
|
|
||||||
|
|
||||||
#include "hal/utils/include/utils.h"
|
|
||||||
|
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
|
||||||
|
|
||||||
COMPILER_ALIGNED(16) static DmacDescriptor dma_descriptors[DMA_CHANNEL_COUNT];
|
|
||||||
|
|
||||||
// Don't use these directly. They are used by the DMA engine itself.
|
|
||||||
COMPILER_ALIGNED(16) static DmacDescriptor write_back_descriptors[DMA_CHANNEL_COUNT];
|
|
||||||
|
|
||||||
#ifdef SAMD21
|
|
||||||
#define FIRST_SERCOM_RX_TRIGSRC 0x01
|
|
||||||
#define FIRST_SERCOM_TX_TRIGSRC 0x02
|
|
||||||
#endif
|
|
||||||
#ifdef SAMD51
|
|
||||||
#define FIRST_SERCOM_RX_TRIGSRC 0x04
|
|
||||||
#define FIRST_SERCOM_TX_TRIGSRC 0x05
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void init_shared_dma(void) {
|
|
||||||
// Turn on the clocks
|
|
||||||
#ifdef SAMD51
|
|
||||||
MCLK->AHBMASK.reg |= MCLK_AHBMASK_DMAC;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SAMD21
|
|
||||||
PM->AHBMASK.reg |= PM_AHBMASK_DMAC;
|
|
||||||
PM->APBBMASK.reg |= PM_APBBMASK_DMAC;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DMAC->CTRL.reg = DMAC_CTRL_SWRST;
|
|
||||||
|
|
||||||
DMAC->BASEADDR.reg = (uint32_t) dma_descriptors;
|
|
||||||
DMAC->WRBADDR.reg = (uint32_t) write_back_descriptors;
|
|
||||||
|
|
||||||
DMAC->CTRL.reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN0;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) {
|
|
||||||
dma_configure(i, 0, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do write and read simultaneously. If buffer_out is NULL, write the tx byte over and over.
|
|
||||||
// If buffer_out is a real buffer, ignore tx.
|
|
||||||
// DMAs buffer_out -> dest
|
|
||||||
// DMAs src -> buffer_in
|
|
||||||
static int32_t shared_dma_transfer(void* peripheral,
|
|
||||||
const uint8_t* buffer_out, volatile uint32_t* dest,
|
|
||||||
volatile uint32_t* src, uint8_t* buffer_in,
|
|
||||||
uint32_t length, uint8_t tx) {
|
|
||||||
if (!dma_channel_free(SHARED_TX_CHANNEL) ||
|
|
||||||
(buffer_in != NULL && !dma_channel_free(SHARED_RX_CHANNEL))) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t beat_size = DMAC_BTCTRL_BEATSIZE_BYTE;
|
|
||||||
bool sercom = true;
|
|
||||||
bool tx_active = false;
|
|
||||||
bool rx_active = false;
|
|
||||||
uint16_t beat_length = length;
|
|
||||||
#ifdef SAMD51
|
|
||||||
if (peripheral == QSPI) {
|
|
||||||
// Check input alignment on word boundaries.
|
|
||||||
if ((((uint32_t) buffer_in) & 0x3) != 0 ||
|
|
||||||
(((uint32_t) buffer_out) & 0x3) != 0) {
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
beat_size = DMAC_BTCTRL_BEATSIZE_WORD | DMAC_BTCTRL_SRCINC | DMAC_BTCTRL_DSTINC;
|
|
||||||
beat_length /= 4;
|
|
||||||
sercom = false;
|
|
||||||
if (buffer_out != NULL) {
|
|
||||||
dma_configure(SHARED_TX_CHANNEL, QSPI_DMAC_ID_TX, false);
|
|
||||||
tx_active = true;
|
|
||||||
} else {
|
|
||||||
dma_configure(SHARED_RX_CHANNEL, QSPI_DMAC_ID_RX, false);
|
|
||||||
rx_active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// sercom index is incorrect for SAMD51
|
|
||||||
dma_configure(SHARED_TX_CHANNEL, sercom_index(peripheral) * 2 + FIRST_SERCOM_TX_TRIGSRC, false);
|
|
||||||
tx_active = true;
|
|
||||||
if (buffer_in != NULL) {
|
|
||||||
dma_configure(SHARED_RX_CHANNEL, sercom_index(peripheral) * 2 + FIRST_SERCOM_RX_TRIGSRC, false);
|
|
||||||
rx_active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SAMD51
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set up RX first.
|
|
||||||
if (rx_active) {
|
|
||||||
DmacDescriptor* rx_descriptor = &dma_descriptors[SHARED_RX_CHANNEL];
|
|
||||||
rx_descriptor->BTCTRL.reg = beat_size | DMAC_BTCTRL_DSTINC;
|
|
||||||
rx_descriptor->BTCNT.reg = beat_length;
|
|
||||||
rx_descriptor->SRCADDR.reg = ((uint32_t) src);
|
|
||||||
#ifdef SAMD51
|
|
||||||
if (peripheral == QSPI) {
|
|
||||||
rx_descriptor->SRCADDR.reg = ((uint32_t) src + length);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
rx_descriptor->DSTADDR.reg = ((uint32_t)buffer_in + length);
|
|
||||||
rx_descriptor->BTCTRL.bit.VALID = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up TX second.
|
|
||||||
if (tx_active) {
|
|
||||||
DmacDescriptor* tx_descriptor = &dma_descriptors[SHARED_TX_CHANNEL];
|
|
||||||
tx_descriptor->BTCTRL.reg = beat_size;
|
|
||||||
tx_descriptor->BTCNT.reg = beat_length;
|
|
||||||
|
|
||||||
if (buffer_out != NULL) {
|
|
||||||
tx_descriptor->SRCADDR.reg = ((uint32_t)buffer_out + length);
|
|
||||||
tx_descriptor->BTCTRL.reg |= DMAC_BTCTRL_SRCINC;
|
|
||||||
} else {
|
|
||||||
tx_descriptor->SRCADDR.reg = ((uint32_t) &tx);
|
|
||||||
}
|
|
||||||
tx_descriptor->DSTADDR.reg = ((uint32_t) dest);
|
|
||||||
tx_descriptor->BTCTRL.bit.VALID = true;
|
|
||||||
}
|
|
||||||
if (sercom) {
|
|
||||||
SercomSpi *s = &((Sercom*) peripheral)->SPI;
|
|
||||||
s->INTFLAG.reg = SERCOM_SPI_INTFLAG_RXC | SERCOM_SPI_INTFLAG_DRE;
|
|
||||||
} else {
|
|
||||||
//QSPI->INTFLAG.reg = QSPI_INTFLAG_RXC | QSPI_INTFLAG_DRE;
|
|
||||||
}
|
|
||||||
// Start the RX job first so we don't miss the first byte. The TX job clocks
|
|
||||||
// the output.
|
|
||||||
if (rx_active) {
|
|
||||||
dma_enable_channel(SHARED_RX_CHANNEL);
|
|
||||||
}
|
|
||||||
if (tx_active) {
|
|
||||||
dma_enable_channel(SHARED_TX_CHANNEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (sercom) {
|
|
||||||
//DMAC->SWTRIGCTRL.reg |= (1 << SHARED_TX_CHANNEL);
|
|
||||||
} else {
|
|
||||||
// Do a manual copy to trigger then DMA. We do 32-bit accesses to match the DMA.
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
|
||||||
if (rx_active) {
|
|
||||||
//buffer_in[0] = *src;
|
|
||||||
DMAC->SWTRIGCTRL.reg |= (1 << SHARED_RX_CHANNEL);
|
|
||||||
} else {
|
|
||||||
//*(uint32_t*)dest = ((uint32_t*) buffer_out)[0];
|
|
||||||
}
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channels cycle between Suspend -> Pending -> Busy and back while transfering. So, we check
|
|
||||||
// the channels transfer status for an error or completion.
|
|
||||||
if (rx_active) {
|
|
||||||
while ((dma_transfer_status(SHARED_RX_CHANNEL) & 0x3) == 0) {}
|
|
||||||
}
|
|
||||||
if (tx_active) {
|
|
||||||
while ((dma_transfer_status(SHARED_TX_CHANNEL) & 0x3) == 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sercom) {
|
|
||||||
Sercom* s = (Sercom*) peripheral;
|
|
||||||
// Wait for the SPI transfer to complete.
|
|
||||||
while (s->SPI.INTFLAG.bit.TXC == 0) {}
|
|
||||||
|
|
||||||
// This transmit will cause the RX buffer overflow but we're OK with that.
|
|
||||||
// So, read the garbage and clear the overflow flag.
|
|
||||||
if (!rx_active) {
|
|
||||||
while (s->SPI.INTFLAG.bit.RXC == 1) {
|
|
||||||
s->SPI.DATA.reg;
|
|
||||||
}
|
|
||||||
s->SPI.STATUS.bit.BUFOVF = 1;
|
|
||||||
s->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!rx_active || dma_transfer_status(SHARED_RX_CHANNEL) == DMAC_CHINTFLAG_TCMPL) &&
|
|
||||||
(!tx_active || dma_transfer_status(SHARED_TX_CHANNEL) == DMAC_CHINTFLAG_TCMPL)) {
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int32_t sercom_dma_transfer(Sercom* sercom, const uint8_t* buffer_out, uint8_t* buffer_in,
|
|
||||||
uint32_t length) {
|
|
||||||
return shared_dma_transfer(sercom, buffer_out, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, buffer_in, length, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t sercom_dma_write(Sercom* sercom, const uint8_t* buffer, uint32_t length) {
|
|
||||||
return shared_dma_transfer(sercom, buffer, &sercom->SPI.DATA.reg, NULL, NULL, length, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t sercom_dma_read(Sercom* sercom, uint8_t* buffer, uint32_t length, uint8_t tx) {
|
|
||||||
return shared_dma_transfer(sercom, NULL, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, buffer, length, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SAMD51
|
|
||||||
int32_t qspi_dma_write(uint32_t address, const uint8_t* buffer, uint32_t length) {
|
|
||||||
return shared_dma_transfer(QSPI, buffer, (uint32_t*) (QSPI_AHB + address), NULL, NULL, length, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t qspi_dma_read(uint32_t address, uint8_t* buffer, uint32_t length) {
|
|
||||||
return shared_dma_transfer(QSPI, NULL, NULL, (uint32_t*) (QSPI_AHB + address), buffer, length, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DmacDescriptor* dma_descriptor(uint8_t channel_number) {
|
|
||||||
return &dma_descriptors[channel_number];
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_PERIPHERALS_DMA_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "include/sam.h"
|
|
||||||
|
|
||||||
// We allocate DMA resources for the entire lifecycle of the board (not the
|
|
||||||
// vm) because the general_dma resource will be shared between the REPL and SPI
|
|
||||||
// flash. Both uses must block each other in order to prevent conflict.
|
|
||||||
#define AUDIO_DMA_CHANNEL_COUNT 3
|
|
||||||
#define DMA_CHANNEL_COUNT (AUDIO_DMA_CHANNEL_COUNT + 2)
|
|
||||||
#define SHARED_TX_CHANNEL (DMA_CHANNEL_COUNT - 2)
|
|
||||||
#define SHARED_RX_CHANNEL (DMA_CHANNEL_COUNT - 1)
|
|
||||||
|
|
||||||
volatile bool audio_dma_in_use;
|
|
||||||
|
|
||||||
void init_shared_dma(void);
|
|
||||||
|
|
||||||
#ifdef SAMD51
|
|
||||||
int32_t qspi_dma_write(uint32_t address, const uint8_t* buffer, uint32_t length);
|
|
||||||
int32_t qspi_dma_read(uint32_t address, uint8_t* buffer, uint32_t length);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t sercom_index(Sercom* sercom);
|
|
||||||
|
|
||||||
int32_t sercom_dma_write(Sercom* sercom, const uint8_t* buffer, uint32_t length);
|
|
||||||
int32_t sercom_dma_read(Sercom* sercom, uint8_t* buffer, uint32_t length, uint8_t tx);
|
|
||||||
int32_t sercom_dma_transfer(Sercom* sercom, const uint8_t* buffer_out, uint8_t* buffer_in, uint32_t length);
|
|
||||||
|
|
||||||
void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event);
|
|
||||||
void dma_enable_channel(uint8_t channel_number);
|
|
||||||
void dma_disable_channel(uint8_t channel_number);
|
|
||||||
void dma_suspend_channel(uint8_t channel_number);
|
|
||||||
void dma_resume_channel(uint8_t channel_number);
|
|
||||||
bool dma_channel_free(uint8_t channel_number);
|
|
||||||
bool dma_channel_enabled(uint8_t channel_number);
|
|
||||||
uint8_t dma_transfer_status(uint8_t channel_number);
|
|
||||||
DmacDescriptor* dma_descriptor(uint8_t channel_number);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H
|
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 <stdint.h>
|
|
||||||
|
|
||||||
#include "peripherals/events.h"
|
|
||||||
#include "py/runtime.h"
|
|
||||||
|
|
||||||
uint8_t find_async_event_channel(void) {
|
|
||||||
int8_t channel;
|
|
||||||
for (channel = EVSYS_CHANNELS - 1; channel > 0; channel--) {
|
|
||||||
if (event_channel_free(channel)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (channel < 0) {
|
|
||||||
mp_raise_RuntimeError("All event channels in use");
|
|
||||||
}
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SAMD21
|
|
||||||
#define EVSYS_SYNCH_NUM EVSYS_CHANNELS
|
|
||||||
#endif
|
|
||||||
uint8_t find_sync_event_channel(void) {
|
|
||||||
uint8_t channel;
|
|
||||||
for (channel = 0; channel < EVSYS_SYNCH_NUM; channel++) {
|
|
||||||
if (event_channel_free(channel)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (channel >= EVSYS_SYNCH_NUM) {
|
|
||||||
mp_raise_RuntimeError("All sync event channels in use");
|
|
||||||
}
|
|
||||||
return channel;
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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_EVENTS_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_EVENTS_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "include/sam.h"
|
|
||||||
|
|
||||||
void turn_on_event_system(void);
|
|
||||||
void reset_event_system(void);
|
|
||||||
uint8_t find_async_event_channel(void);
|
|
||||||
uint8_t find_sync_event_channel(void);
|
|
||||||
void disable_event_channel(uint8_t channel_number);
|
|
||||||
void disable_event_user(uint8_t user_number);
|
|
||||||
void connect_event_user_to_channel(uint8_t user, uint8_t channel);
|
|
||||||
void init_async_event_channel(uint8_t channel, uint8_t generator);
|
|
||||||
void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator);
|
|
||||||
bool event_interrupt_active(uint8_t channel);
|
|
||||||
bool event_interrupt_overflow(uint8_t channel);
|
|
||||||
|
|
||||||
bool event_channel_free(uint8_t channel);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_EVENTS_H
|
|
@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "common-hal/pulseio/PulseIn.h"
|
|
||||||
#include "common-hal/rotaryio/IncrementalEncoder.h"
|
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
|
||||||
#include "peripherals/external_interrupts.h"
|
|
||||||
|
|
||||||
#include "sam.h"
|
|
||||||
|
|
||||||
// This structure is used to share per-channel storage amongst all users of external interrupts.
|
|
||||||
// Without this there would be multiple arrays even though they are disjoint because each channel
|
|
||||||
// has one user.
|
|
||||||
static void *channel_data[EIC_EXTINT_NUM];
|
|
||||||
static uint8_t channel_handler[EIC_EXTINT_NUM];
|
|
||||||
|
|
||||||
void external_interrupt_handler(uint8_t channel) {
|
|
||||||
uint8_t handler = channel_handler[channel];
|
|
||||||
if (handler == EIC_HANDLER_PULSEIN) {
|
|
||||||
pulsein_interrupt_handler(channel);
|
|
||||||
} else if (handler == EIC_HANDLER_INCREMENTAL_ENCODER) {
|
|
||||||
incrementalencoder_interrupt_handler(channel);
|
|
||||||
}
|
|
||||||
EIC->INTFLAG.reg = (1 << channel) << EIC_INTFLAG_EXTINT_Pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void configure_eic_channel(uint8_t eic_channel, uint32_t sense_setting) {
|
|
||||||
uint8_t config_index = eic_channel / 8;
|
|
||||||
uint8_t position = (eic_channel % 8) * 4;
|
|
||||||
#ifdef SAMD51
|
|
||||||
eic_set_enable(false);
|
|
||||||
#endif
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
uint32_t masked_value = EIC->CONFIG[config_index].reg & ~(0xf << position);
|
|
||||||
EIC->CONFIG[config_index].reg = masked_value | (sense_setting << position);
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
#ifdef SAMD51
|
|
||||||
eic_set_enable(true);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void turn_on_eic_channel(uint8_t eic_channel, uint32_t sense_setting,
|
|
||||||
uint8_t channel_interrupt_handler) {
|
|
||||||
// We do very light filtering using majority voting.
|
|
||||||
sense_setting |= EIC_CONFIG_FILTEN0;
|
|
||||||
configure_eic_channel(eic_channel, sense_setting);
|
|
||||||
uint32_t mask = 1 << eic_channel;
|
|
||||||
EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos;
|
|
||||||
if (channel_interrupt_handler != EIC_HANDLER_NO_INTERRUPT) {
|
|
||||||
channel_handler[eic_channel] = channel_interrupt_handler;
|
|
||||||
turn_on_cpu_interrupt(eic_channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void turn_off_eic_channel(uint8_t eic_channel) {
|
|
||||||
uint32_t mask = 1 << eic_channel;
|
|
||||||
EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos;
|
|
||||||
#ifdef SAMD51
|
|
||||||
NVIC_DisableIRQ(EIC_0_IRQn + eic_channel);
|
|
||||||
NVIC_ClearPendingIRQ(EIC_0_IRQn + eic_channel);
|
|
||||||
#endif
|
|
||||||
channel_data[eic_channel] = NULL;
|
|
||||||
|
|
||||||
#ifdef SAMD21
|
|
||||||
if (EIC->INTENSET.reg == 0) {
|
|
||||||
NVIC_DisableIRQ(EIC_IRQn);
|
|
||||||
NVIC_ClearPendingIRQ(EIC_IRQn);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// Test if all channels are null and deinit everything if they are.
|
|
||||||
if (EIC->EVCTRL.reg == 0 && EIC->INTENSET.reg == 0) {
|
|
||||||
turn_off_external_interrupt_controller();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void* get_eic_channel_data(uint8_t eic_channel) {
|
|
||||||
return channel_data[eic_channel];
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_eic_channel_data(uint8_t eic_channel, void* data) {
|
|
||||||
channel_data[eic_channel] = data;
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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_PERIPHERALS_EXTERNAL_INTERRUPTS_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_EXTERNAL_INTERRUPTS_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define EIC_HANDLER_NO_INTERRUPT 0x0
|
|
||||||
#define EIC_HANDLER_PULSEIN 0x1
|
|
||||||
#define EIC_HANDLER_INCREMENTAL_ENCODER 0x2
|
|
||||||
|
|
||||||
void turn_on_external_interrupt_controller(void);
|
|
||||||
void turn_off_external_interrupt_controller(void);
|
|
||||||
void turn_on_cpu_interrupt(uint8_t eic_channel);
|
|
||||||
void turn_on_eic_channel(uint8_t eic_channel, uint32_t sense_setting,
|
|
||||||
uint8_t channel_interrupt_handler);
|
|
||||||
void configure_eic_channel(uint8_t eic_channel, uint32_t sense_setting);
|
|
||||||
void turn_off_eic_channel(uint8_t eic_channel);
|
|
||||||
bool eic_channel_free(uint8_t eic_channel);
|
|
||||||
bool eic_get_enable(void);
|
|
||||||
void eic_set_enable(bool value);
|
|
||||||
void eic_reset(void);
|
|
||||||
|
|
||||||
void* get_eic_channel_data(uint8_t eic_channel);
|
|
||||||
void set_eic_channel_data(uint8_t eic_channel, void* data);
|
|
||||||
|
|
||||||
void external_interrupt_handler(uint8_t channel);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_EXTERNAL_INTERRUPTS_H
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "i2s.h"
|
|
||||||
|
|
||||||
#include "clocks.h"
|
|
||||||
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
#ifdef SAMD21
|
|
||||||
#include "hpl/pm/hpl_pm_base.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void i2s_set_enable(bool enable) {
|
|
||||||
while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
|
|
||||||
I2S->CTRLA.bit.ENABLE = enable;
|
|
||||||
while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void i2s_set_clock_unit_enable(uint8_t clock_unit, bool enable) {
|
|
||||||
while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
|
|
||||||
I2S->CTRLA.vec.CKEN = 1 << clock_unit;
|
|
||||||
while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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_I2S_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_I2S_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "include/sam.h"
|
|
||||||
|
|
||||||
void turn_on_i2s(void);
|
|
||||||
|
|
||||||
void i2s_set_enable(bool enable);
|
|
||||||
void i2s_set_clock_unit_enable(uint8_t clock, bool enable);
|
|
||||||
void i2s_set_serializer_enable(uint8_t serializer, bool enable);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_I2S_H
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
|
|
||||||
// that all necessary includes are already included.
|
|
||||||
|
|
||||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
|
|
||||||
|
|
||||||
#include "mpconfigport.h"
|
|
||||||
|
|
||||||
#ifdef SAMD21
|
|
||||||
#include "peripherals/samd21/pins.h"
|
|
||||||
#endif
|
|
||||||
#ifdef SAMD51
|
|
||||||
#include "peripherals/samd51/pins.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hal/include/hal_adc_sync.h"
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
#include "hpl/pm/hpl_pm_base.h"
|
|
||||||
|
|
||||||
// Do initialization and calibration setup needed for any use of the ADC.
|
|
||||||
// The reference and resolution should be set by the caller.
|
|
||||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
|
|
||||||
// Turn the clocks on.
|
|
||||||
_pm_enable_bus_clock(PM_BUS_APBC, ADC);
|
|
||||||
_gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
|
|
||||||
|
|
||||||
adc_sync_init(adc, instance, (void *)NULL);
|
|
||||||
|
|
||||||
// Load the factory calibration
|
|
||||||
hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos);
|
|
||||||
// Bits 7:5
|
|
||||||
uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
|
|
||||||
// Bits 4:0
|
|
||||||
linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
|
|
||||||
hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity);
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// The SAMD21 doesn't have a cache so we have nothing to do.
|
|
||||||
void samd_peripherals_disable_and_clear_cache(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void samd_peripherals_enable_cache(void) {
|
|
||||||
}
|
|
@ -1,516 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
|
||||||
|
|
||||||
#include "hal/include/hal_flash.h"
|
|
||||||
|
|
||||||
#include "bindings/samd/Clock.h"
|
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
|
|
||||||
#ifdef EXPRESS_BOARD
|
|
||||||
#define INTERNAL_CIRCUITPY_CONFIG_START_ADDR (0x00040000 - NVMCTRL_ROW_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE)
|
|
||||||
#else
|
|
||||||
#define INTERNAL_CIRCUITPY_CONFIG_START_ADDR (0x00040000 - 0x010000 - NVMCTRL_ROW_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool gclk_enabled(uint8_t gclk) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
// Explicitly do a byte write so the peripheral knows we're just wanting to read the channel
|
|
||||||
// rather than write to it.
|
|
||||||
*((uint8_t*) &GCLK->GENCTRL.reg) = gclk;
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
|
||||||
bool enabled = GCLK->GENCTRL.bit.GENEN;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_gclk(uint8_t gclk) {
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
|
||||||
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk);
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral) {
|
|
||||||
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(peripheral) | GCLK_CLKCTRL_GEN(gclk) | GCLK_CLKCTRL_CLKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral) {
|
|
||||||
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(peripheral) | GCLK_CLKCTRL_GEN(gclk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor) {
|
|
||||||
uint32_t divsel = 0;
|
|
||||||
if (gclk == 2 && divisor > 31) {
|
|
||||||
divsel = GCLK_GENCTRL_DIVSEL;
|
|
||||||
for (int i = 15; i > 4; i++) {
|
|
||||||
if (divisor & (1 << i)) {
|
|
||||||
divisor = i - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GCLK->GENDIV.reg = GCLK_GENDIV_ID(gclk) | GCLK_GENDIV_DIV(divisor);
|
|
||||||
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk) | GCLK_GENCTRL_SRC(source) | divsel | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN;
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY != 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_clock_generator(uint8_t gclk) {
|
|
||||||
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk);
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY != 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_clock_source_osc8m(void) {
|
|
||||||
// Preserve CALIB and FRANGE
|
|
||||||
SYSCTRL->OSC8M.bit.ONDEMAND = 0;
|
|
||||||
SYSCTRL->OSC8M.bit.PRESC = 3;
|
|
||||||
SYSCTRL->OSC8M.bit.ENABLE = 1;
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.OSC8MRDY) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_clock_source_osc32k(void) {
|
|
||||||
uint32_t calib = (*((uint32_t *)FUSES_OSC32K_CAL_ADDR) & FUSES_OSC32K_CAL_Msk) >> FUSES_OSC32K_CAL_Pos;
|
|
||||||
SYSCTRL->OSC32K.reg = SYSCTRL_OSC32K_CALIB(calib) |
|
|
||||||
SYSCTRL_OSC32K_EN32K |
|
|
||||||
SYSCTRL_OSC32K_ENABLE;
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.OSC32KRDY) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_clock_source_xosc32k(void) {
|
|
||||||
SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_EN32K |
|
|
||||||
SYSCTRL_XOSC32K_XTALEN |
|
|
||||||
SYSCTRL_XOSC32K_ENABLE;
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.XOSC32KRDY) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_clock_source_dfll48m_xosc(void) {
|
|
||||||
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE;
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {}
|
|
||||||
SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(0x1f / 4) |
|
|
||||||
SYSCTRL_DFLLMUL_FSTEP(0xff / 4) |
|
|
||||||
SYSCTRL_DFLLMUL_MUL(48000000 / 32768);
|
|
||||||
uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) >> FUSES_DFLL48M_COARSE_CAL_Pos;
|
|
||||||
if (coarse == 0x3f) {
|
|
||||||
coarse = 0x1f;
|
|
||||||
}
|
|
||||||
SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) |
|
|
||||||
SYSCTRL_DFLLVAL_FINE(512);
|
|
||||||
|
|
||||||
SYSCTRL->DFLLCTRL.reg = 0;
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {}
|
|
||||||
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_MODE |
|
|
||||||
SYSCTRL_DFLLCTRL_ENABLE;
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {}
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
|
||||||
|
|
||||||
// Wait for the fine lock on the DFLL.
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.DFLLLCKC || !SYSCTRL->PCLKSR.bit.DFLLLCKF) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_clock_source_dfll48m_usb(void) {
|
|
||||||
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE;
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {}
|
|
||||||
SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) |
|
|
||||||
SYSCTRL_DFLLMUL_FSTEP(1) |
|
|
||||||
SYSCTRL_DFLLMUL_MUL(48000);
|
|
||||||
uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) >> FUSES_DFLL48M_COARSE_CAL_Pos;
|
|
||||||
if (coarse == 0x3f) {
|
|
||||||
coarse = 0x1f;
|
|
||||||
}
|
|
||||||
uint32_t fine = 512;
|
|
||||||
#ifdef CALIBRATE_CRYSTALLESS
|
|
||||||
// This is stored in an NVM page after the text and data storage but before
|
|
||||||
// the optional file system. The first 16 bytes are the identifier for the
|
|
||||||
// section.
|
|
||||||
if (strcmp((char*) INTERNAL_CIRCUITPY_CONFIG_START_ADDR, "CIRCUITPYTHON1") == 0) {
|
|
||||||
fine = ((uint16_t *) INTERNAL_CIRCUITPY_CONFIG_START_ADDR)[8];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) |
|
|
||||||
SYSCTRL_DFLLVAL_FINE(fine);
|
|
||||||
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS |
|
|
||||||
SYSCTRL_DFLLCTRL_USBCRM |
|
|
||||||
SYSCTRL_DFLLCTRL_MODE |
|
|
||||||
SYSCTRL_DFLLCTRL_ENABLE;
|
|
||||||
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {}
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clock_init(void)
|
|
||||||
{
|
|
||||||
init_clock_source_osc8m();
|
|
||||||
if (board_has_crystal()) {
|
|
||||||
init_clock_source_xosc32k();
|
|
||||||
} else {
|
|
||||||
init_clock_source_osc32k();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (board_has_crystal()) {
|
|
||||||
enable_clock_generator(3, GCLK_GENCTRL_SRC_XOSC32K_Val, 1);
|
|
||||||
connect_gclk_to_peripheral(3, GCLK_CLKCTRL_ID_DFLL48_Val);
|
|
||||||
init_clock_source_dfll48m_xosc();
|
|
||||||
} else {
|
|
||||||
init_clock_source_dfll48m_usb();
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_clock_generator(0, GCLK_GENCTRL_SRC_DFLL48M_Val, 1);
|
|
||||||
enable_clock_generator(1, GCLK_GENCTRL_SRC_DFLL48M_Val, 150);
|
|
||||||
if (board_has_crystal()) {
|
|
||||||
enable_clock_generator(2, GCLK_GENCTRL_SRC_XOSC32K_Val, 32);
|
|
||||||
} else {
|
|
||||||
enable_clock_generator(2, GCLK_GENCTRL_SRC_OSC32K_Val, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do this after all static clock init so that they aren't used dynamically.
|
|
||||||
init_dynamic_clocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool clk_enabled(uint8_t clk) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
*((uint8_t*) &GCLK->CLKCTRL.reg) = clk;
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
|
||||||
bool enabled = GCLK->CLKCTRL.bit.CLKEN;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t clk_get_generator(uint8_t clk) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
*((uint8_t*) &GCLK->CLKCTRL.reg) = clk;
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
|
||||||
uint8_t gen = GCLK->CLKCTRL.bit.GEN;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
return gen;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t generator_get_source(uint8_t gen) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
*((uint8_t*) &GCLK->GENCTRL.reg) = gen;
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
|
||||||
uint8_t src = GCLK->GENCTRL.bit.SRC;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool osc_enabled(uint8_t index) {
|
|
||||||
switch (index) {
|
|
||||||
case GCLK_SOURCE_XOSC:
|
|
||||||
return SYSCTRL->XOSC.bit.ENABLE;
|
|
||||||
// TODO: GCLK_SOURCE_GCLKIN
|
|
||||||
// TODO: GCLK_SOURCE_GCLKGEN1
|
|
||||||
case GCLK_SOURCE_OSCULP32K:
|
|
||||||
return true;
|
|
||||||
case GCLK_SOURCE_OSC32K:
|
|
||||||
return SYSCTRL->OSC32K.bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_XOSC32K:
|
|
||||||
return SYSCTRL->XOSC32K.bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_OSC8M:
|
|
||||||
return SYSCTRL->OSC8M.bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_DFLL48M:
|
|
||||||
return SYSCTRL->DFLLCTRL.bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_DPLL96M:
|
|
||||||
return SYSCTRL->DPLLCTRLA.bit.ENABLE;
|
|
||||||
};
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t osc_get_frequency(uint8_t index) {
|
|
||||||
switch (index) {
|
|
||||||
case GCLK_SOURCE_XOSC:
|
|
||||||
return 0; // unknown 0.4-32MHz
|
|
||||||
// TODO: GCLK_SOURCE_GCLKIN
|
|
||||||
// TODO: GCLK_SOURCE_GCLKGEN1
|
|
||||||
case GCLK_SOURCE_OSCULP32K:
|
|
||||||
case GCLK_SOURCE_OSC32K:
|
|
||||||
case GCLK_SOURCE_XOSC32K:
|
|
||||||
return 32768;
|
|
||||||
case GCLK_SOURCE_OSC8M:
|
|
||||||
return 8000000;
|
|
||||||
case GCLK_SOURCE_DFLL48M:
|
|
||||||
return 48000000;
|
|
||||||
case GCLK_SOURCE_DPLL96M:
|
|
||||||
return 96000000;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clock_get_enabled(uint8_t type, uint8_t index) {
|
|
||||||
if (type == 0)
|
|
||||||
return osc_enabled(index);
|
|
||||||
if (type == 1)
|
|
||||||
return clk_enabled(index);
|
|
||||||
if (type == 2)
|
|
||||||
return SysTick->CTRL & SysTick_CTRL_ENABLE_Msk;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index) {
|
|
||||||
if (type == 1 && index <= 0x24 && clk_enabled(index)) {
|
|
||||||
*p_type = 0;
|
|
||||||
*p_index = generator_get_source(clk_get_generator(index));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == 2 && index == 0) {
|
|
||||||
*p_type = 0;
|
|
||||||
*p_index = generator_get_source(0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t clock_get_frequency(uint8_t type, uint8_t index) {
|
|
||||||
if (type == 0) {
|
|
||||||
return osc_get_frequency(index);
|
|
||||||
}
|
|
||||||
if (type == 1) {
|
|
||||||
if (!clk_enabled(index))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uint8_t gen = clk_get_generator(index);
|
|
||||||
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
*((uint8_t*) &GCLK->GENCTRL.reg) = gen;
|
|
||||||
*((uint8_t*) &GCLK->GENDIV.reg) = gen;
|
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
|
||||||
|
|
||||||
uint8_t src = GCLK->GENCTRL.bit.SRC;
|
|
||||||
uint32_t div;
|
|
||||||
if (GCLK->GENCTRL.bit.DIVSEL) {
|
|
||||||
div = 1 << (GCLK->GENDIV.bit.DIV + 1);
|
|
||||||
} else {
|
|
||||||
div = GCLK->GENDIV.bit.DIV;
|
|
||||||
if (!div)
|
|
||||||
div = 1;
|
|
||||||
}
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
|
|
||||||
return osc_get_frequency(src) / div;
|
|
||||||
}
|
|
||||||
if (type == 2 && index == 0) {
|
|
||||||
return clock_get_frequency(0, generator_get_source(0)) / SysTick->LOAD;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t clock_get_calibration(uint8_t type, uint8_t index) {
|
|
||||||
if (type == 0) {
|
|
||||||
switch (index) {
|
|
||||||
case GCLK_SOURCE_OSCULP32K:
|
|
||||||
return SYSCTRL->OSCULP32K.bit.CALIB;
|
|
||||||
case GCLK_SOURCE_OSC32K:
|
|
||||||
return SYSCTRL->OSC32K.bit.CALIB;
|
|
||||||
case GCLK_SOURCE_OSC8M:
|
|
||||||
return SYSCTRL->OSC8M.bit.CALIB;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (type == 2 && index == 0) {
|
|
||||||
return SysTick->LOAD + 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val) {
|
|
||||||
if (type == 0) {
|
|
||||||
switch (index) {
|
|
||||||
case GCLK_SOURCE_OSCULP32K:
|
|
||||||
if (val > 0x1f)
|
|
||||||
return -1;
|
|
||||||
SYSCTRL->OSCULP32K.bit.CALIB = val;
|
|
||||||
return 0;
|
|
||||||
case GCLK_SOURCE_OSC32K:
|
|
||||||
if (val > 0x7f)
|
|
||||||
return -1;
|
|
||||||
SYSCTRL->OSC32K.bit.CALIB = val;
|
|
||||||
return 0;
|
|
||||||
case GCLK_SOURCE_OSC8M:
|
|
||||||
if (val > 0xfff)
|
|
||||||
return -1;
|
|
||||||
SYSCTRL->OSC8M.bit.CALIB = val;
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (type == 2 && index == 0) {
|
|
||||||
if (val < 0x1000 || val > 0x1000000)
|
|
||||||
return -1;
|
|
||||||
SysTick->LOAD = val - 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -2; // calibration is read only
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_usb_clock_calibration(void) {
|
|
||||||
#ifndef CALIBRATE_CRYSTALLESS
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
// If we are on USB lets double check our fine calibration for the clock and
|
|
||||||
// save the new value if its different enough.
|
|
||||||
SYSCTRL->DFLLSYNC.bit.READREQ = 1;
|
|
||||||
uint16_t saved_calibration = 0x1ff;
|
|
||||||
if (strcmp((char*) INTERNAL_CIRCUITPY_CONFIG_START_ADDR, "CIRCUITPYTHON1") == 0) {
|
|
||||||
saved_calibration = ((uint16_t *) INTERNAL_CIRCUITPY_CONFIG_START_ADDR)[8];
|
|
||||||
}
|
|
||||||
while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) {
|
|
||||||
// TODO(tannewt): Run the mass storage stuff if this takes a while.
|
|
||||||
}
|
|
||||||
int16_t current_calibration = SYSCTRL->DFLLVAL.bit.FINE;
|
|
||||||
if (abs(current_calibration - saved_calibration) > 10) {
|
|
||||||
// Copy the full internal config page to memory.
|
|
||||||
uint8_t page_buffer[NVMCTRL_ROW_SIZE];
|
|
||||||
memcpy(page_buffer, (uint8_t*) INTERNAL_CIRCUITPY_CONFIG_START_ADDR, NVMCTRL_ROW_SIZE);
|
|
||||||
|
|
||||||
// Modify it.
|
|
||||||
memcpy(page_buffer, "CIRCUITPYTHON1", 15);
|
|
||||||
// First 16 bytes (0-15) are ID. Little endian!
|
|
||||||
page_buffer[16] = current_calibration & 0xff;
|
|
||||||
page_buffer[17] = current_calibration >> 8;
|
|
||||||
|
|
||||||
// Write it back.
|
|
||||||
// We don't use features that use any advanced NVMCTRL features so we can fake the descriptor
|
|
||||||
// whenever we need it instead of storing it long term.
|
|
||||||
struct flash_descriptor desc;
|
|
||||||
desc.dev.hw = NVMCTRL;
|
|
||||||
flash_write(&desc, (uint32_t) INTERNAL_CIRCUITPY_CONFIG_START_ADDR, page_buffer, NVMCTRL_ROW_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SAMD21_EXPOSE_ALL_CLOCKS
|
|
||||||
CLOCK_SOURCE(XOSC);
|
|
||||||
CLOCK_SOURCE(GCLKIN);
|
|
||||||
CLOCK_SOURCE(GCLKGEN1);
|
|
||||||
CLOCK_SOURCE(OSCULP32K);
|
|
||||||
#endif
|
|
||||||
CLOCK_SOURCE(OSC32K);
|
|
||||||
CLOCK_SOURCE(XOSC32K);
|
|
||||||
#ifdef SAMD21_EXPOSE_ALL_CLOCKS
|
|
||||||
CLOCK_SOURCE(OSC8M);
|
|
||||||
CLOCK_SOURCE(DFLL48M);
|
|
||||||
CLOCK_SOURCE(DPLL96M);
|
|
||||||
|
|
||||||
CLOCK_GCLK_(SYSCTRL, DFLL48);
|
|
||||||
CLOCK_GCLK_(SYSCTRL, FDPLL);
|
|
||||||
CLOCK_GCLK_(SYSCTRL, FDPLL32K);
|
|
||||||
CLOCK_GCLK(WDT);
|
|
||||||
#endif
|
|
||||||
CLOCK_GCLK(RTC);
|
|
||||||
#ifdef SAMD21_EXPOSE_ALL_CLOCKS
|
|
||||||
CLOCK_GCLK(EIC);
|
|
||||||
CLOCK_GCLK(USB);
|
|
||||||
CLOCK_GCLK_(EVSYS, 0);
|
|
||||||
CLOCK_GCLK_(EVSYS, 1);
|
|
||||||
CLOCK_GCLK_(EVSYS, 2);
|
|
||||||
CLOCK_GCLK_(EVSYS, 3);
|
|
||||||
CLOCK_GCLK_(EVSYS, 4);
|
|
||||||
CLOCK_GCLK_(EVSYS, 5);
|
|
||||||
CLOCK_GCLK_(EVSYS, 6);
|
|
||||||
CLOCK_GCLK_(EVSYS, 7);
|
|
||||||
CLOCK_GCLK_(EVSYS, 8);
|
|
||||||
CLOCK_GCLK_(EVSYS, 9);
|
|
||||||
CLOCK_GCLK_(EVSYS, 10);
|
|
||||||
CLOCK_GCLK_(EVSYS, 11);
|
|
||||||
CLOCK(SERCOMx_SLOW, 1, 19);
|
|
||||||
CLOCK_GCLK_(SERCOM0, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM1, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM2, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM3, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM4, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM5, CORE);
|
|
||||||
CLOCK(TCC0_TCC1, 1, 26);
|
|
||||||
CLOCK(TCC2_TCC3, 1, 27);
|
|
||||||
CLOCK(TC4_TC5, 1, 28);
|
|
||||||
CLOCK(TC6_TC7, 1, 29);
|
|
||||||
CLOCK_GCLK(ADC);
|
|
||||||
CLOCK_GCLK_(AC, DIG);
|
|
||||||
CLOCK_GCLK_(AC, ANA);
|
|
||||||
CLOCK_GCLK(DAC);
|
|
||||||
CLOCK_GCLK(PTC);
|
|
||||||
CLOCK_GCLK_(I2S, 0);
|
|
||||||
CLOCK_GCLK_(I2S, 1);
|
|
||||||
|
|
||||||
CLOCK(SYSTICK, 2, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t samd_clock_global_dict_table[] = {
|
|
||||||
#ifdef SAMD21_EXPOSE_ALL_CLOCKS
|
|
||||||
CLOCK_ENTRY(XOSC),
|
|
||||||
CLOCK_ENTRY(GCLKIN),
|
|
||||||
CLOCK_ENTRY(GCLKGEN1),
|
|
||||||
CLOCK_ENTRY(OSCULP32K),
|
|
||||||
#endif
|
|
||||||
CLOCK_ENTRY(OSC32K),
|
|
||||||
CLOCK_ENTRY(XOSC32K),
|
|
||||||
#ifdef SAMD21_EXPOSE_ALL_CLOCKS
|
|
||||||
CLOCK_ENTRY(OSC8M),
|
|
||||||
CLOCK_ENTRY(DFLL48M),
|
|
||||||
CLOCK_ENTRY(DPLL96M),
|
|
||||||
CLOCK_ENTRY_(SYSCTRL, DFLL48),
|
|
||||||
CLOCK_ENTRY_(SYSCTRL, FDPLL),
|
|
||||||
CLOCK_ENTRY_(SYSCTRL, FDPLL32K),
|
|
||||||
CLOCK_ENTRY(WDT),
|
|
||||||
#endif
|
|
||||||
CLOCK_ENTRY(RTC),
|
|
||||||
#ifdef SAMD21_EXPOSE_ALL_CLOCKS
|
|
||||||
CLOCK_ENTRY(EIC),
|
|
||||||
CLOCK_ENTRY(USB),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 0),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 1),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 2),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 3),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 4),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 5),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 6),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 7),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 8),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 9),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 10),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 11),
|
|
||||||
CLOCK_ENTRY(SERCOMx_SLOW),
|
|
||||||
CLOCK_ENTRY_(SERCOM0, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM1, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM2, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM3, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM4, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM5, CORE),
|
|
||||||
CLOCK_ENTRY(TCC0_TCC1),
|
|
||||||
CLOCK_ENTRY(TCC2_TCC3),
|
|
||||||
CLOCK_ENTRY(TC4_TC5),
|
|
||||||
CLOCK_ENTRY(TC6_TC7),
|
|
||||||
CLOCK_ENTRY(ADC),
|
|
||||||
CLOCK_ENTRY_(AC, DIG),
|
|
||||||
CLOCK_ENTRY_(AC, ANA),
|
|
||||||
CLOCK_ENTRY(DAC),
|
|
||||||
CLOCK_ENTRY(PTC),
|
|
||||||
CLOCK_ENTRY_(I2S, 0),
|
|
||||||
CLOCK_ENTRY_(I2S, 1),
|
|
||||||
|
|
||||||
CLOCK_ENTRY(SYSTICK),
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
MP_DEFINE_CONST_DICT(samd_clock_globals, samd_clock_global_dict_table);
|
|
@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2018 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 "peripherals/dma.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "py/gc.h"
|
|
||||||
#include "py/mpstate.h"
|
|
||||||
|
|
||||||
#include "hal/utils/include/utils.h"
|
|
||||||
|
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
|
||||||
|
|
||||||
uint8_t sercom_index(Sercom* sercom) {
|
|
||||||
return ((uint32_t) sercom - (uint32_t) SERCOM0) / 0x400;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
/** Select the DMA channel and clear software trigger */
|
|
||||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
|
||||||
DMAC->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
|
|
||||||
DMAC->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
|
|
||||||
DMAC->SWTRIGCTRL.reg &= (uint32_t)(~(1 << channel_number));
|
|
||||||
uint32_t event_output_enable = 0;
|
|
||||||
if (output_event) {
|
|
||||||
event_output_enable = DMAC_CHCTRLB_EVOE;
|
|
||||||
}
|
|
||||||
DMAC->CHCTRLB.reg = DMAC_CHCTRLB_LVL_LVL0 |
|
|
||||||
DMAC_CHCTRLB_TRIGSRC(trigsrc) |
|
|
||||||
DMAC_CHCTRLB_TRIGACT_BEAT |
|
|
||||||
event_output_enable;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_enable_channel(uint8_t channel_number) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
/** Select the DMA channel and clear software trigger */
|
|
||||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
|
||||||
// Clear any previous interrupts.
|
|
||||||
DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
|
|
||||||
DMAC->CHCTRLA.bit.ENABLE = true;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_disable_channel(uint8_t channel_number) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
/** Select the DMA channel and clear software trigger */
|
|
||||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
|
||||||
DMAC->CHCTRLA.bit.ENABLE = false;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_suspend_channel(uint8_t channel_number) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
/** Select the DMA channel and clear software trigger */
|
|
||||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
|
||||||
DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_SUSPEND_Val;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_resume_channel(uint8_t channel_number) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
/** Select the DMA channel and clear software trigger */
|
|
||||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
|
||||||
DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_RESUME_Val;
|
|
||||||
DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_SUSP;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dma_channel_enabled(uint8_t channel_number) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
/** Select the DMA channel and clear software trigger */
|
|
||||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
|
||||||
bool enabled = DMAC->CHCTRLA.bit.ENABLE;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t dma_transfer_status(uint8_t channel_number) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
/** Select the DMA channel and clear software trigger */
|
|
||||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
|
||||||
uint8_t status = DMAC->CHINTFLAG.reg;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dma_channel_free(uint8_t channel_number) {
|
|
||||||
common_hal_mcu_disable_interrupts();
|
|
||||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
|
||||||
bool channel_free = DMAC->CHSTATUS.reg == 0;
|
|
||||||
common_hal_mcu_enable_interrupts();
|
|
||||||
return channel_free;
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "peripherals/events.h"
|
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
|
|
||||||
#include "hpl/pm/hpl_pm_base.h"
|
|
||||||
|
|
||||||
void turn_on_event_system(void) {
|
|
||||||
_pm_enable_bus_clock(PM_BUS_APBC, EVSYS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_event_system(void) {
|
|
||||||
EVSYS->CTRL.bit.SWRST = true;
|
|
||||||
_pm_disable_bus_clock(PM_BUS_APBC, EVSYS);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool event_channel_free(uint8_t channel) {
|
|
||||||
uint8_t generator;
|
|
||||||
// Explicitly do a byte write so the peripheral knows we're just wanting to read the channel
|
|
||||||
// rather than write to it.
|
|
||||||
*((uint8_t*) &EVSYS->CHANNEL.reg) = channel;
|
|
||||||
generator = (EVSYS->CHANNEL.reg & EVSYS_CHANNEL_EVGEN_Msk) >> EVSYS_CHANNEL_EVGEN_Pos;
|
|
||||||
return generator == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_event_channel(uint8_t channel_number) {
|
|
||||||
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_event_user(uint8_t user_number) {
|
|
||||||
EVSYS->USER.reg = EVSYS_USER_USER(user_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
void connect_event_user_to_channel(uint8_t user, uint8_t channel) {
|
|
||||||
EVSYS->USER.reg = EVSYS_USER_USER(user) | EVSYS_USER_CHANNEL(channel + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_async_event_channel(uint8_t channel, uint8_t generator) {
|
|
||||||
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) |
|
|
||||||
EVSYS_CHANNEL_EVGEN(generator) |
|
|
||||||
EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator) {
|
|
||||||
connect_gclk_to_peripheral(gclk, EVSYS_GCLK_ID_0 + channel);
|
|
||||||
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) |
|
|
||||||
EVSYS_CHANNEL_EVGEN(generator) |
|
|
||||||
EVSYS_CHANNEL_PATH_RESYNCHRONIZED |
|
|
||||||
EVSYS_CHANNEL_EDGSEL_RISING_EDGE;
|
|
||||||
if (channel >= 8) {
|
|
||||||
uint8_t value = 1 << (channel - 8);
|
|
||||||
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVDp8(value) | EVSYS_INTFLAG_OVRp8(value);
|
|
||||||
EVSYS->INTENSET.reg = EVSYS_INTENSET_EVDp8(value) | EVSYS_INTENSET_OVRp8(value);
|
|
||||||
} else {
|
|
||||||
uint8_t value = 1 << channel;
|
|
||||||
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value);
|
|
||||||
EVSYS->INTENSET.reg = EVSYS_INTENSET_EVD(value) | EVSYS_INTENSET_OVR(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool event_interrupt_active(uint8_t channel) {
|
|
||||||
bool active = false;
|
|
||||||
if (channel >= 8) {
|
|
||||||
uint8_t value = 1 << (channel - 8);
|
|
||||||
active = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_EVDp8(value)) != 0;
|
|
||||||
// Only clear if we know its active, otherwise there is the possibility it becomes active
|
|
||||||
// after we check but before we clear.
|
|
||||||
if (active) {
|
|
||||||
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVDp8(value) | EVSYS_INTFLAG_OVRp8(value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uint8_t value = 1 << channel;
|
|
||||||
active = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_EVD(value)) != 0;
|
|
||||||
if (active) {
|
|
||||||
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool event_interrupt_overflow(uint8_t channel) {
|
|
||||||
bool overflow = false;
|
|
||||||
if (channel >= 8) {
|
|
||||||
uint8_t value = 1 << (channel - 8);
|
|
||||||
overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVRp8(value)) != 0;
|
|
||||||
} else {
|
|
||||||
uint8_t value = 1 << channel;
|
|
||||||
overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVR(value)) != 0;
|
|
||||||
}
|
|
||||||
return overflow;
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "peripherals/external_interrupts.h"
|
|
||||||
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
#include "peripherals/clocks.h"
|
|
||||||
#include "sam.h"
|
|
||||||
|
|
||||||
void turn_on_external_interrupt_controller(void) {
|
|
||||||
PM->APBAMASK.bit.EIC_ = true;
|
|
||||||
_gclk_enable_channel(EIC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
|
|
||||||
eic_set_enable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void turn_off_external_interrupt_controller(void) {
|
|
||||||
eic_set_enable(false);
|
|
||||||
PM->APBAMASK.bit.EIC_ = false;
|
|
||||||
hri_gclk_write_CLKCTRL_reg(GCLK, GCLK_CLKCTRL_ID(EIC_GCLK_ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
void turn_on_cpu_interrupt(uint8_t eic_channel) {
|
|
||||||
// Ignore the channel since the CPU interrupt line is shared.
|
|
||||||
(void) eic_channel;
|
|
||||||
|
|
||||||
NVIC_DisableIRQ(EIC_IRQn);
|
|
||||||
NVIC_ClearPendingIRQ(EIC_IRQn);
|
|
||||||
NVIC_EnableIRQ(EIC_IRQn);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eic_get_enable(void) {
|
|
||||||
return EIC->CTRL.bit.ENABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void eic_set_enable(bool value) {
|
|
||||||
EIC->CTRL.bit.ENABLE = value;
|
|
||||||
while (EIC->STATUS.bit.SYNCBUSY != 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void eic_reset(void) {
|
|
||||||
EIC->CTRL.bit.SWRST = true;
|
|
||||||
while (EIC->STATUS.bit.SYNCBUSY != 0) {}
|
|
||||||
for (int i = 0; i < EIC_EXTINT_NUM; i++) {
|
|
||||||
set_eic_channel_data(i, NULL);
|
|
||||||
}
|
|
||||||
NVIC_DisableIRQ(EIC_IRQn);
|
|
||||||
NVIC_ClearPendingIRQ(EIC_IRQn);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eic_channel_free(uint8_t eic_channel) {
|
|
||||||
uint32_t mask = 1 << eic_channel;
|
|
||||||
return get_eic_channel_data(eic_channel) == NULL &&
|
|
||||||
(EIC->INTENSET.vec.EXTINT & mask) == 0 &&
|
|
||||||
(EIC->EVCTRL.vec.EXTINTEO & mask) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EIC_Handler(void) {
|
|
||||||
for (uint8_t i = 0; i < 16; i++) {
|
|
||||||
if ((EIC->INTFLAG.vec.EXTINT & (1 << i)) != 0) {
|
|
||||||
external_interrupt_handler(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "peripherals/i2s.h"
|
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
|
||||||
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
#include "hpl/pm/hpl_pm_base.h"
|
|
||||||
|
|
||||||
void turn_on_i2s(void) {
|
|
||||||
_pm_enable_bus_clock(PM_BUS_APBC, I2S);
|
|
||||||
}
|
|
||||||
|
|
||||||
void i2s_set_serializer_enable(uint8_t serializer, bool enable) {
|
|
||||||
while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
|
|
||||||
if (enable) {
|
|
||||||
I2S->CTRLA.vec.SEREN = 1 << serializer;
|
|
||||||
} else {
|
|
||||||
I2S->CTRLA.vec.SEREN &= ~(1 << serializer);
|
|
||||||
}
|
|
||||||
while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
|
|
||||||
}
|
|
@ -1,529 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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 "shared-bindings/microcontroller/Pin.h"
|
|
||||||
|
|
||||||
#define SERCOM(sercom_index, p_pad) \
|
|
||||||
{ \
|
|
||||||
.index = sercom_index, \
|
|
||||||
.pad = p_pad \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NO_SERCOM \
|
|
||||||
{ \
|
|
||||||
.index = 0x3f, \
|
|
||||||
.pad = 0 \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define TCC(p_index, p_wave_output) \
|
|
||||||
{ \
|
|
||||||
.index = p_index, \
|
|
||||||
.is_tc = false, \
|
|
||||||
.wave_output = p_wave_output \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TC(p_index, p_wave_output) \
|
|
||||||
{ \
|
|
||||||
.index = p_index - 3, \
|
|
||||||
.is_tc = true, \
|
|
||||||
.wave_output = p_wave_output \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NO_TIMER TCC(0xff, 0)
|
|
||||||
|
|
||||||
#define TOUCH(y_line) \
|
|
||||||
.has_touch = true, \
|
|
||||||
.touch_y_line = y_line,
|
|
||||||
|
|
||||||
#define NO_TOUCH \
|
|
||||||
.has_touch = false,
|
|
||||||
|
|
||||||
#define EXTINT_CHANNEL(channel) \
|
|
||||||
.has_extint = true, \
|
|
||||||
.extint_channel = channel,
|
|
||||||
|
|
||||||
#define NO_EXTINT \
|
|
||||||
.has_extint = false,
|
|
||||||
|
|
||||||
#define ADC_INPUT(input) input
|
|
||||||
|
|
||||||
#define NO_ADC 0xff
|
|
||||||
|
|
||||||
// This macro is used to simplify pin definition in boards/<board>/pins.c
|
|
||||||
#define PIN(p_name, p_extint, p_adc, p_touch, \
|
|
||||||
p_primary_sercom, p_secondary_sercom, \
|
|
||||||
p_primary_timer, p_secondary_timer) \
|
|
||||||
const mcu_pin_obj_t pin_## p_name = { \
|
|
||||||
{ &mcu_pin_type }, \
|
|
||||||
.name = MP_QSTR_## p_name, \
|
|
||||||
.pin = (PIN_## p_name), \
|
|
||||||
p_extint \
|
|
||||||
p_touch \
|
|
||||||
.adc_input = {p_adc}, \
|
|
||||||
.timer = { p_primary_timer, p_secondary_timer}, \
|
|
||||||
.sercom = {p_primary_sercom, p_secondary_sercom}, \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pins in datasheet order.
|
|
||||||
// NOTE(tannewt): TC wave out 0 is commented out because the first channel is
|
|
||||||
// used to vary the 16 bit timer's frequency.
|
|
||||||
#if defined(PIN_PA00) && !defined(IGNORE_PIN_PA00)
|
|
||||||
PIN(PA00, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(1, 0),
|
|
||||||
TCC(2, 0),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA01) && !defined(IGNORE_PIN_PA01)
|
|
||||||
PIN(PA01, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(1, 1),
|
|
||||||
TCC(2, 1),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA02) && !defined(IGNORE_PIN_PA02)
|
|
||||||
// Touch is not allowed on A0 (PA02) on Circuit Playground Express.
|
|
||||||
PIN(PA02, EXTINT_CHANNEL(2), ADC_INPUT(0),
|
|
||||||
#ifdef PA02_NO_TOUCH
|
|
||||||
NO_TOUCH,
|
|
||||||
#else
|
|
||||||
TOUCH(0),
|
|
||||||
#endif
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_TIMER,
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA03) && !defined(IGNORE_PIN_PA03)
|
|
||||||
PIN(PA03, EXTINT_CHANNEL(3), ADC_INPUT(1), TOUCH(1),
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_TIMER,
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB04) && !defined(IGNORE_PIN_PB04)
|
|
||||||
PIN(PB04, EXTINT_CHANNEL(4), ADC_INPUT(12), TOUCH(10),
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_TIMER,
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB05) && !defined(IGNORE_PIN_PB05)
|
|
||||||
PIN(PB05, EXTINT_CHANNEL(5), ADC_INPUT(13), TOUCH(11),
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_TIMER,
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB06) && !defined(IGNORE_PIN_PB06)
|
|
||||||
PIN(PB06, EXTINT_CHANNEL(6), ADC_INPUT(14), TOUCH(12),
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_TIMER,
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB07) && !defined(IGNORE_PIN_PB07)
|
|
||||||
PIN(PB07, EXTINT_CHANNEL(7), ADC_INPUT(15), TOUCH(13),
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_TIMER,
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB08) && !defined(IGNORE_PIN_PB08)
|
|
||||||
PIN(PB08, EXTINT_CHANNEL(8), ADC_INPUT(2), TOUCH(14),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(4, 0),
|
|
||||||
TC(4, 0),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB09) && !defined(IGNORE_PIN_PB09)
|
|
||||||
PIN(PB09, EXTINT_CHANNEL(9), ADC_INPUT(3), TOUCH(15),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(4, 1),
|
|
||||||
TC(4, 1),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA04) && !defined(IGNORE_PIN_PA04)
|
|
||||||
PIN(PA04, EXTINT_CHANNEL(4), ADC_INPUT(4), TOUCH(2),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(0, 0),
|
|
||||||
TCC(0, 0),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA05) && !defined(IGNORE_PIN_PA05)
|
|
||||||
PIN(PA05, EXTINT_CHANNEL(5), ADC_INPUT(5), TOUCH(3),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(0, 1),
|
|
||||||
TCC(0, 1),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA06) && !defined(IGNORE_PIN_PA06)
|
|
||||||
PIN(PA06, EXTINT_CHANNEL(6), ADC_INPUT(6), TOUCH(4),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(0, 2),
|
|
||||||
TCC(1, 0),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA07) && !defined(IGNORE_PIN_PA07)
|
|
||||||
PIN(PA07, EXTINT_CHANNEL(7), ADC_INPUT(7), TOUCH(5),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(0, 3),
|
|
||||||
TCC(1, 1),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA08) && !defined(IGNORE_PIN_PA08)
|
|
||||||
PIN(PA08, NO_EXTINT, ADC_INPUT(16), NO_TOUCH,
|
|
||||||
SERCOM(0, 0),
|
|
||||||
SERCOM(2, 0),
|
|
||||||
TCC(0, 0),
|
|
||||||
TCC(1, 2));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA09) && !defined(IGNORE_PIN_PA09)
|
|
||||||
PIN(PA09, EXTINT_CHANNEL(9), ADC_INPUT(17), NO_TOUCH,
|
|
||||||
SERCOM(0, 1),
|
|
||||||
SERCOM(2, 1),
|
|
||||||
TCC(0, 1),
|
|
||||||
TCC(1, 3));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA10) && !defined(IGNORE_PIN_PA10)
|
|
||||||
PIN(PA10, EXTINT_CHANNEL(10), ADC_INPUT(18), NO_TOUCH,
|
|
||||||
SERCOM(0, 2),
|
|
||||||
SERCOM(2, 2),
|
|
||||||
TCC(1, 0),
|
|
||||||
TCC(0, 2));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA11) && !defined(IGNORE_PIN_PA11)
|
|
||||||
PIN(PA11, EXTINT_CHANNEL(11), ADC_INPUT(19), NO_TOUCH,
|
|
||||||
SERCOM(0, 3),
|
|
||||||
SERCOM(2, 3),
|
|
||||||
TCC(1, 1),
|
|
||||||
TCC(0, 3));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB10) && !defined(IGNORE_PIN_PB10)
|
|
||||||
PIN(PB10, EXTINT_CHANNEL(10), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(4, 2),
|
|
||||||
TC(5, 0),
|
|
||||||
TCC(0, 4));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB11) && !defined(IGNORE_PIN_PB11)
|
|
||||||
PIN(PB11, EXTINT_CHANNEL(11), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(4, 3),
|
|
||||||
TC(5, 1),
|
|
||||||
TCC(0, 5));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB12) && !defined(IGNORE_PIN_PB12)
|
|
||||||
PIN(PB12, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(4, 0),
|
|
||||||
NO_SERCOM,
|
|
||||||
TC(4, 0),
|
|
||||||
TCC(0, 6));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB13) && !defined(IGNORE_PIN_PB13)
|
|
||||||
PIN(PB13, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(4, 1),
|
|
||||||
NO_SERCOM,
|
|
||||||
TC(4, 1),
|
|
||||||
TCC(0, 7));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB14) && !defined(IGNORE_PIN_PB14)
|
|
||||||
PIN(PB14, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(4, 2),
|
|
||||||
NO_SERCOM,
|
|
||||||
TC(5, 0),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Second page.
|
|
||||||
#if defined(PIN_PB15) && !defined(IGNORE_PIN_PB15)
|
|
||||||
PIN(PB15, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(4, 3),
|
|
||||||
NO_SERCOM,
|
|
||||||
TC(5, 1),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA12) && !defined(IGNORE_PIN_PA12)
|
|
||||||
PIN(PA12, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(2, 0),
|
|
||||||
SERCOM(4, 0),
|
|
||||||
TCC(2, 0),
|
|
||||||
TCC(0, 6));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA13) && !defined(IGNORE_PIN_PA13)
|
|
||||||
PIN(PA13, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(2, 1),
|
|
||||||
SERCOM(4, 1),
|
|
||||||
TCC(2, 1),
|
|
||||||
TCC(0, 7));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA14) && !defined(IGNORE_PIN_PA14)
|
|
||||||
PIN(PA14, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(2, 2),
|
|
||||||
#ifdef SERCOM4
|
|
||||||
SERCOM(4, 2),
|
|
||||||
#else
|
|
||||||
NO_SERCOM,
|
|
||||||
#endif
|
|
||||||
TC(3, 0),
|
|
||||||
TCC(0, 4));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA15) && !defined(IGNORE_PIN_PA15)
|
|
||||||
PIN(PA15, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(2, 3),
|
|
||||||
#ifdef SERCOM4
|
|
||||||
SERCOM(4, 3),
|
|
||||||
#else
|
|
||||||
NO_SERCOM,
|
|
||||||
#endif
|
|
||||||
TC(3, 1),
|
|
||||||
TCC(0, 5));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA16) && !defined(IGNORE_PIN_PA16)
|
|
||||||
PIN(PA16, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(1, 0),
|
|
||||||
SERCOM(3, 0),
|
|
||||||
TCC(2, 0),
|
|
||||||
TCC(0, 6));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA17) && !defined(IGNORE_PIN_PA17)
|
|
||||||
PIN(PA17, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(1, 1),
|
|
||||||
SERCOM(3, 1),
|
|
||||||
TCC(2, 1),
|
|
||||||
TCC(0, 7));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA18) && !defined(IGNORE_PIN_PA18)
|
|
||||||
PIN(PA18, EXTINT_CHANNEL(2), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(1, 2),
|
|
||||||
SERCOM(3, 2),
|
|
||||||
TC(3, 0),
|
|
||||||
TCC(0, 2));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA19) && !defined(IGNORE_PIN_PA19)
|
|
||||||
PIN(PA19, EXTINT_CHANNEL(3), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(1, 3),
|
|
||||||
SERCOM(3, 3),
|
|
||||||
TC(3, 1),
|
|
||||||
TCC(0, 3));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB16) && !defined(IGNORE_PIN_PB16)
|
|
||||||
PIN(PB16, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(5, 0),
|
|
||||||
NO_SERCOM,
|
|
||||||
#ifdef TC6
|
|
||||||
TC(6, 0),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
TCC(0, 4));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17)
|
|
||||||
PIN(PB17, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(5, 1),
|
|
||||||
NO_SERCOM,
|
|
||||||
#ifdef TC6
|
|
||||||
TC(6, 1),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
TCC(0, 5));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA20) && !defined(IGNORE_PIN_PA20)
|
|
||||||
PIN(PA20, EXTINT_CHANNEL(4), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(5, 2),
|
|
||||||
SERCOM(3, 2),
|
|
||||||
#ifdef TC7
|
|
||||||
TC(7, 0),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
TCC(0, 6));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA21) && !defined(IGNORE_PIN_PA21)
|
|
||||||
PIN(PA21, EXTINT_CHANNEL(5), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(5, 3),
|
|
||||||
SERCOM(3, 3),
|
|
||||||
#ifdef TC7
|
|
||||||
TC(7, 1),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
TCC(0, 7));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA22) && !defined(IGNORE_PIN_PA22)
|
|
||||||
PIN(PA22, EXTINT_CHANNEL(6), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(3, 0),
|
|
||||||
#ifdef SERCOM5
|
|
||||||
SERCOM(5, 0),
|
|
||||||
#else
|
|
||||||
NO_SERCOM,
|
|
||||||
#endif
|
|
||||||
TC(4, 0),
|
|
||||||
TCC(0, 4));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA23) && !defined(IGNORE_PIN_PA23)
|
|
||||||
PIN(PA23, EXTINT_CHANNEL(7), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(3, 1),
|
|
||||||
#ifdef SERCOM5
|
|
||||||
SERCOM(5, 1),
|
|
||||||
#else
|
|
||||||
NO_SERCOM,
|
|
||||||
#endif
|
|
||||||
TC(4, 1),
|
|
||||||
TCC(0, 5));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA24) && !defined(IGNORE_PIN_PA24)
|
|
||||||
PIN(PA24, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(3, 2),
|
|
||||||
#ifdef SERCOM5
|
|
||||||
SERCOM(5, 2),
|
|
||||||
#else
|
|
||||||
NO_SERCOM,
|
|
||||||
#endif
|
|
||||||
TC(5, 0),
|
|
||||||
TCC(0, 2));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA25) && !defined(IGNORE_PIN_PA25)
|
|
||||||
PIN(PA25, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH,
|
|
||||||
SERCOM(3, 3),
|
|
||||||
#ifdef SERCOM5
|
|
||||||
SERCOM(5, 3),
|
|
||||||
#else
|
|
||||||
NO_SERCOM,
|
|
||||||
#endif
|
|
||||||
TC(5, 1),
|
|
||||||
TCC(1, 3));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22)
|
|
||||||
PIN(PB22, EXTINT_CHANNEL(6), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(5, 2),
|
|
||||||
#ifdef TC7
|
|
||||||
TC(7, 0, 0),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB23) && !defined(IGNORE_PIN_PB23)
|
|
||||||
PIN(PB23, EXTINT_CHANNEL(7), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(5, 3),
|
|
||||||
#ifdef TC7
|
|
||||||
TC(7, 1, 1),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA27) && !defined(IGNORE_PIN_PA27)
|
|
||||||
PIN(PA27, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_TIMER,
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA28) && !defined(IGNORE_PIN_PA28)
|
|
||||||
PIN(PA28, EXTINT_CHANNEL(8), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_SERCOM,
|
|
||||||
NO_TIMER,
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA30) && !defined(IGNORE_PIN_PA30)
|
|
||||||
PIN(PA30, EXTINT_CHANNEL(10), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(1, 2),
|
|
||||||
TCC(1, 0),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PA31) && !defined(IGNORE_PIN_PA31)
|
|
||||||
PIN(PA31, EXTINT_CHANNEL(11), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(1, 3),
|
|
||||||
TCC(1, 1),
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB30) && !defined(IGNORE_PIN_PB30)
|
|
||||||
PIN(PB30, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(5, 0),
|
|
||||||
TCC(0, 0),
|
|
||||||
TCC(1, 2));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB31) && !defined(IGNORE_PIN_PB31)
|
|
||||||
PIN(PB31, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH,
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(5, 1),
|
|
||||||
TCC(0, 1),
|
|
||||||
TCC(1, 3));
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB00) && !defined(IGNORE_PIN_PB00)
|
|
||||||
PIN(PB00, EXTINT_CHANNEL(0), ADC_INPUT(8), TOUCH(6),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(5, 2),
|
|
||||||
#ifdef TC7
|
|
||||||
TC(7, 0, 0),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB01) && !defined(IGNORE_PIN_PB01)
|
|
||||||
PIN(PB01, EXTINT_CHANNEL(1), ADC_INPUT(9), TOUCH(7),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(5, 3)),
|
|
||||||
#ifdef TC7
|
|
||||||
TC(7, 1),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
NO_TIMER;
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB02) && !defined(IGNORE_PIN_PB02)
|
|
||||||
PIN(PB02, EXTINT_CHANNEL(2), ADC_INPUT(10), TOUCH(8),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(5, 0),
|
|
||||||
#ifdef TC6
|
|
||||||
TC(6, 0),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
||||||
#if defined(PIN_PB03) && !defined(IGNORE_PIN_PB03)
|
|
||||||
PIN(PB03, EXTINT_CHANNEL(3), ADC_INPUT(11), TOUCH(9),
|
|
||||||
NO_SERCOM,
|
|
||||||
SERCOM(5, 1),
|
|
||||||
#ifdef TC6
|
|
||||||
TC(6, 1),
|
|
||||||
#else
|
|
||||||
NO_TIMER,
|
|
||||||
#endif
|
|
||||||
NO_TIMER);
|
|
||||||
#endif
|
|
@ -1,205 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017 by 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
|
|
||||||
// that all necessary includes are already included.
|
|
||||||
|
|
||||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
|
|
||||||
|
|
||||||
#include "include/sam.h"
|
|
||||||
|
|
||||||
void reset_pin(uint8_t pin);
|
|
||||||
|
|
||||||
#define MUX_C 2
|
|
||||||
#define MUX_D 3
|
|
||||||
#define MUX_E 4
|
|
||||||
#define MUX_F 5
|
|
||||||
#define PINMUX(pin, mux) ((((uint32_t) pin) << 16) | (mux))
|
|
||||||
|
|
||||||
#define NO_PIN PORT_BITS
|
|
||||||
|
|
||||||
// Pins in datasheet order.
|
|
||||||
#ifdef PIN_PA00
|
|
||||||
extern const mcu_pin_obj_t pin_PA00;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA01
|
|
||||||
extern const mcu_pin_obj_t pin_PA01;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA02
|
|
||||||
extern const mcu_pin_obj_t pin_PA02;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA03
|
|
||||||
extern const mcu_pin_obj_t pin_PA03;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB04
|
|
||||||
extern const mcu_pin_obj_t pin_PB04;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB05
|
|
||||||
extern const mcu_pin_obj_t pin_PB05;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB06
|
|
||||||
extern const mcu_pin_obj_t pin_PB06;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB07
|
|
||||||
extern const mcu_pin_obj_t pin_PB07;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB08
|
|
||||||
extern const mcu_pin_obj_t pin_PB08;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB09
|
|
||||||
extern const mcu_pin_obj_t pin_PB09;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA04
|
|
||||||
extern const mcu_pin_obj_t pin_PA04;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA05
|
|
||||||
extern const mcu_pin_obj_t pin_PA05;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA06
|
|
||||||
extern const mcu_pin_obj_t pin_PA06;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA07
|
|
||||||
extern const mcu_pin_obj_t pin_PA07;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA08
|
|
||||||
extern const mcu_pin_obj_t pin_PA08;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA09
|
|
||||||
extern const mcu_pin_obj_t pin_PA09;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA10
|
|
||||||
extern const mcu_pin_obj_t pin_PA10;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA11
|
|
||||||
extern const mcu_pin_obj_t pin_PA11;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB10
|
|
||||||
extern const mcu_pin_obj_t pin_PB10;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB11
|
|
||||||
extern const mcu_pin_obj_t pin_PB11;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB12
|
|
||||||
extern const mcu_pin_obj_t pin_PB12;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB13
|
|
||||||
extern const mcu_pin_obj_t pin_PB13;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB14
|
|
||||||
extern const mcu_pin_obj_t pin_PB14;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Second page.
|
|
||||||
#ifdef PIN_PB15
|
|
||||||
extern const mcu_pin_obj_t pin_PB15;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA12
|
|
||||||
extern const mcu_pin_obj_t pin_PA12;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA13
|
|
||||||
extern const mcu_pin_obj_t pin_PA13;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA14
|
|
||||||
extern const mcu_pin_obj_t pin_PA14;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA15
|
|
||||||
extern const mcu_pin_obj_t pin_PA15;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA16
|
|
||||||
extern const mcu_pin_obj_t pin_PA16;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA17
|
|
||||||
extern const mcu_pin_obj_t pin_PA17;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA18
|
|
||||||
extern const mcu_pin_obj_t pin_PA18;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA19
|
|
||||||
extern const mcu_pin_obj_t pin_PA19;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB16
|
|
||||||
extern const mcu_pin_obj_t pin_PB16;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB17
|
|
||||||
extern const mcu_pin_obj_t pin_PB17;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA20
|
|
||||||
extern const mcu_pin_obj_t pin_PA20;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA21
|
|
||||||
extern const mcu_pin_obj_t pin_PA21;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA22
|
|
||||||
extern const mcu_pin_obj_t pin_PA22;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA23
|
|
||||||
extern const mcu_pin_obj_t pin_PA23;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA24
|
|
||||||
extern const mcu_pin_obj_t pin_PA24;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA25
|
|
||||||
extern const mcu_pin_obj_t pin_PA25;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB22
|
|
||||||
extern const mcu_pin_obj_t pin_PB22;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB23
|
|
||||||
extern const mcu_pin_obj_t pin_PB23;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA27
|
|
||||||
extern const mcu_pin_obj_t pin_PA27;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA28
|
|
||||||
extern const mcu_pin_obj_t pin_PA28;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA30
|
|
||||||
extern const mcu_pin_obj_t pin_PA30;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA31
|
|
||||||
extern const mcu_pin_obj_t pin_PA31;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB30
|
|
||||||
extern const mcu_pin_obj_t pin_PB30;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB31
|
|
||||||
extern const mcu_pin_obj_t pin_PB31;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB00
|
|
||||||
extern const mcu_pin_obj_t pin_PB00;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB01
|
|
||||||
extern const mcu_pin_obj_t pin_PB01;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB02
|
|
||||||
extern const mcu_pin_obj_t pin_PB02;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB03
|
|
||||||
extern const mcu_pin_obj_t pin_PB03;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
|
|
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
#include "hpl/pm/hpl_pm_base.h"
|
|
||||||
|
|
||||||
// The clock initializer values are rather random, so we need to put them in
|
|
||||||
// tables for lookup. We can't compute them.
|
|
||||||
|
|
||||||
static const uint8_t SERCOMx_GCLK_ID_CORE[] = {
|
|
||||||
SERCOM0_GCLK_ID_CORE,
|
|
||||||
SERCOM1_GCLK_ID_CORE,
|
|
||||||
SERCOM2_GCLK_ID_CORE,
|
|
||||||
SERCOM3_GCLK_ID_CORE,
|
|
||||||
#ifdef SERCOM4
|
|
||||||
SERCOM4_GCLK_ID_CORE,
|
|
||||||
#endif
|
|
||||||
#ifdef SERCOM5
|
|
||||||
SERCOM5_GCLK_ID_CORE,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t SERCOMx_GCLK_ID_SLOW[] = {
|
|
||||||
SERCOM0_GCLK_ID_SLOW,
|
|
||||||
SERCOM1_GCLK_ID_SLOW,
|
|
||||||
SERCOM2_GCLK_ID_SLOW,
|
|
||||||
SERCOM3_GCLK_ID_SLOW,
|
|
||||||
#ifdef SERCOM4
|
|
||||||
SERCOM4_GCLK_ID_SLOW,
|
|
||||||
#endif
|
|
||||||
#ifdef SERCOM5
|
|
||||||
SERCOM5_GCLK_ID_SLOW,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS;
|
|
||||||
|
|
||||||
// Clock initialization as done in Atmel START.
|
|
||||||
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) {
|
|
||||||
_pm_enable_bus_clock(PM_BUS_APBC, sercom);
|
|
||||||
_gclk_enable_channel(SERCOMx_GCLK_ID_CORE[sercom_index], GCLK_CLKCTRL_GEN_GCLK0_Val);
|
|
||||||
_gclk_enable_channel(SERCOMx_GCLK_ID_SLOW[sercom_index], GCLK_CLKCTRL_GEN_GCLK3_Val);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out the DOPO value given the chosen clock pad and mosi pad.
|
|
||||||
// Return an out-of-range value (255) if the combination is not permitted.
|
|
||||||
// <0x0=>PAD[0,1]_DO_SCK
|
|
||||||
// <0x1=>PAD[2,3]_DO_SCK
|
|
||||||
// <0x2=>PAD[3,1]_DO_SCK
|
|
||||||
// <0x3=>PAD[0,3]_DO_SCK
|
|
||||||
uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) {
|
|
||||||
if (clock_pad == 1) {
|
|
||||||
if (mosi_pad == 0) {
|
|
||||||
return 0;
|
|
||||||
} else if (mosi_pad == 3) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
} else if (clock_pad == 3) {
|
|
||||||
if (mosi_pad == 0) {
|
|
||||||
return 3;
|
|
||||||
} else if (mosi_pad == 2) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) {
|
|
||||||
return clock_pad == 1 || clock_pad == 3;
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "peripherals/timers.h"
|
|
||||||
|
|
||||||
//#include "common-hal/pulseio/PulseOut.h"
|
|
||||||
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
|
|
||||||
const uint8_t tcc_cc_num[3] = {4, 2, 2};
|
|
||||||
const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC3_GCLK_ID,
|
|
||||||
TC4_GCLK_ID,
|
|
||||||
TC5_GCLK_ID,
|
|
||||||
#ifdef TC6_GCLK_ID
|
|
||||||
TC6_GCLK_ID,
|
|
||||||
#endif
|
|
||||||
#ifdef TC7_GCLK_ID
|
|
||||||
TC7_GCLK_ID,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
const uint8_t tcc_gclk_ids[3] = {TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID};
|
|
||||||
|
|
||||||
void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
|
|
||||||
uint8_t gclk_id;
|
|
||||||
if (is_tc) {
|
|
||||||
gclk_id = tc_gclk_ids[index];
|
|
||||||
} else {
|
|
||||||
gclk_id = tcc_gclk_ids[index];
|
|
||||||
}
|
|
||||||
// Determine the clock slot on the APBC bus. TCC0 is the first and 8 slots in.
|
|
||||||
uint8_t clock_slot = 8 + index;
|
|
||||||
// We index TCs starting at zero but in memory they begin at three so we have to add three.
|
|
||||||
if (is_tc) {
|
|
||||||
clock_slot += 3;
|
|
||||||
}
|
|
||||||
PM->APBCMASK.reg |= 1 << clock_slot;
|
|
||||||
_gclk_enable_channel(gclk_id, gclk_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tc_set_enable(Tc* tc, bool enable) {
|
|
||||||
tc->COUNT16.CTRLA.bit.ENABLE = enable;
|
|
||||||
while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {
|
|
||||||
/* Wait for sync */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tc_wait_for_sync(Tc* tc) {
|
|
||||||
while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hal/include/hal_adc_sync.h"
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
#include "hri/hri_mclk_d51.h"
|
|
||||||
|
|
||||||
// Do initialization and calibration setup needed for any use of the ADC.
|
|
||||||
// The reference and resolution should be set by the caller.
|
|
||||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
|
|
||||||
// Turn the clocks on.
|
|
||||||
if (instance == ADC0) {
|
|
||||||
hri_mclk_set_APBDMASK_ADC0_bit(MCLK);
|
|
||||||
hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
|
||||||
} else if (instance == ADC1) {
|
|
||||||
hri_mclk_set_APBDMASK_ADC1_bit(MCLK);
|
|
||||||
hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
adc_sync_init(adc, instance, (void *)NULL);
|
|
||||||
|
|
||||||
// SAMD51 has a CALIB register but doesn't have documented fuses for them.
|
|
||||||
uint8_t biasrefbuf;
|
|
||||||
uint8_t biasr2r;
|
|
||||||
uint8_t biascomp;
|
|
||||||
if (instance == ADC0) {
|
|
||||||
biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
|
|
||||||
biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
|
|
||||||
biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
|
|
||||||
} else {
|
|
||||||
biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos;
|
|
||||||
biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos;
|
|
||||||
biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos;
|
|
||||||
}
|
|
||||||
hri_adc_write_CALIB_BIASREFBUF_bf(instance, biasrefbuf);
|
|
||||||
hri_adc_write_CALIB_BIASR2R_bf(instance, biasr2r);
|
|
||||||
hri_adc_write_CALIB_BIASCOMP_bf(instance, biascomp);
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sam.h"
|
|
||||||
|
|
||||||
// Turn off cache and invalidate all data in it.
|
|
||||||
void samd_peripherals_disable_and_clear_cache(void) {
|
|
||||||
CMCC->CTRL.bit.CEN = 0;
|
|
||||||
while (CMCC->SR.bit.CSTS) {}
|
|
||||||
CMCC->MAINT0.bit.INVALL = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable cache
|
|
||||||
void samd_peripherals_enable_cache(void) {
|
|
||||||
CMCC->CTRL.bit.CEN = 1;
|
|
||||||
}
|
|
@ -1,480 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "peripherals/clocks.h"
|
|
||||||
|
|
||||||
#include "hpl_gclk_config.h"
|
|
||||||
|
|
||||||
#include "bindings/samd/Clock.h"
|
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
|
|
||||||
bool gclk_enabled(uint8_t gclk) {
|
|
||||||
return GCLK->GENCTRL[gclk].bit.GENEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_gclk(uint8_t gclk) {
|
|
||||||
while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {}
|
|
||||||
GCLK->GENCTRL[gclk].bit.GENEN = false;
|
|
||||||
while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral) {
|
|
||||||
GCLK->PCHCTRL[peripheral].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk);
|
|
||||||
while(GCLK->SYNCBUSY.reg != 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral) {
|
|
||||||
GCLK->PCHCTRL[peripheral].reg = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enable_clock_generator_sync(uint8_t gclk, uint32_t source, uint16_t divisor, bool sync) {
|
|
||||||
uint32_t divsel = 0;
|
|
||||||
// The datasheet says 8 bits and max value of 512, how is that possible?
|
|
||||||
if (divisor > 255) { // Generator 1 has 16 bits
|
|
||||||
divsel = GCLK_GENCTRL_DIVSEL;
|
|
||||||
for (int i = 15; i > 0; i--) {
|
|
||||||
if (divisor & (1 << i)) {
|
|
||||||
divisor = i - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GCLK->GENCTRL[gclk].reg = GCLK_GENCTRL_SRC(source) | GCLK_GENCTRL_DIV(divisor) | divsel | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN;
|
|
||||||
if (sync)
|
|
||||||
while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor) {
|
|
||||||
enable_clock_generator_sync(gclk, source, divisor, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_clock_generator(uint8_t gclk) {
|
|
||||||
GCLK->GENCTRL[gclk].reg = 0;
|
|
||||||
while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_clock_source_osculp32k(void) {
|
|
||||||
// Calibration value is loaded at startup
|
|
||||||
OSC32KCTRL->OSCULP32K.bit.EN1K = 1;
|
|
||||||
OSC32KCTRL->OSCULP32K.bit.EN32K = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_clock_source_xosc32k(void) {
|
|
||||||
OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ONDEMAND |
|
|
||||||
OSC32KCTRL_XOSC32K_EN1K |
|
|
||||||
OSC32KCTRL_XOSC32K_XTALEN |
|
|
||||||
OSC32KCTRL_XOSC32K_ENABLE |
|
|
||||||
OSC32KCTRL_XOSC32K_CGM(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_clock_source_dpll0(void)
|
|
||||||
{
|
|
||||||
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(5);
|
|
||||||
OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0) | OSCCTRL_DPLLRATIO_LDR(59);
|
|
||||||
OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK(0);
|
|
||||||
OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE;
|
|
||||||
|
|
||||||
while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY)) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clock_init(void) {
|
|
||||||
// DFLL48M is enabled by default
|
|
||||||
|
|
||||||
init_clock_source_osculp32k();
|
|
||||||
|
|
||||||
if (board_has_crystal()) {
|
|
||||||
init_clock_source_xosc32k();
|
|
||||||
OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K_Val;
|
|
||||||
} else {
|
|
||||||
OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K_Val;
|
|
||||||
}
|
|
||||||
|
|
||||||
MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV(1);
|
|
||||||
|
|
||||||
enable_clock_generator_sync(0, GCLK_GENCTRL_SRC_DPLL0_Val, 1, false);
|
|
||||||
enable_clock_generator_sync(1, GCLK_GENCTRL_SRC_DFLL_Val, 1, false);
|
|
||||||
enable_clock_generator_sync(4, GCLK_GENCTRL_SRC_DPLL0_Val, 1, false);
|
|
||||||
enable_clock_generator_sync(5, GCLK_GENCTRL_SRC_DFLL_Val, 24, false);
|
|
||||||
|
|
||||||
init_clock_source_dpll0();
|
|
||||||
|
|
||||||
// Do this after all static clock init so that they aren't used dynamically.
|
|
||||||
init_dynamic_clocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool clk_enabled(uint8_t clk) {
|
|
||||||
return GCLK->PCHCTRL[clk].bit.CHEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t clk_get_generator(uint8_t clk) {
|
|
||||||
return GCLK->PCHCTRL[clk].bit.GEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t generator_get_source(uint8_t gen) {
|
|
||||||
return GCLK->GENCTRL[gen].bit.SRC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool osc_enabled(uint8_t index) {
|
|
||||||
switch (index) {
|
|
||||||
case GCLK_SOURCE_XOSC0:
|
|
||||||
return OSCCTRL->XOSCCTRL[0].bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_XOSC1:
|
|
||||||
return OSCCTRL->XOSCCTRL[1].bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_OSCULP32K:
|
|
||||||
return true;
|
|
||||||
case GCLK_SOURCE_XOSC32K:
|
|
||||||
return OSC32KCTRL->XOSC32K.bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_DFLL:
|
|
||||||
return OSCCTRL->DFLLCTRLA.bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_DPLL0:
|
|
||||||
return OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE;
|
|
||||||
case GCLK_SOURCE_DPLL1:
|
|
||||||
return OSCCTRL->Dpll[1].DPLLCTRLA.bit.ENABLE;
|
|
||||||
};
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t osc_get_source(uint8_t index) {
|
|
||||||
uint8_t dpll_index = index - GCLK_SOURCE_DPLL0;
|
|
||||||
uint32_t refclk = OSCCTRL->Dpll[dpll_index].DPLLCTRLB.bit.REFCLK;
|
|
||||||
switch (refclk) {
|
|
||||||
case 0x0:
|
|
||||||
return generator_get_source(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + dpll_index].bit.GEN);
|
|
||||||
case 0x1:
|
|
||||||
return GCLK_SOURCE_XOSC32K;
|
|
||||||
case 0x2:
|
|
||||||
return GCLK_SOURCE_XOSC0;
|
|
||||||
case 0x3:
|
|
||||||
return GCLK_SOURCE_XOSC1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t osc_get_frequency(uint8_t index);
|
|
||||||
|
|
||||||
static uint32_t generator_get_frequency(uint8_t gen) {
|
|
||||||
uint8_t src = GCLK->GENCTRL[gen].bit.SRC;
|
|
||||||
uint32_t div;
|
|
||||||
if (GCLK->GENCTRL[gen].bit.DIVSEL) {
|
|
||||||
div = 1 << (GCLK->GENCTRL[gen].bit.DIV + 1);
|
|
||||||
} else {
|
|
||||||
div = GCLK->GENCTRL[gen].bit.DIV;
|
|
||||||
if (!div)
|
|
||||||
div = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return osc_get_frequency(src) / div;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t dpll_get_frequency(uint8_t index) {
|
|
||||||
uint8_t dpll_index = index - GCLK_SOURCE_DPLL0;
|
|
||||||
uint32_t refclk = OSCCTRL->Dpll[dpll_index].DPLLCTRLB.bit.REFCLK;
|
|
||||||
uint32_t freq;
|
|
||||||
|
|
||||||
switch (refclk) {
|
|
||||||
case 0x0: // GCLK
|
|
||||||
freq = generator_get_frequency(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + dpll_index].bit.GEN);
|
|
||||||
break;
|
|
||||||
case 0x1: // XOSC32
|
|
||||||
freq = 32768;
|
|
||||||
break;
|
|
||||||
case 0x2: // XOSC0
|
|
||||||
case 0x3: // XOSC1
|
|
||||||
default:
|
|
||||||
return 0; // unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
return (freq * (OSCCTRL->Dpll[dpll_index].DPLLRATIO.bit.LDR + 1)) +
|
|
||||||
(freq * OSCCTRL->Dpll[dpll_index].DPLLRATIO.bit.LDRFRAC / 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t osc_get_frequency(uint8_t index) {
|
|
||||||
switch (index) {
|
|
||||||
case GCLK_SOURCE_XOSC0:
|
|
||||||
case GCLK_SOURCE_XOSC1:
|
|
||||||
return 0; // unknown
|
|
||||||
case GCLK_SOURCE_OSCULP32K:
|
|
||||||
case GCLK_SOURCE_XOSC32K:
|
|
||||||
return 32768;
|
|
||||||
case GCLK_SOURCE_DFLL:
|
|
||||||
return 48000000;
|
|
||||||
case GCLK_SOURCE_DPLL0:
|
|
||||||
case GCLK_SOURCE_DPLL1:
|
|
||||||
return dpll_get_frequency(index);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clock_get_enabled(uint8_t type, uint8_t index) {
|
|
||||||
if (type == 0)
|
|
||||||
return osc_enabled(index);
|
|
||||||
if (type == 1)
|
|
||||||
return clk_enabled(index);
|
|
||||||
if (type == 2)
|
|
||||||
return SysTick->CTRL & SysTick_CTRL_ENABLE_Msk;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index) {
|
|
||||||
if (type == 0 && osc_enabled(index)) {
|
|
||||||
if (index == GCLK_SOURCE_DPLL0 || index == GCLK_SOURCE_DPLL1) {
|
|
||||||
*p_type = 0;
|
|
||||||
*p_index = osc_get_source(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (type == 1 && index <= 47 && clk_enabled(index)) {
|
|
||||||
*p_type = 0;
|
|
||||||
*p_index = generator_get_source(clk_get_generator(index));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == 2) {
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
*p_type = 0;
|
|
||||||
*p_index = generator_get_source(0);
|
|
||||||
return true;
|
|
||||||
case 2:
|
|
||||||
*p_type = 0;
|
|
||||||
switch (OSC32KCTRL->RTCCTRL.bit.RTCSEL) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
*p_index = GCLK_SOURCE_OSCULP32K;
|
|
||||||
return true;
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
*p_index = GCLK_SOURCE_XOSC32K;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t clock_get_frequency(uint8_t type, uint8_t index) {
|
|
||||||
if (type == 0) {
|
|
||||||
return osc_get_frequency(index);
|
|
||||||
}
|
|
||||||
if (type == 1 && index <= 47 && clk_enabled(index)) {
|
|
||||||
return generator_get_frequency(clk_get_generator(index));
|
|
||||||
}
|
|
||||||
if (type == 2) {
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
return clock_get_frequency(0, generator_get_source(0)) / SysTick->LOAD;
|
|
||||||
case 1:
|
|
||||||
return clock_get_frequency(0, generator_get_source(0)) / MCLK->CPUDIV.bit.DIV;
|
|
||||||
case 2:
|
|
||||||
switch (OSC32KCTRL->RTCCTRL.bit.RTCSEL) {
|
|
||||||
case 0:
|
|
||||||
case 4:
|
|
||||||
return 1024;
|
|
||||||
case 1:
|
|
||||||
case 5:
|
|
||||||
return 32768;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t clock_get_calibration(uint8_t type, uint8_t index) {
|
|
||||||
if (type == 0) {
|
|
||||||
switch (index) {
|
|
||||||
case GCLK_SOURCE_OSCULP32K:
|
|
||||||
return OSC32KCTRL->OSCULP32K.bit.CALIB;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (type == 2 && index == 0) {
|
|
||||||
return SysTick->LOAD + 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val) {
|
|
||||||
if (type == 0) {
|
|
||||||
switch (index) {
|
|
||||||
case GCLK_SOURCE_OSCULP32K:
|
|
||||||
if (val > 0x3f)
|
|
||||||
return -1;
|
|
||||||
OSC32KCTRL->OSCULP32K.bit.CALIB = val;
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (type == 2 && index == 0) {
|
|
||||||
if (val < 0x1000 || val > 0x1000000)
|
|
||||||
return -1;
|
|
||||||
SysTick->LOAD = val - 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void save_usb_clock_calibration(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <instance/can0.h>
|
|
||||||
#include <instance/can1.h>
|
|
||||||
#include <instance/i2s.h>
|
|
||||||
#include <instance/sdhc1.h>
|
|
||||||
#include <instance/sercom6.h>
|
|
||||||
#include <instance/sercom7.h>
|
|
||||||
#include <instance/tcc4.h>
|
|
||||||
|
|
||||||
CLOCK_SOURCE(XOSC0);
|
|
||||||
CLOCK_SOURCE(XOSC1);
|
|
||||||
CLOCK_SOURCE(GCLKIN);
|
|
||||||
CLOCK_SOURCE(GCLKGEN1);
|
|
||||||
CLOCK_SOURCE(OSCULP32K);
|
|
||||||
CLOCK_SOURCE(XOSC32K);
|
|
||||||
CLOCK_SOURCE(DFLL);
|
|
||||||
CLOCK_SOURCE(DPLL0);
|
|
||||||
CLOCK_SOURCE(DPLL1);
|
|
||||||
|
|
||||||
CLOCK_GCLK_(OSCCTRL, DFLL48);
|
|
||||||
CLOCK_GCLK_(OSCCTRL, FDPLL0);
|
|
||||||
CLOCK_GCLK_(OSCCTRL, FDPLL1);
|
|
||||||
CLOCK_GCLK_(OSCCTRL, FDPLL032K); // GCLK_OSCCTRL_FDPLL1_32K, GCLK_SDHC0_SLOW, GCLK_SDHC1_SLOW, GCLK_SERCOM[0..7]_SLOW
|
|
||||||
CLOCK_GCLK(EIC);
|
|
||||||
CLOCK_GCLK_(FREQM, MSR);
|
|
||||||
// 6: GCLK_FREQM_REF
|
|
||||||
CLOCK_GCLK_(SERCOM0, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM1, CORE);
|
|
||||||
CLOCK(TC0_TC1, 1, 9);
|
|
||||||
CLOCK_GCLK(USB);
|
|
||||||
CLOCK_GCLK_(EVSYS, 0);
|
|
||||||
CLOCK_GCLK_(EVSYS, 1);
|
|
||||||
CLOCK_GCLK_(EVSYS, 2);
|
|
||||||
CLOCK_GCLK_(EVSYS, 3);
|
|
||||||
CLOCK_GCLK_(EVSYS, 4);
|
|
||||||
CLOCK_GCLK_(EVSYS, 5);
|
|
||||||
CLOCK_GCLK_(EVSYS, 6);
|
|
||||||
CLOCK_GCLK_(EVSYS, 7);
|
|
||||||
CLOCK_GCLK_(EVSYS, 8);
|
|
||||||
CLOCK_GCLK_(EVSYS, 9);
|
|
||||||
CLOCK_GCLK_(EVSYS, 10);
|
|
||||||
CLOCK_GCLK_(EVSYS, 11);
|
|
||||||
CLOCK_GCLK_(SERCOM2, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM3, CORE);
|
|
||||||
CLOCK(TCC0_TCC1, 1, 25);
|
|
||||||
CLOCK(TC2_TC3, 1, 26);
|
|
||||||
CLOCK_GCLK(CAN0);
|
|
||||||
CLOCK_GCLK(CAN1);
|
|
||||||
CLOCK(TCC2_TCC3, 1, 29);
|
|
||||||
CLOCK(TC4_TC5, 1, 30);
|
|
||||||
CLOCK_GCLK(PDEC);
|
|
||||||
CLOCK_GCLK(AC);
|
|
||||||
CLOCK_GCLK(CCL);
|
|
||||||
CLOCK_GCLK_(SERCOM4, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM5, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM6, CORE);
|
|
||||||
CLOCK_GCLK_(SERCOM7, CORE);
|
|
||||||
CLOCK_GCLK(TCC4);
|
|
||||||
CLOCK(TC6_TC7, 1, 39);
|
|
||||||
CLOCK_GCLK(ADC0);
|
|
||||||
CLOCK_GCLK(ADC1);
|
|
||||||
CLOCK_GCLK(DAC);
|
|
||||||
CLOCK_GCLK_(I2S, 0);
|
|
||||||
CLOCK_GCLK_(I2S, 1);
|
|
||||||
CLOCK_GCLK(SDHC0);
|
|
||||||
CLOCK_GCLK(SDHC1);
|
|
||||||
// 47: GCLK_CM4_TRACE
|
|
||||||
|
|
||||||
CLOCK(SYSTICK, 2, 0);
|
|
||||||
CLOCK(CPU, 2, 1);
|
|
||||||
CLOCK(RTC, 2, 2);
|
|
||||||
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t samd_clock_global_dict_table[] = {
|
|
||||||
CLOCK_ENTRY(XOSC0),
|
|
||||||
CLOCK_ENTRY(XOSC1),
|
|
||||||
CLOCK_ENTRY(GCLKIN),
|
|
||||||
CLOCK_ENTRY(GCLKGEN1),
|
|
||||||
CLOCK_ENTRY(OSCULP32K),
|
|
||||||
CLOCK_ENTRY(XOSC32K),
|
|
||||||
CLOCK_ENTRY(DFLL),
|
|
||||||
CLOCK_ENTRY(DPLL0),
|
|
||||||
CLOCK_ENTRY(DPLL1),
|
|
||||||
|
|
||||||
CLOCK_ENTRY_(OSCCTRL, DFLL48),
|
|
||||||
CLOCK_ENTRY_(OSCCTRL, FDPLL0),
|
|
||||||
CLOCK_ENTRY_(OSCCTRL, FDPLL1),
|
|
||||||
CLOCK_ENTRY_(OSCCTRL, FDPLL032K),
|
|
||||||
CLOCK_ENTRY(EIC),
|
|
||||||
CLOCK_ENTRY_(FREQM, MSR),
|
|
||||||
CLOCK_ENTRY_(SERCOM0, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM1, CORE),
|
|
||||||
CLOCK_ENTRY(TC0_TC1),
|
|
||||||
CLOCK_ENTRY(USB),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 0),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 1),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 2),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 3),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 4),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 5),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 6),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 7),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 8),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 9),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 10),
|
|
||||||
CLOCK_ENTRY_(EVSYS, 11),
|
|
||||||
CLOCK_ENTRY_(SERCOM2, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM3, CORE),
|
|
||||||
CLOCK_ENTRY(TCC0_TCC1),
|
|
||||||
CLOCK_ENTRY(TC2_TC3),
|
|
||||||
CLOCK_ENTRY(CAN0),
|
|
||||||
CLOCK_ENTRY(CAN1),
|
|
||||||
CLOCK_ENTRY(TCC2_TCC3),
|
|
||||||
CLOCK_ENTRY(TC4_TC5),
|
|
||||||
CLOCK_ENTRY(PDEC),
|
|
||||||
CLOCK_ENTRY(AC),
|
|
||||||
CLOCK_ENTRY(CCL),
|
|
||||||
CLOCK_ENTRY_(SERCOM4, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM5, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM6, CORE),
|
|
||||||
CLOCK_ENTRY_(SERCOM7, CORE),
|
|
||||||
CLOCK_ENTRY(TCC4),
|
|
||||||
CLOCK_ENTRY(TC6_TC7),
|
|
||||||
CLOCK_ENTRY(ADC0),
|
|
||||||
CLOCK_ENTRY(ADC1),
|
|
||||||
CLOCK_ENTRY(DAC),
|
|
||||||
CLOCK_ENTRY_(I2S, 0),
|
|
||||||
CLOCK_ENTRY_(I2S, 1),
|
|
||||||
CLOCK_ENTRY(SDHC0),
|
|
||||||
CLOCK_ENTRY(SDHC1),
|
|
||||||
|
|
||||||
CLOCK_ENTRY(SYSTICK),
|
|
||||||
CLOCK_ENTRY(CPU),
|
|
||||||
CLOCK_ENTRY(RTC),
|
|
||||||
};
|
|
||||||
MP_DEFINE_CONST_DICT(samd_clock_globals, samd_clock_global_dict_table);
|
|
@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "peripherals/dma.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "py/gc.h"
|
|
||||||
#include "py/mpstate.h"
|
|
||||||
|
|
||||||
#include "hal/utils/include/utils.h"
|
|
||||||
|
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
|
||||||
|
|
||||||
uint8_t sercom_index(Sercom* sercom) {
|
|
||||||
const Sercom* sercoms[SERCOM_INST_NUM] = SERCOM_INSTS;
|
|
||||||
for (uint8_t i = 0; i < SERCOM_INST_NUM; i++) {
|
|
||||||
if (sercoms[i] == sercom) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) {
|
|
||||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
|
||||||
channel->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
|
|
||||||
channel->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
|
|
||||||
if (output_event) {
|
|
||||||
channel->CHEVCTRL.reg = DMAC_CHEVCTRL_EVOE;
|
|
||||||
}
|
|
||||||
channel->CHCTRLA.reg = DMAC_CHCTRLA_TRIGSRC(trigsrc) |
|
|
||||||
DMAC_CHCTRLA_TRIGACT_BURST |
|
|
||||||
DMAC_CHCTRLA_BURSTLEN_SINGLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_enable_channel(uint8_t channel_number) {
|
|
||||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
|
||||||
channel->CHCTRLA.bit.ENABLE = true;
|
|
||||||
// Clear any previous interrupts.
|
|
||||||
channel->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_disable_channel(uint8_t channel_number) {
|
|
||||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
|
||||||
channel->CHCTRLA.bit.ENABLE = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_suspend_channel(uint8_t channel_number) {
|
|
||||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
|
||||||
channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_SUSPEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dma_resume_channel(uint8_t channel_number) {
|
|
||||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
|
||||||
channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_RESUME;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dma_channel_enabled(uint8_t channel_number) {
|
|
||||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
|
||||||
return channel->CHCTRLA.bit.ENABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t dma_transfer_status(uint8_t channel_number) {
|
|
||||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
|
||||||
return channel->CHINTFLAG.reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dma_channel_free(uint8_t channel_number) {
|
|
||||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
|
||||||
return channel->CHSTATUS.reg == 0;
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "peripherals/events.h"
|
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
|
|
||||||
#include "hri/hri_mclk_d51.h"
|
|
||||||
|
|
||||||
void turn_on_event_system(void) {
|
|
||||||
hri_mclk_set_APBBMASK_EVSYS_bit(MCLK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_event_system(void) {
|
|
||||||
EVSYS->CTRLA.bit.SWRST = true;
|
|
||||||
hri_mclk_clear_APBBMASK_EVSYS_bit(MCLK);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool event_channel_free(uint8_t channel) {
|
|
||||||
uint8_t generator;
|
|
||||||
generator = EVSYS->Channel[channel].CHANNEL.bit.EVGEN;
|
|
||||||
return generator == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_event_channel(uint8_t channel_number) {
|
|
||||||
EVSYS->Channel[channel_number].CHANNEL.reg = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_event_user(uint8_t user_number) {
|
|
||||||
EVSYS->USER[user_number].reg = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void connect_event_user_to_channel(uint8_t user, uint8_t channel) {
|
|
||||||
EVSYS->USER[user].reg = channel + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_async_event_channel(uint8_t channel, uint8_t generator) {
|
|
||||||
EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator) {
|
|
||||||
connect_gclk_to_peripheral(gclk, EVSYS_GCLK_ID_0 + channel);
|
|
||||||
EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) |
|
|
||||||
EVSYS_CHANNEL_PATH_SYNCHRONOUS |
|
|
||||||
EVSYS_CHANNEL_EDGSEL_RISING_EDGE;
|
|
||||||
EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
|
|
||||||
EVSYS->Channel[channel].CHINTENSET.reg = EVSYS_CHINTENSET_EVD | EVSYS_CHINTENSET_OVR;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool event_interrupt_active(uint8_t channel) {
|
|
||||||
bool active = false;
|
|
||||||
active = EVSYS->Channel[channel].CHINTFLAG.bit.EVD;
|
|
||||||
// Only clear if we know its active, otherwise there is the possibility it becomes after we
|
|
||||||
// check but before we clear.
|
|
||||||
if (active) {
|
|
||||||
EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
|
|
||||||
}
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool event_interrupt_overflow(uint8_t channel) {
|
|
||||||
return EVSYS->Channel[channel].CHINTFLAG.bit.OVR;
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "peripherals/external_interrupts.h"
|
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
|
||||||
#include "sam.h"
|
|
||||||
|
|
||||||
void turn_on_external_interrupt_controller(void) {
|
|
||||||
MCLK->APBAMASK.bit.EIC_ = true;
|
|
||||||
|
|
||||||
// We use the 48mhz clock to lightly filter the incoming pulse to reduce spurious interrupts.
|
|
||||||
connect_gclk_to_peripheral(GCLK_PCHCTRL_GEN_GCLK1_Val, EIC_GCLK_ID);
|
|
||||||
eic_set_enable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void turn_off_external_interrupt_controller(void) {
|
|
||||||
eic_set_enable(false);
|
|
||||||
MCLK->APBAMASK.bit.EIC_ = false;
|
|
||||||
disconnect_gclk_from_peripheral(GCLK_PCHCTRL_GEN_GCLK1_Val, EIC_GCLK_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void turn_on_cpu_interrupt(uint8_t eic_channel) {
|
|
||||||
// Ignore the channel since the CPU interrupt line is shared.
|
|
||||||
(void) eic_channel;
|
|
||||||
|
|
||||||
NVIC_DisableIRQ(EIC_0_IRQn + eic_channel);
|
|
||||||
NVIC_ClearPendingIRQ(EIC_0_IRQn + eic_channel);
|
|
||||||
NVIC_EnableIRQ(EIC_0_IRQn + eic_channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eic_get_enable(void) {
|
|
||||||
return EIC->CTRLA.bit.ENABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void eic_set_enable(bool value) {
|
|
||||||
EIC->CTRLA.bit.ENABLE = value;
|
|
||||||
while (EIC->SYNCBUSY.bit.ENABLE != 0) {}
|
|
||||||
// This won't actually block long enough in Rev A of SAMD51 and will miss edges in the first
|
|
||||||
// three cycles of the peripheral clock. See the errata for details. It shouldn't impact us.
|
|
||||||
}
|
|
||||||
|
|
||||||
void eic_reset(void) {
|
|
||||||
EIC->CTRLA.bit.SWRST = true;
|
|
||||||
while (EIC->SYNCBUSY.bit.SWRST != 0) {}
|
|
||||||
// This won't actually block long enough in Rev A of SAMD51 and will miss edges in the first
|
|
||||||
// three cycles of the peripheral clock. See the errata for details. It shouldn't impact us.
|
|
||||||
for (int i = 0; i < EIC_EXTINT_NUM; i++) {
|
|
||||||
set_eic_channel_data(i, NULL);
|
|
||||||
NVIC_DisableIRQ(EIC_0_IRQn + i);
|
|
||||||
NVIC_ClearPendingIRQ(EIC_0_IRQn + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eic_channel_free(uint8_t eic_channel) {
|
|
||||||
uint32_t mask = 1 << eic_channel;
|
|
||||||
return get_eic_channel_data(eic_channel) == NULL &&
|
|
||||||
(EIC->INTENSET.bit.EXTINT & mask) == 0 &&
|
|
||||||
(EIC->EVCTRL.bit.EXTINTEO & mask) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EIC_0_Handler(void) {
|
|
||||||
external_interrupt_handler(0);
|
|
||||||
}
|
|
||||||
void EIC_1_Handler(void) {
|
|
||||||
external_interrupt_handler(1);
|
|
||||||
}
|
|
||||||
void EIC_2_Handler(void) {
|
|
||||||
external_interrupt_handler(2);
|
|
||||||
}
|
|
||||||
void EIC_3_Handler(void) {
|
|
||||||
external_interrupt_handler(3);
|
|
||||||
}
|
|
||||||
void EIC_4_Handler(void) {
|
|
||||||
external_interrupt_handler(4);
|
|
||||||
}
|
|
||||||
void EIC_5_Handler(void) {
|
|
||||||
external_interrupt_handler(5);
|
|
||||||
}
|
|
||||||
void EIC_6_Handler(void) {
|
|
||||||
external_interrupt_handler(6);
|
|
||||||
}
|
|
||||||
void EIC_7_Handler(void) {
|
|
||||||
external_interrupt_handler(7);
|
|
||||||
}
|
|
||||||
void EIC_8_Handler(void) {
|
|
||||||
external_interrupt_handler(8);
|
|
||||||
}
|
|
||||||
void EIC_9_Handler(void) {
|
|
||||||
external_interrupt_handler(9);
|
|
||||||
}
|
|
||||||
void EIC_10_Handler(void) {
|
|
||||||
external_interrupt_handler(10);
|
|
||||||
}
|
|
||||||
void EIC_11_Handler(void) {
|
|
||||||
external_interrupt_handler(11);
|
|
||||||
}
|
|
||||||
void EIC_12_Handler(void) {
|
|
||||||
external_interrupt_handler(12);
|
|
||||||
}
|
|
||||||
void EIC_13_Handler(void) {
|
|
||||||
external_interrupt_handler(13);
|
|
||||||
}
|
|
||||||
void EIC_14_Handler(void) {
|
|
||||||
external_interrupt_handler(14);
|
|
||||||
}
|
|
||||||
void EIC_15_Handler(void) {
|
|
||||||
external_interrupt_handler(15);
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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 "peripherals/i2s.h"
|
|
||||||
|
|
||||||
#include "peripherals/clocks.h"
|
|
||||||
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
|
|
||||||
void turn_on_i2s(void) {
|
|
||||||
// Make sure the I2S peripheral is running so we can see if the resources we need are free.
|
|
||||||
hri_mclk_set_APBDMASK_I2S_bit(MCLK);
|
|
||||||
|
|
||||||
// Connect the clock units to the 2mhz clock by default. They can't reset without it.
|
|
||||||
connect_gclk_to_peripheral(5, I2S_GCLK_ID_0);
|
|
||||||
connect_gclk_to_peripheral(5, I2S_GCLK_ID_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void i2s_set_serializer_enable(uint8_t serializer, bool enable) {
|
|
||||||
if (serializer == 0) {
|
|
||||||
while (I2S->SYNCBUSY.bit.TXEN == 1) {}
|
|
||||||
I2S->CTRLA.bit.TXEN = enable;
|
|
||||||
while (I2S->SYNCBUSY.bit.TXEN == 1) {}
|
|
||||||
} else {
|
|
||||||
while (I2S->SYNCBUSY.bit.RXEN == 1) {}
|
|
||||||
I2S->CTRLA.bit.RXEN = enable;
|
|
||||||
while (I2S->SYNCBUSY.bit.RXEN == 1) {}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,349 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
|
|
||||||
// that all necessary includes are already included.
|
|
||||||
|
|
||||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H
|
|
||||||
|
|
||||||
#include "include/sam.h"
|
|
||||||
|
|
||||||
void reset_pin(uint8_t pin);
|
|
||||||
|
|
||||||
#define MUX_C 2
|
|
||||||
#define MUX_D 3
|
|
||||||
#define MUX_E 4
|
|
||||||
#define MUX_F 5
|
|
||||||
#define PINMUX(pin, mux) ((((uint32_t) pin) << 16) | (mux))
|
|
||||||
|
|
||||||
#define NO_PIN PORT_BITS
|
|
||||||
|
|
||||||
// Pins in datasheet order.
|
|
||||||
#ifdef PIN_PB03
|
|
||||||
extern const mcu_pin_obj_t pin_PB03;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA00
|
|
||||||
extern const mcu_pin_obj_t pin_PA00;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA01
|
|
||||||
extern const mcu_pin_obj_t pin_PA01;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC00
|
|
||||||
extern const mcu_pin_obj_t pin_PC00;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC01
|
|
||||||
extern const mcu_pin_obj_t pin_PC01;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC02
|
|
||||||
extern const mcu_pin_obj_t pin_PC02;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC03
|
|
||||||
extern const mcu_pin_obj_t pin_PC03;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA02
|
|
||||||
extern const mcu_pin_obj_t pin_PA02;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA03
|
|
||||||
extern const mcu_pin_obj_t pin_PA03;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB04
|
|
||||||
extern const mcu_pin_obj_t pin_PB04;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB05
|
|
||||||
extern const mcu_pin_obj_t pin_PB05;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD00
|
|
||||||
extern const mcu_pin_obj_t pin_PD00;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD01
|
|
||||||
extern const mcu_pin_obj_t pin_PD01;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB06
|
|
||||||
extern const mcu_pin_obj_t pin_PB06;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB07
|
|
||||||
extern const mcu_pin_obj_t pin_PB07;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB08
|
|
||||||
extern const mcu_pin_obj_t pin_PB08;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB09
|
|
||||||
extern const mcu_pin_obj_t pin_PB09;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA04
|
|
||||||
extern const mcu_pin_obj_t pin_PA04;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA05
|
|
||||||
extern const mcu_pin_obj_t pin_PA05;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA06
|
|
||||||
extern const mcu_pin_obj_t pin_PA06;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Second page
|
|
||||||
#ifdef PIN_PA07
|
|
||||||
extern const mcu_pin_obj_t pin_PA07;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC04
|
|
||||||
extern const mcu_pin_obj_t pin_PC04;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC05
|
|
||||||
extern const mcu_pin_obj_t pin_PC05;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC06
|
|
||||||
extern const mcu_pin_obj_t pin_PC06;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC07
|
|
||||||
extern const mcu_pin_obj_t pin_PC07;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA08
|
|
||||||
extern const mcu_pin_obj_t pin_PA08;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA09
|
|
||||||
extern const mcu_pin_obj_t pin_PA09;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA10
|
|
||||||
extern const mcu_pin_obj_t pin_PA10;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA11
|
|
||||||
extern const mcu_pin_obj_t pin_PA11;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB10
|
|
||||||
extern const mcu_pin_obj_t pin_PB10;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB11
|
|
||||||
extern const mcu_pin_obj_t pin_PB11;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB12
|
|
||||||
extern const mcu_pin_obj_t pin_PB12;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB13
|
|
||||||
extern const mcu_pin_obj_t pin_PB13;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB14
|
|
||||||
extern const mcu_pin_obj_t pin_PB14;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB15
|
|
||||||
extern const mcu_pin_obj_t pin_PB15;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD08
|
|
||||||
extern const mcu_pin_obj_t pin_PD08;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD09
|
|
||||||
extern const mcu_pin_obj_t pin_PD09;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD10
|
|
||||||
extern const mcu_pin_obj_t pin_PD10;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD11
|
|
||||||
extern const mcu_pin_obj_t pin_PD11;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD12
|
|
||||||
extern const mcu_pin_obj_t pin_PD12;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC10
|
|
||||||
extern const mcu_pin_obj_t pin_PC10;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC11
|
|
||||||
extern const mcu_pin_obj_t pin_PC11;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC12
|
|
||||||
extern const mcu_pin_obj_t pin_PC12;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC13
|
|
||||||
extern const mcu_pin_obj_t pin_PC13;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC14
|
|
||||||
extern const mcu_pin_obj_t pin_PC14;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC15
|
|
||||||
extern const mcu_pin_obj_t pin_PC15;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA12
|
|
||||||
extern const mcu_pin_obj_t pin_PA12;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA13
|
|
||||||
extern const mcu_pin_obj_t pin_PA13;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Third page
|
|
||||||
#ifdef PIN_PA14
|
|
||||||
extern const mcu_pin_obj_t pin_PA14;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA15
|
|
||||||
extern const mcu_pin_obj_t pin_PA15;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA16
|
|
||||||
extern const mcu_pin_obj_t pin_PA16;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA17
|
|
||||||
extern const mcu_pin_obj_t pin_PA17;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA18
|
|
||||||
extern const mcu_pin_obj_t pin_PA18;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA19
|
|
||||||
extern const mcu_pin_obj_t pin_PA19;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC16
|
|
||||||
extern const mcu_pin_obj_t pin_PC16;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC17
|
|
||||||
extern const mcu_pin_obj_t pin_PC17;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC18
|
|
||||||
extern const mcu_pin_obj_t pin_PC18;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC19
|
|
||||||
extern const mcu_pin_obj_t pin_PC19;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC20
|
|
||||||
extern const mcu_pin_obj_t pin_PC20;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC21
|
|
||||||
extern const mcu_pin_obj_t pin_PC21;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC22
|
|
||||||
extern const mcu_pin_obj_t pin_PC22;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC23
|
|
||||||
extern const mcu_pin_obj_t pin_PC23;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD20
|
|
||||||
extern const mcu_pin_obj_t pin_PD20;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PD21
|
|
||||||
extern const mcu_pin_obj_t pin_PD21;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB16
|
|
||||||
extern const mcu_pin_obj_t pin_PB16;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB17
|
|
||||||
extern const mcu_pin_obj_t pin_PB17;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB18
|
|
||||||
extern const mcu_pin_obj_t pin_PB18;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB19
|
|
||||||
extern const mcu_pin_obj_t pin_PB19;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB20
|
|
||||||
extern const mcu_pin_obj_t pin_PB20;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB21
|
|
||||||
extern const mcu_pin_obj_t pin_PB21;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA20
|
|
||||||
extern const mcu_pin_obj_t pin_PA20;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA21
|
|
||||||
extern const mcu_pin_obj_t pin_PA21;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA22
|
|
||||||
extern const mcu_pin_obj_t pin_PA22;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA23
|
|
||||||
extern const mcu_pin_obj_t pin_PA23;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA24
|
|
||||||
extern const mcu_pin_obj_t pin_PA24;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA25
|
|
||||||
extern const mcu_pin_obj_t pin_PA25;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Fourth page
|
|
||||||
#ifdef PIN_PB22
|
|
||||||
extern const mcu_pin_obj_t pin_PB22;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB23
|
|
||||||
extern const mcu_pin_obj_t pin_PB23;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB24
|
|
||||||
extern const mcu_pin_obj_t pin_PB24;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB25
|
|
||||||
extern const mcu_pin_obj_t pin_PB25;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB26
|
|
||||||
extern const mcu_pin_obj_t pin_PB26;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB27
|
|
||||||
extern const mcu_pin_obj_t pin_PB27;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB28
|
|
||||||
extern const mcu_pin_obj_t pin_PB28;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB29
|
|
||||||
extern const mcu_pin_obj_t pin_PB29;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC24
|
|
||||||
extern const mcu_pin_obj_t pin_PC24;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC25
|
|
||||||
extern const mcu_pin_obj_t pin_PC25;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC26
|
|
||||||
extern const mcu_pin_obj_t pin_PC26;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC27
|
|
||||||
extern const mcu_pin_obj_t pin_PC27;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC28
|
|
||||||
extern const mcu_pin_obj_t pin_PC28;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA27
|
|
||||||
extern const mcu_pin_obj_t pin_PA27;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA30
|
|
||||||
extern const mcu_pin_obj_t pin_PA30;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PA31
|
|
||||||
extern const mcu_pin_obj_t pin_PA31;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB30
|
|
||||||
extern const mcu_pin_obj_t pin_PB30;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB31
|
|
||||||
extern const mcu_pin_obj_t pin_PB31;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC30
|
|
||||||
extern const mcu_pin_obj_t pin_PC30;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PC31
|
|
||||||
extern const mcu_pin_obj_t pin_PC31;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB00
|
|
||||||
extern const mcu_pin_obj_t pin_PB00;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB01
|
|
||||||
extern const mcu_pin_obj_t pin_PB01;
|
|
||||||
#endif
|
|
||||||
#ifdef PIN_PB02
|
|
||||||
extern const mcu_pin_obj_t pin_PB02;
|
|
||||||
#endif
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H
|
|
@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hal/include/hal_adc_sync.h"
|
|
||||||
#include "hpl/gclk/hpl_gclk_base.h"
|
|
||||||
#include "hri/hri_mclk_d51.h"
|
|
||||||
|
|
||||||
// The clock initializer values are rather random, so we need to put them in
|
|
||||||
// tables for lookup. We can't compute them.
|
|
||||||
|
|
||||||
static const uint8_t SERCOMx_GCLK_ID_CORE[] = {
|
|
||||||
SERCOM0_GCLK_ID_CORE,
|
|
||||||
SERCOM1_GCLK_ID_CORE,
|
|
||||||
SERCOM2_GCLK_ID_CORE,
|
|
||||||
SERCOM3_GCLK_ID_CORE,
|
|
||||||
SERCOM4_GCLK_ID_CORE,
|
|
||||||
SERCOM5_GCLK_ID_CORE,
|
|
||||||
#ifdef SERCOM6
|
|
||||||
SERCOM6_GCLK_ID_CORE,
|
|
||||||
#endif
|
|
||||||
#ifdef SERCOM7
|
|
||||||
SERCOM7_GCLK_ID_CORE,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t SERCOMx_GCLK_ID_SLOW[] = {
|
|
||||||
SERCOM0_GCLK_ID_SLOW,
|
|
||||||
SERCOM1_GCLK_ID_SLOW,
|
|
||||||
SERCOM2_GCLK_ID_SLOW,
|
|
||||||
SERCOM3_GCLK_ID_SLOW,
|
|
||||||
SERCOM4_GCLK_ID_SLOW,
|
|
||||||
SERCOM5_GCLK_ID_SLOW,
|
|
||||||
#ifdef SERCOM6
|
|
||||||
SERCOM6_GCLK_ID_SLOW,
|
|
||||||
#endif
|
|
||||||
#ifdef SERCOM7
|
|
||||||
SERCOM7_GCLK_ID_SLOW,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS;
|
|
||||||
|
|
||||||
// Clock initialization as done in Atmel START.
|
|
||||||
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) {
|
|
||||||
hri_gclk_write_PCHCTRL_reg(GCLK,
|
|
||||||
SERCOMx_GCLK_ID_CORE[sercom_index],
|
|
||||||
GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
|
||||||
hri_gclk_write_PCHCTRL_reg(GCLK,
|
|
||||||
SERCOMx_GCLK_ID_SLOW[sercom_index],
|
|
||||||
GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
|
||||||
|
|
||||||
// hri_mclk_set_APBAMASK_SERCOMx_bit is an inline, so let's use a switch, not a table.
|
|
||||||
switch (sercom_index) {
|
|
||||||
case 0:
|
|
||||||
hri_mclk_set_APBAMASK_SERCOM0_bit(MCLK);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
hri_mclk_set_APBAMASK_SERCOM1_bit(MCLK);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
hri_mclk_set_APBBMASK_SERCOM2_bit(MCLK);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
hri_mclk_set_APBBMASK_SERCOM3_bit(MCLK);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
hri_mclk_set_APBDMASK_SERCOM4_bit(MCLK);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
hri_mclk_set_APBDMASK_SERCOM5_bit(MCLK);
|
|
||||||
break;
|
|
||||||
#ifdef SERCOM6
|
|
||||||
case 6:
|
|
||||||
hri_mclk_set_APBDMASK_SERCOM6_bit(MCLK);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef SERCOM7
|
|
||||||
case 7:
|
|
||||||
hri_mclk_set_APBDMASK_SERCOM7_bit(MCLK);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Figure out the DOPO value given the chosen clock pad and mosi pad.
|
|
||||||
// Return an out-of-range value (255) if the combination is not permitted
|
|
||||||
// The ASF4 config files list this, but the SAMD51 datasheet
|
|
||||||
// says 0x1 and 0x3 are reserved, so don't allow pad 3 SCK.
|
|
||||||
// Transmit Data Pinout
|
|
||||||
// <0x0=>PAD[0,1]_DO_SCK
|
|
||||||
// <0x1=>PAD[2,3]_DO_SCK [RESERVED]
|
|
||||||
// <0x2=>PAD[3,1]_DO_SCK
|
|
||||||
// <0x3=>PAD[0,3]_DO_SCK [RESERVED]
|
|
||||||
uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) {
|
|
||||||
if (clock_pad != 1) {
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
if (mosi_pad == 0) {
|
|
||||||
return 0x1;
|
|
||||||
}
|
|
||||||
if (mosi_pad == 3) {
|
|
||||||
return 0x2;
|
|
||||||
}
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) {
|
|
||||||
return clock_pad == 1;
|
|
||||||
}
|
|
@ -1,137 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "peripherals/timers.h"
|
|
||||||
|
|
||||||
#include "hri/hri_gclk_d51.h"
|
|
||||||
|
|
||||||
const uint8_t tcc_cc_num[5] = {6, 4, 3, 2, 2};
|
|
||||||
const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC0_GCLK_ID,
|
|
||||||
TC1_GCLK_ID,
|
|
||||||
TC2_GCLK_ID,
|
|
||||||
TC3_GCLK_ID,
|
|
||||||
#ifdef TC4_GCLK_ID
|
|
||||||
TC4_GCLK_ID,
|
|
||||||
#endif
|
|
||||||
#ifdef TC5_GCLK_ID
|
|
||||||
TC5_GCLK_ID,
|
|
||||||
#endif
|
|
||||||
#ifdef TC6_GCLK_ID
|
|
||||||
TC6_GCLK_ID,
|
|
||||||
#endif
|
|
||||||
#ifdef TC7_GCLK_ID
|
|
||||||
TC7_GCLK_ID,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
const uint8_t tcc_gclk_ids[TCC_INST_NUM] = {TCC0_GCLK_ID,
|
|
||||||
TCC1_GCLK_ID,
|
|
||||||
TCC2_GCLK_ID,
|
|
||||||
#ifdef TCC3_GCLK_ID
|
|
||||||
TCC3_GCLK_ID,
|
|
||||||
#endif
|
|
||||||
#ifdef TCC4_GCLK_ID
|
|
||||||
TCC4_GCLK_ID
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
|
|
||||||
uint8_t gclk_id;
|
|
||||||
if (is_tc) {
|
|
||||||
gclk_id = tc_gclk_ids[index];
|
|
||||||
} else {
|
|
||||||
gclk_id = tcc_gclk_ids[index];
|
|
||||||
}
|
|
||||||
// Turn on the clocks for the peripherals.
|
|
||||||
if (is_tc) {
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC2;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC3;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC4;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC5;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
MCLK->APBDMASK.reg |= MCLK_APBDMASK_TC6;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
MCLK->APBDMASK.reg |= MCLK_APBDMASK_TC7;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC2;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC3;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
MCLK->APBDMASK.reg |= MCLK_APBDMASK_TCC4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(tannewt): TC4-TC7 can only have 100mhz inputs.
|
|
||||||
|
|
||||||
hri_gclk_write_PCHCTRL_reg(GCLK, gclk_id,
|
|
||||||
gclk_index | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
void tc_set_enable(Tc* tc, bool enable) {
|
|
||||||
tc->COUNT16.CTRLA.bit.ENABLE = enable;
|
|
||||||
while (tc->COUNT16.SYNCBUSY.bit.ENABLE != 0) {
|
|
||||||
/* Wait for sync */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tc_wait_for_sync(Tc* tc) {
|
|
||||||
while (tc->COUNT16.SYNCBUSY.reg != 0) {}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "peripherals/sercom.h"
|
|
||||||
|
|
||||||
#include "hpl_sercom_config.h"
|
|
||||||
|
|
||||||
// Routines that are the same across all samd variants.
|
|
||||||
|
|
||||||
|
|
||||||
// Convert frequency to clock-speed-dependent value. Return 255 if > 255.
|
|
||||||
uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate) {
|
|
||||||
uint32_t baud_reg_value = (uint32_t) (((float) PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY /
|
|
||||||
(2 * baudrate)) - 0.5f);
|
|
||||||
return (uint8_t) (baud_reg_value > 255 ? 255 : baud_reg_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert BAUD reg value back to a frequency.
|
|
||||||
uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value) {
|
|
||||||
return PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY / (2 * (baud_reg_value + 1));
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python 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_PERIPHERALS_SPI_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "mpconfigport.h"
|
|
||||||
|
|
||||||
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
|
|
||||||
uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
|
|
||||||
uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate);
|
|
||||||
uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value);
|
|
||||||
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
|
|
||||||
|
|
||||||
Sercom* sercom_insts[SERCOM_INST_NUM];
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H
|
|
@ -1,147 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "timers.h"
|
|
||||||
|
|
||||||
#include "common-hal/pulseio/PulseOut.h"
|
|
||||||
|
|
||||||
const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024};
|
|
||||||
|
|
||||||
Tc* const tc_insts[TC_INST_NUM] = TC_INSTS;
|
|
||||||
Tcc* const tcc_insts[TCC_INST_NUM] = TCC_INSTS;
|
|
||||||
|
|
||||||
IRQn_Type const tc_irq[TC_INST_NUM] = {
|
|
||||||
#ifdef TC0
|
|
||||||
TC0_IRQn,
|
|
||||||
#endif
|
|
||||||
#ifdef TC1
|
|
||||||
TC1_IRQn,
|
|
||||||
#endif
|
|
||||||
#ifdef TC2
|
|
||||||
TC2_IRQn,
|
|
||||||
#endif
|
|
||||||
#ifdef TC3
|
|
||||||
TC3_IRQn,
|
|
||||||
#endif
|
|
||||||
#ifdef TC4
|
|
||||||
TC4_IRQn,
|
|
||||||
#endif
|
|
||||||
#ifdef TC5
|
|
||||||
TC5_IRQn,
|
|
||||||
#endif
|
|
||||||
#ifdef TC6
|
|
||||||
TC6_IRQn,
|
|
||||||
#endif
|
|
||||||
#ifdef TC7
|
|
||||||
TC7_IRQn,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
void tc_enable_interrupts(uint8_t tc_index) {
|
|
||||||
NVIC_DisableIRQ(tc_irq[tc_index]);
|
|
||||||
NVIC_ClearPendingIRQ(tc_irq[tc_index]);
|
|
||||||
NVIC_EnableIRQ(tc_irq[tc_index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tc_disable_interrupts(uint8_t tc_index) {
|
|
||||||
NVIC_DisableIRQ(tc_irq[tc_index]);
|
|
||||||
NVIC_ClearPendingIRQ(tc_irq[tc_index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tcc_set_enable(Tcc* tcc, bool enable) {
|
|
||||||
tcc->CTRLA.bit.ENABLE = enable;
|
|
||||||
while (tcc->SYNCBUSY.bit.ENABLE != 0) {
|
|
||||||
/* Wait for sync */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tc_reset(Tc* tc) {
|
|
||||||
tc->COUNT16.CTRLA.bit.SWRST = 1;
|
|
||||||
while (tc->COUNT16.CTRLA.bit.SWRST == 1) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void shared_timer_handler(bool is_tc, uint8_t index) {
|
|
||||||
// Add calls to interrupt handlers for specific functionality here.
|
|
||||||
if (is_tc) {
|
|
||||||
pulseout_interrupt_handler(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SAMD51
|
|
||||||
#define TC_OFFSET 0
|
|
||||||
#endif
|
|
||||||
#ifdef SAMD21
|
|
||||||
#define TC_OFFSET 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void TCC0_Handler(void) {
|
|
||||||
shared_timer_handler(false, 0);
|
|
||||||
}
|
|
||||||
void TCC1_Handler(void) {
|
|
||||||
shared_timer_handler(false, 1);
|
|
||||||
}
|
|
||||||
void TCC2_Handler(void) {
|
|
||||||
shared_timer_handler(false, 2);
|
|
||||||
}
|
|
||||||
// TC0 - TC2 only exist on the SAMD51
|
|
||||||
#ifdef TC0
|
|
||||||
void TC0_Handler(void) {
|
|
||||||
shared_timer_handler(true, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef TC1
|
|
||||||
void TC1_Handler(void) {
|
|
||||||
shared_timer_handler(true, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef TC2
|
|
||||||
void TC2_Handler(void) {
|
|
||||||
shared_timer_handler(true, 2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void TC3_Handler(void) {
|
|
||||||
shared_timer_handler(true, 3 - TC_OFFSET);
|
|
||||||
}
|
|
||||||
void TC4_Handler(void) {
|
|
||||||
shared_timer_handler(true, 4 - TC_OFFSET);
|
|
||||||
}
|
|
||||||
void TC5_Handler(void) {
|
|
||||||
shared_timer_handler(true, 5 - TC_OFFSET);
|
|
||||||
}
|
|
||||||
#ifdef TC6
|
|
||||||
void TC6_Handler(void) {
|
|
||||||
shared_timer_handler(true, 6 - TC_OFFSET);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef TC7
|
|
||||||
void TC7_Handler(void) {
|
|
||||||
shared_timer_handler(true, 7 - TC_OFFSET);
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 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_TIMERS_H
|
|
||||||
#define MICROPY_INCLUDED_ATMEL_SAMD_TIMERS_H
|
|
||||||
|
|
||||||
#include "include/sam.h"
|
|
||||||
|
|
||||||
const uint16_t prescaler[8];
|
|
||||||
|
|
||||||
#ifdef SAMD21
|
|
||||||
const uint8_t tcc_cc_num[3];
|
|
||||||
const uint8_t tc_gclk_ids[TC_INST_NUM];
|
|
||||||
const uint8_t tcc_gclk_ids[3];
|
|
||||||
#endif
|
|
||||||
#ifdef SAMD51
|
|
||||||
const uint8_t tcc_cc_num[5];
|
|
||||||
const uint8_t tc_gclk_ids[TC_INST_NUM];
|
|
||||||
const uint8_t tcc_gclk_ids[TCC_INST_NUM];
|
|
||||||
#endif
|
|
||||||
Tc* const tc_insts[TC_INST_NUM];
|
|
||||||
Tcc* const tcc_insts[TCC_INST_NUM];
|
|
||||||
|
|
||||||
void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index);
|
|
||||||
void tc_set_enable(Tc* tc, bool enable);
|
|
||||||
void tcc_set_enable(Tcc* tcc, bool enable);
|
|
||||||
void tc_wait_for_sync(Tc* tc);
|
|
||||||
void tc_reset(Tc* tc);
|
|
||||||
|
|
||||||
void tc_enable_interrupts(uint8_t tc_index);
|
|
||||||
void tc_disable_interrupts(uint8_t tc_index);
|
|
||||||
|
|
||||||
// Handlers
|
|
||||||
void TCC0_Handler(void);
|
|
||||||
void TCC1_Handler(void);
|
|
||||||
void TCC2_Handler(void);
|
|
||||||
void TC3_Handler(void);
|
|
||||||
void TC4_Handler(void);
|
|
||||||
void TC5_Handler(void);
|
|
||||||
#ifdef TC6
|
|
||||||
void TC6_Handler(void);
|
|
||||||
#endif
|
|
||||||
#ifdef TC7
|
|
||||||
void TC7_Handler(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_TIMERS_H
|
|
@ -55,11 +55,11 @@
|
|||||||
#include "common-hal/rtc/RTC.h"
|
#include "common-hal/rtc/RTC.h"
|
||||||
#include "common-hal/touchio/TouchIn.h"
|
#include "common-hal/touchio/TouchIn.h"
|
||||||
#include "common-hal/usb_hid/Device.h"
|
#include "common-hal/usb_hid/Device.h"
|
||||||
#include "peripherals/cache.h"
|
#include "samd/cache.h"
|
||||||
#include "peripherals/clocks.h"
|
#include "samd/clocks.h"
|
||||||
#include "peripherals/events.h"
|
#include "samd/events.h"
|
||||||
#include "peripherals/external_interrupts.h"
|
#include "samd/external_interrupts.h"
|
||||||
#include "peripherals/dma.h"
|
#include "samd/dma.h"
|
||||||
#include "shared-bindings/rtc/__init__.h"
|
#include "shared-bindings/rtc/__init__.h"
|
||||||
#include "tick.h"
|
#include "tick.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
@ -38,18 +38,11 @@ extern const mcu_pin_obj_t pin_MTMS;
|
|||||||
extern const mcu_pin_obj_t pin_MTCK;
|
extern const mcu_pin_obj_t pin_MTCK;
|
||||||
extern const mcu_pin_obj_t pin_MTDI;
|
extern const mcu_pin_obj_t pin_MTDI;
|
||||||
|
|
||||||
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
void busio_spi_init_gpio(uint8_t sysclk_as_spiclk, const mcu_pin_obj_t * clock,
|
||||||
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
|
const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) {
|
||||||
const mcu_pin_obj_t * miso) {
|
|
||||||
if (clock != &pin_MTMS || !((mosi == &pin_MTCK && miso == MP_OBJ_TO_PTR(mp_const_none)) ||
|
|
||||||
(mosi == MP_OBJ_TO_PTR(mp_const_none) && miso == &pin_MTDI) ||
|
|
||||||
(mosi == &pin_MTCK && miso == &pin_MTDI))) {
|
|
||||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
|
||||||
"Pins not valid for SPI"));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t clock_div_flag = 0;
|
uint32_t clock_div_flag = 0;
|
||||||
if (SPI_CLK_USE_DIV) {
|
if (sysclk_as_spiclk) {
|
||||||
clock_div_flag = 0x0001;
|
clock_div_flag = 0x0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +58,23 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
|||||||
}
|
}
|
||||||
// GPIO14 is HSPI CLK pin (Clock)
|
// GPIO14 is HSPI CLK pin (Clock)
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||||
|
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
|
||||||
|
const mcu_pin_obj_t * miso) {
|
||||||
|
if (clock != &pin_MTMS || !((mosi == &pin_MTCK && miso == MP_OBJ_TO_PTR(mp_const_none)) ||
|
||||||
|
(mosi == MP_OBJ_TO_PTR(mp_const_none) && miso == &pin_MTDI) ||
|
||||||
|
(mosi == &pin_MTCK && miso == &pin_MTDI))) {
|
||||||
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||||
|
"Pins not valid for SPI"));
|
||||||
|
}
|
||||||
|
|
||||||
|
busio_spi_init_gpio(SPI_CLK_USE_DIV, clock, mosi, miso);
|
||||||
|
self->clock = clock;
|
||||||
|
self->mosi = mosi;
|
||||||
|
self->miso = miso;
|
||||||
|
|
||||||
spi_clock(HSPI, SPI_CLK_PREDIV, SPI_CLK_CNTDIV);
|
spi_clock(HSPI, SPI_CLK_PREDIV, SPI_CLK_CNTDIV);
|
||||||
self->frequency = SPI_CLK_FREQ;
|
self->frequency = SPI_CLK_FREQ;
|
||||||
@ -106,7 +116,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
|
|||||||
}
|
}
|
||||||
if (baudrate == 80000000L) {
|
if (baudrate == 80000000L) {
|
||||||
// Special case for full speed.
|
// Special case for full speed.
|
||||||
spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV);
|
busio_spi_init_gpio(SPI_CLK_80MHZ_NODIV, self->clock, self->mosi, self->miso);
|
||||||
spi_clock(HSPI, 0, 0);
|
spi_clock(HSPI, 0, 0);
|
||||||
self->frequency = 80000000L;
|
self->frequency = 80000000L;
|
||||||
} else if (baudrate > 40000000L) {
|
} else if (baudrate > 40000000L) {
|
||||||
@ -118,7 +128,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
|
|||||||
if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) {
|
if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
spi_init_gpio(HSPI, SPI_CLK_USE_DIV);
|
busio_spi_init_gpio(SPI_CLK_USE_DIV, self->clock, self->mosi, self->miso);
|
||||||
spi_clock(HSPI, prediv, cntdiv);
|
spi_clock(HSPI, prediv, cntdiv);
|
||||||
self->frequency = 80000000L / (prediv * cntdiv);
|
self->frequency = 80000000L / (prediv * cntdiv);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,9 @@ typedef struct {
|
|||||||
uint32_t frequency;
|
uint32_t frequency;
|
||||||
bool locked;
|
bool locked;
|
||||||
bool deinited;
|
bool deinited;
|
||||||
|
const mcu_pin_obj_t * mosi;
|
||||||
|
const mcu_pin_obj_t * miso;
|
||||||
|
const mcu_pin_obj_t * clock;
|
||||||
} busio_spi_obj_t;
|
} busio_spi_obj_t;
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H
|
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H
|
||||||
|
@ -3,8 +3,8 @@ MCU_VARIANT = nrf52
|
|||||||
MCU_SUB_VARIANT = nrf52832
|
MCU_SUB_VARIANT = nrf52832
|
||||||
SOFTDEV_VERSION ?= 2.0.1
|
SOFTDEV_VERSION ?= 2.0.1
|
||||||
|
|
||||||
LD_FILE = boards/feather52/custom_nrf52832_dfu_app_$(SOFTDEV_VERSION).ld
|
LD_FILE = boards/feather52832/custom_nrf52832_dfu_app_$(SOFTDEV_VERSION).ld
|
||||||
BOOTLOADER_PKG = boards/feather52/bootloader/feather52_bootloader_$(SOFTDEV_VERSION)_s132_single.zip
|
BOOTLOADER_PKG = boards/feather52832/bootloader/feather52_bootloader_$(SOFTDEV_VERSION)_s132_single.zip
|
||||||
|
|
||||||
BOOT_SETTING_ADDR = 0x7F000
|
BOOT_SETTING_ADDR = 0x7F000
|
||||||
NRF_DEFINES += -DNRF52832_XXAA
|
NRF_DEFINES += -DNRF52832_XXAA
|
@ -1,7 +1,7 @@
|
|||||||
MCU_SERIES = m4
|
MCU_SERIES = m4
|
||||||
MCU_VARIANT = nrf52
|
MCU_VARIANT = nrf52
|
||||||
MCU_SUB_VARIANT = nrf52840
|
MCU_SUB_VARIANT = nrf52840
|
||||||
SOFTDEV_VERSION ?= 6.0.0-6.alpha
|
SOFTDEV_VERSION ?= 6.0.0
|
||||||
|
|
||||||
LD_FILE = boards/feather52840/bluefruit_nrf52840_s140_6.0.0.ld
|
LD_FILE = boards/feather52840/bluefruit_nrf52840_s140_6.0.0.ld
|
||||||
BOOT_UART_FILE = boards/feather52840/bootloader/uart/feather52840_bootloader_6.0.0_s140_single
|
BOOT_UART_FILE = boards/feather52840/bootloader/uart/feather52840_bootloader_6.0.0_s140_single
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
GNU linker script for NRF52840 w/ s140 6.0.0-6.alpha SoftDevice
|
GNU linker script for NRF52840 w/ s140 6.0.0 SoftDevice
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Specify the memory areas */
|
/* Specify the memory areas */
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
|
||||||
FLASH_ISR (rx) : ORIGIN = 0x00025000, LENGTH = 0x001000 /* sector 0, 4 KiB */
|
FLASH_ISR (rx) : ORIGIN = 0x00026000, LENGTH = 0x001000 /* sector 0, 4 KiB */
|
||||||
FLASH_TEXT (rx) : ORIGIN = 0x00026000, LENGTH = 0x09A000 /* 616 KiB */
|
FLASH_TEXT (rx) : ORIGIN = 0x00027000, LENGTH = 0x099000 /* 612 KiB */
|
||||||
FLASH_FATFS (r) : ORIGIN = 0x000C0000, LENGTH = 0x040000 /* File system 256 KiB */
|
FLASH_FATFS (r) : ORIGIN = 0x000C0000, LENGTH = 0x040000 /* File system 256 KiB */
|
||||||
RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x03C000 /* 240 KiB */
|
RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x03C000 /* 240 KiB */
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@ MEMORY
|
|||||||
/* produce a link error if there is not this amount of RAM for these sections */
|
/* produce a link error if there is not this amount of RAM for these sections */
|
||||||
_minimum_stack_size = 40K;
|
_minimum_stack_size = 40K;
|
||||||
_minimum_heap_size = 0;
|
_minimum_heap_size = 0;
|
||||||
|
|
||||||
/* top end of the stack */
|
/* top end of the stack */
|
||||||
|
|
||||||
/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
|
/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
|
@ -1,7 +1,7 @@
|
|||||||
MCU_SERIES = m4
|
MCU_SERIES = m4
|
||||||
MCU_VARIANT = nrf52
|
MCU_VARIANT = nrf52
|
||||||
MCU_SUB_VARIANT = nrf52840
|
MCU_SUB_VARIANT = nrf52840
|
||||||
SOFTDEV_VERSION ?= 6.0.0-6.alpha
|
SOFTDEV_VERSION ?= 6.0.0
|
||||||
|
|
||||||
LD_FILE = boards/nrf52840_1M_256k.ld
|
LD_FILE = boards/nrf52840_1M_256k.ld
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
MCU_SERIES = m4
|
MCU_SERIES = m4
|
||||||
MCU_VARIANT = nrf52
|
MCU_VARIANT = nrf52
|
||||||
MCU_SUB_VARIANT = nrf52840
|
MCU_SUB_VARIANT = nrf52840
|
||||||
SOFTDEV_VERSION ?= 6.0.0-6.alpha
|
SOFTDEV_VERSION ?= 6.0.0
|
||||||
|
|
||||||
LD_FILE = boards/nrf52840_1M_256k_s140_$(SOFTDEV_VERSION).ld
|
LD_FILE = boards/nrf52840_1M_256k_s140_$(SOFTDEV_VERSION).ld
|
||||||
|
|
||||||
|
@ -60,6 +60,10 @@
|
|||||||
#define BLE_SLAVE_LATENCY 0
|
#define BLE_SLAVE_LATENCY 0
|
||||||
#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
|
#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
|
||||||
|
|
||||||
|
#ifndef BLE_GAP_ADV_MAX_SIZE
|
||||||
|
#define BLE_GAP_ADV_MAX_SIZE 31
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SD_TEST_OR_ENABLE() \
|
#define SD_TEST_OR_ENABLE() \
|
||||||
if (ble_drv_stack_enabled() == 0) { \
|
if (ble_drv_stack_enabled() == 0) { \
|
||||||
(void)ble_drv_stack_enable(); \
|
(void)ble_drv_stack_enable(); \
|
||||||
@ -90,6 +94,17 @@ static mp_obj_t mp_gattc_disc_service_observer;
|
|||||||
static mp_obj_t mp_gattc_disc_char_observer;
|
static mp_obj_t mp_gattc_disc_char_observer;
|
||||||
static mp_obj_t mp_gattc_char_data_observer;
|
static mp_obj_t mp_gattc_char_data_observer;
|
||||||
|
|
||||||
|
#if (BLUETOOTH_SD == 140)
|
||||||
|
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
|
||||||
|
static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN];
|
||||||
|
|
||||||
|
static ble_data_t m_scan_buffer =
|
||||||
|
{
|
||||||
|
m_scan_buffer_data,
|
||||||
|
BLE_GAP_SCAN_BUFFER_MIN
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "nrf_nvic.h"
|
#include "nrf_nvic.h"
|
||||||
|
|
||||||
nrf_nvic_state_t nrf_nvic_state = {0};
|
nrf_nvic_state_t nrf_nvic_state = {0};
|
||||||
@ -133,7 +148,7 @@ uint32_t ble_drv_stack_enable(void) {
|
|||||||
err_code = sd_nvic_EnableIRQ(SWI2_EGU2_IRQn);
|
err_code = sd_nvic_EnableIRQ(SWI2_EGU2_IRQn);
|
||||||
|
|
||||||
BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code);
|
BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code);
|
||||||
|
|
||||||
// Enable BLE stack.
|
// Enable BLE stack.
|
||||||
#if (BLE_API_VERSION == 2)
|
#if (BLE_API_VERSION == 2)
|
||||||
ble_enable_params_t ble_enable_params;
|
ble_enable_params_t ble_enable_params;
|
||||||
@ -359,12 +374,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
|
|||||||
SD_TEST_OR_ENABLE();
|
SD_TEST_OR_ENABLE();
|
||||||
|
|
||||||
uint8_t byte_pos = 0;
|
uint8_t byte_pos = 0;
|
||||||
|
|
||||||
#if (BLUETOOTH_SD == 140)
|
|
||||||
uint8_t adv_data[BLE_GAP_ADV_SR_MAX_LEN_DEFAULT];
|
|
||||||
#else
|
|
||||||
uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE];
|
uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE];
|
||||||
#endif
|
|
||||||
|
|
||||||
if (p_adv_params->device_name_len > 0) {
|
if (p_adv_params->device_name_len > 0) {
|
||||||
ble_gap_conn_sec_mode_t sec_mode;
|
ble_gap_conn_sec_mode_t sec_mode;
|
||||||
@ -518,11 +528,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) {
|
if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) {
|
||||||
#if (BLUETOOTH_SD == 140)
|
|
||||||
if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_SR_MAX_LEN_DEFAULT) {
|
|
||||||
#else
|
|
||||||
if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) {
|
if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) {
|
||||||
#endif
|
|
||||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||||
"Can not fit data into the advertisment packet."));
|
"Can not fit data into the advertisment packet."));
|
||||||
}
|
}
|
||||||
@ -533,20 +539,14 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
|
|||||||
|
|
||||||
// scan response data not set
|
// scan response data not set
|
||||||
uint32_t err_code;
|
uint32_t err_code;
|
||||||
#if (BLUETOOTH_SD == 140)
|
#if (BLUETOOTH_SD == 132)
|
||||||
const ble_data_t ble_adv_data = {
|
|
||||||
.p_data = adv_data,
|
|
||||||
.len = byte_pos
|
|
||||||
};
|
|
||||||
|
|
||||||
if ((err_code = sd_ble_gap_adv_data_set(BLE_GAP_ADV_SET_HANDLE_DEFAULT, &ble_adv_data, NULL)) != 0) {
|
|
||||||
#else
|
|
||||||
if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) {
|
if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) {
|
||||||
#endif
|
|
||||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||||
"Can not apply advertisment data. status: 0x" HEX2_FMT, (uint16_t)err_code));
|
"Can not apply advertisment data. status: 0x" HEX2_FMT, (uint16_t)err_code));
|
||||||
}
|
}
|
||||||
BLE_DRIVER_LOG("Set Adv data size: " UINT_FMT "\n", byte_pos);
|
BLE_DRIVER_LOG("Set Adv data size: " UINT_FMT "\n", byte_pos);
|
||||||
|
#endif
|
||||||
|
|
||||||
static ble_gap_adv_params_t m_adv_params;
|
static ble_gap_adv_params_t m_adv_params;
|
||||||
|
|
||||||
@ -554,34 +554,44 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
|
|||||||
memset(&m_adv_params, 0, sizeof(m_adv_params));
|
memset(&m_adv_params, 0, sizeof(m_adv_params));
|
||||||
if (p_adv_params->connectable) {
|
if (p_adv_params->connectable) {
|
||||||
#if (BLUETOOTH_SD == 140)
|
#if (BLUETOOTH_SD == 140)
|
||||||
m_adv_params.properties.connectable = 1;
|
m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
|
||||||
m_adv_params.properties.scannable = 1;
|
|
||||||
#else
|
#else
|
||||||
m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
|
m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if (BLUETOOTH_SD == 140)
|
#if (BLUETOOTH_SD == 140)
|
||||||
m_adv_params.properties.connectable = 0;
|
m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
|
||||||
#else
|
#else
|
||||||
m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
|
m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
m_adv_params.p_peer_addr = NULL; // undirected advertisement
|
m_adv_params.p_peer_addr = NULL; // undirected advertisement
|
||||||
m_adv_params.fp = BLE_GAP_ADV_FP_ANY;
|
|
||||||
m_adv_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); // approx 8 ms
|
m_adv_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); // approx 8 ms
|
||||||
#if (BLUETOOTH_SD == 140)
|
#if (BLUETOOTH_SD == 140)
|
||||||
m_adv_params.duration = 0; // infinite advertisment
|
m_adv_params.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
|
||||||
m_adv_params.properties.legacy_pdu = 1;
|
m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
|
||||||
m_adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
|
m_adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
|
||||||
#else
|
#else
|
||||||
|
m_adv_params.fp = BLE_GAP_ADV_FP_ANY;
|
||||||
m_adv_params.timeout = 0; // infinite advertisment
|
m_adv_params.timeout = 0; // infinite advertisment
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ble_drv_advertise_stop();
|
ble_drv_advertise_stop();
|
||||||
|
|
||||||
#if (BLUETOOTH_SD == 140)
|
#if (BLUETOOTH_SD == 140)
|
||||||
err_code = sd_ble_gap_adv_start(BLE_GAP_ADV_SET_HANDLE_DEFAULT, &m_adv_params, BLE_CONN_CFG_TAG_DEFAULT);
|
const ble_gap_adv_data_t ble_gap_adv_data = {
|
||||||
|
.adv_data = {
|
||||||
|
.p_data = adv_data,
|
||||||
|
.len = byte_pos
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params)) != 0) {
|
||||||
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||||
|
"Can not apply advertisment data. status: 0x" HEX2_FMT, (uint16_t)err_code));
|
||||||
|
}
|
||||||
|
err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_DEFAULT);
|
||||||
#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4)
|
#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4)
|
||||||
err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_DEFAULT);
|
err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_DEFAULT);
|
||||||
#else
|
#else
|
||||||
@ -601,7 +611,7 @@ void ble_drv_advertise_stop(void) {
|
|||||||
if (m_adv_in_progress == true) {
|
if (m_adv_in_progress == true) {
|
||||||
uint32_t err_code;
|
uint32_t err_code;
|
||||||
#if (BLUETOOTH_SD == 140)
|
#if (BLUETOOTH_SD == 140)
|
||||||
if ((err_code = sd_ble_gap_adv_stop(BLE_GAP_ADV_SET_HANDLE_DEFAULT)) != 0) {
|
if ((err_code = sd_ble_gap_adv_stop(m_adv_handle)) != 0) {
|
||||||
#else
|
#else
|
||||||
if ((err_code = sd_ble_gap_adv_stop()) != 0) {
|
if ((err_code = sd_ble_gap_adv_stop()) != 0) {
|
||||||
#endif
|
#endif
|
||||||
@ -738,7 +748,6 @@ void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, u
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ble_drv_scan_start(void) {
|
void ble_drv_scan_start(void) {
|
||||||
SD_TEST_OR_ENABLE();
|
SD_TEST_OR_ENABLE();
|
||||||
|
|
||||||
@ -749,16 +758,16 @@ void ble_drv_scan_start(void) {
|
|||||||
scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
|
scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
|
||||||
scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS);
|
scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS);
|
||||||
#if (BLUETOOTH_SD == 140)
|
#if (BLUETOOTH_SD == 140)
|
||||||
scan_params.filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL;
|
scan_params.scan_phys = BLE_GAP_PHY_1MBPS;
|
||||||
scan_params.filter_duplicates = BLE_GAP_SCAN_DUPLICATES_SUPPRESS;
|
|
||||||
scan_params.scan_phy = BLE_GAP_PHY_1MBPS;
|
|
||||||
scan_params.duration = 0; // Infinite
|
|
||||||
#else
|
|
||||||
scan_params.timeout = 0; // Infinite
|
|
||||||
#endif
|
#endif
|
||||||
|
scan_params.timeout = 0; // Infinite
|
||||||
|
|
||||||
uint32_t err_code;
|
uint32_t err_code;
|
||||||
|
#if (BLUETOOTH_SD == 140)
|
||||||
|
if ((err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer)) != 0) {
|
||||||
|
#else
|
||||||
if ((err_code = sd_ble_gap_scan_start(&scan_params)) != 0) {
|
if ((err_code = sd_ble_gap_scan_start(&scan_params)) != 0) {
|
||||||
|
#endif
|
||||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||||
"Can not start scanning. status: 0x" HEX2_FMT, (uint16_t)err_code));
|
"Can not start scanning. status: 0x" HEX2_FMT, (uint16_t)err_code));
|
||||||
}
|
}
|
||||||
@ -775,11 +784,7 @@ void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type) {
|
|||||||
scan_params.active = 1;
|
scan_params.active = 1;
|
||||||
scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
|
scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
|
||||||
scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS);
|
scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS);
|
||||||
#if (BLUETOOTH_SD == 140)
|
|
||||||
scan_params.duration = 0; // Infinite
|
|
||||||
#else
|
|
||||||
scan_params.timeout = 0; // Infinite
|
scan_params.timeout = 0; // Infinite
|
||||||
#endif
|
|
||||||
|
|
||||||
ble_gap_addr_t addr;
|
ble_gap_addr_t addr;
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
@ -962,8 +967,13 @@ static void ble_evt_handler(ble_evt_t * p_ble_evt) {
|
|||||||
.is_scan_resp = p_ble_evt->evt.gap_evt.params.adv_report.scan_rsp,
|
.is_scan_resp = p_ble_evt->evt.gap_evt.params.adv_report.scan_rsp,
|
||||||
#endif
|
#endif
|
||||||
.rssi = p_ble_evt->evt.gap_evt.params.adv_report.rssi,
|
.rssi = p_ble_evt->evt.gap_evt.params.adv_report.rssi,
|
||||||
|
#if (BLUETOOTH_SD == 140)
|
||||||
|
.data_len = p_ble_evt->evt.gap_evt.params.adv_report.data.len,
|
||||||
|
.p_data = p_ble_evt->evt.gap_evt.params.adv_report.data.p_data,
|
||||||
|
#else
|
||||||
.data_len = p_ble_evt->evt.gap_evt.params.adv_report.dlen,
|
.data_len = p_ble_evt->evt.gap_evt.params.adv_report.dlen,
|
||||||
.p_data = p_ble_evt->evt.gap_evt.params.adv_report.data,
|
.p_data = p_ble_evt->evt.gap_evt.params.adv_report.data,
|
||||||
|
#endif
|
||||||
#if (BLUETOOTH_SD == 132)
|
#if (BLUETOOTH_SD == 132)
|
||||||
.adv_type = p_ble_evt->evt.gap_evt.params.adv_report.type
|
.adv_type = p_ble_evt->evt.gap_evt.params.adv_report.type
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
ifeq ($(SD), s132)
|
ifeq ($(SD), s132)
|
||||||
SOFTDEV_VERSION_LONG = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)
|
|
||||||
CFLAGS += -DBLUETOOTH_SD=132
|
CFLAGS += -DBLUETOOTH_SD=132
|
||||||
|
|
||||||
ifeq ($(SOFTDEV_VERSION), 2.0.1)
|
ifeq ($(SOFTDEV_VERSION), 2.0.1)
|
||||||
@ -8,12 +7,6 @@ else ifeq ($(SOFTDEV_VERSION), 5.0.0)
|
|||||||
CFLAGS += -DBLE_API_VERSION=4
|
CFLAGS += -DBLE_API_VERSION=4
|
||||||
endif
|
endif
|
||||||
else ifeq ($(SD), s140)
|
else ifeq ($(SD), s140)
|
||||||
ifeq ($(SOFTDEV_VERSION), 6.0.0-6.alpha)
|
|
||||||
SOFTDEV_VERSION_LONG = $(SD)_$(MCU_SUB_VARIANT)_$(SOFTDEV_VERSION)
|
|
||||||
else
|
|
||||||
SOFTDEV_VERSION_LONG = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS += -DBLUETOOTH_SD=140
|
CFLAGS += -DBLUETOOTH_SD=140
|
||||||
CFLAGS += -DBLE_API_VERSION=4
|
CFLAGS += -DBLE_API_VERSION=4
|
||||||
else
|
else
|
||||||
@ -22,10 +15,10 @@ endif
|
|||||||
|
|
||||||
CFLAGS += -DBLUETOOTH_SD_DEBUG=1
|
CFLAGS += -DBLUETOOTH_SD_DEBUG=1
|
||||||
|
|
||||||
INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SOFTDEV_VERSION_LONG)_API/include
|
INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include
|
||||||
INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SOFTDEV_VERSION_LONG)_API/include/$(MCU_VARIANT)
|
INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT)
|
||||||
|
|
||||||
SOFTDEV_HEX_NAME = $(SOFTDEV_VERSION_LONG)_softdevice.hex
|
SOFTDEV_HEX_NAME = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_softdevice.hex
|
||||||
SOFTDEV_HEX_PATH = drivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)
|
SOFTDEV_HEX_PATH = drivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)
|
||||||
SOFTDEV_HEX = $(SOFTDEV_HEX_PATH)/$(SOFTDEV_HEX_NAME)
|
SOFTDEV_HEX = $(SOFTDEV_HEX_PATH)/$(SOFTDEV_HEX_NAME)
|
||||||
|
|
||||||
|
@ -35,24 +35,6 @@ function download_s132_nrf52_5_0_0
|
|||||||
cd -
|
cd -
|
||||||
}
|
}
|
||||||
|
|
||||||
function download_s140_nrf52_6_0_0_6_alpha
|
|
||||||
{
|
|
||||||
echo ""
|
|
||||||
echo "############################################"
|
|
||||||
echo "### Downloading s140_nrf52_6.0.0-6.alpha ###"
|
|
||||||
echo "############################################"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
mkdir -p "${1}/s140_nrf52_6.0.0-6.alpha"
|
|
||||||
cd "${1}/s140_nrf52_6.0.0-6.alpha"
|
|
||||||
|
|
||||||
wget http://www.nordicsemi.com/eng/nordic/download_resource/60624/18/61756799/116072
|
|
||||||
mv 116072 temp.zip
|
|
||||||
unzip -u temp.zip
|
|
||||||
rm temp.zip
|
|
||||||
cd -
|
|
||||||
}
|
|
||||||
|
|
||||||
function download_s140_nrf52_6_0_0
|
function download_s140_nrf52_6_0_0
|
||||||
{
|
{
|
||||||
echo ""
|
echo ""
|
||||||
@ -64,7 +46,7 @@ function download_s140_nrf52_6_0_0
|
|||||||
mkdir -p "${1}/s140_nrf52_6.0.0"
|
mkdir -p "${1}/s140_nrf52_6.0.0"
|
||||||
cd "${1}/s140_nrf52_6.0.0"
|
cd "${1}/s140_nrf52_6.0.0"
|
||||||
|
|
||||||
wget https://www.nordicsemi.com/eng/nordic/download_resource/60624/19/10544096/116072
|
wget https://www.nordicsemi.com/eng/nordic/download_resource/60624/20/49271410/116072
|
||||||
mv 116072 temp.zip
|
mv 116072 temp.zip
|
||||||
unzip -u temp.zip
|
unzip -u temp.zip
|
||||||
rm temp.zip
|
rm temp.zip
|
||||||
@ -77,7 +59,6 @@ if [ $# -eq 0 ]; then
|
|||||||
echo "No Bluetooth LE stack defined, downloading all."
|
echo "No Bluetooth LE stack defined, downloading all."
|
||||||
download_s132_nrf52_2_0_1 "${SCRIPT_DIR}"
|
download_s132_nrf52_2_0_1 "${SCRIPT_DIR}"
|
||||||
download_s132_nrf52_5_0_0 "${SCRIPT_DIR}"
|
download_s132_nrf52_5_0_0 "${SCRIPT_DIR}"
|
||||||
download_s140_nrf52_6_0_0_6_alpha "${SCRIPT_DIR}"
|
|
||||||
download_s140_nrf52_6_0_0 "${SCRIPT_DIR}"
|
download_s140_nrf52_6_0_0 "${SCRIPT_DIR}"
|
||||||
else
|
else
|
||||||
case $1 in
|
case $1 in
|
||||||
@ -85,10 +66,8 @@ else
|
|||||||
download_s132_nrf52_2_0_1 "${SCRIPT_DIR}" ;;
|
download_s132_nrf52_2_0_1 "${SCRIPT_DIR}" ;;
|
||||||
"s132_nrf52_5_0_0" )
|
"s132_nrf52_5_0_0" )
|
||||||
download_s132_nrf52_5_0_0 "${SCRIPT_DIR}" ;;
|
download_s132_nrf52_5_0_0 "${SCRIPT_DIR}" ;;
|
||||||
"s140_nrf52_6_0_0_6_alpha" )
|
|
||||||
download_s140_nrf52_6_0_0_6_alpha "${SCRIPT_DIR}" ;;
|
|
||||||
"s140_nrf52_6_0_0" )
|
"s140_nrf52_6_0_0" )
|
||||||
download_s140_nrf52_6_0_0 "${SCRIPT_DIR}" ;;
|
download_s140_nrf52_6_0_0 "${SCRIPT_DIR}" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ mp_obj_t os_listdir(size_t n_args, const mp_obj_t *args) {
|
|||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
path = mp_obj_str_get_str(args[0]);
|
path = mp_obj_str_get_str(args[0]);
|
||||||
} else {
|
} else {
|
||||||
path = "";
|
path = mp_obj_str_get_str(common_hal_os_getcwd());
|
||||||
}
|
}
|
||||||
return common_hal_os_listdir(path);
|
return common_hal_os_listdir(path);
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ mp_obj_t common_hal_os_listdir(const char* path) {
|
|||||||
iter.base.type = &mp_type_polymorph_iter;
|
iter.base.type = &mp_type_polymorph_iter;
|
||||||
iter.iternext = mp_vfs_ilistdir_it_iternext;
|
iter.iternext = mp_vfs_ilistdir_it_iternext;
|
||||||
iter.cur.vfs = MP_STATE_VM(vfs_mount_table);
|
iter.cur.vfs = MP_STATE_VM(vfs_mount_table);
|
||||||
iter.is_str = mp_obj_get_type(path) == &mp_type_str;
|
iter.is_str = true;
|
||||||
iter.is_iter = false;
|
iter.is_iter = false;
|
||||||
} else {
|
} else {
|
||||||
iter_obj = mp_vfs_proxy_call(vfs, MP_QSTR_ilistdir, 1, &path_out);
|
iter_obj = mp_vfs_proxy_call(vfs, MP_QSTR_ilistdir, 1, &path_out);
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
#include "shared-bindings/os/__init__.h"
|
||||||
#include "shared-bindings/storage/__init__.h"
|
#include "shared-bindings/storage/__init__.h"
|
||||||
|
|
||||||
STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) {
|
||||||
@ -63,8 +64,14 @@ void common_hal_storage_mount(mp_obj_t vfs_obj, const char* mount_path, bool rea
|
|||||||
args[0] = readonly ? mp_const_true : mp_const_false;
|
args[0] = readonly ? mp_const_true : mp_const_false;
|
||||||
args[1] = mp_const_false; // Don't make the file system automatically when mounting.
|
args[1] = mp_const_false; // Don't make the file system automatically when mounting.
|
||||||
|
|
||||||
// call the underlying object to do any mounting operation
|
// Check that there's no file or directory with the same name as the mount point.
|
||||||
mp_vfs_proxy_call(vfs, MP_QSTR_mount, 2, (mp_obj_t*)&args);
|
nlr_buf_t nlr;
|
||||||
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
common_hal_os_stat(mount_path);
|
||||||
|
nlr_pop();
|
||||||
|
// Something with the same name exists.
|
||||||
|
mp_raise_OSError(MP_EEXIST);
|
||||||
|
}
|
||||||
|
|
||||||
// check that the destination mount point is unused
|
// check that the destination mount point is unused
|
||||||
const char *path_out;
|
const char *path_out;
|
||||||
@ -78,6 +85,9 @@ void common_hal_storage_mount(mp_obj_t vfs_obj, const char* mount_path, bool rea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call the underlying object to do any mounting operation
|
||||||
|
mp_vfs_proxy_call(vfs, MP_QSTR_mount, 2, (mp_obj_t*)&args);
|
||||||
|
|
||||||
// Insert the vfs into the mount table by pushing it onto the front of the
|
// Insert the vfs into the mount table by pushing it onto the front of the
|
||||||
// mount table.
|
// mount table.
|
||||||
mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table);
|
mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table);
|
||||||
|
@ -2,7 +2,7 @@ rm -rf ports/atmel-samd/build*
|
|||||||
rm -rf ports/esp8266/build*
|
rm -rf ports/esp8266/build*
|
||||||
rm -rf ports/nrf/build*
|
rm -rf ports/nrf/build*
|
||||||
|
|
||||||
ATMEL_BOARDS="arduino_zero circuitplayground_express circuitplayground_express_crickit feather_m0_basic feather_m0_adalogger itsybitsy_m0_express itsybitsy_m4_express feather_m0_rfm69 feather_m0_rfm9x feather_m0_express feather_m0_express_crickit feather_m4_express metro_m0_express metro_m4_express pirkey_m0 trinket_m0 gemma_m0 feather52 feather_huzzah"
|
ATMEL_BOARDS="arduino_zero circuitplayground_express circuitplayground_express_crickit feather_m0_basic feather_m0_adalogger itsybitsy_m0_express itsybitsy_m4_express feather_m0_rfm69 feather_m0_rfm9x feather_m0_express feather_m0_express_crickit feather_m4_express metro_m0_express metro_m4_express pirkey_m0 trinket_m0 gemma_m0 feather52832 feather_huzzah pca10056"
|
||||||
ROSIE_SETUPS="rosie-ci"
|
ROSIE_SETUPS="rosie-ci"
|
||||||
|
|
||||||
PARALLEL="-j 5"
|
PARALLEL="-j 5"
|
||||||
@ -20,8 +20,11 @@ for board in $boards; do
|
|||||||
if [ $board == "feather_huzzah" ]; then
|
if [ $board == "feather_huzzah" ]; then
|
||||||
make $PARALLEL -C ports/esp8266 BOARD=feather_huzzah
|
make $PARALLEL -C ports/esp8266 BOARD=feather_huzzah
|
||||||
(( exit_status = exit_status || $? ))
|
(( exit_status = exit_status || $? ))
|
||||||
elif [ $board == "feather52" ]; then
|
elif [ $board == "feather52832" ]; then
|
||||||
make $PARALLEL -C ports/nrf BOARD=feather52
|
make $PARALLEL -C ports/nrf BOARD=feather52832
|
||||||
|
(( exit_status = exit_status || $? ))
|
||||||
|
elif [ $board == "pca10056" ]; then
|
||||||
|
make $PARALLEL -C ports/nrf BOARD=pca10056 SD=s140
|
||||||
(( exit_status = exit_status || $? ))
|
(( exit_status = exit_status || $? ))
|
||||||
else
|
else
|
||||||
make $PARALLEL -C ports/atmel-samd BOARD=$board
|
make $PARALLEL -C ports/atmel-samd BOARD=$board
|
||||||
@ -50,10 +53,14 @@ for board in $boards; do
|
|||||||
cp ports/esp8266/build/firmware-combined.bin bin/$board/adafruit-circuitpython-$board-$version.bin
|
cp ports/esp8266/build/firmware-combined.bin bin/$board/adafruit-circuitpython-$board-$version.bin
|
||||||
(( exit_status = exit_status || $? ))
|
(( exit_status = exit_status || $? ))
|
||||||
extension=bin
|
extension=bin
|
||||||
elif [ $board == "feather52" ]; then
|
elif [ $board == "feather52832" ]; then
|
||||||
cp ports/nrf/build-$board-s132/firmware.bin bin/$board/adafruit-circuitpython-$board-$version.bin
|
cp ports/nrf/build-$board-s132/firmware.bin bin/$board/adafruit-circuitpython-$board-$version.bin
|
||||||
(( exit_status = exit_status || $? ))
|
(( exit_status = exit_status || $? ))
|
||||||
extension=bin
|
extension=bin
|
||||||
|
elif [ $board == "pca10056" ]; then
|
||||||
|
cp ports/nrf/build-$board-s140/firmware.bin bin/$board/adafruit-circuitpython-$board-$version.bin
|
||||||
|
(( exit_status = exit_status || $? ))
|
||||||
|
extension=bin
|
||||||
else
|
else
|
||||||
cp ports/atmel-samd/build-$board/firmware.bin bin/$board/adafruit-circuitpython-$board-$version.bin
|
cp ports/atmel-samd/build-$board/firmware.bin bin/$board/adafruit-circuitpython-$board-$version.bin
|
||||||
(( exit_status = exit_status || $? ))
|
(( exit_status = exit_status || $? ))
|
||||||
|
Loading…
Reference in New Issue
Block a user