Split out the peripherals library in preparation of sharing with MakeCode.

This commit is contained in:
Scott Shawcroft 2018-06-15 16:16:21 -07:00
parent 5ce1d71206
commit a5e03b76a6
64 changed files with 67 additions and 5952 deletions

3
.gitmodules vendored
View File

@ -67,3 +67,6 @@
[submodule "frozen/Adafruit_CircuitPython_DotStar"]
path = frozen/Adafruit_CircuitPython_DotStar
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

View File

@ -55,6 +55,7 @@ INC += -I. \
-Iasf4_conf/$(CHIP_FAMILY) \
-Iboards/$(BOARD) \
-Iboards/ \
-Iperipherals/ \
-Ifreetouch \
-I$(BUILD)
@ -248,21 +249,21 @@ SRC_C = \
flash_api.c \
mphalport.c \
reset.c \
peripherals/clocks.c \
peripherals/dma.c \
peripherals/events.c \
peripherals/external_interrupts.c \
peripherals/sercom.c \
peripherals/timers.c \
peripherals/$(CHIP_FAMILY)/adc.c \
peripherals/$(CHIP_FAMILY)/cache.c \
peripherals/$(CHIP_FAMILY)/clocks.c \
peripherals/$(CHIP_FAMILY)/dma.c \
peripherals/$(CHIP_FAMILY)/events.c \
peripherals/$(CHIP_FAMILY)/external_interrupts.c \
peripherals/$(CHIP_FAMILY)/pins.c \
peripherals/$(CHIP_FAMILY)/sercom.c \
peripherals/$(CHIP_FAMILY)/timers.c \
peripherals/samd/clocks.c \
peripherals/samd/dma.c \
peripherals/samd/events.c \
peripherals/samd/external_interrupts.c \
peripherals/samd/sercom.c \
peripherals/samd/timers.c \
peripherals/samd/$(CHIP_FAMILY)/adc.c \
peripherals/samd/$(CHIP_FAMILY)/cache.c \
peripherals/samd/$(CHIP_FAMILY)/clocks.c \
peripherals/samd/$(CHIP_FAMILY)/dma.c \
peripherals/samd/$(CHIP_FAMILY)/events.c \
peripherals/samd/$(CHIP_FAMILY)/external_interrupts.c \
peripherals/samd/$(CHIP_FAMILY)/pins.c \
peripherals/samd/$(CHIP_FAMILY)/sercom.c \
peripherals/samd/$(CHIP_FAMILY)/timers.c \
tick.c \
usb.c \
usb_mass_storage.c \
@ -402,7 +403,7 @@ ifneq ($(CHIP_VARIANT),SAMD51G18A)
audiobusio/__init__.c \
audiobusio/I2SOut.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

View File

@ -25,9 +25,9 @@
*/
#include "audio_dma.h"
#include "peripherals/clocks.h"
#include "peripherals/events.h"
#include "peripherals/dma.h"
#include "samd/clocks.h"
#include "samd/events.h"
#include "samd/dma.h"
#include "shared-bindings/audioio/RawSample.h"
#include "shared-bindings/audioio/WaveFile.h"

View File

@ -25,7 +25,7 @@
*/
#include "bindings/samd/Clock.h"
#include "peripherals/clocks.h"
#include "samd/clocks.h"
#include "py/obj.h"
#include "py/objproperty.h"
#include "py/runtime.h"

View File

@ -30,7 +30,7 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "mpconfigboard.h"
#include "peripherals/pins.h"
#include "samd/pins.h"
#include "py/runtime.h"
#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)

View File

@ -34,7 +34,7 @@
#include "py/binary.h"
#include "py/mphal.h"
#include "peripherals/adc.h"
#include "samd/adc.h"
#include "shared-bindings/analogio/AnalogIn.h"
#include "atmel_start_pins.h"

View File

@ -45,12 +45,12 @@
#include "hpl/pm/hpl_pm_base.h"
#endif
#include "peripherals/clocks.h"
#include "peripherals/dma.h"
#include "peripherals/events.h"
#include "peripherals/i2s.h"
#include "peripherals/pins.h"
#include "peripherals/timers.h"
#include "samd/clocks.h"
#include "samd/dma.h"
#include "samd/events.h"
#include "samd/i2s.h"
#include "samd/pins.h"
#include "samd/timers.h"
#include "audio_dma.h"

View File

