Compare commits
17 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e4161d7d6d | |||
|
|
53e9084696 | ||
|
|
6b531fc923 | ||
|
|
af5d3eafc4 | ||
|
|
bfbc88fd6b | ||
|
|
df39529b42 | ||
| f528240c2a | |||
|
|
e363863910 | ||
|
|
f9cff25530 | ||
|
|
b89811f22a | ||
| 5ca3a8a02b | |||
| 28ad937da2 | |||
| 168f636785 | |||
|
|
4c0deecf88 | ||
|
|
bb26a4145c | ||
|
|
2ba5b20ba7 | ||
| 7c1c7e3195 |
22 changed files with 165 additions and 394 deletions
|
|
@ -31,15 +31,17 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "include/sam.h"
|
||||
#include "mpconfigboard.h" // for BOARD_HAS_CRYSTAL
|
||||
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
#define CLOCK_48MHZ GCLK_GENCTRL_SRC_DFLL_Val
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
#define CLOCK_48MHZ GCLK_GENCTRL_SRC_DFLL48M_Val
|
||||
#endif
|
||||
|
||||
// Pass to clock_init() if fine calibration not known.
|
||||
#define DEFAULT_DFLL48M_FINE_CALIBRATION 512
|
||||
|
||||
#define CORE_GCLK 0
|
||||
|
||||
uint8_t find_free_gclk(uint16_t divisor);
|
||||
|
|
@ -54,15 +56,7 @@ 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 clock_init(bool has_crystal, uint32_t dfll48m_fine_calibration);
|
||||
void init_dynamic_clocks(void);
|
||||
|
||||
bool clock_get_enabled(uint8_t type, uint8_t index);
|
||||
|
|
@ -70,6 +64,5 @@ bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_i
|
|||
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
|
||||
|
|
|
|||
57
samd/dma.c
57
samd/dma.c
|
|
@ -43,14 +43,14 @@ COMPILER_ALIGNED(16) static DmacDescriptor write_back_descriptors[DMA_CHANNEL_CO
|
|||
#define FIRST_SERCOM_RX_TRIGSRC 0x01
|
||||
#define FIRST_SERCOM_TX_TRIGSRC 0x02
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
#define FIRST_SERCOM_RX_TRIGSRC 0x04
|
||||
#define FIRST_SERCOM_TX_TRIGSRC 0x05
|
||||
#endif
|
||||
|
||||
void init_shared_dma(void) {
|
||||
// Turn on the clocks
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
MCLK->AHBMASK.reg |= MCLK_AHBMASK_DMAC;
|
||||
#endif
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ static int32_t shared_dma_transfer(void* peripheral,
|
|||
bool tx_active = false;
|
||||
bool rx_active = false;
|
||||
uint16_t beat_length = length;
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
if (peripheral == QSPI) {
|
||||
// Check input alignment on word boundaries.
|
||||
if ((((uint32_t) buffer_in) & 0x3) != 0 ||
|
||||
|
|
@ -110,7 +110,6 @@ static int32_t shared_dma_transfer(void* peripheral,
|
|||
} 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) {
|
||||
|
|
@ -118,7 +117,7 @@ static int32_t shared_dma_transfer(void* peripheral,
|
|||
rx_active = true;
|
||||
}
|
||||
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -128,7 +127,7 @@ static int32_t shared_dma_transfer(void* peripheral,
|
|||
rx_descriptor->BTCTRL.reg = beat_size | DMAC_BTCTRL_DSTINC;
|
||||
rx_descriptor->BTCNT.reg = beat_length;
|
||||
rx_descriptor->SRCADDR.reg = ((uint32_t) src);
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
if (peripheral == QSPI) {
|
||||
rx_descriptor->SRCADDR.reg = ((uint32_t) src + length);
|
||||
}
|
||||
|
|
@ -155,8 +154,6 @@ static int32_t shared_dma_transfer(void* peripheral,
|
|||
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.
|
||||
|
|
@ -168,23 +165,41 @@ static int32_t shared_dma_transfer(void* peripheral,
|
|||
}
|
||||
|
||||
|
||||
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 (!sercom) {
|
||||
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.
|
||||
#ifdef SAM_D5X_E5X
|
||||
// Sometimes (silicon bug?) this DMA transfer never starts, and another channel sits with
|
||||
// CHSTATUS.reg = 0x3 (BUSY | PENDING). On the other hand, this is a
|
||||
// legitimate state for a DMA channel to be in (apparently), so we can't use that alone as a check.
|
||||
// Instead, let's look at the ACTIVE flag. When DMA is hung, everything in ACTIVE is zeros.
|
||||
bool is_okay = false;
|
||||
for (int i=0; i<10 && !is_okay; i++) {
|
||||
bool complete = true;
|
||||
if (rx_active) {
|
||||
if (DMAC->Channel[SHARED_RX_CHANNEL].CHSTATUS.reg & 0x3)
|
||||
complete = false;
|
||||
}
|
||||
if (tx_active) {
|
||||
if (DMAC->Channel[SHARED_TX_CHANNEL].CHSTATUS.reg & 0x3)
|
||||
complete = false;
|
||||
}
|
||||
is_okay = is_okay || (DMAC->ACTIVE.bit.ABUSY || complete);
|
||||
}
|
||||
if (!is_okay) {
|
||||
for (int i=0; i<AUDIO_DMA_CHANNEL_COUNT; i++) {
|
||||
if(DMAC->Channel[i].CHCTRLA.bit.ENABLE) {
|
||||
DMAC->Channel[i].CHCTRLA.bit.ENABLE = 0;
|
||||
DMAC->Channel[i].CHCTRLA.bit.ENABLE = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// busy-wait for the RX and TX DMAs to either complete or encounter an error
|
||||
if (rx_active) {
|
||||
while ((dma_transfer_status(SHARED_RX_CHANNEL) & 0x3) == 0) {}
|
||||
}
|
||||
|
|
@ -229,7 +244,7 @@ int32_t sercom_dma_read(Sercom* sercom, uint8_t* buffer, uint32_t length, uint8_
|
|||
return shared_dma_transfer(sercom, NULL, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, buffer, length, tx);
|
||||
}
|
||||
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ volatile bool audio_dma_in_use;
|
|||
|
||||
void init_shared_dma(void);
|
||||
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
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
|
||||
|
|
|
|||
|
|
@ -44,14 +44,14 @@ void external_interrupt_handler(uint8_t channel) {
|
|||
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
|
||||
#ifdef SAM_D5X_E5X
|
||||
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
|
||||
#ifdef SAM_D5X_E5X
|
||||
eic_set_enable(true);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ void turn_on_eic_channel(uint8_t eic_channel, uint32_t sense_setting) {
|
|||
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
|
||||
#ifdef SAM_D5X_E5X
|
||||
NVIC_DisableIRQ(EIC_0_IRQn + eic_channel);
|
||||
NVIC_ClearPendingIRQ(EIC_0_IRQn + eic_channel);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ typedef struct {
|
|||
#define NUM_TIMERS_PER_PIN 2
|
||||
#define NUM_ADC_PER_PIN 1
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
#define NUM_TIMERS_PER_PIN 3
|
||||
#define NUM_ADC_PER_PIN 2
|
||||
#endif
|
||||
|
|
@ -73,8 +73,8 @@ typedef struct {
|
|||
#ifdef SAMD21
|
||||
#include "samd/samd21/pins.h"
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#include "samd/samd51/pins.h"
|
||||
#ifdef SAM_D5X_E5X
|
||||
#include "samd/sam_d5x_e5x/pins.h"
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "hal/include/hal_adc_sync.h"
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#include "hri/hri_mclk_d51.h"
|
||||
#include "hri_mclk.h"
|
||||
|
||||
// Do initialization and calibration setup needed for any use of the ADC.
|
||||
// The reference and resolution should be set by the caller.
|
||||
|
|
@ -28,11 +28,6 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -81,13 +76,13 @@ void disable_clock_generator(uint8_t gclk) {
|
|||
|
||||
static void init_clock_source_osculp32k(void) {
|
||||
// Calibration value is loaded at startup
|
||||
OSC32KCTRL->OSCULP32K.bit.EN1K = 1;
|
||||
OSC32KCTRL->OSCULP32K.bit.EN32K = 0;
|
||||
OSC32KCTRL->OSCULP32K.bit.EN1K = 0;
|
||||
OSC32KCTRL->OSCULP32K.bit.EN32K = 1;
|
||||
}
|
||||
|
||||
static void init_clock_source_xosc32k(void) {
|
||||
OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ONDEMAND |
|
||||
OSC32KCTRL_XOSC32K_EN1K |
|
||||
OSC32KCTRL_XOSC32K_EN32K |
|
||||
OSC32KCTRL_XOSC32K_XTALEN |
|
||||
OSC32KCTRL_XOSC32K_ENABLE |
|
||||
OSC32KCTRL_XOSC32K_CGM(1);
|
||||
|
|
@ -103,16 +98,17 @@ static void init_clock_source_dpll0(void)
|
|||
while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY)) {}
|
||||
}
|
||||
|
||||
void clock_init(void) {
|
||||
void clock_init(bool has_crystal, uint32_t dfll48m_fine_calibration) {
|
||||
// DFLL48M is enabled by default
|
||||
// TODO: handle fine calibration data.
|
||||
|
||||
init_clock_source_osculp32k();
|
||||
|
||||
if (board_has_crystal()) {
|
||||
if (has_crystal) {
|
||||
init_clock_source_xosc32k();
|
||||
OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K_Val;
|
||||
OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K_Val;
|
||||
} else {
|
||||
OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K_Val;
|
||||
OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_ULP32K_Val;
|
||||
}
|
||||
|
||||
MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV(1);
|
||||
|
|
@ -121,6 +117,7 @@ void clock_init(void) {
|
|||
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);
|
||||
enable_clock_generator_sync(6, GCLK_GENCTRL_SRC_DFLL_Val, 4, false);
|
||||
|
||||
init_clock_source_dpll0();
|
||||
|
||||
|
|
@ -338,143 +335,3 @@ int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val) {
|
|||
}
|
||||
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);
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "hri/hri_mclk_d51.h"
|
||||
#include "hri_mclk.h"
|
||||
|
||||
void turn_on_event_system(void) {
|
||||
hri_mclk_set_APBBMASK_EVSYS_bit(MCLK);
|
||||
36
samd/sam_d5x_e5x/hri_gclk.h
Normal file
36
samd/sam_d5x_e5x/hri_gclk.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Jeff Epler 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_HRI_GCLK_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_HRI_GCLK_H
|
||||
|
||||
#ifdef SAMD51
|
||||
#include "hri/hri_gclk_d51.h"
|
||||
#else
|
||||
#include "hri/hri_gclk_e54.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
36
samd/sam_d5x_e5x/hri_mclk.h
Normal file
36
samd/sam_d5x_e5x/hri_mclk.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Jeff Epler 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_HRI_MCLK_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_HRI_MCLK_H
|
||||
|
||||
#ifdef SAMD51
|
||||
#include "hri/hri_mclk_d51.h"
|
||||
#else
|
||||
#include "hri/hri_mclk_e54.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "hal/include/hal_adc_sync.h"
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#include "hri/hri_mclk_d51.h"
|
||||
#include "hri_mclk.h"
|
||||
|
||||
// The clock initializer values are rather random, so we need to put them in
|
||||
// tables for lookup. We can't compute them.
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "timer_handler.h"
|
||||
|
||||
#include "hri/hri_gclk_d51.h"
|
||||
#include "hri_gclk.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,
|
||||
|
|
@ -24,32 +24,19 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hal_atomic.h"
|
||||
#include "samd/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();
|
||||
volatile hal_atomic_t atomic;
|
||||
atomic_enter_critical(&atomic);
|
||||
|
||||
// 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();
|
||||
atomic_leave_critical(&atomic);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +122,7 @@ static void init_clock_source_dfll48m_xosc(void) {
|
|||
while (!SYSCTRL->PCLKSR.bit.DFLLLCKC || !SYSCTRL->PCLKSR.bit.DFLLLCKF) {}
|
||||
}
|
||||
|
||||
static void init_clock_source_dfll48m_usb(void) {
|
||||
static void init_clock_source_dfll48m_usb(uint32_t fine_calibration) {
|
||||
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE;
|
||||
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {}
|
||||
SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) |
|
||||
|
|
@ -145,17 +132,8 @@ static void init_clock_source_dfll48m_usb(void) {
|
|||
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_DFLLVAL_FINE(fine_calibration);
|
||||
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS |
|
||||
SYSCTRL_DFLLCTRL_USBCRM |
|
||||
SYSCTRL_DFLLCTRL_MODE |
|
||||
|
|
@ -164,28 +142,28 @@ static void init_clock_source_dfll48m_usb(void) {
|
|||
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
||||
}
|
||||
|
||||
void clock_init(void)
|
||||
void clock_init(bool has_crystal, uint32_t dfll48m_fine_calibration)
|
||||
{
|
||||
init_clock_source_osc8m();
|
||||
if (board_has_crystal()) {
|
||||
if (has_crystal) {
|
||||
init_clock_source_xosc32k();
|
||||
} else {
|
||||
init_clock_source_osc32k();
|
||||
}
|
||||
|
||||
if (board_has_crystal()) {
|
||||
if (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();
|
||||
init_clock_source_dfll48m_usb(dfll48m_fine_calibration);
|
||||
}
|
||||
|
||||
enable_clock_generator(0, GCLK_GENCTRL_SRC_DFLL48M_Val, 1);
|
||||
if (board_has_crystal()) {
|
||||
enable_clock_generator(2, GCLK_GENCTRL_SRC_XOSC32K_Val, 32);
|
||||
if (has_crystal) {
|
||||
enable_clock_generator(2, GCLK_GENCTRL_SRC_XOSC32K_Val, 1);
|
||||
} else {
|
||||
enable_clock_generator(2, GCLK_GENCTRL_SRC_OSC32K_Val, 32);
|
||||
enable_clock_generator(2, GCLK_GENCTRL_SRC_OSC32K_Val, 1);
|
||||
}
|
||||
|
||||
// Do this after all static clock init so that they aren't used dynamically.
|
||||
|
|
@ -193,29 +171,32 @@ void clock_init(void)
|
|||
}
|
||||
|
||||
static bool clk_enabled(uint8_t clk) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
volatile hal_atomic_t atomic;
|
||||
atomic_enter_critical(&atomic);
|
||||
*((uint8_t*) &GCLK->CLKCTRL.reg) = clk;
|
||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
||||
bool enabled = GCLK->CLKCTRL.bit.CLKEN;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
atomic_leave_critical(&atomic);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
static uint8_t clk_get_generator(uint8_t clk) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
volatile hal_atomic_t atomic;
|
||||
atomic_enter_critical(&atomic);
|
||||
*((uint8_t*) &GCLK->CLKCTRL.reg) = clk;
|
||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
||||
uint8_t gen = GCLK->CLKCTRL.bit.GEN;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
atomic_leave_critical(&atomic);
|
||||
return gen;
|
||||
}
|
||||
|
||||
static uint8_t generator_get_source(uint8_t gen) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
volatile hal_atomic_t atomic;
|
||||
atomic_enter_critical(&atomic);
|
||||
*((uint8_t*) &GCLK->GENCTRL.reg) = gen;
|
||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
||||
uint8_t src = GCLK->GENCTRL.bit.SRC;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
atomic_leave_critical(&atomic);
|
||||
return src;
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +276,8 @@ uint32_t clock_get_frequency(uint8_t type, uint8_t index) {
|
|||
|
||||
uint8_t gen = clk_get_generator(index);
|
||||
|
||||
common_hal_mcu_disable_interrupts();
|
||||
volatile hal_atomic_t atomic;
|
||||
atomic_enter_critical(&atomic);
|
||||
*((uint8_t*) &GCLK->GENCTRL.reg) = gen;
|
||||
*((uint8_t*) &GCLK->GENDIV.reg) = gen;
|
||||
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
|
||||
|
|
@ -309,7 +291,7 @@ uint32_t clock_get_frequency(uint8_t type, uint8_t index) {
|
|||
if (!div)
|
||||
div = 1;
|
||||
}
|
||||
common_hal_mcu_enable_interrupts();
|
||||
atomic_leave_critical(&atomic);
|
||||
|
||||
return osc_get_frequency(src) / div;
|
||||
}
|
||||
|
|
@ -364,152 +346,3 @@ int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val) {
|
|||
}
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -496,13 +496,13 @@ PIN(PB00, EXTINT_CHANNEL(0), ADC_INPUT(8), TOUCH(6),
|
|||
#if defined(PIN_PB01) && !defined(IGNORE_PIN_PB01)
|
||||
PIN(PB01, EXTINT_CHANNEL(1), ADC_INPUT(9), TOUCH(7),
|
||||
NO_SERCOM,
|
||||
SERCOM(5, 3)),
|
||||
SERCOM(5, 3),
|
||||
#ifdef TC7
|
||||
TC(7, 1),
|
||||
#else
|
||||
NO_TIMER,
|
||||
#endif
|
||||
NO_TIMER;
|
||||
NO_TIMER);
|
||||
#endif
|
||||
#if defined(PIN_PB02) && !defined(IGNORE_PIN_PB02)
|
||||
PIN(PB02, EXTINT_CHANNEL(2), ADC_INPUT(10), TOUCH(8),
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ void tc_reset(Tc* tc) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef SAMD51
|
||||
#ifdef SAM_D5X_E5X
|
||||
#define TC_OFFSET 0
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
|
|
@ -111,7 +111,7 @@ void TCC1_Handler(void) {
|
|||
void TCC2_Handler(void) {
|
||||
shared_timer_handler(false, 2);
|
||||
}
|
||||
// TC0 - TC2 only exist on the SAMD51
|
||||
// TC0 - TC2 only exist on the SAM_D5X_E5X
|
||||
#ifdef TC0
|
||||
void TC0_Handler(void) {
|
||||
shared_timer_handler(true, 0);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_TIMERS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_TIMERS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "include/sam.h"
|
||||
|
||||
const uint16_t prescaler[8];
|
||||
|
|
@ -35,7 +36,7 @@ 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
|
||||
#ifdef SAM_D5X_E5X
|
||||
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];
|
||||
|
|
|
|||
Loading…
Reference in a new issue