@ -41,11 +41,11 @@
#include "hal/include/hal_gpio.h"
#include "hal/utils/include/utils.h"
#include "peripherals/clocks.h"
#include "peripherals/events.h"
#include "peripherals/i2s.h"
#include "peripherals/pins.h"
#include "peripherals/dma.h"
#include "samd/clocks.h"
#include "samd/events.h"
#include "samd/i2s.h"
#include "samd/pins.h"
#include "samd/dma.h"
#include "audio_dma.h"
#include "tick.h"

View File

@ -46,10 +46,10 @@
#include "audio_dma.h"
#include "peripherals/dma.h"
#include "peripherals/events.h"
#include "peripherals/pins.h"
#include "peripherals/timers.h"
#include "samd/dma.h"
#include "samd/events.h"
#include "samd/pins.h"
#include "samd/timers.h"
void audioout_reset(void) {
}

View File

@ -32,7 +32,7 @@
#include "hal/include/hal_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"

View File

@ -36,8 +36,8 @@
#include "hal/include/hpl_spi_m_sync.h"
#include "supervisor/shared/rgb_led_status.h"
#include "peripherals/dma.h"
#include "peripherals/sercom.h"
#include "samd/dma.h"
#include "samd/sercom.h"
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,

View File

@ -42,7 +42,7 @@
#include "hal/include/hal_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.
// See comment below re usart_async_register_callback()

View File

@ -29,7 +29,7 @@
#include "atmel_start_pins.h"
#include "hal/include/hal_gpio.h"
#include "peripherals/pins.h"
#include "samd/pins.h"
#include "supervisor/shared/rgb_led_status.h"
#ifdef MICROPY_HW_NEOPIXEL

View File

@ -81,6 +81,6 @@ void reset_all_pins(void);
void reset_pin(uint8_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

View File

@ -63,7 +63,7 @@
#include "common-hal/microcontroller/Processor.h"
#include "peripherals/adc.h"
#include "samd/adc.h"
#include "peripheral_clk_config.h"

View File

@ -34,9 +34,9 @@
#include "atmel_start_pins.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

View File

@ -35,8 +35,8 @@
#include "mpconfigport.h"
#include "py/gc.h"
#include "py/runtime.h"
#include "peripherals/external_interrupts.h"
#include "peripherals/pins.h"
#include "samd/external_interrupts.h"
#include "samd/pins.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/pulseio/PulseIn.h"

View File

@ -31,8 +31,8 @@
#include "hal/include/hal_gpio.h"
#include "mpconfigport.h"
#include "peripherals/pins.h"
#include "peripherals/timers.h"
#include "samd/pins.h"
#include "samd/timers.h"
#include "py/gc.h"
#include "py/runtime.h"
#include "shared-bindings/pulseio/PulseOut.h"

View File

@ -28,7 +28,7 @@
#include "atmel_start_pins.h"
#include "peripherals/external_interrupts.h"
#include "samd/external_interrupts.h"
#include "py/runtime.h"
void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self,

View File

@ -37,8 +37,8 @@
#include "hpl/pm/hpl_pm_base.h"
#endif
#include "peripherals/clocks.h"
#include "peripherals/pins.h"
#include "samd/clocks.h"
#include "samd/pins.h"
#include "tick.h"
#include "adafruit_ptc.h"

View File

@ -32,8 +32,8 @@
#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL
#include "external_flash/common_commands.h"
#include "peripherals/cache.h"
#include "peripherals/dma.h"
#include "samd/cache.h"
#include "samd/dma.h"
#include "atmel_start_pins.h"
#include "hal_gpio.h"

View File

@ -29,7 +29,7 @@
#include <string.h>
#include "external_flash/common_commands.h"
#include "peripherals/sercom.h"
#include "samd/sercom.h"
#include "py/mpconfig.h"
#include "hal_gpio.h"

View File

@ -318,7 +318,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
#define MP_STATE_PORT MP_STATE_VM
#include "peripherals/dma.h"
#include "peripherals/samd/dma.h"
#define MICROPY_PORT_ROOT_POINTERS \
const char *readline_hist[8]; \

@ -0,0 +1 @@
Subproject commit 5b18f0a58a620fc11b630438d84b2b374ad1188b

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -55,11 +55,11 @@
#include "common-hal/rtc/RTC.h"
#include "common-hal/touchio/TouchIn.h"
#include "common-hal/usb_hid/Device.h"
#include "peripherals/cache.h"
#include "peripherals/clocks.h"
#include "peripherals/events.h"
#include "peripherals/external_interrupts.h"
#include "peripherals/dma.h"
#include "samd/cache.h"
#include "samd/clocks.h"
#include "samd/events.h"
#include "samd/external_interrupts.h"
#include "samd/dma.h"
#include "shared-bindings/rtc/__init__.h"
#include "tick.h"
#include "usb.h"